mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 19:29:13 +08:00
feat(ql3): separate cluster secret transition authority
This commit is contained in:
@@ -515,6 +515,73 @@ export const pluginPackageSecretBindingTransitionReceipts = ql3Schema.table(
|
||||
],
|
||||
);
|
||||
|
||||
export const pluginPackageSecretBindingTransitionApprovalPlans =
|
||||
ql3Schema.table(
|
||||
'plugin_package_secret_binding_transition_approval_plans',
|
||||
{
|
||||
actionRef: varchar('action_ref', { length: 255 }).primaryKey(),
|
||||
approvalPlanDigest: char('approval_plan_digest', { length: 64 }).notNull(),
|
||||
transitionDigest: char('transition_digest', { length: 64 }).notNull(),
|
||||
generationDigest: char('generation_digest', { length: 64 }).notNull(),
|
||||
projectId: varchar('project_id', { length: 128 }).notNull(),
|
||||
packageName: varchar('package_name', { length: 63 }).notNull(),
|
||||
installationId: varchar('installation_id', { length: 128 }).notNull(),
|
||||
lockDigest: char('lock_digest', { length: 64 }).notNull(),
|
||||
generation: integer('generation').notNull(),
|
||||
manifestDigest: char('manifest_digest', { length: 64 }).notNull(),
|
||||
previousActiveLockDigest: char('previous_active_lock_digest', {
|
||||
length: 64,
|
||||
}).notNull(),
|
||||
requestedByType: varchar('requested_by_type', { length: 16 }).notNull(),
|
||||
requestedById: varchar('requested_by_id', { length: 255 }).notNull(),
|
||||
plannedAtMs: bigint('planned_at_ms', { mode: 'number' }).notNull(),
|
||||
expiresAtMs: bigint('expires_at_ms', { mode: 'number' }).notNull(),
|
||||
planJson: jsonb('plan_json').$type<Record<string, unknown>>().notNull(),
|
||||
},
|
||||
(table) => [
|
||||
foreignKey({
|
||||
name: 'ql3_pp_secret_transition_plan_project_fk',
|
||||
columns: [table.projectId],
|
||||
foreignColumns: [projects.id],
|
||||
})
|
||||
.onDelete('restrict')
|
||||
.onUpdate('restrict'),
|
||||
foreignKey({
|
||||
name: 'ql3_pp_secret_transition_plan_install_fk',
|
||||
columns: [table.installationId],
|
||||
foreignColumns: [pluginPackageInstalls.installationId],
|
||||
})
|
||||
.onDelete('restrict')
|
||||
.onUpdate('restrict'),
|
||||
check(
|
||||
'ql3_pp_secret_transition_plan_identity_check',
|
||||
sql`${table.actionRef} ~ '^[A-Za-z0-9][A-Za-z0-9._:/-]{0,254}$' and ${table.projectId} ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' and ${table.packageName} ~ '^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$' and ${table.installationId} ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' and ${table.generation} between 2 and 2147483647 and ${table.requestedByType} = 'user' and octet_length(${table.requestedById}) between 1 and 255 and ${table.requestedById} !~ '[[:cntrl:]]'`,
|
||||
),
|
||||
check(
|
||||
'ql3_pp_secret_transition_plan_digest_check',
|
||||
sql`${table.approvalPlanDigest} ~ '^[0-9a-f]{64}$' and ${table.transitionDigest} ~ '^[0-9a-f]{64}$' and ${table.generationDigest} ~ '^[0-9a-f]{64}$' and ${table.lockDigest} ~ '^[0-9a-f]{64}$' and ${table.manifestDigest} ~ '^[0-9a-f]{64}$' and ${table.previousActiveLockDigest} ~ '^[0-9a-f]{64}$'`,
|
||||
),
|
||||
check(
|
||||
'ql3_pp_secret_transition_plan_time_check',
|
||||
sql`${table.plannedAtMs} >= 0 and ${table.expiresAtMs} > ${table.plannedAtMs} and ${table.expiresAtMs} - ${table.plannedAtMs} <= 900000`,
|
||||
),
|
||||
check(
|
||||
'ql3_pp_secret_transition_plan_json_check',
|
||||
sql`jsonb_typeof(${table.planJson}) = 'object' and octet_length(${table.planJson}::text) between 2 and 229376 and ${table.planJson} @> jsonb_build_object('schema', 'qinglong/plugin-package-secret-binding-transition-approval-plan@v1', 'actionRef', ${table.actionRef}, 'approvalPlanDigest', ${table.approvalPlanDigest}, 'requestedBy', jsonb_build_object('type', ${table.requestedByType}, 'id', ${table.requestedById}), 'plannedAtMs', ${table.plannedAtMs}, 'expiresAtMs', ${table.expiresAtMs}, 'transitionPlan', jsonb_build_object('schema', 'qinglong/plugin-package-secret-binding-transition-plan@v1', 'transitionDigest', ${table.transitionDigest}, 'previousActiveLockDigest', ${table.previousActiveLockDigest}, 'nextTarget', jsonb_build_object('generationDigest', ${table.generationDigest}, 'projectId', ${table.projectId}, 'packageName', ${table.packageName}, 'installationId', ${table.installationId}, 'lockDigest', ${table.lockDigest}, 'generation', ${table.generation}, 'manifestDigest', ${table.manifestDigest}))) and jsonb_typeof(${table.planJson} #> '{transitionPlan,changes}') = 'array' and jsonb_array_length(${table.planJson} #> '{transitionPlan,changes}') between 1 and 64`,
|
||||
),
|
||||
uniqueIndex('ql3_pp_secret_transition_plan_digest_uidx').on(
|
||||
table.approvalPlanDigest,
|
||||
),
|
||||
uniqueIndex('ql3_pp_secret_transition_plan_target_uidx').on(
|
||||
table.generationDigest,
|
||||
),
|
||||
index('ql3_pp_secret_transition_plan_expiry_idx').on(
|
||||
table.expiresAtMs,
|
||||
table.actionRef,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
export const projectToolDefinitionSnapshots = ql3Schema.table(
|
||||
'project_tool_definition_snapshots',
|
||||
{
|
||||
@@ -6003,6 +6070,7 @@ export const ql3PostgresTables = [
|
||||
pluginPackageMaterializedRevisions,
|
||||
pluginPackageSecretBindings,
|
||||
pluginPackageSecretBindingApprovalPlans,
|
||||
pluginPackageSecretBindingTransitionApprovalPlans,
|
||||
pluginPackageSecretBindingTransitionReceipts,
|
||||
projectToolDefinitionSnapshots,
|
||||
projectToolDefinitionSnapshotSources,
|
||||
|
||||
@@ -21,8 +21,8 @@ export interface PostgresSchemaContractTrigger {
|
||||
export interface PostgresSchemaContract {
|
||||
readonly schema: 'ql3';
|
||||
readonly contractName: 'control-core';
|
||||
readonly contractVersion: 62;
|
||||
readonly migrationId: 'pg-0063-plugin-package-secret-binding-transition-receipts';
|
||||
readonly contractVersion: 63;
|
||||
readonly migrationId: 'pg-0064-plugin-package-secret-binding-transition-approval-plans';
|
||||
readonly minimumServerMajor: 16;
|
||||
readonly maximumServerMajor: 18;
|
||||
readonly capabilities: Readonly<{
|
||||
@@ -64,6 +64,7 @@ export interface PostgresSchemaContract {
|
||||
plugin_package_secret_binding: 1;
|
||||
plugin_package_secret_binding_approval_plan: 1;
|
||||
plugin_package_secret_binding_transition: 1;
|
||||
plugin_package_secret_binding_transition_approval_plan: 1;
|
||||
plugin_package_secret_binding_transition_receipt: 1;
|
||||
plugin_package_secret_materialization: 1;
|
||||
plugin_package_proposal: 1;
|
||||
@@ -116,8 +117,8 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
Object.freeze({
|
||||
schema: 'ql3',
|
||||
contractName: 'control-core',
|
||||
contractVersion: 62,
|
||||
migrationId: 'pg-0063-plugin-package-secret-binding-transition-receipts',
|
||||
contractVersion: 63,
|
||||
migrationId: 'pg-0064-plugin-package-secret-binding-transition-approval-plans',
|
||||
minimumServerMajor: 16,
|
||||
maximumServerMajor: 18,
|
||||
capabilities: Object.freeze({
|
||||
@@ -152,6 +153,7 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
plugin_package_secret_binding: 1,
|
||||
plugin_package_secret_binding_approval_plan: 1,
|
||||
plugin_package_secret_binding_transition: 1,
|
||||
plugin_package_secret_binding_transition_approval_plan: 1,
|
||||
plugin_package_secret_binding_transition_receipt: 1,
|
||||
plugin_package_secret_materialization: 1,
|
||||
plugin_package_proposal: 1,
|
||||
@@ -290,6 +292,24 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'expires_at_ms',
|
||||
'plan_json',
|
||||
]),
|
||||
table('plugin_package_secret_binding_transition_approval_plans', [
|
||||
'action_ref',
|
||||
'approval_plan_digest',
|
||||
'transition_digest',
|
||||
'generation_digest',
|
||||
'project_id',
|
||||
'package_name',
|
||||
'installation_id',
|
||||
'lock_digest',
|
||||
'generation',
|
||||
'manifest_digest',
|
||||
'previous_active_lock_digest',
|
||||
'requested_by_type',
|
||||
'requested_by_id',
|
||||
'planned_at_ms',
|
||||
'expires_at_ms',
|
||||
'plan_json',
|
||||
]),
|
||||
table('plugin_package_secret_binding_transition_receipts', [
|
||||
'generation_digest',
|
||||
'transition_digest',
|
||||
@@ -1494,6 +1514,10 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'ql3_package_secret_transition_receipt_transition_uidx',
|
||||
'ql3_package_secret_transition_receipt_digest_uidx',
|
||||
'ql3_package_secret_transition_receipt_install_idx',
|
||||
'plugin_package_secret_binding_transition_approval_plans_pkey',
|
||||
'ql3_pp_secret_transition_plan_digest_uidx',
|
||||
'ql3_pp_secret_transition_plan_target_uidx',
|
||||
'ql3_pp_secret_transition_plan_expiry_idx',
|
||||
'project_tool_definition_snapshots_pkey',
|
||||
'ql3_project_tool_snapshot_withdrawal_key',
|
||||
'ql3_project_tool_definition_snapshot_digest_uidx',
|
||||
@@ -1795,6 +1819,10 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'ql3_package_secret_transition_receipt_identity_check',
|
||||
'ql3_package_secret_transition_receipt_digest_check',
|
||||
'ql3_package_secret_transition_receipt_json_check',
|
||||
'ql3_pp_secret_transition_plan_identity_check',
|
||||
'ql3_pp_secret_transition_plan_digest_check',
|
||||
'ql3_pp_secret_transition_plan_time_check',
|
||||
'ql3_pp_secret_transition_plan_json_check',
|
||||
'ql3_plugin_package_quarantine_identity_check',
|
||||
'ql3_plugin_package_quarantine_state_check',
|
||||
'ql3_plugin_package_quarantine_subject_check',
|
||||
@@ -2254,6 +2282,8 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'ql3_plugin_package_secret_binding_approval_plan_install_fk',
|
||||
'ql3_plugin_package_secret_binding_transition_receipt_project_fk',
|
||||
'ql3_plugin_package_secret_binding_transition_receipt_install_fk',
|
||||
'ql3_pp_secret_transition_plan_project_fk',
|
||||
'ql3_pp_secret_transition_plan_install_fk',
|
||||
'ql3_project_tool_definition_snapshot_project_fk',
|
||||
'ql3_project_tool_definition_snapshot_source_snapshot_fk',
|
||||
'ql3_project_tool_definition_snapshot_source_install_fk',
|
||||
@@ -2404,6 +2434,23 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'ql3_run_retry_policies_run_fk',
|
||||
]),
|
||||
functions: Object.freeze([
|
||||
Object.freeze({
|
||||
name: 'plugin_package_secret_binding_transition_snapshot',
|
||||
identityArguments:
|
||||
'p_project_id character varying, p_package_name character varying',
|
||||
owner: 'ql3_migration',
|
||||
securityDefiner: true,
|
||||
volatility: 'volatile',
|
||||
configuration: Object.freeze(['search_path=pg_catalog, ql3']),
|
||||
}),
|
||||
Object.freeze({
|
||||
name: 'create_plugin_package_secret_transition_plan',
|
||||
identityArguments: 'p_plan_json jsonb',
|
||||
owner: 'ql3_migration',
|
||||
securityDefiner: true,
|
||||
volatility: 'volatile',
|
||||
configuration: Object.freeze(['search_path=pg_catalog, ql3']),
|
||||
}),
|
||||
Object.freeze({
|
||||
name: 'plugin_package_secret_binding_planning_snapshot',
|
||||
identityArguments:
|
||||
|
||||
@@ -186,6 +186,12 @@ const REQUIRED_RUNTIME_PRIVILEGES = Object.freeze({
|
||||
update: false,
|
||||
delete: false,
|
||||
}),
|
||||
plugin_package_secret_binding_transition_approval_plans: Object.freeze({
|
||||
select: false,
|
||||
insert: false,
|
||||
update: false,
|
||||
delete: false,
|
||||
}),
|
||||
plugin_package_secret_binding_transition_receipts: Object.freeze({
|
||||
select: false,
|
||||
insert: false,
|
||||
@@ -717,6 +723,12 @@ const REQUIRED_ADMIN_PRIVILEGES = Object.freeze({
|
||||
update: false,
|
||||
delete: false,
|
||||
}),
|
||||
plugin_package_secret_binding_transition_approval_plans: Object.freeze({
|
||||
select: false,
|
||||
insert: false,
|
||||
update: false,
|
||||
delete: false,
|
||||
}),
|
||||
plugin_package_secret_binding_transition_receipts: Object.freeze({
|
||||
select: false,
|
||||
insert: false,
|
||||
@@ -1225,6 +1237,7 @@ const REQUIRED_PACKAGE_MANAGER_PRIVILEGES: RequiredPrivileges = Object.freeze(
|
||||
name === 'project_role_bindings' ||
|
||||
name === 'plugin_package_lifecycle_plans' ||
|
||||
name === 'plugin_package_secret_binding_approval_plans' ||
|
||||
name === 'plugin_package_secret_binding_transition_approval_plans' ||
|
||||
name === 'plugin_package_automation_publications' ||
|
||||
name === 'plugin_package_automation_publication_heads' ||
|
||||
name === 'plugin_package_publisher_trust_transition_receipts'
|
||||
@@ -1268,6 +1281,7 @@ const REQUIRED_PACKAGE_EXECUTOR_PRIVILEGES: RequiredPrivileges = Object.freeze(
|
||||
name === 'project_role_bindings' ||
|
||||
name === 'plugin_package_install_proposals' ||
|
||||
name === 'plugin_package_secret_binding_approval_plans' ||
|
||||
name === 'plugin_package_secret_binding_transition_approval_plans' ||
|
||||
name === 'plugin_package_publisher_revocation_proposals' ||
|
||||
name === 'plugin_package_publisher_trust_transition_proposals'
|
||||
? { ...NO_TABLE_PRIVILEGES, select: true }
|
||||
@@ -1538,6 +1552,7 @@ const REQUIRED_ADMIN_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges =
|
||||
|
||||
const REQUIRED_RUNTIME_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges =
|
||||
Object.freeze({
|
||||
create_plugin_package_secret_transition_plan: false,
|
||||
create_plugin_package_secret_binding_approval_plan: false,
|
||||
commit_plugin_package_lifecycle: false,
|
||||
commit_plugin_package_quarantine: false,
|
||||
@@ -1555,12 +1570,14 @@ const REQUIRED_RUNTIME_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges =
|
||||
plugin_package_lifecycle_blocking_runs: false,
|
||||
plugin_package_run_start_allowed: true,
|
||||
plugin_package_secret_binding_planning_snapshot: false,
|
||||
plugin_package_secret_binding_transition_snapshot: false,
|
||||
plugin_package_tool_start_allowed: true,
|
||||
register_plugin_package_automation_disposition_event: false,
|
||||
});
|
||||
|
||||
const REQUIRED_PACKAGE_MANAGER_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges =
|
||||
Object.freeze({
|
||||
create_plugin_package_secret_transition_plan: true,
|
||||
create_plugin_package_secret_binding_approval_plan: true,
|
||||
commit_plugin_package_lifecycle: false,
|
||||
commit_plugin_package_quarantine: false,
|
||||
@@ -1578,12 +1595,14 @@ const REQUIRED_PACKAGE_MANAGER_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges =
|
||||
plugin_package_lifecycle_blocking_runs: false,
|
||||
plugin_package_run_start_allowed: false,
|
||||
plugin_package_secret_binding_planning_snapshot: true,
|
||||
plugin_package_secret_binding_transition_snapshot: true,
|
||||
plugin_package_tool_start_allowed: false,
|
||||
register_plugin_package_automation_disposition_event: false,
|
||||
});
|
||||
|
||||
const REQUIRED_PACKAGE_EXECUTOR_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges =
|
||||
Object.freeze({
|
||||
create_plugin_package_secret_transition_plan: false,
|
||||
create_plugin_package_secret_binding_approval_plan: false,
|
||||
commit_plugin_package_lifecycle: true,
|
||||
commit_plugin_package_quarantine: true,
|
||||
@@ -1601,6 +1620,7 @@ const REQUIRED_PACKAGE_EXECUTOR_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges
|
||||
plugin_package_lifecycle_blocking_runs: true,
|
||||
plugin_package_run_start_allowed: false,
|
||||
plugin_package_secret_binding_planning_snapshot: false,
|
||||
plugin_package_secret_binding_transition_snapshot: false,
|
||||
plugin_package_tool_start_allowed: false,
|
||||
register_plugin_package_automation_disposition_event: false,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user