mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 10:32:40 +08:00
feat(ql3): materialize package secret bindings
This commit is contained in:
@@ -303,5 +303,10 @@ export const postgresqlMainMigrationManifest: MigrationStreamManifest =
|
||||
checksum:
|
||||
'87582d256c868bd7f5af352c4b052fdab9f3714e1e7179e35d33bfa5d62957be',
|
||||
}),
|
||||
Object.freeze({
|
||||
id: 'pg-0060-plugin-package-secret-materialization-guard',
|
||||
checksum:
|
||||
'28284ca860b39ff9de5b2aa1a2a60ef2c463fd6a72798d237040174272b64b1e',
|
||||
}),
|
||||
]),
|
||||
});
|
||||
|
||||
@@ -62,6 +62,7 @@ import { pg0056RunManagementBoundaryMigration } from '../run-management/pg-0056-
|
||||
import { pg0057RunManagementStopBoundaryMigration } from '../run-management/pg-0057-run-management-stop-boundary';
|
||||
import { pg0058PluginPackageAutomationDispositionEventsMigration } from './pg-0058-plugin-package-automation-disposition-events';
|
||||
import { pg0059PluginPackageSecretBindingsMigration } from './pg-0059-plugin-package-secret-bindings';
|
||||
import { pg0060PluginPackageSecretMaterializationGuardMigration } from './pg-0060-plugin-package-secret-materialization-guard';
|
||||
|
||||
export const postgresqlMainMigrationStream: MigrationStreamDefinition<PostgresMigrationContext> =
|
||||
Object.freeze({
|
||||
@@ -129,5 +130,6 @@ export const postgresqlMainMigrationStream: MigrationStreamDefinition<PostgresMi
|
||||
pg0057RunManagementStopBoundaryMigration,
|
||||
pg0058PluginPackageAutomationDispositionEventsMigration,
|
||||
pg0059PluginPackageSecretBindingsMigration,
|
||||
pg0060PluginPackageSecretMaterializationGuardMigration,
|
||||
]),
|
||||
});
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
import { CAPABILITIES_V58 } from './pg-0059-plugin-package-secret-bindings';
|
||||
import { definePostgresSqlMigration } from './sqlMigration';
|
||||
|
||||
export const CAPABILITIES_V59 = CAPABILITIES_V58.replace(
|
||||
'"plugin_package_secret_binding":1,',
|
||||
'"plugin_package_secret_binding":1,"plugin_package_secret_materialization":1,',
|
||||
);
|
||||
|
||||
export const pg0060PluginPackageSecretMaterializationGuardMigration =
|
||||
definePostgresSqlMigration({
|
||||
id: 'pg-0060-plugin-package-secret-materialization-guard',
|
||||
statements: [
|
||||
`
|
||||
CREATE FUNCTION "ql3"."enforce_plugin_package_secret_materialization"()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
VOLATILE
|
||||
SET search_path = pg_catalog, ql3
|
||||
AS $ql3$
|
||||
DECLARE
|
||||
secret_count integer;
|
||||
embedded_binding jsonb;
|
||||
stored_binding jsonb;
|
||||
BEGIN
|
||||
IF jsonb_typeof(
|
||||
NEW.revision_json #> '{manifest,spec,permissions,secrets}'
|
||||
) IS DISTINCT FROM 'array' THEN
|
||||
RAISE EXCEPTION 'Package Secret permission declarations are malformed'
|
||||
USING ERRCODE = 'check_violation';
|
||||
END IF;
|
||||
|
||||
secret_count := jsonb_array_length(
|
||||
NEW.revision_json #> '{manifest,spec,permissions,secrets}'
|
||||
);
|
||||
embedded_binding := NEW.revision_json -> 'secretBinding';
|
||||
|
||||
IF secret_count = 0 THEN
|
||||
IF embedded_binding IS NOT NULL THEN
|
||||
RAISE EXCEPTION 'unexpected Package Secret binding'
|
||||
USING ERRCODE = 'check_violation';
|
||||
END IF;
|
||||
ELSE
|
||||
SELECT binding.binding_json
|
||||
INTO stored_binding
|
||||
FROM "ql3"."plugin_package_secret_bindings" AS binding
|
||||
WHERE binding.generation_digest = NEW.generation_digest;
|
||||
IF stored_binding IS NULL OR stored_binding <> embedded_binding THEN
|
||||
RAISE EXCEPTION 'Package Secret binding is absent or mismatched'
|
||||
USING ERRCODE = 'check_violation';
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM jsonb_array_elements(NEW.revision_json -> 'resources') AS resource
|
||||
CROSS JOIN LATERAL jsonb_array_elements(
|
||||
COALESCE(
|
||||
resource #> '{value,spec,config,environment}',
|
||||
'[]'::jsonb
|
||||
)
|
||||
) AS environment
|
||||
WHERE resource ->> 'kind' = 'task'
|
||||
AND environment ->> 'kind' = 'package-secret'
|
||||
) THEN
|
||||
RAISE EXCEPTION 'unresolved Package Secret placeholder'
|
||||
USING ERRCODE = 'check_violation';
|
||||
END IF;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM jsonb_array_elements(NEW.revision_json -> 'resources') AS resource
|
||||
CROSS JOIN LATERAL jsonb_array_elements(
|
||||
COALESCE(
|
||||
resource #> '{value,spec,config,environment}',
|
||||
'[]'::jsonb
|
||||
)
|
||||
) AS environment
|
||||
WHERE resource ->> 'kind' = 'task'
|
||||
AND environment ->> 'kind' = 'secret'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM jsonb_array_elements(
|
||||
COALESCE(embedded_binding -> 'entries', '[]'::jsonb)
|
||||
) AS binding_entry
|
||||
WHERE binding_entry ->> 'secretRef' =
|
||||
environment ->> 'secretRef'
|
||||
)
|
||||
) THEN
|
||||
RAISE EXCEPTION 'Task SecretRef is outside Package binding'
|
||||
USING ERRCODE = 'check_violation';
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END
|
||||
$ql3$
|
||||
`.trim(),
|
||||
`REVOKE ALL ON FUNCTION "ql3"."enforce_plugin_package_secret_materialization"() FROM PUBLIC, ql3_runtime, ql3_admin, ql3_package_manager, ql3_package_executor, ql3_worker_ingress`,
|
||||
`CREATE TRIGGER ql3_plugin_package_secret_materialization_guard BEFORE INSERT ON "ql3"."plugin_package_materialized_revisions" FOR EACH ROW EXECUTE FUNCTION "ql3"."enforce_plugin_package_secret_materialization"()`,
|
||||
`DO $ql3$ BEGIN UPDATE "ql3"."schema_capabilities" SET contract_version = 59, migration_id = 'pg-0060-plugin-package-secret-materialization-guard', capabilities = '${CAPABILITIES_V59}'::jsonb, updated_at_ms = floor(extract(epoch FROM transaction_timestamp()) * 1000)::bigint WHERE contract_name = 'control-core' AND contract_version = 58 AND migration_id = 'pg-0059-plugin-package-secret-bindings' AND capabilities = '${CAPABILITIES_V58}'::jsonb; IF NOT FOUND THEN RAISE EXCEPTION 'control-core capability is not at version 58' USING ERRCODE = 'check_violation'; END IF; END $ql3$`,
|
||||
],
|
||||
});
|
||||
@@ -15,8 +15,8 @@ export interface PostgresSchemaContractFunction {
|
||||
export interface PostgresSchemaContract {
|
||||
readonly schema: 'ql3';
|
||||
readonly contractName: 'control-core';
|
||||
readonly contractVersion: 58;
|
||||
readonly migrationId: 'pg-0059-plugin-package-secret-bindings';
|
||||
readonly contractVersion: 59;
|
||||
readonly migrationId: 'pg-0060-plugin-package-secret-materialization-guard';
|
||||
readonly minimumServerMajor: 16;
|
||||
readonly maximumServerMajor: 18;
|
||||
readonly capabilities: Readonly<{
|
||||
@@ -56,6 +56,7 @@ export interface PostgresSchemaContract {
|
||||
plugin_package_management_quota: 1;
|
||||
plugin_package_materialized_revision: 1;
|
||||
plugin_package_secret_binding: 1;
|
||||
plugin_package_secret_materialization: 1;
|
||||
plugin_package_proposal: 1;
|
||||
plugin_package_publisher_provenance: 1;
|
||||
plugin_package_publisher_trust_authority: 1;
|
||||
@@ -105,8 +106,8 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
Object.freeze({
|
||||
schema: 'ql3',
|
||||
contractName: 'control-core',
|
||||
contractVersion: 58,
|
||||
migrationId: 'pg-0059-plugin-package-secret-bindings',
|
||||
contractVersion: 59,
|
||||
migrationId: 'pg-0060-plugin-package-secret-materialization-guard',
|
||||
minimumServerMajor: 16,
|
||||
maximumServerMajor: 18,
|
||||
capabilities: Object.freeze({
|
||||
@@ -139,6 +140,7 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
plugin_package_management_quota: 1,
|
||||
plugin_package_materialized_revision: 1,
|
||||
plugin_package_secret_binding: 1,
|
||||
plugin_package_secret_materialization: 1,
|
||||
plugin_package_proposal: 1,
|
||||
plugin_package_publisher_provenance: 1,
|
||||
plugin_package_publisher_trust_authority: 1,
|
||||
@@ -2336,6 +2338,14 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'ql3_run_retry_policies_run_fk',
|
||||
]),
|
||||
functions: Object.freeze([
|
||||
Object.freeze({
|
||||
name: 'enforce_plugin_package_secret_materialization',
|
||||
identityArguments: '',
|
||||
owner: 'ql3_migration',
|
||||
securityDefiner: false,
|
||||
volatility: 'volatile',
|
||||
configuration: Object.freeze(['search_path=pg_catalog, ql3']),
|
||||
}),
|
||||
Object.freeze({
|
||||
name: 'register_plugin_package_automation_disposition_event',
|
||||
identityArguments: '',
|
||||
|
||||
@@ -1507,6 +1507,7 @@ const REQUIRED_RUNTIME_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges =
|
||||
commit_plugin_package_lifecycle: false,
|
||||
commit_plugin_package_quarantine: false,
|
||||
commit_plugin_package_task_reconciliation: false,
|
||||
enforce_plugin_package_secret_materialization: false,
|
||||
enforce_plugin_package_stage_provenance: false,
|
||||
lock_active_plugin_package_project: false,
|
||||
lock_approval_policy_fence: false,
|
||||
@@ -1525,6 +1526,7 @@ const REQUIRED_PACKAGE_MANAGER_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges =
|
||||
commit_plugin_package_lifecycle: false,
|
||||
commit_plugin_package_quarantine: false,
|
||||
commit_plugin_package_task_reconciliation: false,
|
||||
enforce_plugin_package_secret_materialization: false,
|
||||
enforce_plugin_package_stage_provenance: false,
|
||||
lock_active_plugin_package_project: false,
|
||||
lock_approval_policy_fence: true,
|
||||
@@ -1543,6 +1545,7 @@ const REQUIRED_PACKAGE_EXECUTOR_FUNCTION_PRIVILEGES: RequiredFunctionPrivileges
|
||||
commit_plugin_package_lifecycle: true,
|
||||
commit_plugin_package_quarantine: true,
|
||||
commit_plugin_package_task_reconciliation: true,
|
||||
enforce_plugin_package_secret_materialization: false,
|
||||
enforce_plugin_package_stage_provenance: false,
|
||||
lock_active_plugin_package_project: true,
|
||||
lock_approval_policy_fence: true,
|
||||
|
||||
Reference in New Issue
Block a user