mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): admit plugin secret action jobs
This commit is contained in:
+56
@@ -379,6 +379,62 @@ export class PostgresApprovedActionExecutionRepository
|
||||
}
|
||||
}
|
||||
|
||||
async listReconciliableExecutions(
|
||||
query: Readonly<{
|
||||
nowMs: number;
|
||||
limit: number;
|
||||
actionTypes: readonly string[];
|
||||
}>,
|
||||
): Promise<Readonly<{
|
||||
executions: readonly Readonly<ApprovedActionExecutionSnapshot>[];
|
||||
truncated: boolean;
|
||||
}>> {
|
||||
assertPageSize(query.limit);
|
||||
const handledActionTypes = actionTypes(query.actionTypes);
|
||||
if (!Number.isSafeInteger(query.nowMs) || query.nowMs < 0) {
|
||||
throw new ApprovedActionExecutionStateConflictError();
|
||||
}
|
||||
if (handledActionTypes.length === 0) {
|
||||
return Object.freeze({ executions: Object.freeze([]), truncated: false });
|
||||
}
|
||||
try {
|
||||
const result = await this.pool.query<Row>(
|
||||
`SELECT execution.execution_json AS "executionJson",
|
||||
execution.execution_digest AS "executionDigest",
|
||||
dispatch.dispatch_json AS "dispatchJson"
|
||||
FROM "ql3"."approved_action_executions" AS execution
|
||||
JOIN "ql3"."approved_action_dispatches" AS dispatch
|
||||
ON dispatch.dispatch_id = execution.dispatch_id
|
||||
WHERE dispatch.action_type = ANY($1::varchar[])
|
||||
AND (
|
||||
(
|
||||
execution.status IN ('pending','leased','retry_wait')
|
||||
AND execution.eligible_at_ms <= $2
|
||||
)
|
||||
OR execution.status = 'executing'
|
||||
)
|
||||
ORDER BY execution.updated_at_ms, execution.dispatch_id
|
||||
LIMIT $3`,
|
||||
[handledActionTypes, query.nowMs, query.limit + 1],
|
||||
);
|
||||
const truncated = result.rows.length > query.limit;
|
||||
const rows = truncated ? result.rows.slice(0, query.limit) : result.rows;
|
||||
return Object.freeze({
|
||||
executions: Object.freeze(
|
||||
rows.map((row) =>
|
||||
normalizeApprovedActionExecutionSnapshot({
|
||||
dispatch: parseDispatch(row),
|
||||
execution: parseExecution(row),
|
||||
}),
|
||||
),
|
||||
),
|
||||
truncated,
|
||||
});
|
||||
} catch (error) {
|
||||
throw mappedError(error);
|
||||
}
|
||||
}
|
||||
|
||||
claimExecution(
|
||||
command: ClaimApprovedActionExecutionCommand,
|
||||
): Promise<ClaimApprovedActionExecutionResult> {
|
||||
|
||||
@@ -41,6 +41,7 @@ export {
|
||||
|
||||
export { PostgresPluginPackageMaterializedRevisionRepository } from '../plugin-package/installation/pluginPackageMaterializedRevisionRepository';
|
||||
export { PostgresApprovalRequestRepository } from '../approved-action/approvalRequestRepository';
|
||||
export { PostgresApprovedActionExecutionRepository } from '../approved-action/approvedActionExecutionRepository';
|
||||
export { PostgresProjectPolicyRepository } from '../security/projectPolicyRepository';
|
||||
export { PostgresPluginPackageSecretBindingRepository } from '../plugin-package/installation/pluginPackageSecretBindingRepository';
|
||||
export { PostgresPluginPackageSecretBindingActivationPrerequisite } from '../plugin-package/secret-binding/pluginPackageSecretBindingActivationPrerequisite';
|
||||
|
||||
@@ -367,11 +367,16 @@ test('Approved Action execution authority is isolated behind its explicit subpat
|
||||
const runtime = require('@qinglong/cluster-postgres/runtime');
|
||||
const admin = require('@qinglong/cluster-postgres/admin');
|
||||
const ingress = require('@qinglong/cluster-postgres/worker-ingress');
|
||||
const packageExecutor = require('@qinglong/cluster-postgres/package-executor');
|
||||
const authority = require('@qinglong/cluster-postgres/approved-action-execution');
|
||||
assert.equal(root.PostgresApprovedActionExecutionRepository, undefined);
|
||||
assert.equal(runtime.PostgresApprovedActionExecutionRepository, undefined);
|
||||
assert.equal(admin.PostgresApprovedActionExecutionRepository, undefined);
|
||||
assert.equal(ingress.PostgresApprovedActionExecutionRepository, undefined);
|
||||
assert.equal(
|
||||
packageExecutor.PostgresApprovedActionExecutionRepository,
|
||||
authority.PostgresApprovedActionExecutionRepository,
|
||||
);
|
||||
assert.equal(
|
||||
typeof authority.PostgresApprovedActionExecutionRepository,
|
||||
'function',
|
||||
|
||||
@@ -3581,6 +3581,22 @@ if (!migrationConnectionString) {
|
||||
const executions = new PostgresApprovedActionExecutionRepository(
|
||||
executorDatabase.pool,
|
||||
);
|
||||
const pendingSecretActions =
|
||||
await executions.listReconciliableExecutions({
|
||||
nowMs: claimedAtMs,
|
||||
limit: 1,
|
||||
actionTypes: [consumed.dispatch.action.actionType],
|
||||
});
|
||||
assert.equal(pendingSecretActions.truncated, false);
|
||||
assert.equal(pendingSecretActions.executions.length, 1);
|
||||
assert.equal(
|
||||
pendingSecretActions.executions[0].dispatch.id,
|
||||
consumed.dispatch.id,
|
||||
);
|
||||
assert.equal(
|
||||
pendingSecretActions.executions[0].execution.status,
|
||||
'pending',
|
||||
);
|
||||
const claimed = await executions.claimExecution({
|
||||
dispatchId: consumed.dispatch.id,
|
||||
owner: 'package_admission_dispatcher',
|
||||
@@ -3598,6 +3614,22 @@ if (!migrationConnectionString) {
|
||||
expectedVersion: claimed.snapshot.execution.version,
|
||||
startedAtMs: admittedAtMs,
|
||||
});
|
||||
const executingSecretActions =
|
||||
await executions.listReconciliableExecutions({
|
||||
nowMs: admittedAtMs,
|
||||
limit: 1,
|
||||
actionTypes: [consumed.dispatch.action.actionType],
|
||||
});
|
||||
assert.equal(executingSecretActions.truncated, false);
|
||||
assert.equal(executingSecretActions.executions.length, 1);
|
||||
assert.equal(
|
||||
executingSecretActions.executions[0].dispatch.id,
|
||||
consumed.dispatch.id,
|
||||
);
|
||||
assert.equal(
|
||||
executingSecretActions.executions[0].execution.status,
|
||||
'executing',
|
||||
);
|
||||
const lock = resolvePluginPackageInstallProposal(
|
||||
proposal,
|
||||
consumed.dispatch,
|
||||
|
||||
Reference in New Issue
Block a user