mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 19:29:13 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const LOCK_DIRECTORY = 'deploy/kubernetes/ql3-cluster/operators/barman-cloud';
|
||||
const RELEASE_MANIFEST =
|
||||
'https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v0.13.0/manifest.yaml';
|
||||
const RELEASE_MANIFEST_SHA256 =
|
||||
'd2e71e7b06822448f1a421f05781846cfdb9cc621e7ef32eef5e20c5133213b0';
|
||||
const RELEASE_BLOCKERS = Object.freeze([
|
||||
'live-object-store-backup-wal-latest-restore-pitr-evidence',
|
||||
]);
|
||||
const CONTROLLER = Object.freeze({
|
||||
manifestReference: 'ghcr.io/cloudnative-pg/plugin-barman-cloud:v0.13.0',
|
||||
image:
|
||||
'ghcr.io/cloudnative-pg/plugin-barman-cloud:v0.13.0@sha256:71589dbac582333442812b07b31f7ea4d00324a8358aac7ca507dabf9f4b6c96',
|
||||
platforms: Object.freeze({
|
||||
'linux/amd64':
|
||||
'sha256:417449fe4f6f0a56acdeb30e4131930815f2b46b9afeb808059b57aa8b4c2ef5',
|
||||
'linux/arm64':
|
||||
'sha256:de612e3ad8633a198b91ffbea53848407424155daf2183d656490d843a83b100',
|
||||
}),
|
||||
});
|
||||
const SIDECAR = Object.freeze({
|
||||
manifestReference:
|
||||
'ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar:v0.13.0',
|
||||
image:
|
||||
'ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar:v0.13.0@sha256:990361af3319f9e23aafa0f6d7981f99bf1f69b4e6a85cf1bc7d71d6f09bb288',
|
||||
platforms: Object.freeze({
|
||||
'linux/amd64':
|
||||
'sha256:15cb1a01e7c5235eedac2061cab8208e5f7c39dbda292f9c2d4ddaa0c1f211e6',
|
||||
'linux/arm64':
|
||||
'sha256:f53e168e341661cd76334215ead9dfd69f06117685d3232206192cf25218da71',
|
||||
}),
|
||||
});
|
||||
|
||||
function finding(code, detail) {
|
||||
return Object.freeze({ code, detail });
|
||||
}
|
||||
|
||||
function exactJson(actual, expected) {
|
||||
return JSON.stringify(actual) === JSON.stringify(expected);
|
||||
}
|
||||
|
||||
function auditBarmanCloudSupplyChain(options = {}) {
|
||||
const root = path.resolve(options.root ?? path.join(__dirname, '..'));
|
||||
const readFile = options.readFile ?? fs.readFileSync;
|
||||
const readDirectory = options.readDirectory ?? fs.readdirSync;
|
||||
const findings = [];
|
||||
|
||||
try {
|
||||
const directory = path.join(root, LOCK_DIRECTORY);
|
||||
const entries = [...readDirectory(directory)].sort();
|
||||
if (!exactJson(entries, ['plugin-lock.json'])) {
|
||||
findings.push(
|
||||
finding(
|
||||
'QL3_BARMAN_INSTALLER_UNREVIEWED',
|
||||
'the candidate lock directory must not contain an install manifest before the certificate authority and image rewrite are reviewed',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const lock = JSON.parse(
|
||||
readFile(path.join(directory, 'plugin-lock.json'), 'utf8'),
|
||||
);
|
||||
if (
|
||||
lock?.schemaVersion !== 1 ||
|
||||
lock?.observedAt !== '2026-08-03' ||
|
||||
lock?.plugin?.name !== 'barman-cloud.cloudnative-pg.io' ||
|
||||
lock?.plugin?.version !== '0.13.0' ||
|
||||
lock?.compatibility?.cloudNativePg !== '>=1.26.0' ||
|
||||
lock?.compatibility?.reviewedCloudNativePg !== '1.30.0'
|
||||
) {
|
||||
findings.push(
|
||||
finding(
|
||||
'QL3_BARMAN_LOCK_ENVELOPE',
|
||||
'the plugin candidate must stay bound to the reviewed Barman and CloudNativePG versions',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (
|
||||
lock?.plugin?.releaseManifest !== RELEASE_MANIFEST ||
|
||||
lock?.plugin?.releaseManifestSha256 !== RELEASE_MANIFEST_SHA256
|
||||
) {
|
||||
findings.push(
|
||||
finding(
|
||||
'QL3_BARMAN_RELEASE_ASSET',
|
||||
'the official release manifest URL and observed SHA-256 must be exact',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (!exactJson(lock?.plugin?.controller, CONTROLLER)) {
|
||||
findings.push(
|
||||
finding(
|
||||
'QL3_BARMAN_CONTROLLER_IMAGE',
|
||||
'the controller index and native amd64/arm64 manifests must remain digest locked',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (!exactJson(lock?.plugin?.sidecar, SIDECAR)) {
|
||||
findings.push(
|
||||
finding(
|
||||
'QL3_BARMAN_SIDECAR_IMAGE',
|
||||
'the PostgreSQL sidecar index and native amd64/arm64 manifests must remain digest locked',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (
|
||||
lock?.certificateAuthority?.mode !== 'cert-manager' ||
|
||||
lock?.certificateAuthority?.version !== '1.20.3' ||
|
||||
lock?.certificateAuthority?.selectionLock !==
|
||||
'deploy/kubernetes/ql3-cluster/operators/cert-manager/selection-lock.json' ||
|
||||
lock?.certificateAuthority?.releaseManifestUses !==
|
||||
'cert-manager.io/v1' ||
|
||||
!exactJson(lock?.certificateAuthority?.requiredSecrets, [
|
||||
'barman-cloud-client-tls',
|
||||
'barman-cloud-server-tls',
|
||||
]) ||
|
||||
lock?.certificateAuthority?.status !== 'supply-chain-verified'
|
||||
) {
|
||||
findings.push(
|
||||
finding(
|
||||
'QL3_BARMAN_CERTIFICATE_GATE',
|
||||
'the certificate authority dependency must remain supply-chain locked while live readiness fails closed independently',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (
|
||||
lock?.releaseReady !== false ||
|
||||
!exactJson(lock?.releaseBlockers, RELEASE_BLOCKERS)
|
||||
) {
|
||||
findings.push(
|
||||
finding(
|
||||
'QL3_BARMAN_PREMATURE_RELEASE',
|
||||
'the candidate lock cannot become release-ready before certificate supply-chain and live restore evidence exist',
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
findings.push(
|
||||
finding(
|
||||
'QL3_BARMAN_SUPPLY_CHAIN_AUDIT_UNAVAILABLE',
|
||||
error instanceof Error ? error.message : 'unknown audit failure',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
schemaVersion: 1,
|
||||
pluginVersion: '0.13.0',
|
||||
controller: CONTROLLER.image,
|
||||
sidecar: SIDECAR.image,
|
||||
releaseReady: false,
|
||||
releaseBlockers: RELEASE_BLOCKERS,
|
||||
findings: Object.freeze(findings),
|
||||
compatible: findings.length === 0,
|
||||
});
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
const report = auditBarmanCloudSupplyChain();
|
||||
process.stdout.write(`${JSON.stringify(report)}\n`);
|
||||
if (!report.compatible) process.exitCode = 1;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
auditBarmanCloudSupplyChain,
|
||||
};
|
||||
Reference in New Issue
Block a user