@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,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview aifabrix secret get – read one secret (local user file or shared-only)
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 2.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const { getAifabrixSecretsPath } = require('../core/config');
|
|
9
|
+
const { decryptSecretsObject } = require('../core/secrets-load');
|
|
10
|
+
const { loadPrimaryUserSecrets } = require('../utils/secrets-utils');
|
|
11
|
+
const { loadConfiguredSharedSecretsStore } = require('../utils/remote-secrets-loader');
|
|
12
|
+
const remoteDevAuth = require('../utils/remote-dev-auth');
|
|
13
|
+
const devApi = require('../api/dev.api');
|
|
14
|
+
const logger = require('../utils/logger');
|
|
15
|
+
|
|
16
|
+
const REMOTE_NOT_CONFIGURED_MSG =
|
|
17
|
+
'Remote server is not configured. Set remote-server and run "aifabrix dev init" first.';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Human-readable label for which store(s) were queried (paths included for file stores).
|
|
21
|
+
* @param {{ shared?: boolean }} options
|
|
22
|
+
* @returns {Promise<string>}
|
|
23
|
+
*/
|
|
24
|
+
async function resolveSecretsScopeLabel(options) {
|
|
25
|
+
const useSharedOnly = Boolean(options.shared || options['shared']);
|
|
26
|
+
const generalSecretsPath = await getAifabrixSecretsPath();
|
|
27
|
+
|
|
28
|
+
if (useSharedOnly) {
|
|
29
|
+
if (!generalSecretsPath) {
|
|
30
|
+
return 'shared secrets (aifabrix-secrets not configured; run aifabrix secret set-secrets-file <path>)';
|
|
31
|
+
}
|
|
32
|
+
const target = await remoteDevAuth.resolveSharedSecretsEndpoint(generalSecretsPath);
|
|
33
|
+
if (remoteDevAuth.isRemoteSecretsUrl(target)) {
|
|
34
|
+
const host = remoteDevAuth.getSharedSecretsRemoteHostname(target) || target;
|
|
35
|
+
return `shared secrets API (${host})`;
|
|
36
|
+
}
|
|
37
|
+
const resolved = path.isAbsolute(target) ? target : path.resolve(process.cwd(), target);
|
|
38
|
+
return `shared secrets file ${resolved}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const pathsUtil = require('../utils/paths');
|
|
42
|
+
const userPath = pathsUtil.getPrimaryUserSecretsLocalPath();
|
|
43
|
+
return `local secrets file ${userPath}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {unknown} value
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
*/
|
|
50
|
+
function isSecretPresent(value) {
|
|
51
|
+
if (value === undefined || value === null) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return String(value).trim() !== '';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {Array<{ name?: string, key?: string, value?: unknown }>} items
|
|
59
|
+
* @returns {Record<string, string>}
|
|
60
|
+
*/
|
|
61
|
+
function remoteSecretItemsToMap(items) {
|
|
62
|
+
const raw = {};
|
|
63
|
+
for (const item of items) {
|
|
64
|
+
const name = item?.name || item?.key;
|
|
65
|
+
if (typeof name === 'string' && item.value !== undefined) {
|
|
66
|
+
raw[name] = String(item.value);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return raw;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @param {string} target
|
|
74
|
+
* @returns {Promise<Record<string, string>>}
|
|
75
|
+
*/
|
|
76
|
+
async function loadRemoteSharedSecretsDecrypted(target) {
|
|
77
|
+
const auth = await remoteDevAuth.getRemoteDevAuth();
|
|
78
|
+
if (!auth) {
|
|
79
|
+
throw new Error(REMOTE_NOT_CONFIGURED_MSG);
|
|
80
|
+
}
|
|
81
|
+
const items = await devApi.listSecrets(
|
|
82
|
+
auth.serverUrl,
|
|
83
|
+
auth.clientCertPem,
|
|
84
|
+
auth.serverCaPem || undefined,
|
|
85
|
+
target
|
|
86
|
+
);
|
|
87
|
+
const label = remoteDevAuth.getSharedSecretsRemoteHostname(target) || 'shared secrets API';
|
|
88
|
+
return decryptSecretsObject(remoteSecretItemsToMap(items), { defaultSourceLabel: label });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Load shared secrets (file or remote), decrypted.
|
|
93
|
+
* @returns {Promise<Record<string, string>>}
|
|
94
|
+
*/
|
|
95
|
+
async function loadSharedSecretsDecrypted() {
|
|
96
|
+
const generalSecretsPath = await getAifabrixSecretsPath();
|
|
97
|
+
if (!generalSecretsPath) {
|
|
98
|
+
throw new Error('Shared secrets not configured. Set aifabrix-secrets in config.yaml.');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const target = await remoteDevAuth.resolveSharedSecretsEndpoint(generalSecretsPath);
|
|
102
|
+
if (remoteDevAuth.isRemoteSecretsUrl(target)) {
|
|
103
|
+
return loadRemoteSharedSecretsDecrypted(target);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const raw = await loadConfiguredSharedSecretsStore();
|
|
107
|
+
if (!raw || typeof raw !== 'object') {
|
|
108
|
+
return {};
|
|
109
|
+
}
|
|
110
|
+
const resolvedPath = path.isAbsolute(target) ? target : path.resolve(process.cwd(), target);
|
|
111
|
+
return decryptSecretsObject(raw, { defaultSourceLabel: resolvedPath });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Load and decrypt the primary user secrets file only (not aifabrix-secrets / shared).
|
|
116
|
+
* @returns {Promise<Record<string, string>>}
|
|
117
|
+
*/
|
|
118
|
+
async function loadLocalUserSecretsDecrypted() {
|
|
119
|
+
const pathsUtil = require('../utils/paths');
|
|
120
|
+
const userPath = pathsUtil.getPrimaryUserSecretsLocalPath();
|
|
121
|
+
const raw = loadPrimaryUserSecrets();
|
|
122
|
+
return decryptSecretsObject(raw || {}, { defaultSourceLabel: userPath });
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Load secrets for lookup: local user file (default) or shared store only (--shared).
|
|
127
|
+
* @param {{ shared?: boolean }} options
|
|
128
|
+
* @returns {Promise<Record<string, string>>}
|
|
129
|
+
*/
|
|
130
|
+
async function loadSecretsForGet(options) {
|
|
131
|
+
if (options.shared || options['shared']) {
|
|
132
|
+
return loadSharedSecretsDecrypted();
|
|
133
|
+
}
|
|
134
|
+
return loadLocalUserSecretsDecrypted();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Handle secret get command.
|
|
139
|
+
* @param {string} key - Secret key (no kv:// prefix)
|
|
140
|
+
* @param {Object} options
|
|
141
|
+
* @param {boolean} [options.shared] - Shared store only (aifabrix-secrets); default is local user file only
|
|
142
|
+
* @param {boolean} [options.exists] - Exit 0 when present; no stdout (script-friendly)
|
|
143
|
+
* @param {boolean} [options.json] - JSON { key, exists, value }
|
|
144
|
+
* @returns {Promise<{ key: string, exists: boolean, value?: string }>}
|
|
145
|
+
*/
|
|
146
|
+
async function handleSecretsGet(key, options = {}) {
|
|
147
|
+
if (!key || typeof key !== 'string') {
|
|
148
|
+
throw new Error('Secret key is required and must be a string');
|
|
149
|
+
}
|
|
150
|
+
if (key.startsWith('kv://')) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
'Secret key must not start with kv://. Use the key path without the prefix (e.g. hubspot-demo/token).'
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const secrets = await loadSecretsForGet(options);
|
|
157
|
+
const value = secrets[key];
|
|
158
|
+
const present = isSecretPresent(value);
|
|
159
|
+
|
|
160
|
+
if (!present) {
|
|
161
|
+
const scope = await resolveSecretsScopeLabel(options);
|
|
162
|
+
throw new Error(`Secret '${key}' is missing or empty in ${scope}.`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (options.exists || options['exists']) {
|
|
166
|
+
return { key, exists: true };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (options.json || options['json']) {
|
|
170
|
+
logger.log(JSON.stringify({ key, exists: true, value: String(value) }));
|
|
171
|
+
return { key, exists: true, value: String(value) };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
logger.log(String(value));
|
|
175
|
+
return { key, exists: true, value: String(value) };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
module.exports = {
|
|
179
|
+
handleSecretsGet,
|
|
180
|
+
isSecretPresent,
|
|
181
|
+
loadSecretsForGet,
|
|
182
|
+
loadLocalUserSecretsDecrypted,
|
|
183
|
+
resolveSecretsScopeLabel
|
|
184
|
+
};
|
|
@@ -56,6 +56,8 @@ function listKeysFromYamlFile(filePath) {
|
|
|
56
56
|
* @param {string} filePath - Absolute path
|
|
57
57
|
*/
|
|
58
58
|
function writeEmptySecretsFile(filePath) {
|
|
59
|
+
const { assertWritableSecretsPathForTests } = require('../utils/aifabrix-test-runtime-guard');
|
|
60
|
+
assertWritableSecretsPathForTests(filePath);
|
|
59
61
|
const yamlContent = yaml.dump({}, { indent: 2, lineWidth: -1, noRefs: true, sortKeys: false });
|
|
60
62
|
fs.writeFileSync(filePath, yamlContent, { mode: 0o600 });
|
|
61
63
|
}
|
|
@@ -217,4 +219,4 @@ async function handleSecretsRemoveAll(options) {
|
|
|
217
219
|
await removeAllSharedSecrets(generalSecretsPath, options);
|
|
218
220
|
}
|
|
219
221
|
|
|
220
|
-
module.exports = { handleSecretsRemoveAll };
|
|
222
|
+
module.exports = { handleSecretsRemoveAll, writeEmptySecretsFile };
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template materialization and Docker image pull for `aifabrix setup` modes.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Setup image refresh and platform template bootstrap
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const chalk = require('chalk');
|
|
14
|
+
|
|
15
|
+
const config = require('../core/config');
|
|
16
|
+
const pathsUtil = require('../utils/paths');
|
|
17
|
+
const logger = require('../utils/logger');
|
|
18
|
+
const dockerUtils = require('../utils/docker');
|
|
19
|
+
const dockerExec = require('../utils/docker-exec');
|
|
20
|
+
const infraHelpers = require('../infrastructure/helpers');
|
|
21
|
+
const upCommon = require('./up-common');
|
|
22
|
+
const { sectionTitle, formatDatasourceListRow } = require('../utils/cli-test-layout-chalk');
|
|
23
|
+
const { startSpinner, stopSpinnerSuccess } = require('./setup-spinners');
|
|
24
|
+
|
|
25
|
+
const PLATFORM_APPS = ['keycloak', 'miso-controller', 'dataplane'];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Pull infra-compose images (postgres, redis, optional pgadmin/redis-commander/traefik).
|
|
29
|
+
*
|
|
30
|
+
* @async
|
|
31
|
+
* @param {{ quiet?: boolean }} [opts]
|
|
32
|
+
* @returns {Promise<void>}
|
|
33
|
+
*/
|
|
34
|
+
async function pullInfraImages(opts = {}) {
|
|
35
|
+
const quiet = Boolean(opts.quiet);
|
|
36
|
+
const devId = await config.getDeveloperId();
|
|
37
|
+
const infraDir = path.join(pathsUtil.getAifabrixSystemDir(), infraHelpers.getInfraDirName(devId));
|
|
38
|
+
const composePath = path.join(infraDir, 'compose.yaml');
|
|
39
|
+
if (!fs.existsSync(composePath)) {
|
|
40
|
+
if (!quiet) {
|
|
41
|
+
logger.log(chalk.yellow(`No infra compose file at ${composePath}; skipping image pull.`));
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const project = infraHelpers.getInfraProjectName(devId);
|
|
46
|
+
const composeCmd = await dockerUtils.getComposeCommand();
|
|
47
|
+
if (!quiet) {
|
|
48
|
+
logger.log('');
|
|
49
|
+
logger.log(sectionTitle('Pull images'));
|
|
50
|
+
}
|
|
51
|
+
if (quiet) {
|
|
52
|
+
await dockerExec.execWithDockerEnv(`${composeCmd} -f "${composePath}" -p ${project} pull`, { cwd: infraDir });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const spin = startSpinner('Pulling infrastructure images...');
|
|
56
|
+
await dockerExec.execWithDockerEnv(`${composeCmd} -f "${composePath}" -p ${project} pull`, { cwd: infraDir });
|
|
57
|
+
stopSpinnerSuccess(spin, 'Infrastructure images pulled');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {string} appName
|
|
62
|
+
* @returns {string} deploy.image or empty
|
|
63
|
+
*/
|
|
64
|
+
function readPlatformDeployImageRef(appName) {
|
|
65
|
+
try {
|
|
66
|
+
const { loadConfigFile } = require('../utils/config-format');
|
|
67
|
+
const builderPath = pathsUtil.getBuilderPath(appName);
|
|
68
|
+
const configPath = pathsUtil.resolveApplicationConfigPath(builderPath);
|
|
69
|
+
const cfg = loadConfigFile(configPath) || {};
|
|
70
|
+
const image = cfg.deploy && cfg.deploy.image;
|
|
71
|
+
return typeof image === 'string' ? image.trim() : '';
|
|
72
|
+
} catch {
|
|
73
|
+
return '';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Pull one platform app image from `builder/<app>/application.yaml` deploy.image.
|
|
79
|
+
*
|
|
80
|
+
* @async
|
|
81
|
+
* @param {string} appName
|
|
82
|
+
* @param {{ quiet?: boolean }} [opts]
|
|
83
|
+
* @returns {Promise<boolean>} True when a pull was attempted
|
|
84
|
+
*/
|
|
85
|
+
async function pullPlatformAppImage(appName, opts = {}) {
|
|
86
|
+
const quiet = Boolean(opts.quiet);
|
|
87
|
+
const imageRef = readPlatformDeployImageRef(appName);
|
|
88
|
+
if (!imageRef) {
|
|
89
|
+
if (!quiet) {
|
|
90
|
+
logger.log(formatDatasourceListRow('skipped', appName, 'no image ref'));
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
if (!quiet) {
|
|
96
|
+
const spin = startSpinner(`Pulling ${appName} image...`);
|
|
97
|
+
await dockerExec.execWithDockerEnv(`docker pull ${imageRef}`);
|
|
98
|
+
stopSpinnerSuccess(spin, `Pulled ${appName} image`);
|
|
99
|
+
} else {
|
|
100
|
+
await dockerExec.execWithDockerEnv(`docker pull ${imageRef}`);
|
|
101
|
+
}
|
|
102
|
+
} catch (err) {
|
|
103
|
+
logger.log(chalk.yellow(`Could not pull ${imageRef}: ${err.message}`));
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @async
|
|
110
|
+
* @param {{ quiet?: boolean }} [opts]
|
|
111
|
+
* @returns {Promise<number>} Count of images pulled
|
|
112
|
+
*/
|
|
113
|
+
async function pullPlatformImages(opts = {}) {
|
|
114
|
+
let pulled = 0;
|
|
115
|
+
for (const appName of PLATFORM_APPS) {
|
|
116
|
+
if (await pullPlatformAppImage(appName, opts)) {
|
|
117
|
+
pulled += 1;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return pulled;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Materialize platform templates and pull infra + platform images.
|
|
125
|
+
*
|
|
126
|
+
* @async
|
|
127
|
+
* @param {{ quiet?: boolean }} [opts]
|
|
128
|
+
* @returns {Promise<void>}
|
|
129
|
+
*/
|
|
130
|
+
async function runSetupImageRefresh(opts = {}) {
|
|
131
|
+
const quiet = Boolean(opts.quiet);
|
|
132
|
+
const spin = quiet ? startSpinner('Preparing platform configuration...') : null;
|
|
133
|
+
await upCommon.prepareUrlsLocalRegistryForUpPlatform({ silent: quiet });
|
|
134
|
+
await pullInfraImages({ quiet });
|
|
135
|
+
await pullPlatformImages({ quiet });
|
|
136
|
+
if (quiet) {
|
|
137
|
+
stopSpinnerSuccess(spin, 'Platform configuration ready');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
module.exports = {
|
|
142
|
+
PLATFORM_APPS,
|
|
143
|
+
pullInfraImages,
|
|
144
|
+
pullPlatformImages,
|
|
145
|
+
runSetupImageRefresh
|
|
146
|
+
};
|