mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const {
|
||||
chmod,
|
||||
copyFile,
|
||||
mkdtemp,
|
||||
readdir,
|
||||
rm,
|
||||
writeFile,
|
||||
} = require('node:fs/promises');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { test } = require('node:test');
|
||||
const {
|
||||
WorkerProcessIdentityError,
|
||||
createWorkerProcessCredentialProvider,
|
||||
} = require('@qinglong/worker-runtime/process-identity');
|
||||
|
||||
const FIXTURES = path.resolve(
|
||||
__dirname,
|
||||
'../../ql3-cluster-control/test/fixtures/mtls',
|
||||
);
|
||||
|
||||
async function fixture(t) {
|
||||
const root = await mkdtemp(path.join(os.tmpdir(), 'ql3-worker-identity-'));
|
||||
t.after(() => rm(root, { recursive: true, force: true }));
|
||||
await chmod(root, 0o700);
|
||||
const privateKeyFile = path.join(root, 'client-key.pem');
|
||||
const certificateChainFile = path.join(root, 'client-cert.pem');
|
||||
const trustAnchorFile = path.join(root, 'ca-cert.pem');
|
||||
const credentialTokenFile = path.join(root, 'credential-token');
|
||||
await Promise.all([
|
||||
copyFile(path.join(FIXTURES, 'client-key.pem'), privateKeyFile),
|
||||
copyFile(path.join(FIXTURES, 'client-cert.pem'), certificateChainFile),
|
||||
copyFile(path.join(FIXTURES, 'ca-cert.pem'), trustAnchorFile),
|
||||
writeFile(
|
||||
credentialTokenFile,
|
||||
`ql3w_worker_primary_${Buffer.alloc(32, 7).toString('base64url')}\n`,
|
||||
),
|
||||
]);
|
||||
await Promise.all([
|
||||
chmod(privateKeyFile, 0o600),
|
||||
chmod(certificateChainFile, 0o444),
|
||||
chmod(trustAnchorFile, 0o444),
|
||||
chmod(credentialTokenFile, 0o600),
|
||||
]);
|
||||
return {
|
||||
root,
|
||||
config: {
|
||||
certificateStoreRoot: path.join(root, 'store'),
|
||||
trustAnchorFile,
|
||||
credentialTokenFile,
|
||||
expectedCredentialId: 'worker_primary',
|
||||
bootstrap: {
|
||||
privateKeyFile,
|
||||
certificateChainFile,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test('bootstraps one durable identity and returns disposable request credentials', async (t) => {
|
||||
const current = await fixture(t);
|
||||
const provider = await createWorkerProcessCredentialProvider(
|
||||
current.config,
|
||||
);
|
||||
const first = await provider.load();
|
||||
assert.match(first.authorization, /^Worker ql3w_worker_primary_/);
|
||||
assert.equal(Buffer.isBuffer(first.privateKeyPem), true);
|
||||
assert.equal(Buffer.isBuffer(first.certificateChainPem), true);
|
||||
assert.equal(first.trustAnchors.length, 1);
|
||||
first.dispose();
|
||||
|
||||
const generations = await readdir(
|
||||
path.join(current.config.certificateStoreRoot, 'generations'),
|
||||
);
|
||||
assert.equal(generations.length, 1);
|
||||
const reloaded = await createWorkerProcessCredentialProvider(
|
||||
current.config,
|
||||
);
|
||||
const afterReload = await reloaded.load();
|
||||
afterReload.dispose();
|
||||
assert.equal(
|
||||
(
|
||||
await readdir(
|
||||
path.join(current.config.certificateStoreRoot, 'generations'),
|
||||
)
|
||||
).length,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
test('fails closed for unsafe bootstrap material or absent active identity', async (t) => {
|
||||
const current = await fixture(t);
|
||||
await chmod(current.config.bootstrap.privateKeyFile, 0o644);
|
||||
await assert.rejects(
|
||||
createWorkerProcessCredentialProvider(current.config),
|
||||
WorkerProcessIdentityError,
|
||||
);
|
||||
await assert.rejects(
|
||||
createWorkerProcessCredentialProvider({
|
||||
certificateStoreRoot: path.join(current.root, 'empty-store'),
|
||||
trustAnchorFile: current.config.trustAnchorFile,
|
||||
credentialTokenFile: current.config.credentialTokenFile,
|
||||
}),
|
||||
WorkerProcessIdentityError,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user