PanOS Docs

Reference Implementations

End-to-end implementation blueprints for PanOS-based services, workers, gateways, and release pipelines

Reference Implementations

This document provides practical blueprints you can adapt with minimal changes.

Blueprint 1 — Runtime API Service

Project Structure

runtime-api/
├─ app/
│  ├─ server.js
│  ├─ routes/
│  │  ├─ health.js
│  │  └─ runtime.js
│  ├─ middleware/
│  │  └─ request-id.js
│  └─ lib/
│     ├─ logger.js
│     └─ config.js
└─ package.json

Server Entry

import http from "node:http";
import { randomUUID } from "node:crypto";

function json(res, status, body) {
  res.writeHead(status, { "content-type": "application/json" });
  res.end(JSON.stringify(body));
}

const server = http.createServer((req, res) => {
  const requestId = randomUUID();

  if (req.url === "/health") {
    return json(res, 200, { status: "ok", requestId });
  }

  if (req.url === "/runtime") {
    return json(res, 200, {
      requestId,
      node: process.version,
      pid: process.pid,
      uptimeSec: Math.floor(process.uptime()),
    });
  }

  return json(res, 404, { requestId, error: "not-found" });
});

server.listen(8080, "0.0.0.0", () => {
  console.log("runtime-api-up");
});

Blueprint 2 — Deterministic Batch Processor

Project Structure

batch-processor/
├─ app/
│  ├─ batch.js
│  ├─ parser.js
│  └─ writer.js
└─ data/
   ├─ input.ndjson
   └─ output.json

Batch Entry

import { parseInput } from "./parser.js";
import { writeOutput } from "./writer.js";

const inputPath = process.env.INPUT_PATH ?? "/tmp/input.ndjson";
const outputPath = process.env.OUTPUT_PATH ?? "/tmp/output.json";

const rows = await parseInput(inputPath);
const summary = {
  total: rows.length,
  byKind: rows.reduce((acc, row) => {
    acc[row.kind] = (acc[row.kind] ?? 0) + 1;
    return acc;
  }, {}),
};

await writeOutput(outputPath, summary);
console.log("batch-complete", summary);

Blueprint 3 — Embedded Gateway Runtime

Project Structure

gateway/
├─ app/
│  ├─ main.js
│  ├─ readers/
│  │  ├─ serial.js
│  │  └─ gpio.js
│  ├─ adapters/
│  │  ├─ mqtt.js
│  │  └─ http.js
│  └─ queue/
│     └─ memory-queue.js
└─ config/
   └─ devices.json

Main Loop

import { readFromDevices } from "./readers/serial.js";
import { publishBatch } from "./adapters/http.js";

setInterval(async () => {
  try {
    const samples = await readFromDevices();
    await publishBatch(samples);
    console.log("gateway-cycle-ok", { count: samples.length });
  } catch (error) {
    console.error("gateway-cycle-failed", error);
  }
}, 5000);

Blueprint 4 — Plugin Runtime Host

Plugin Contract

export type PluginContext = {
  env: Record<string, string | undefined>;
  logger: { info(msg: string, data?: unknown): void };
};

export interface PluginModule {
  id: string;
  setup(ctx: PluginContext): Promise<void>;
  execute(input: unknown): Promise<unknown>;
}

Host Loader

import { readdir } from "node:fs/promises";

export async function loadPluginModules(dir) {
  const files = await readdir(dir);
  const modules = [];

  for (const file of files) {
    if (!file.endsWith(".mjs")) continue;
    const mod = await import(`${dir}/${file}`);
    if (mod.default?.id && typeof mod.default.execute === "function") {
      modules.push(mod.default);
    }
  }

  return modules;
}

Blueprint 5 — CI Release Validation

CI Workflow Skeleton

name: panos-release-check

on:
  push:
    branches: [main]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./0-install-deps.sh
      - run: ./1-build.sh
      - run: timeout 80s ./2-run.sh > boot.log 2>&1 || true
      - run: grep -E "PanOS|Shell Ready" boot.log

Contract Assertion Script

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";

const bootLog = await readFile("boot.log", "utf8");
assert.match(bootLog, /Shell Ready/);
assert.match(bootLog, /Linux version/);

console.log("release-contract-ok");

Blueprint 6 — Runtime Config Layering

Layering Strategy

defaults -> file config -> env config -> runtime overrides

Example

const defaults = {
  port: 8080,
  logLevel: "info",
  mode: "production",
};

const env = {
  port: Number(process.env.PORT ?? defaults.port),
  logLevel: process.env.LOG_LEVEL ?? defaults.logLevel,
  mode: process.env.MODE ?? defaults.mode,
};

export const config = { ...defaults, ...env };

Blueprint 7 — Structured Logging Package

Logger Utility

export function log(level, event, data = {}) {
  console.log(
    JSON.stringify({
      ts: new Date().toISOString(),
      level,
      event,
      ...data,
    })
  );
}

Usage

import { log } from "./logger.js";

log("info", "startup", { node: process.version });
log("error", "upstream.timeout", { retries: 3 });

Implementation Readiness Checklist

  • autostart path defined and tested
  • startup behavior idempotent
  • configuration schema validated at boot
  • health endpoint available and versioned
  • logs and metrics are machine-readable
  • failure and retry policies explicitly documented

Next Read

See 15-fumadocs-authoring-guide.mdx to extend this documentation with the same MDX/Fumadocs structure.

On this page