phoenix-deploy-api: OpenAPI, server, systemd install, env example
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
Made-with: Cursor
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
* GET /api/v1/infra/storage — Storage pools (Proxmox or stub)
|
||||
* GET /api/v1/ve/vms — List VMs/CTs (Proxmox or stub)
|
||||
* GET /api/v1/ve/vms/:node/:vmid/status — VM/CT status
|
||||
* GET /api/v1/public-sector/programs — Public-sector / eIDAS program manifest (JSON)
|
||||
* GET /health — Health check
|
||||
*
|
||||
* Env: PORT, GITEA_URL, GITEA_TOKEN, PHOENIX_DEPLOY_SECRET
|
||||
@@ -18,7 +19,7 @@
|
||||
import crypto from 'crypto';
|
||||
import https from 'https';
|
||||
import path from 'path';
|
||||
import { readFileSync } from 'fs';
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import express from 'express';
|
||||
|
||||
@@ -42,6 +43,26 @@ const PHOENIX_WEBHOOK_URL = process.env.PHOENIX_WEBHOOK_URL || '';
|
||||
const PHOENIX_WEBHOOK_SECRET = process.env.PHOENIX_WEBHOOK_SECRET || '';
|
||||
const PARTNER_KEYS = (process.env.PHOENIX_PARTNER_KEYS || '').split(',').map((k) => k.trim()).filter(Boolean);
|
||||
|
||||
/**
|
||||
* Manifest resolution order:
|
||||
* 1) PUBLIC_SECTOR_MANIFEST_PATH (explicit file)
|
||||
* 2) public-sector-program-manifest.json next to server.js (systemd install copies this)
|
||||
* 3) PHOENIX_REPO_ROOT or PROXMOX_REPO_PATH + config/public-sector-program-manifest.json
|
||||
* 4) ../config/... (running from phoenix-deploy-api inside full proxmox clone)
|
||||
*/
|
||||
function resolvePublicSectorManifestPath() {
|
||||
const override = (process.env.PUBLIC_SECTOR_MANIFEST_PATH || '').trim();
|
||||
if (override && existsSync(override)) return override;
|
||||
const bundled = path.join(__dirname, 'public-sector-program-manifest.json');
|
||||
if (existsSync(bundled)) return bundled;
|
||||
const repoRoot = (process.env.PHOENIX_REPO_ROOT || process.env.PROXMOX_REPO_PATH || '').trim().replace(/\/$/, '');
|
||||
if (repoRoot) {
|
||||
const fromRepo = path.join(repoRoot, 'config', 'public-sector-program-manifest.json');
|
||||
if (existsSync(fromRepo)) return fromRepo;
|
||||
}
|
||||
return path.join(__dirname, '..', 'config', 'public-sector-program-manifest.json');
|
||||
}
|
||||
|
||||
const httpsAgent = new https.Agent({ rejectUnauthorized: process.env.PROXMOX_TLS_VERIFY !== '0' });
|
||||
|
||||
async function proxmoxRequest(endpoint, method = 'GET', body = null) {
|
||||
@@ -207,6 +228,28 @@ app.post('/api/deploy', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/v1/public-sector/programs — Program registry for operators / Phoenix UI (non-secret).
|
||||
* Registered before partnerKeyMiddleware so callers do not need X-API-Key.
|
||||
*/
|
||||
app.get('/api/v1/public-sector/programs', (req, res) => {
|
||||
const manifestPath = resolvePublicSectorManifestPath();
|
||||
try {
|
||||
if (!existsSync(manifestPath)) {
|
||||
return res.status(503).json({
|
||||
error: 'Manifest not found',
|
||||
path: manifestPath,
|
||||
hint: 'Set PUBLIC_SECTOR_MANIFEST_PATH or deploy repo with config/public-sector-program-manifest.json next to phoenix-deploy-api/',
|
||||
});
|
||||
}
|
||||
const raw = readFileSync(manifestPath, 'utf8');
|
||||
const data = JSON.parse(raw);
|
||||
res.type('application/json').json(data);
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message, path: manifestPath });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/v1', partnerKeyMiddleware);
|
||||
|
||||
/**
|
||||
@@ -431,5 +474,7 @@ app.listen(PORT, () => {
|
||||
if (!GITEA_TOKEN) console.warn('GITEA_TOKEN not set — commit status updates disabled');
|
||||
if (!hasProxmox) console.warn('PROXMOX_* not set — Infra/VE API returns stub data');
|
||||
if (PHOENIX_WEBHOOK_URL) console.log('Outbound webhook enabled:', PHOENIX_WEBHOOK_URL);
|
||||
if (PARTNER_KEYS.length > 0) console.log('Partner API key auth enabled for /api/v1/*');
|
||||
if (PARTNER_KEYS.length > 0) console.log('Partner API key auth enabled for /api/v1/* (except GET /api/v1/public-sector/programs)');
|
||||
const mpath = resolvePublicSectorManifestPath();
|
||||
console.log(`Public-sector manifest: ${mpath} (${existsSync(mpath) ? 'ok' : 'missing'})`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user