mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-21 18:08:20 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const test = require('node:test');
|
||||
const {
|
||||
auditClusterImageSbom,
|
||||
componentRef,
|
||||
createClusterImageSbom,
|
||||
} = require('../../scripts/ql3-cluster-image-sbom.cjs');
|
||||
|
||||
const root = path.resolve(__dirname, '../..');
|
||||
|
||||
function clone(value) {
|
||||
return JSON.parse(JSON.stringify(value));
|
||||
}
|
||||
|
||||
test('generates the exact reviewed cluster image runtime closure', () => {
|
||||
const document = createClusterImageSbom({ root });
|
||||
const report = auditClusterImageSbom(document, { root });
|
||||
|
||||
assert.deepEqual(report, {
|
||||
image: 'control',
|
||||
root: 'pkg:npm/%40qinglong/cluster-control-image-dependencies@3.0.0-alpha.0',
|
||||
components: 46,
|
||||
externalComponents: 43,
|
||||
internalComponents: 3,
|
||||
dependencyNodes: 47,
|
||||
inventoryVerified: false,
|
||||
});
|
||||
assert.equal(
|
||||
document.components.some((component) => component.name === 'pg-protocol'),
|
||||
true,
|
||||
);
|
||||
assert.equal(
|
||||
document.components.some((component) => component.name === 'typescript'),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test('generates the optional Cluster AI image runtime closure', () => {
|
||||
const document = createClusterImageSbom({ root, image: 'control-ai' });
|
||||
const report = auditClusterImageSbom(document, {
|
||||
root,
|
||||
image: 'control-ai',
|
||||
});
|
||||
|
||||
assert.deepEqual(report, {
|
||||
image: 'control-ai',
|
||||
root: 'pkg:npm/%40qinglong/cluster-control-image-dependencies@3.0.0-alpha.0',
|
||||
components: 47,
|
||||
externalComponents: 43,
|
||||
internalComponents: 4,
|
||||
dependencyNodes: 48,
|
||||
inventoryVerified: false,
|
||||
});
|
||||
assert.equal(
|
||||
document.components.some((component) => component.name === '@qinglong/ai'),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
test('generates the independent reviewed cluster-admin image closure', () => {
|
||||
const document = createClusterImageSbom({ root, image: 'admin' });
|
||||
const report = auditClusterImageSbom(document, {
|
||||
root,
|
||||
image: 'admin',
|
||||
});
|
||||
|
||||
assert.deepEqual(report, {
|
||||
image: 'admin',
|
||||
root: 'pkg:npm/%40qinglong/cluster-admin-image-dependencies@3.0.0-alpha.0',
|
||||
components: 88,
|
||||
externalComponents: 84,
|
||||
internalComponents: 4,
|
||||
dependencyNodes: 89,
|
||||
inventoryVerified: false,
|
||||
});
|
||||
assert.equal(
|
||||
document.components.some(
|
||||
(component) => component.name === '@kubernetes/client-node',
|
||||
),
|
||||
true,
|
||||
);
|
||||
assert.equal(
|
||||
document.components.some(
|
||||
(component) => component.name === '@aws-sdk/client-s3',
|
||||
),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test('generates the AI-excluded local application image closure', () => {
|
||||
const document = createClusterImageSbom({ root, image: 'local' });
|
||||
const report = auditClusterImageSbom(document, {
|
||||
root,
|
||||
image: 'local',
|
||||
});
|
||||
|
||||
assert.deepEqual(report, {
|
||||
image: 'local',
|
||||
root: 'pkg:npm/%40qinglong/local-application-image@3.0.0-alpha.0',
|
||||
components: 10,
|
||||
externalComponents: 2,
|
||||
internalComponents: 8,
|
||||
dependencyNodes: 11,
|
||||
inventoryVerified: false,
|
||||
});
|
||||
assert.deepEqual(
|
||||
document.components
|
||||
.filter((component) =>
|
||||
['@qinglong/ai', 'drizzle-orm', 'typescript'].includes(component.name),
|
||||
)
|
||||
.map((component) => component.name),
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects a control SBOM presented as cluster-admin evidence', () => {
|
||||
const document = createClusterImageSbom({ root });
|
||||
assert.throws(
|
||||
() =>
|
||||
auditClusterImageSbom(document, {
|
||||
root,
|
||||
image: 'admin',
|
||||
}),
|
||||
/selected image profile|image manifest/,
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects widened metadata and root component drift', () => {
|
||||
const widened = createClusterImageSbom({ root });
|
||||
widened.metadata.generatedBy = 'unreviewed';
|
||||
assert.throws(
|
||||
() => auditClusterImageSbom(widened, { root }),
|
||||
/root component/,
|
||||
);
|
||||
|
||||
const drifted = createClusterImageSbom({ root });
|
||||
drifted.metadata.component.purl = 'pkg:npm/unrelated@1.0.0';
|
||||
assert.throws(
|
||||
() => auditClusterImageSbom(drifted, { root }),
|
||||
/root component/,
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects a missing internal dependency edge', () => {
|
||||
const document = createClusterImageSbom({ root });
|
||||
const controlRef = componentRef('@qinglong/cluster-control', '3.0.0-alpha.0');
|
||||
const edge = document.dependencies.find((entry) => entry.ref === controlRef);
|
||||
edge.dependsOn = edge.dependsOn.slice(1);
|
||||
|
||||
assert.throws(
|
||||
() => auditClusterImageSbom(document, { root }),
|
||||
/dependency edges.*reviewed runtime closure/,
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects an unexpected development component', () => {
|
||||
const document = createClusterImageSbom({ root });
|
||||
document.components.push({
|
||||
type: 'library',
|
||||
'bom-ref': componentRef('typescript', '5.9.3'),
|
||||
name: 'typescript',
|
||||
version: '5.9.3',
|
||||
purl: componentRef('typescript', '5.9.3'),
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => auditClusterImageSbom(document, { root }),
|
||||
/development component leaked/,
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects tampered locked component metadata', () => {
|
||||
const document = createClusterImageSbom({ root });
|
||||
const pg = document.components.find((component) => component.name === 'pg');
|
||||
pg.version = '8.21.0';
|
||||
|
||||
assert.throws(
|
||||
() => auditClusterImageSbom(document, { root }),
|
||||
/component metadata differs/,
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects a missing or unreviewed runtime license', () => {
|
||||
const missing = createClusterImageSbom({ root, image: 'local' });
|
||||
delete missing.components[0].licenses;
|
||||
assert.throws(
|
||||
() => auditClusterImageSbom(missing, { root, image: 'local' }),
|
||||
/unreviewed license/,
|
||||
);
|
||||
|
||||
const unreviewed = createClusterImageSbom({ root, image: 'local' });
|
||||
unreviewed.components[0].licenses = [{ license: { id: 'GPL-3.0-only' } }];
|
||||
assert.throws(
|
||||
() => auditClusterImageSbom(unreviewed, { root, image: 'local' }),
|
||||
/unreviewed license/,
|
||||
);
|
||||
});
|
||||
|
||||
test('verifies a bounded package inventory against the SBOM', (t) => {
|
||||
const document = createClusterImageSbom({ root });
|
||||
const temporaryRoot = fs.mkdtempSync(
|
||||
path.join(os.tmpdir(), 'ql3-image-inventory-'),
|
||||
);
|
||||
t.after(() => fs.rmSync(temporaryRoot, { recursive: true, force: true }));
|
||||
|
||||
for (const component of document.components) {
|
||||
const packageDirectory = component.name.startsWith('@')
|
||||
? path.join(temporaryRoot, ...component.name.split('/'))
|
||||
: path.join(temporaryRoot, component.name);
|
||||
fs.mkdirSync(packageDirectory, { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(packageDirectory, 'package.json'),
|
||||
JSON.stringify({
|
||||
name: component.name,
|
||||
version: component.version,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
assert.equal(
|
||||
auditClusterImageSbom(document, {
|
||||
root,
|
||||
inventoryRoot: temporaryRoot,
|
||||
}).inventoryVerified,
|
||||
true,
|
||||
);
|
||||
|
||||
const unexpected = path.join(temporaryRoot, 'unexpected');
|
||||
fs.mkdirSync(unexpected);
|
||||
fs.writeFileSync(
|
||||
path.join(unexpected, 'package.json'),
|
||||
JSON.stringify({ name: 'unexpected', version: '1.0.0' }),
|
||||
);
|
||||
assert.throws(
|
||||
() =>
|
||||
auditClusterImageSbom(clone(document), {
|
||||
root,
|
||||
inventoryRoot: temporaryRoot,
|
||||
}),
|
||||
/runtime image package inventory differs/,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user