@aifabrix/builder 2.45.0 → 2.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/cli-layout.mdc +2 -0
- package/.cursor/rules/cli-product-neutral.mdc +43 -0
- package/.cursor/rules/docs-rules.mdc +3 -1
- package/.cursor/rules/project-rules.mdc +1 -0
- package/README.md +43 -17
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
- package/jest.config.default.js +2 -1
- package/jest.config.isolated.js +2 -1
- package/jest.global-live-fabrix-hooks.js +36 -0
- package/jest.isolated-projects.js +130 -0
- package/jest.projects.js +69 -121
- package/lib/api/agent-metadata-validation.api.js +93 -0
- package/lib/api/api-response-errors.js +124 -0
- package/lib/api/audit-api-helpers.js +68 -0
- package/lib/api/audit.api.js +119 -0
- package/lib/api/auth-cache.api.js +44 -0
- package/lib/api/certificates.api.js +4 -4
- package/lib/api/credential.api.js +2 -2
- package/lib/api/dataplane-health.api.js +137 -0
- package/lib/api/dataplane-sync.api.js +27 -0
- package/lib/api/datasources-core.api.js +21 -18
- package/lib/api/datasources-extended.api.js +22 -22
- package/lib/api/dimensions.api.js +3 -0
- package/lib/api/external-systems.api.js +13 -13
- package/lib/api/governance-scenario-pack.api.js +159 -0
- package/lib/api/governance-scenarios.api.js +39 -0
- package/lib/api/groups.api.js +79 -0
- package/lib/api/index.js +88 -5
- package/lib/api/lifecycle.api.js +77 -0
- package/lib/api/pipeline.api.js +7 -5
- package/lib/api/protection.api.js +157 -0
- package/lib/api/records-bulk.api.js +43 -0
- package/lib/api/records-search-parse.js +49 -0
- package/lib/api/records-search.api.js +29 -0
- package/lib/api/types/agent-metadata-validation.types.js +67 -0
- package/lib/api/types/audit.types.js +72 -0
- package/lib/api/types/dataplane-health.types.js +27 -0
- package/lib/api/types/dimensions.types.js +2 -0
- package/lib/api/types/governance-scenarios.types.js +39 -0
- package/lib/api/types/protection.types.js +69 -0
- package/lib/api/types/records-bulk.types.js +35 -0
- package/lib/api/types/records-search.types.js +28 -0
- package/lib/api/user-groups.api.js +50 -0
- package/lib/api/users.api.js +95 -0
- package/lib/api/validation-run.api.js +3 -3
- package/lib/api/validation-runner.js +5 -3
- package/lib/api/wizard-platform.api.js +3 -3
- package/lib/api/wizard.api.js +21 -21
- package/lib/app/deploy-config.js +4 -1
- package/lib/app/deploy.js +34 -19
- package/lib/app/down.js +20 -1
- package/lib/app/push.js +4 -5
- package/lib/app/register.js +7 -4
- package/lib/app/run-env-compose.js +84 -30
- package/lib/build/index.js +5 -0
- package/lib/certification/sync-system-certification.js +13 -6
- package/lib/cli/index.js +8 -2
- package/lib/cli/infra-guided-auth.js +109 -0
- package/lib/cli/infra-guided.js +91 -69
- package/lib/cli/setup-app.help.js +19 -2
- package/lib/cli/setup-app.js +58 -23
- package/lib/cli/setup-app.test-commands.js +28 -21
- package/lib/cli/setup-auth.js +55 -3
- package/lib/cli/setup-certification-commands.js +147 -0
- package/lib/cli/setup-certification.help.js +141 -0
- package/lib/cli/setup-environment.js +19 -2
- package/lib/cli/setup-external-system-help.js +62 -0
- package/lib/cli/setup-external-system.js +62 -6
- package/lib/cli/setup-infra.js +9 -1
- package/lib/cli/setup-platform.js +6 -1
- package/lib/cli/setup-secrets.js +33 -1
- package/lib/cli/setup-utility-help-after.js +65 -0
- package/lib/cli/setup-utility-repair.js +198 -0
- package/lib/cli/setup-utility-resolve.js +42 -6
- package/lib/cli/setup-utility-validate.js +197 -0
- package/lib/cli/setup-utility.js +41 -258
- package/lib/commands/auth-status-client-tokens.js +214 -0
- package/lib/commands/auth-status-dataplane-version.js +269 -0
- package/lib/commands/auth-status-display.js +94 -0
- package/lib/commands/auth-status.js +111 -53
- package/lib/commands/credential-push.js +10 -5
- package/lib/commands/datasource-load-export-cli.js +178 -0
- package/lib/commands/datasource-test-trust-cli.js +118 -0
- package/lib/commands/datasource-unified-test-cli.js +31 -20
- package/lib/commands/datasource-unified-test-cli.options.js +22 -3
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
- package/lib/commands/datasource-verify-audit-cli.js +96 -0
- package/lib/commands/datasource.js +68 -1
- package/lib/commands/dev-show-display.js +8 -1
- package/lib/commands/dimension-value.js +43 -13
- package/lib/commands/dimension.js +38 -7
- package/lib/commands/governance-cli-shared.js +94 -0
- package/lib/commands/governance-command-action.js +132 -0
- package/lib/commands/governance-download-external.js +34 -0
- package/lib/commands/governance-generate-external.js +71 -0
- package/lib/commands/governance-upload-external.js +36 -0
- package/lib/commands/governance-verify-external.js +64 -0
- package/lib/commands/governance.js +144 -0
- package/lib/commands/identity-apply-sync.js +131 -0
- package/lib/commands/identity-group-cli.js +146 -0
- package/lib/commands/identity-membership-role-cache.js +175 -0
- package/lib/commands/identity-shared.js +94 -0
- package/lib/commands/identity-user-cli.js +158 -0
- package/lib/commands/identity.js +43 -0
- package/lib/commands/lifecycle-command-action.js +123 -0
- package/lib/commands/lifecycle-external.js +268 -0
- package/lib/commands/login.js +56 -17
- package/lib/commands/protection-cli-leaves.js +286 -0
- package/lib/commands/protection.js +50 -0
- package/lib/commands/repair-auth-apply.js +127 -0
- package/lib/commands/repair-changed-files.js +41 -0
- package/lib/commands/repair-datasource-keys.js +4 -1
- package/lib/commands/repair-datasource-run.js +59 -0
- package/lib/commands/repair-datasource-test-payload.js +259 -0
- package/lib/commands/repair-datasource.js +1 -51
- package/lib/commands/repair-env-template.js +64 -13
- package/lib/commands/repair-external-run.js +216 -0
- package/lib/commands/repair-openapi-sync.js +23 -0
- package/lib/commands/repair-persist.js +4 -0
- package/lib/commands/repair-rbac.js +52 -1
- package/lib/commands/repair-steps.js +145 -0
- package/lib/commands/repair.js +29 -286
- package/lib/commands/secrets-get.js +184 -0
- package/lib/commands/secrets-remove-all.js +3 -1
- package/lib/commands/setup-image-refresh.js +146 -0
- package/lib/commands/setup-modes.js +158 -162
- package/lib/commands/setup-platform-auth.js +76 -0
- package/lib/commands/setup-prompts-admin.js +244 -0
- package/lib/commands/setup-prompts-platform-mode.js +67 -0
- package/lib/commands/setup-prompts-validators.js +36 -0
- package/lib/commands/setup-prompts.js +24 -76
- package/lib/commands/setup-run-context.js +45 -0
- package/lib/commands/setup-spinners.js +39 -0
- package/lib/commands/setup.js +27 -5
- package/lib/commands/teardown.js +39 -0
- package/lib/commands/test-e2e-external.js +61 -14
- package/lib/commands/test-governance-cli-options.js +47 -0
- package/lib/commands/test-governance-external.js +67 -0
- package/lib/commands/test-trust-cli-options.js +32 -0
- package/lib/commands/test-trust-external.js +126 -0
- package/lib/commands/up-common.js +25 -13
- package/lib/commands/up-dataplane.js +50 -13
- package/lib/commands/upload-publish-context.js +75 -0
- package/lib/commands/upload-sidecar-followups.js +89 -0
- package/lib/commands/upload.js +108 -105
- package/lib/commands/verify-governance-combined-external.js +61 -0
- package/lib/commands/verify-governance-command-action.js +64 -0
- package/lib/commands/verify-governance-db.js +102 -0
- package/lib/commands/verify-governance-external.js +77 -0
- package/lib/commands/verify-governance-result-builders.js +71 -0
- package/lib/commands/verify-operations-command-action.js +68 -0
- package/lib/commands/verify-operations-external.js +268 -0
- package/lib/commands/verify-operations-persist.js +75 -0
- package/lib/commands/verify-operations-step-plan.js +68 -0
- package/lib/commands/verify-operations-steps.js +111 -0
- package/lib/commands/verify-trust-command-action.js +70 -0
- package/lib/commands/verify-trust-external.js +67 -0
- package/lib/commands/wizard-config-normalizer.js +43 -23
- package/lib/commands/wizard-core.js +5 -0
- package/lib/core/admin-password-generator.js +38 -0
- package/lib/core/admin-secrets-bundle.js +111 -0
- package/lib/core/admin-secrets-env-overlay.js +62 -0
- package/lib/core/admin-secrets.js +32 -4
- package/lib/core/config-attach-extensions.js +3 -0
- package/lib/core/config-device-dataplane.js +185 -0
- package/lib/core/config-platform-controller.js +44 -0
- package/lib/core/config-setup-installation-profile.js +42 -0
- package/lib/core/config-setup-platform-mode.js +46 -0
- package/lib/core/config.js +46 -36
- package/lib/core/secrets-admin-env.js +6 -2
- package/lib/core/secrets-ensure.js +4 -0
- package/lib/core/secrets-env-content.js +54 -48
- package/lib/core/secrets-env-write.js +10 -1
- package/lib/core/secrets-infra-placeholder-sync.js +2 -0
- package/lib/core/setup-installation-profile.js +43 -0
- package/lib/core/setup-platform-mode.js +55 -0
- package/lib/datasource/agent-trust-debug-log.js +45 -0
- package/lib/datasource/agent-trust-fetch.js +115 -0
- package/lib/datasource/agent-trust-map.js +101 -0
- package/lib/datasource/agent-trust-mock.js +44 -0
- package/lib/datasource/agent-trust-run.js +95 -0
- package/lib/datasource/agent-trust-timeout.js +25 -0
- package/lib/datasource/audit-evidence-display.js +80 -0
- package/lib/datasource/audit-evidence-extract-debug.js +115 -0
- package/lib/datasource/audit-evidence-extract.js +180 -0
- package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
- package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
- package/lib/datasource/audit-evidence-poll.js +109 -0
- package/lib/datasource/audit-evidence-run.js +177 -0
- package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
- package/lib/datasource/audit-evidence-verify-matrix.js +205 -0
- package/lib/datasource/audit-evidence-verify.js +108 -0
- package/lib/datasource/bulk-loader-run-batches.js +100 -0
- package/lib/datasource/bulk-loader-service-retry.js +52 -0
- package/lib/datasource/bulk-loader-service.js +127 -0
- package/lib/datasource/capability/run-capability-dimension.js +2 -1
- package/lib/datasource/datasource-exporter-resolve.js +82 -0
- package/lib/datasource/datasource-exporter-service.js +144 -0
- package/lib/datasource/datasource-identifier.js +148 -0
- package/lib/datasource/datasource-load-export-context.js +95 -0
- package/lib/datasource/integration-context.js +6 -4
- package/lib/datasource/local-data-paths.js +145 -0
- package/lib/datasource/log-cleaner.js +241 -0
- package/lib/datasource/log-viewer.js +111 -6
- package/lib/datasource/record-file-parser.js +85 -0
- package/lib/datasource/record-mapper.js +129 -0
- package/lib/datasource/resolve-app.js +74 -55
- package/lib/datasource/test-e2e.js +29 -2
- package/lib/datasource/unified-validation-run-body.js +3 -1
- package/lib/datasource/unified-validation-run-resolve.js +45 -12
- package/lib/datasource/unified-validation-run.js +47 -18
- package/lib/datasource/validate.js +37 -20
- package/lib/deployment/environment-poll-status.js +138 -0
- package/lib/deployment/environment.js +42 -34
- package/lib/external-system/download.js +21 -20
- package/lib/external-system/generator.js +5 -1
- package/lib/external-system/integration-auth-context.js +45 -0
- package/lib/external-system/test-auth.js +12 -5
- package/lib/external-system/test-system-level.js +25 -4
- package/lib/external-system/test.js +9 -7
- package/lib/generator/external-controller-manifest.js +15 -0
- package/lib/governance/governance-cli-errors.js +96 -0
- package/lib/governance/governance-download-display.js +38 -0
- package/lib/governance/governance-pack-loader.js +70 -0
- package/lib/governance/governance-run-display.js +309 -0
- package/lib/identity/identity-apply-core.js +108 -0
- package/lib/identity/identity-apply-phases.js +244 -0
- package/lib/identity/identity-apply-service.js +77 -0
- package/lib/identity/identity-csv-parser.js +114 -0
- package/lib/infrastructure/admin-secrets-apply.js +84 -0
- package/lib/infrastructure/admin-secrets-ensure.js +130 -0
- package/lib/infrastructure/admin-secrets-resolve.js +95 -0
- package/lib/infrastructure/admin-secrets-sync.js +91 -0
- package/lib/infrastructure/helpers.js +23 -129
- package/lib/infrastructure/index.js +5 -6
- package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
- package/lib/internal/fs-real-sync.js +29 -1
- package/lib/lifecycle/certification-progress.js +231 -0
- package/lib/lifecycle/dataplane-ui-url.js +145 -0
- package/lib/lifecycle/exit-codes.js +24 -0
- package/lib/lifecycle/json-envelope.js +25 -0
- package/lib/lifecycle/lifecycle-governance-options.js +51 -0
- package/lib/lifecycle/logger-quiet.js +29 -0
- package/lib/lifecycle/open-api-published.js +59 -0
- package/lib/lifecycle/operations-readiness-metrics.js +101 -0
- package/lib/lifecycle/product-model.js +196 -0
- package/lib/lifecycle/report-display.js +471 -0
- package/lib/lifecycle/scenario-upload.js +191 -0
- package/lib/lifecycle/verify-step-progress.js +87 -0
- package/lib/parameters/infra-kv-discovery.js +27 -2
- package/lib/protection/auth-context.js +51 -0
- package/lib/protection/convert-batch.js +90 -0
- package/lib/protection/load.js +41 -0
- package/lib/protection/paths.js +158 -0
- package/lib/protection/preflight-datasource-ready.js +46 -0
- package/lib/protection/protection-create-probe-lines.js +142 -0
- package/lib/protection/protection-create-probes.js +95 -0
- package/lib/protection/protection-create-scaffold.js +281 -0
- package/lib/protection/protection-display-helpers.js +445 -0
- package/lib/protection/protection-display.js +215 -0
- package/lib/protection/protection-preset-registry.js +97 -0
- package/lib/protection/report-exit.js +62 -0
- package/lib/protection/resolve.js +202 -0
- package/lib/protection/run-commands-validate.js +130 -0
- package/lib/protection/run-commands.js +216 -0
- package/lib/protection/run-protection-create-helpers.js +134 -0
- package/lib/protection/run-protection-create-probes-flow.js +43 -0
- package/lib/protection/run-protection-create.js +191 -0
- package/lib/protection/scope.js +22 -0
- package/lib/protection/sync-after-upload.js +64 -0
- package/lib/protection/upload-batch.js +127 -0
- package/lib/protection/validate-batch.js +113 -0
- package/lib/protection/validate-local.js +65 -0
- package/lib/resolvers/dimension-file.js +29 -4
- package/lib/schema/application-schema.json +1 -1
- package/lib/schema/datasource-test-run.schema.json +89 -6
- package/lib/schema/external-datasource.schema.json +2636 -2588
- package/lib/schema/external-system.schema.json +1089 -761
- package/lib/schema/flag-map-validation-run.json +2 -2
- package/lib/schema/infra.parameter.yaml +45 -0
- package/lib/schema/protection.schema.json +374 -0
- package/lib/schema/type/credential-field-registry.json +642 -0
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/agent-trust-run-display.js +231 -0
- package/lib/utils/agent-trust-run-exit.js +59 -0
- package/lib/utils/agent-trust-wait-ui.js +94 -0
- package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
- package/lib/utils/api.js +55 -31
- package/lib/utils/app-relative-path-env.js +112 -0
- package/lib/utils/cli-exit-codes.js +30 -0
- package/lib/utils/cli-secrets-error-format.js +83 -21
- package/lib/utils/cli-sync-options.js +33 -0
- package/lib/utils/cli-utils.js +16 -4
- package/lib/utils/compose-generate-docker-compose.js +4 -0
- package/lib/utils/compose-traefik-ingress-base.js +16 -1
- package/lib/utils/config-secrets-path.js +46 -0
- package/lib/utils/controller-url.js +88 -1
- package/lib/utils/credential-push-ui.js +90 -0
- package/lib/utils/credential-secrets-env.js +137 -9
- package/lib/utils/dataplane-cli-version-gate.js +202 -0
- package/lib/utils/dataplane-cli-version-help.js +74 -0
- package/lib/utils/dataplane-resolver.js +129 -2
- package/lib/utils/datasource-export-display.js +137 -0
- package/lib/utils/datasource-load-display.js +174 -0
- package/lib/utils/datasource-load-export-ui.js +120 -0
- package/lib/utils/datasource-test-run-capability-scope.js +3 -3
- package/lib/utils/datasource-test-run-display.js +3 -3
- package/lib/utils/datasource-test-run-tty-log.js +5 -1
- package/lib/utils/declarative-url-ports.js +3 -3
- package/lib/utils/deployment-auth-mode.js +41 -0
- package/lib/utils/developer-volume-id.js +33 -0
- package/lib/utils/env-copy.js +14 -9
- package/lib/utils/env-kv-orphan-lines.js +43 -0
- package/lib/utils/error-formatters/network-errors.js +13 -4
- package/lib/utils/external-env-template.js +1 -0
- package/lib/utils/external-system-readiness-core.js +10 -0
- package/lib/utils/external-system-readiness-display.js +80 -23
- package/lib/utils/health-check.js +4 -1
- package/lib/utils/help-builder.js +35 -26
- package/lib/utils/keycloak-realm-ready.js +101 -0
- package/lib/utils/load-cip-capacity-display-config.js +61 -15
- package/lib/utils/manifest-source-emit.js +24 -0
- package/lib/utils/pipeline-upload-auth-retry.js +82 -0
- package/lib/utils/platform-controller-url.js +156 -0
- package/lib/utils/postgres-platform-bootstrap.js +199 -0
- package/lib/utils/postgres-wipe.js +9 -2
- package/lib/utils/resolve-env-mode.js +47 -0
- package/lib/utils/secrets-generator.js +31 -25
- package/lib/utils/secrets-missing-error.js +164 -0
- package/lib/utils/semver-compare.js +127 -0
- package/lib/utils/service-url-label.js +81 -0
- package/lib/utils/setup-quiet-output.js +25 -0
- package/lib/utils/template-helpers.js +15 -0
- package/lib/utils/token-manager-client-credentials.js +201 -0
- package/lib/utils/token-manager-messages.js +8 -0
- package/lib/utils/token-manager-refresh.js +12 -2
- package/lib/utils/token-manager.js +86 -105
- package/lib/utils/upload-pipeline-ui.js +98 -0
- package/lib/utils/upload-sync-options.js +42 -0
- package/lib/utils/url-declarative-public-base.js +21 -3
- package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
- package/lib/utils/validation-poll-ui.js +22 -7
- package/lib/utils/validation-run-stage.js +45 -0
- package/lib/validation/wizard-config-validator.js +58 -19
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +2 -1
- package/templates/applications/dataplane/env.template +36 -1
- package/templates/applications/dataplane/rbac.yaml +4 -0
- package/templates/applications/miso-controller/env.template +16 -0
- package/templates/external-system/README.md.hbs +116 -11
- package/templates/python/docker-compose.hbs +19 -18
- package/templates/typescript/docker-compose.hbs +18 -17
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Step plan for verify-operations (plan 150.0).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const { validateExternalSystemComplete } = require('../validation/validate');
|
|
8
|
+
const { testExternalSystem, testExternalSystemIntegration } = require('../external-system/test');
|
|
9
|
+
const { runTestE2EForExternalSystem } = require('./test-e2e-external');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} systemKey
|
|
13
|
+
* @param {Object} options
|
|
14
|
+
* @returns {{ beforeSync: Array, afterSync: Array, e2e: Object }}
|
|
15
|
+
*/
|
|
16
|
+
function buildOperationsVerifyStepPlan(systemKey, options) {
|
|
17
|
+
return {
|
|
18
|
+
beforeSync: [
|
|
19
|
+
{
|
|
20
|
+
key: 'validation',
|
|
21
|
+
run: () => validateExternalSystemComplete(systemKey, { type: 'external' }),
|
|
22
|
+
ok: (result) => result.valid === true
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
key: 'unit',
|
|
26
|
+
run: () => testExternalSystem(systemKey, { verbose: false }),
|
|
27
|
+
ok: (result) => result.valid === true
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
afterSync: [
|
|
31
|
+
{
|
|
32
|
+
key: 'integration',
|
|
33
|
+
run: () =>
|
|
34
|
+
testExternalSystemIntegration(systemKey, {
|
|
35
|
+
environment: options.env,
|
|
36
|
+
noSync: true,
|
|
37
|
+
verbose: false,
|
|
38
|
+
debug: options.debug === true
|
|
39
|
+
}),
|
|
40
|
+
ok: (result) => result.success === true
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
e2e: {
|
|
44
|
+
key: 'e2e',
|
|
45
|
+
run: (progress) =>
|
|
46
|
+
runTestE2EForExternalSystem(systemKey, {
|
|
47
|
+
env: options.env,
|
|
48
|
+
noSync: true,
|
|
49
|
+
verbose: false,
|
|
50
|
+
debug: options.debug === true,
|
|
51
|
+
async: options.async !== false,
|
|
52
|
+
authConfig: options.authConfig,
|
|
53
|
+
dataplaneUrl: options.dataplaneUrl,
|
|
54
|
+
silentResolve: options.silentResolve === true,
|
|
55
|
+
quietPollUi: true,
|
|
56
|
+
onDatasourceProgress: progress?.setLabel
|
|
57
|
+
? ({ key, index, total }) =>
|
|
58
|
+
progress.setLabel(`Running E2E: ${key} (${index + 1}/${total})`)
|
|
59
|
+
: undefined
|
|
60
|
+
}),
|
|
61
|
+
ok: (result) => result.success === true
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = {
|
|
67
|
+
buildOperationsVerifyStepPlan
|
|
68
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview verify-operations step runners (plan 150.0).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const { syncLocalIfRequested } = require('./test-e2e-external');
|
|
8
|
+
const { cliOptsSkipSync } = require('../utils/cli-sync-options');
|
|
9
|
+
const { buildOperationsVerifyStepPlan } = require('./verify-operations-step-plan');
|
|
10
|
+
const { runWithVerifyStepProgress } = require('../lifecycle/verify-step-progress');
|
|
11
|
+
|
|
12
|
+
const STEP_PROGRESS = {
|
|
13
|
+
validation: 'Validating local integration',
|
|
14
|
+
unit: 'Running unit tests',
|
|
15
|
+
integration: 'Running integration tests on dataplane',
|
|
16
|
+
e2e: 'Running E2E tests'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {Object} options
|
|
21
|
+
* @param {Object} uploadCtx
|
|
22
|
+
*/
|
|
23
|
+
function attachUploadAuthToOptions(options, uploadCtx) {
|
|
24
|
+
if (!uploadCtx?.authConfig || !uploadCtx?.dataplaneUrl) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
options.authConfig = uploadCtx.authConfig;
|
|
28
|
+
options.dataplaneUrl = uploadCtx.dataplaneUrl;
|
|
29
|
+
options.silentResolve = true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {Function} runner
|
|
34
|
+
* @param {Function} isSuccess
|
|
35
|
+
* @param {Object} options
|
|
36
|
+
* @returns {Promise<boolean>}
|
|
37
|
+
*/
|
|
38
|
+
async function runVerifyStep(runner, isSuccess) {
|
|
39
|
+
const outcome = await runner();
|
|
40
|
+
return isSuccess(outcome);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {Object} stepResults
|
|
45
|
+
* @param {string} key
|
|
46
|
+
* @param {boolean} passed
|
|
47
|
+
* @param {boolean} continueOnFail
|
|
48
|
+
* @returns {boolean} false when the verify flow should stop early
|
|
49
|
+
*/
|
|
50
|
+
function recordVerifyStep(stepResults, key, passed, continueOnFail) {
|
|
51
|
+
stepResults[key] = passed;
|
|
52
|
+
return passed || continueOnFail;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {Object} stepResults
|
|
57
|
+
* @param {Object} step
|
|
58
|
+
* @param {boolean} continueOnFail
|
|
59
|
+
* @param {Object} options
|
|
60
|
+
* @returns {Promise<boolean>}
|
|
61
|
+
*/
|
|
62
|
+
async function runTrackedVerifyStep(stepResults, step, continueOnFail, options) {
|
|
63
|
+
const label = STEP_PROGRESS[step.key] || step.key;
|
|
64
|
+
const passed = await runWithVerifyStepProgress(
|
|
65
|
+
label,
|
|
66
|
+
async(progress) => runVerifyStep(() => step.run(progress), step.ok),
|
|
67
|
+
options
|
|
68
|
+
);
|
|
69
|
+
return recordVerifyStep(stepResults, step.key, passed, continueOnFail);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @async
|
|
74
|
+
* @param {string} systemKey
|
|
75
|
+
* @param {Object} options
|
|
76
|
+
* @returns {Promise<{ stepResults: Object, hardFailure: boolean, stoppedEarly: boolean }>}
|
|
77
|
+
*/
|
|
78
|
+
async function runOperationsVerifySteps(systemKey, options) {
|
|
79
|
+
const stepResults = { validation: false, unit: false, integration: false, e2e: false };
|
|
80
|
+
const continueOnFail = options.continue === true;
|
|
81
|
+
const plan = buildOperationsVerifyStepPlan(systemKey, options);
|
|
82
|
+
|
|
83
|
+
for (const step of plan.beforeSync) {
|
|
84
|
+
if (!(await runTrackedVerifyStep(stepResults, step, continueOnFail, options))) {
|
|
85
|
+
return { stepResults, hardFailure: true, stoppedEarly: true };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!cliOptsSkipSync(options)) {
|
|
90
|
+
const uploadCtx = await syncLocalIfRequested(systemKey, options);
|
|
91
|
+
attachUploadAuthToOptions(options, uploadCtx);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
for (const step of plan.afterSync) {
|
|
95
|
+
if (!(await runTrackedVerifyStep(stepResults, step, continueOnFail, options))) {
|
|
96
|
+
return { stepResults, hardFailure: true, stoppedEarly: true };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const e2eLabel = STEP_PROGRESS.e2e;
|
|
101
|
+
stepResults.e2e = await runWithVerifyStepProgress(
|
|
102
|
+
e2eLabel,
|
|
103
|
+
async(progress) => runVerifyStep(() => plan.e2e.run(progress), plan.e2e.ok),
|
|
104
|
+
options
|
|
105
|
+
);
|
|
106
|
+
return { stepResults, hardFailure: !stepResults.e2e, stoppedEarly: false };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = {
|
|
110
|
+
runOperationsVerifySteps
|
|
111
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CLI action for `aifabrix verify-trust` (plan 150.0).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const logger = require('../utils/logger');
|
|
10
|
+
const { handleCommandError } = require('../utils/cli-utils');
|
|
11
|
+
const { runVerifyTrustForExternalSystem } = require('./verify-trust-external');
|
|
12
|
+
const { normalizeTestTrustCliOptions } = require('./test-trust-cli-options');
|
|
13
|
+
const { displayVerifyTrustTTY } = require('../lifecycle/report-display');
|
|
14
|
+
const { exitCodeFromVerdict } = require('../lifecycle/exit-codes');
|
|
15
|
+
const { buildJsonEnvelope } = require('../lifecycle/json-envelope');
|
|
16
|
+
|
|
17
|
+
async function runVerifyTrustCommandAction(appName, options, cmd) {
|
|
18
|
+
const opts = normalizeTestTrustCliOptions(options, cmd);
|
|
19
|
+
const pathsUtil = require('../utils/paths');
|
|
20
|
+
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
21
|
+
if (!appType || appType.baseDir !== 'integration') {
|
|
22
|
+
throw new Error(
|
|
23
|
+
'verify-trust applies to external integration folders only (integration/<systemKey>/).'
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const result = await runVerifyTrustForExternalSystem(appName, {
|
|
28
|
+
env: opts.env,
|
|
29
|
+
verbose: opts.verbose,
|
|
30
|
+
debug: opts.debug,
|
|
31
|
+
noSync: opts.noSync === true,
|
|
32
|
+
revalidate: opts.revalidate === true,
|
|
33
|
+
timeout: opts.timeout
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (opts.json) {
|
|
37
|
+
const envelope = buildJsonEnvelope(
|
|
38
|
+
{
|
|
39
|
+
systemKey: result.systemKey,
|
|
40
|
+
command: result.command,
|
|
41
|
+
verdict: result.verdict,
|
|
42
|
+
businessContextConfidencePercent: result.businessContextConfidencePercent,
|
|
43
|
+
datasourceRows: opts.details ? result.datasourceRows : undefined
|
|
44
|
+
},
|
|
45
|
+
opts.details || opts.verbose
|
|
46
|
+
);
|
|
47
|
+
logger.log(JSON.stringify(envelope, null, 2));
|
|
48
|
+
} else {
|
|
49
|
+
displayVerifyTrustTTY(result.systemKey, result, { details: opts.verbose || opts.details });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const exitCode = exitCodeFromVerdict(result.verdict);
|
|
53
|
+
if (exitCode !== 0) {
|
|
54
|
+
process.exit(exitCode);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function verifyTrustCommandHandler(appName, options, cmd) {
|
|
59
|
+
try {
|
|
60
|
+
await runVerifyTrustCommandAction(appName, options, cmd);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
handleCommandError(error, 'verify-trust');
|
|
63
|
+
process.exit(3);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = {
|
|
68
|
+
runVerifyTrustCommandAction,
|
|
69
|
+
verifyTrustCommandHandler
|
|
70
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview verify-trust orchestration with product-model rollup (plan 150.0).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { runTestTrustForExternalSystem } = require('./test-trust-external');
|
|
10
|
+
const {
|
|
11
|
+
VERDICT,
|
|
12
|
+
verdictFromPassed,
|
|
13
|
+
worstConfidencePercent
|
|
14
|
+
} = require('../lifecycle/product-model');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {Array<Object>} rows
|
|
18
|
+
* @returns {Array<Object>}
|
|
19
|
+
*/
|
|
20
|
+
function mapTrustDatasourceRows(rows) {
|
|
21
|
+
return (rows || []).map(row => {
|
|
22
|
+
const tr = row.trustRun;
|
|
23
|
+
const confidencePercent =
|
|
24
|
+
tr && typeof tr.confidence === 'number' ? Math.round(tr.confidence * 100) : null;
|
|
25
|
+
const verdict = row.success ? VERDICT.VERIFIED : VERDICT.FAILED;
|
|
26
|
+
return {
|
|
27
|
+
datasourceKey: row.key,
|
|
28
|
+
verdict,
|
|
29
|
+
confidencePercent,
|
|
30
|
+
trustDecision: tr?.trustDecision,
|
|
31
|
+
error: row.error
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @async
|
|
38
|
+
* @param {string} systemKey
|
|
39
|
+
* @param {Object} options
|
|
40
|
+
* @returns {Promise<Object>}
|
|
41
|
+
*/
|
|
42
|
+
async function runVerifyTrustForExternalSystem(systemKey, options = {}) {
|
|
43
|
+
const { success, results, systemKey: resolvedKey } = await runTestTrustForExternalSystem(
|
|
44
|
+
systemKey,
|
|
45
|
+
options
|
|
46
|
+
);
|
|
47
|
+
const datasourceRows = mapTrustDatasourceRows(results);
|
|
48
|
+
const confidences = datasourceRows
|
|
49
|
+
.map(r => (typeof r.confidencePercent === 'number' ? r.confidencePercent / 100 : null))
|
|
50
|
+
.filter(v => v !== null);
|
|
51
|
+
const businessContextConfidencePercent = worstConfidencePercent(confidences);
|
|
52
|
+
const verdict = verdictFromPassed(success);
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
systemKey: resolvedKey || systemKey,
|
|
56
|
+
command: 'verify-trust',
|
|
57
|
+
verdict,
|
|
58
|
+
businessContextConfidencePercent,
|
|
59
|
+
datasourceRows,
|
|
60
|
+
results
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = {
|
|
65
|
+
runVerifyTrustForExternalSystem,
|
|
66
|
+
mapTrustDatasourceRows
|
|
67
|
+
};
|
|
@@ -17,6 +17,7 @@ const VALID_ENTITY_TYPES = new Set([
|
|
|
17
17
|
'none'
|
|
18
18
|
]);
|
|
19
19
|
const VALID_PORTAL_FIELDS = new Set(['text', 'textarea', 'select', 'json', 'boolean', 'number']);
|
|
20
|
+
const { repairTestPayload } = require('./repair-datasource-test-payload');
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Normalize system config fields to schema constraints
|
|
@@ -34,6 +35,45 @@ function normalizeSystemConfig(systemConfig) {
|
|
|
34
35
|
return systemConfig;
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
/**
|
|
39
|
+
* @param {Object} datasourceConfig - Datasource config (mutated)
|
|
40
|
+
*/
|
|
41
|
+
function normalizePortalInput(datasourceConfig) {
|
|
42
|
+
if (!Array.isArray(datasourceConfig.portalInput)) return;
|
|
43
|
+
datasourceConfig.portalInput = datasourceConfig.portalInput.filter(item => {
|
|
44
|
+
if (!item || typeof item !== 'object') return false;
|
|
45
|
+
if (!item.name || !item.field || !item.label) return false;
|
|
46
|
+
return VALID_PORTAL_FIELDS.has(item.field);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {Object} datasourceConfig - Datasource config (mutated)
|
|
52
|
+
*/
|
|
53
|
+
function normalizeCipOutputModes(datasourceConfig) {
|
|
54
|
+
const operations = datasourceConfig.execution?.cip?.operations;
|
|
55
|
+
if (!operations) return;
|
|
56
|
+
for (const operation of Object.values(operations)) {
|
|
57
|
+
if (!operation || !Array.isArray(operation.steps)) continue;
|
|
58
|
+
for (const step of operation.steps) {
|
|
59
|
+
if (step?.output?.mode && step.output.mode !== 'records') {
|
|
60
|
+
step.output.mode = 'records';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {Object} datasourceConfig - Datasource config (mutated)
|
|
68
|
+
*/
|
|
69
|
+
function normalizeWizardTestPayload(datasourceConfig) {
|
|
70
|
+
const attrs = datasourceConfig.fieldMappings?.attributes;
|
|
71
|
+
if (!datasourceConfig.metadataSchema || !attrs || Object.keys(attrs).length === 0) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
repairTestPayload(datasourceConfig, []);
|
|
75
|
+
}
|
|
76
|
+
|
|
37
77
|
/**
|
|
38
78
|
* Normalize datasource config fields to schema constraints
|
|
39
79
|
* @function normalizeDatasourceConfig
|
|
@@ -47,29 +87,9 @@ function normalizeDatasourceConfig(datasourceConfig) {
|
|
|
47
87
|
if (datasourceConfig.entityType && !VALID_ENTITY_TYPES.has(datasourceConfig.entityType)) {
|
|
48
88
|
datasourceConfig.entityType = ENTITY_TYPE_FALLBACK;
|
|
49
89
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
if (!item.name || !item.field || !item.label) {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
return VALID_PORTAL_FIELDS.has(item.field);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
if (datasourceConfig.execution?.cip?.operations) {
|
|
62
|
-
for (const operation of Object.values(datasourceConfig.execution.cip.operations)) {
|
|
63
|
-
if (!operation || !Array.isArray(operation.steps)) {
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
for (const step of operation.steps) {
|
|
67
|
-
if (step?.output?.mode && step.output.mode !== 'records') {
|
|
68
|
-
step.output.mode = 'records';
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
90
|
+
normalizePortalInput(datasourceConfig);
|
|
91
|
+
normalizeCipOutputModes(datasourceConfig);
|
|
92
|
+
normalizeWizardTestPayload(datasourceConfig);
|
|
73
93
|
return datasourceConfig;
|
|
74
94
|
}
|
|
75
95
|
|
|
@@ -512,7 +512,9 @@ async function setupDataplaneAndAuth(options, appName) {
|
|
|
512
512
|
} catch (error) {
|
|
513
513
|
throw new Error(`Authentication failed: ${error.message}`);
|
|
514
514
|
}
|
|
515
|
+
const { applyLabDataplaneApiKeyBearer } = require('../utils/token-manager');
|
|
515
516
|
requireBearerForDataplanePipeline(authConfig);
|
|
517
|
+
applyLabDataplaneApiKeyBearer(authConfig);
|
|
516
518
|
const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
|
|
517
519
|
let dataplaneUrl;
|
|
518
520
|
try {
|
|
@@ -525,6 +527,9 @@ async function setupDataplaneAndAuth(options, appName) {
|
|
|
525
527
|
' aifabrix login'
|
|
526
528
|
);
|
|
527
529
|
}
|
|
530
|
+
// Plan 142.0: gate wizard dataplane calls by the dataplane-advertised minimum Builder CLI version.
|
|
531
|
+
const { assertDataplaneCliVersionCompatible } = require('../utils/dataplane-cli-version-gate');
|
|
532
|
+
await assertDataplaneCliVersionCompatible(dataplaneUrl, { controllerUrl });
|
|
528
533
|
return { dataplaneUrl, authConfig };
|
|
529
534
|
}
|
|
530
535
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cryptographically strong passwords for pro setup autogenerate.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Pro installation password generation (show-once in setup wizard)
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const crypto = require('crypto');
|
|
12
|
+
|
|
13
|
+
const PRO_PASSWORD_BYTE_LENGTH = 18;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* One random password suitable for admin roles (URL-safe, no quotes).
|
|
17
|
+
* @returns {string}
|
|
18
|
+
*/
|
|
19
|
+
function generateRandomAdminPassword() {
|
|
20
|
+
return crypto.randomBytes(PRO_PASSWORD_BYTE_LENGTH).toString('base64url');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Distinct passwords for infra, Keycloak install, and platform UI login.
|
|
25
|
+
* @returns {{ infra: string, keycloak: string, platform: string }}
|
|
26
|
+
*/
|
|
27
|
+
function generateProAdminPasswords() {
|
|
28
|
+
return {
|
|
29
|
+
infra: generateRandomAdminPassword(),
|
|
30
|
+
keycloak: generateRandomAdminPassword(),
|
|
31
|
+
platform: generateRandomAdminPassword()
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
generateRandomAdminPassword,
|
|
37
|
+
generateProAdminPasswords
|
|
38
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map setup password bundles onto admin-secrets.env keys.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Single (dev) vs split (pro) admin credential bundles
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const DEFAULT_REDIS_HOST = 'local:redis:6379:0:';
|
|
12
|
+
const DEFAULT_REDIS_COMMANDER_USER = 'admin';
|
|
13
|
+
const DEFAULT_KEYCLOAK_ADMIN_USERNAME = 'admin';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {'single'|'split'} AdminPasswordBundleMode
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {Object} AdminPasswordBundleSingle
|
|
21
|
+
* @property {'single'} mode
|
|
22
|
+
* @property {string} password
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {Object} AdminPasswordBundleSplit
|
|
27
|
+
* @property {'split'} mode
|
|
28
|
+
* @property {string} infra
|
|
29
|
+
* @property {string} keycloak
|
|
30
|
+
* @property {string} platform
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {string} password
|
|
35
|
+
* @returns {AdminPasswordBundleSingle}
|
|
36
|
+
*/
|
|
37
|
+
function singlePasswordBundle(password) {
|
|
38
|
+
return { mode: 'single', password: String(password) };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {{ infra: string, keycloak: string, platform: string }} parts
|
|
43
|
+
* @returns {AdminPasswordBundleSplit}
|
|
44
|
+
*/
|
|
45
|
+
function splitPasswordBundle(parts) {
|
|
46
|
+
return {
|
|
47
|
+
mode: 'split',
|
|
48
|
+
infra: String(parts.infra),
|
|
49
|
+
keycloak: String(parts.keycloak),
|
|
50
|
+
platform: String(parts.platform)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Apply bundle onto a decrypted admin-secrets object (mutates copy).
|
|
56
|
+
* @param {Object.<string, string>} adminObj
|
|
57
|
+
* @param {AdminPasswordBundleSingle|AdminPasswordBundleSplit} bundle
|
|
58
|
+
* @returns {Object.<string, string>}
|
|
59
|
+
*/
|
|
60
|
+
function applyPasswordBundleToAdminObj(adminObj, bundle) {
|
|
61
|
+
const merged = { ...(adminObj || {}) };
|
|
62
|
+
merged.REDIS_HOST = merged.REDIS_HOST || DEFAULT_REDIS_HOST;
|
|
63
|
+
merged.REDIS_COMMANDER_USER = merged.REDIS_COMMANDER_USER || DEFAULT_REDIS_COMMANDER_USER;
|
|
64
|
+
merged.KEYCLOAK_ADMIN_USERNAME = DEFAULT_KEYCLOAK_ADMIN_USERNAME;
|
|
65
|
+
|
|
66
|
+
if (bundle.mode === 'single') {
|
|
67
|
+
const p = bundle.password;
|
|
68
|
+
merged.POSTGRES_PASSWORD = p;
|
|
69
|
+
merged.PGADMIN_DEFAULT_PASSWORD = p;
|
|
70
|
+
merged.REDIS_COMMANDER_PASSWORD = p;
|
|
71
|
+
merged.KEYCLOAK_ADMIN_PASSWORD = p;
|
|
72
|
+
merged.PLATFORM_ADMIN_PASSWORD = p;
|
|
73
|
+
return merged;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
merged.POSTGRES_PASSWORD = bundle.infra;
|
|
77
|
+
merged.PGADMIN_DEFAULT_PASSWORD = bundle.infra;
|
|
78
|
+
merged.REDIS_COMMANDER_PASSWORD = bundle.infra;
|
|
79
|
+
merged.KEYCLOAK_ADMIN_PASSWORD = bundle.keycloak;
|
|
80
|
+
merged.PLATFORM_ADMIN_PASSWORD = bundle.platform;
|
|
81
|
+
return merged;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Build bundle from setup / up-infra CLI options.
|
|
86
|
+
* @param {Object} [options]
|
|
87
|
+
* @returns {AdminPasswordBundleSingle|AdminPasswordBundleSplit|null}
|
|
88
|
+
*/
|
|
89
|
+
function passwordBundleFromCliOptions(options = {}) {
|
|
90
|
+
if (options.passwordBundle && options.passwordBundle.mode) {
|
|
91
|
+
return options.passwordBundle;
|
|
92
|
+
}
|
|
93
|
+
const infra = String(options.infraAdminPassword || '').trim();
|
|
94
|
+
const keycloak = String(options.keycloakAdminPassword || '').trim();
|
|
95
|
+
const platform = String(options.platformAdminPassword || '').trim();
|
|
96
|
+
if (infra && keycloak && platform) {
|
|
97
|
+
return splitPasswordBundle({ infra, keycloak, platform });
|
|
98
|
+
}
|
|
99
|
+
const single = String(options.adminPassword || options.adminPwd || '').trim();
|
|
100
|
+
if (single) {
|
|
101
|
+
return singlePasswordBundle(single);
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
singlePasswordBundle,
|
|
108
|
+
splitPasswordBundle,
|
|
109
|
+
applyPasswordBundleToAdminObj,
|
|
110
|
+
passwordBundleFromCliOptions
|
|
111
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map decrypted admin-secrets.env into platform container env keys.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Overlay KEYCLOAK_* / ONBOARDING_* from admin-secrets (plan 185 Phase 2)
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {Object.<string, string>} adminObj
|
|
13
|
+
* @returns {Object.<string, string>}
|
|
14
|
+
*/
|
|
15
|
+
function buildPlatformEnvOverlayFromAdminSecrets(adminObj) {
|
|
16
|
+
if (!adminObj || typeof adminObj !== 'object') return {};
|
|
17
|
+
const platformPwd =
|
|
18
|
+
adminObj.PLATFORM_ADMIN_PASSWORD ||
|
|
19
|
+
adminObj.ONBOARDING_ADMIN_PASSWORD ||
|
|
20
|
+
adminObj.MISO_ADMIN_PASSWORD ||
|
|
21
|
+
'';
|
|
22
|
+
const overlay = {};
|
|
23
|
+
if (adminObj.KEYCLOAK_ADMIN_USERNAME) {
|
|
24
|
+
overlay.KEYCLOAK_ADMIN_USERNAME = adminObj.KEYCLOAK_ADMIN_USERNAME;
|
|
25
|
+
}
|
|
26
|
+
if (adminObj.KEYCLOAK_ADMIN_PASSWORD) {
|
|
27
|
+
overlay.KEYCLOAK_ADMIN_PASSWORD = adminObj.KEYCLOAK_ADMIN_PASSWORD;
|
|
28
|
+
// Keycloak image reads KC_BOOTSTRAP_* on first start; keep in sync with admin-secrets (pro split bundles).
|
|
29
|
+
overlay.KC_BOOTSTRAP_ADMIN_PASSWORD = adminObj.KEYCLOAK_ADMIN_PASSWORD;
|
|
30
|
+
overlay.KC_BOOTSTRAP_ADMIN_USERNAME =
|
|
31
|
+
adminObj.KEYCLOAK_ADMIN_USERNAME || adminObj.KC_BOOTSTRAP_ADMIN_USERNAME || 'admin';
|
|
32
|
+
}
|
|
33
|
+
if (platformPwd) {
|
|
34
|
+
overlay.PLATFORM_ADMIN_PASSWORD = platformPwd;
|
|
35
|
+
overlay.ONBOARDING_ADMIN_PASSWORD = platformPwd;
|
|
36
|
+
overlay.MISO_ADMIN_PASSWORD = platformPwd;
|
|
37
|
+
}
|
|
38
|
+
const email = adminObj.PGADMIN_DEFAULT_EMAIL || adminObj.ONBOARDING_ADMIN_EMAIL;
|
|
39
|
+
if (email) {
|
|
40
|
+
overlay.ONBOARDING_ADMIN_EMAIL = email;
|
|
41
|
+
}
|
|
42
|
+
return overlay;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Apply admin-secrets values over resolved app env (admin-secrets wins for platform keys).
|
|
47
|
+
* @param {Object.<string, string>} envMap
|
|
48
|
+
* @param {Object.<string, string>} adminObj
|
|
49
|
+
*/
|
|
50
|
+
function applyAdminSecretsPlatformOverlay(envMap, adminObj) {
|
|
51
|
+
const overlay = buildPlatformEnvOverlayFromAdminSecrets(adminObj);
|
|
52
|
+
for (const [key, value] of Object.entries(overlay)) {
|
|
53
|
+
if (value !== undefined && value !== null && String(value).trim() !== '') {
|
|
54
|
+
envMap[key] = String(value);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = {
|
|
60
|
+
buildPlatformEnvOverlayFromAdminSecrets,
|
|
61
|
+
applyAdminSecretsPlatformOverlay
|
|
62
|
+
};
|
|
@@ -16,6 +16,31 @@ const config = require('./config');
|
|
|
16
16
|
const { decryptSecret, isEncrypted } = require('../utils/secrets-encryption');
|
|
17
17
|
const { ensureSecureFilePermissions } = require('../utils/secure-file-permissions');
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Whether an admin-secrets.env value must be double-quoted for safe round-trip parsing.
|
|
21
|
+
* @param {string} value
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
*/
|
|
24
|
+
function needsAdminEnvQuoting(value) {
|
|
25
|
+
const s = String(value ?? '');
|
|
26
|
+
return /[,\s#=]/.test(s) || s !== s.trim();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Format one KEY=value line for admin-secrets.env (quotes when needed).
|
|
31
|
+
* @param {string} key
|
|
32
|
+
* @param {string} value - Plaintext value (not yet encrypted)
|
|
33
|
+
* @returns {string}
|
|
34
|
+
*/
|
|
35
|
+
function formatAdminEnvLine(key, value) {
|
|
36
|
+
const safe = String(value ?? '').replace(/\n/g, ' ').trim();
|
|
37
|
+
if (!needsAdminEnvQuoting(safe)) {
|
|
38
|
+
return `${key}=${safe}`;
|
|
39
|
+
}
|
|
40
|
+
const escaped = safe.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
41
|
+
return `${key}="${escaped}"`;
|
|
42
|
+
}
|
|
43
|
+
|
|
19
44
|
/**
|
|
20
45
|
* Parse .env-style content into key-value map (excludes comments and empty lines).
|
|
21
46
|
* Values are trimmed; does not unescape quotes.
|
|
@@ -33,7 +58,9 @@ function parseAdminEnvContent(content) {
|
|
|
33
58
|
if (eq > 0) {
|
|
34
59
|
const key = trimmed.substring(0, eq).trim();
|
|
35
60
|
let value = trimmed.substring(eq + 1);
|
|
36
|
-
if (value.length >= 2 &&
|
|
61
|
+
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
|
|
62
|
+
value = value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
|
63
|
+
} else if (value.length >= 2 && value.startsWith('\'') && value.endsWith('\'')) {
|
|
37
64
|
value = value.slice(1, -1);
|
|
38
65
|
}
|
|
39
66
|
map[key] = value.trim();
|
|
@@ -94,8 +121,7 @@ function envObjectToContent(obj) {
|
|
|
94
121
|
const lines = [];
|
|
95
122
|
for (const [key, value] of Object.entries(obj)) {
|
|
96
123
|
if (key === undefined || key === '') continue;
|
|
97
|
-
|
|
98
|
-
lines.push(`${key}=${safe}`);
|
|
124
|
+
lines.push(formatAdminEnvLine(key, value));
|
|
99
125
|
}
|
|
100
126
|
return lines.join('\n');
|
|
101
127
|
}
|
|
@@ -103,5 +129,7 @@ function envObjectToContent(obj) {
|
|
|
103
129
|
module.exports = {
|
|
104
130
|
readAndDecryptAdminSecrets,
|
|
105
131
|
parseAdminEnvContent,
|
|
106
|
-
envObjectToContent
|
|
132
|
+
envObjectToContent,
|
|
133
|
+
needsAdminEnvQuoting,
|
|
134
|
+
formatAdminEnvLine
|
|
107
135
|
};
|