@aifabrix/builder 2.45.5 → 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/project-rules.mdc +1 -0
- package/README.md +43 -17
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.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 +41 -136
- package/lib/api/api-response-errors.js +124 -0
- package/lib/api/governance-scenario-pack.api.js +159 -0
- package/lib/api/index.js +43 -3
- package/lib/api/lifecycle.api.js +77 -0
- package/lib/api/pipeline.api.js +3 -1
- package/lib/api/records-bulk.api.js +14 -1
- package/lib/api/validation-runner.js +3 -1
- package/lib/app/deploy-config.js +4 -1
- 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 +4 -0
- package/lib/cli/infra-guided-auth.js +109 -0
- package/lib/cli/infra-guided.js +84 -81
- package/lib/cli/setup-app.help.js +0 -31
- package/lib/cli/setup-app.js +28 -2
- package/lib/cli/setup-app.test-commands.js +5 -57
- package/lib/cli/setup-auth.js +25 -0
- 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 +25 -3
- 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 +22 -2
- package/lib/cli/setup-utility-repair.js +198 -0
- package/lib/cli/setup-utility-resolve.js +40 -4
- package/lib/cli/setup-utility-validate.js +197 -0
- package/lib/cli/setup-utility.js +4 -239
- package/lib/commands/auth-status-client-tokens.js +214 -0
- package/lib/commands/auth-status-dataplane-version.js +58 -20
- package/lib/commands/auth-status.js +41 -47
- package/lib/commands/datasource-test-trust-cli.js +27 -23
- package/lib/commands/datasource-unified-test-cli.js +6 -3
- package/lib/commands/datasource-unified-test-cli.options.js +5 -1
- package/lib/commands/datasource.js +7 -7
- package/lib/commands/dev-show-display.js +8 -1
- 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/lifecycle-command-action.js +123 -0
- package/lib/commands/lifecycle-external.js +268 -0
- package/lib/commands/login.js +11 -2
- 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 -296
- 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 +24 -8
- package/lib/commands/test-governance-external.js +3 -24
- package/lib/commands/test-trust-external.js +20 -21
- 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 +90 -108
- 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 +2 -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-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 +1 -1
- package/lib/datasource/agent-trust-run.js +5 -3
- package/lib/datasource/audit-evidence-extract-debug.js +30 -18
- package/lib/datasource/audit-evidence-extract.js +7 -4
- package/lib/datasource/audit-evidence-verify-matrix.js +54 -26
- package/lib/datasource/bulk-loader-run-batches.js +15 -3
- package/lib/datasource/datasource-load-export-context.js +3 -0
- package/lib/datasource/log-cleaner.js +2 -2
- package/lib/datasource/log-viewer.js +8 -8
- package/lib/datasource/test-e2e.js +4 -1
- package/lib/datasource/unified-validation-run-body.js +3 -1
- package/lib/datasource/unified-validation-run.js +5 -2
- 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.js +6 -6
- 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-run-display.js +215 -25
- 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/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 +10 -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 -2622
- package/lib/schema/external-system.schema.json +1089 -761
- package/lib/schema/infra.parameter.yaml +45 -0
- package/lib/schema/type/credential-field-registry.json +103 -97
- 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-secrets-error-format.js +83 -21
- 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-secrets-env.js +137 -9
- package/lib/utils/dataplane-resolver.js +129 -2
- 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 +11 -8
- 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 +2 -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/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 +12 -5
- 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 +8 -0
- package/lib/utils/validation-run-stage.js +45 -0
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +2 -1
- package/templates/applications/dataplane/env.template +24 -1
- package/templates/applications/miso-controller/env.template +16 -0
- package/templates/external-system/README.md.hbs +74 -17
- package/templates/python/docker-compose.hbs +19 -18
- package/templates/typescript/docker-compose.hbs +18 -17
- package/lib/commands/test-governance-command-action.js +0 -55
- package/lib/commands/test-trust-command-action.js +0 -118
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reuse dataplane auth resolved during sync/upload across verify and test commands.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Integration auth context helpers
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const { setupIntegrationTestAuth } = require('./test-auth');
|
|
12
|
+
const { getConfig } = require('../core/config');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {Object} options
|
|
16
|
+
* @returns {Object}
|
|
17
|
+
*/
|
|
18
|
+
function integrationAuthOptions(options) {
|
|
19
|
+
const base = {
|
|
20
|
+
environment: options.env,
|
|
21
|
+
silentResolve: options.silentResolve === true
|
|
22
|
+
};
|
|
23
|
+
if (options.authConfig && options.dataplaneUrl) {
|
|
24
|
+
return { ...base, authConfig: options.authConfig, dataplaneUrl: options.dataplaneUrl };
|
|
25
|
+
}
|
|
26
|
+
return base;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {string} systemKey
|
|
31
|
+
* @param {Object} options
|
|
32
|
+
* @returns {Promise<{ authConfig: Object, dataplaneUrl: string }>}
|
|
33
|
+
*/
|
|
34
|
+
async function resolveIntegrationAuth(systemKey, options) {
|
|
35
|
+
if (options.authConfig && options.dataplaneUrl) {
|
|
36
|
+
return { authConfig: options.authConfig, dataplaneUrl: options.dataplaneUrl };
|
|
37
|
+
}
|
|
38
|
+
const configObj = await getConfig();
|
|
39
|
+
return setupIntegrationTestAuth(systemKey, integrationAuthOptions(options), configObj);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = {
|
|
43
|
+
integrationAuthOptions,
|
|
44
|
+
resolveIntegrationAuth
|
|
45
|
+
};
|
|
@@ -26,9 +26,14 @@ const { resolveControllerUrl } = require('../utils/controller-url');
|
|
|
26
26
|
* @throws {Error} If authentication fails
|
|
27
27
|
*/
|
|
28
28
|
async function setupIntegrationTestAuth(appName, options, _config) {
|
|
29
|
+
const opts = options && typeof options === 'object' ? options : {};
|
|
30
|
+
if (opts.authConfig && opts.dataplaneUrl) {
|
|
31
|
+
return { authConfig: opts.authConfig, dataplaneUrl: opts.dataplaneUrl };
|
|
32
|
+
}
|
|
33
|
+
|
|
29
34
|
const { resolveEnvironment } = require('../core/config');
|
|
30
|
-
const environment = (
|
|
31
|
-
?
|
|
35
|
+
const environment = (opts.environment && typeof opts.environment === 'string' && opts.environment.trim())
|
|
36
|
+
? opts.environment.trim()
|
|
32
37
|
: await resolveEnvironment();
|
|
33
38
|
const controllerUrl = await resolveControllerUrl();
|
|
34
39
|
const authConfig = await getDeploymentAuth(controllerUrl, environment, appName);
|
|
@@ -38,10 +43,12 @@ async function setupIntegrationTestAuth(appName, options, _config) {
|
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
let dataplaneUrl;
|
|
41
|
-
if (
|
|
42
|
-
dataplaneUrl =
|
|
46
|
+
if (opts.dataplane && typeof opts.dataplane === 'string' && opts.dataplane.trim()) {
|
|
47
|
+
dataplaneUrl = opts.dataplane.trim();
|
|
43
48
|
} else {
|
|
44
|
-
dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig
|
|
49
|
+
dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig, {
|
|
50
|
+
silent: opts.silentResolve === true
|
|
51
|
+
});
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
return { authConfig, dataplaneUrl };
|
|
@@ -38,6 +38,7 @@ const {
|
|
|
38
38
|
} = require('./test-execution');
|
|
39
39
|
const { runSystemLevelTest } = require('./test-system-level');
|
|
40
40
|
const { shouldUseSystemLevelIntegrationCall } = require('./integration-test-dispatch');
|
|
41
|
+
const { cliOptsSkipSync } = require('../utils/cli-sync-options');
|
|
41
42
|
|
|
42
43
|
/**
|
|
43
44
|
* Loads and parses application config file
|
|
@@ -412,7 +413,8 @@ function determineDatasourcesToTest(datasourceFiles, datasourceFilter) {
|
|
|
412
413
|
* @param {string} [options.controller] - Controller URL
|
|
413
414
|
* @param {boolean} [options.verbose] - Show detailed test output
|
|
414
415
|
* @param {number} [options.timeout] - Request timeout in milliseconds
|
|
415
|
-
* @param {boolean} [options.
|
|
416
|
+
* @param {boolean} [options.noSync] - When true, skip publish (exercise dataplane config already deployed)
|
|
417
|
+
* @param {boolean} [options.sync] - Legacy explicit sync; ignored when `noSync` / `--no-sync` is set
|
|
416
418
|
* @returns {Promise<Object>} Integration test results
|
|
417
419
|
* @throws {Error} If testing fails
|
|
418
420
|
*/
|
|
@@ -457,13 +459,11 @@ async function testExternalSystemIntegration(appName, options = {}) {
|
|
|
457
459
|
|
|
458
460
|
const { systemKey, authConfig, dataplaneUrl, datasourcesToTest, customPayload } = await prepareIntegrationTestEnvironment(appName, options);
|
|
459
461
|
|
|
460
|
-
if (options
|
|
462
|
+
if (!cliOptsSkipSync(options)) {
|
|
461
463
|
logger.log(chalk.cyan('Syncing local config to dataplane…'));
|
|
462
464
|
const { uploadExternalSystem } = require('../commands/upload');
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
minimal: true
|
|
466
|
-
});
|
|
465
|
+
const { buildMinimalUploadSyncOptions } = require('../utils/upload-sync-options');
|
|
466
|
+
await uploadExternalSystem(systemKey, buildMinimalUploadSyncOptions(options));
|
|
467
467
|
logger.log(formatSuccessLine('Sync complete'));
|
|
468
468
|
}
|
|
469
469
|
|
|
@@ -22,6 +22,19 @@ const { loadVariables, loadRbac } = require('./helpers');
|
|
|
22
22
|
* @param {Object} systemJson - System JSON object
|
|
23
23
|
* @param {Object|null} rbac - RBAC configuration
|
|
24
24
|
*/
|
|
25
|
+
/**
|
|
26
|
+
* Maps legacy integration auth method names to schema 1.3.0 values before upload/deploy.
|
|
27
|
+
* @param {Object} systemJson - System JSON object (mutated in place)
|
|
28
|
+
*/
|
|
29
|
+
function normalizeLegacyAuthMethod(systemJson) {
|
|
30
|
+
const auth = systemJson && systemJson.authentication;
|
|
31
|
+
if (!auth || typeof auth !== 'object') return;
|
|
32
|
+
const method = String(auth.method || '').trim().toLowerCase();
|
|
33
|
+
if (method === 'bearerkey') {
|
|
34
|
+
auth.method = 'bearerToken';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
function mergeRbacIntoSystemJson(systemJson, rbac) {
|
|
26
39
|
if (!rbac) {
|
|
27
40
|
return;
|
|
@@ -78,6 +91,7 @@ function extractAppMetadata(variables, appName) {
|
|
|
78
91
|
*/
|
|
79
92
|
async function loadSystemWithRbac(appPath, schemaBasePath, systemFile) {
|
|
80
93
|
const systemJson = await loadSystemFile(appPath, schemaBasePath, systemFile);
|
|
94
|
+
normalizeLegacyAuthMethod(systemJson);
|
|
81
95
|
const rbacPath = resolveRbacPath(appPath);
|
|
82
96
|
const rbac = rbacPath ? loadRbac(rbacPath) : null;
|
|
83
97
|
mergeRbacIntoSystemJson(systemJson, rbac);
|
|
@@ -187,6 +201,7 @@ function toDeployJsonShape(manifest) {
|
|
|
187
201
|
}
|
|
188
202
|
|
|
189
203
|
module.exports = {
|
|
204
|
+
normalizeLegacyAuthMethod,
|
|
190
205
|
generateControllerManifest,
|
|
191
206
|
toDeployJsonShape
|
|
192
207
|
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Governance CLI error messages (424.0).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {Error|string} err
|
|
9
|
+
* @returns {boolean}
|
|
10
|
+
*/
|
|
11
|
+
function isGovernancePackNotFoundError(err) {
|
|
12
|
+
const raw = (err && err.message) || String(err);
|
|
13
|
+
return /not found/i.test(raw) || /\b404\b/.test(raw);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {Error|string} err
|
|
18
|
+
* @returns {boolean}
|
|
19
|
+
*/
|
|
20
|
+
function isGovernanceCoverageSchemaError(err) {
|
|
21
|
+
const raw = (err && err.message) || String(err);
|
|
22
|
+
return (
|
|
23
|
+
raw.includes('\'coverage\' is a required property') || /spec\.coverage/i.test(raw)
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Short, non-duplicative CLI message from a dataplane governance API error.
|
|
29
|
+
* @param {Error|string} err
|
|
30
|
+
* @returns {string}
|
|
31
|
+
*/
|
|
32
|
+
function shortGovernanceApiError(err) {
|
|
33
|
+
const raw = ((err && err.message) || String(err)).trim();
|
|
34
|
+
if (isGovernancePackNotFoundError(err)) {
|
|
35
|
+
return 'No active pack on dataplane';
|
|
36
|
+
}
|
|
37
|
+
if (isGovernanceCoverageSchemaError(err)) {
|
|
38
|
+
return 'Pack missing spec.coverage (424.0 schema)';
|
|
39
|
+
}
|
|
40
|
+
const firstLine = raw.split('\n').find(line => line.trim()) || raw;
|
|
41
|
+
if (/^Governance scenario pack not found/i.test(firstLine)) {
|
|
42
|
+
return 'No active pack on dataplane';
|
|
43
|
+
}
|
|
44
|
+
return firstLine.length > 100 ? `${firstLine.slice(0, 97)}...` : firstLine;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* User-facing hint after a failed governance pack upload (validation).
|
|
49
|
+
* @param {string} systemKey
|
|
50
|
+
* @returns {string}
|
|
51
|
+
*/
|
|
52
|
+
function governanceUploadSchemaHint(systemKey) {
|
|
53
|
+
return (
|
|
54
|
+
'Scenario pack does not meet the 424.0 schema. Use dataplane-first generation:\n' +
|
|
55
|
+
` aifabrix governance generate ${systemKey} --subject-email <email>\n` +
|
|
56
|
+
'Or: aifabrix verify-governance ' +
|
|
57
|
+
`${systemKey} --subject-email <email>`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Clarify subject-resolution 400s (dataplane reachable; User row missing).
|
|
63
|
+
* @param {Error} err
|
|
64
|
+
* @param {{ subjectEmails?: string[] }} [context]
|
|
65
|
+
* @returns {Error}
|
|
66
|
+
*/
|
|
67
|
+
function enrichUnresolvableGovernanceSubjectsError(err, context = {}) {
|
|
68
|
+
const hay = `${err.message || ''} ${err.formatted || ''}`;
|
|
69
|
+
if (!hay.includes('No resolvable subjects')) {
|
|
70
|
+
return err;
|
|
71
|
+
}
|
|
72
|
+
const emails = Array.isArray(context.subjectEmails)
|
|
73
|
+
? context.subjectEmails.filter(Boolean)
|
|
74
|
+
: [];
|
|
75
|
+
const lines = [
|
|
76
|
+
'',
|
|
77
|
+
'The dataplane is reachable. This is not a network or controller error.',
|
|
78
|
+
'Pack generation needs --subject-email values that match existing dataplane User rows.',
|
|
79
|
+
emails.length > 0 ? `Subject email(s) you passed: ${emails.join(', ')}` : null,
|
|
80
|
+
'Check:',
|
|
81
|
+
' aifabrix identity user list --search <email>',
|
|
82
|
+
'If the user is missing, apply your identity CSV first:',
|
|
83
|
+
' aifabrix identity apply --file integration/<systemKey>/fixtures/<users>.csv --filter-prefix <systemKey>',
|
|
84
|
+
' aifabrix identity sync -e dev --purge-cache'
|
|
85
|
+
].filter(line => line !== null);
|
|
86
|
+
err.formatted = `${err.formatted || err.message}${lines.join('\n')}`;
|
|
87
|
+
return err;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = {
|
|
91
|
+
isGovernancePackNotFoundError,
|
|
92
|
+
isGovernanceCoverageSchemaError,
|
|
93
|
+
shortGovernanceApiError,
|
|
94
|
+
governanceUploadSchemaHint,
|
|
95
|
+
enrichUnresolvableGovernanceSubjectsError
|
|
96
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview TTY summary when governance download finds no active packs.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const chalk = require('chalk');
|
|
8
|
+
const { failureGlyph } = require('../utils/cli-test-layout-chalk');
|
|
9
|
+
const logger = require('../utils/logger');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {Array<{ datasourceKey: string, reason: string }>} missing
|
|
13
|
+
*/
|
|
14
|
+
function printGovernanceDownloadMisses(missing) {
|
|
15
|
+
if (!missing || missing.length === 0) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
for (const row of missing) {
|
|
19
|
+
logger.log(
|
|
20
|
+
chalk.white(`${row.datasourceKey}: ${failureGlyph()} ${row.reason}`)
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
logger.log('');
|
|
24
|
+
logger.log(chalk.gray('Next steps:'));
|
|
25
|
+
logger.log(
|
|
26
|
+
chalk.gray(
|
|
27
|
+
' • Run: aifabrix governance generate <systemKey> --subject-email <email>'
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
logger.log(
|
|
31
|
+
chalk.gray(' • Or use: aifabrix verify-governance <systemKey> --subject-email <email>')
|
|
32
|
+
);
|
|
33
|
+
logger.log(chalk.gray(' • Ensure protection is published and identity sync has run'));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
37
|
+
printGovernanceDownloadMisses
|
|
38
|
+
};
|
|
@@ -16,7 +16,45 @@ const {
|
|
|
16
16
|
formatBlockingError
|
|
17
17
|
} = require('../utils/cli-test-layout-chalk');
|
|
18
18
|
|
|
19
|
-
const SEP = '
|
|
19
|
+
const SEP = '────────────────────────';
|
|
20
|
+
const MAX_SAMPLE_KEYS = 5;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {Object|null|undefined} packDocument
|
|
24
|
+
* @returns {Map<string, { mustIncludeKeys: string[], mustExcludeKeys: string[] }>}
|
|
25
|
+
*/
|
|
26
|
+
function buildScenarioExpectMap(packDocument) {
|
|
27
|
+
const map = new Map();
|
|
28
|
+
const scenarios = packDocument?.spec?.scenarios;
|
|
29
|
+
if (!Array.isArray(scenarios)) {
|
|
30
|
+
return map;
|
|
31
|
+
}
|
|
32
|
+
for (const scenario of scenarios) {
|
|
33
|
+
if (!scenario || typeof scenario.id !== 'string') {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const expect = scenario.expect || {};
|
|
37
|
+
map.set(scenario.id, {
|
|
38
|
+
mustIncludeKeys: Array.isArray(expect.mustIncludeKeys) ? expect.mustIncludeKeys : [],
|
|
39
|
+
mustExcludeKeys: Array.isArray(expect.mustExcludeKeys) ? expect.mustExcludeKeys : []
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return map;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {string[]} keys
|
|
47
|
+
* @param {number} [maxKeys]
|
|
48
|
+
* @returns {string}
|
|
49
|
+
*/
|
|
50
|
+
function formatKeySample(keys, maxKeys = MAX_SAMPLE_KEYS) {
|
|
51
|
+
if (!Array.isArray(keys) || keys.length === 0) {
|
|
52
|
+
return '—';
|
|
53
|
+
}
|
|
54
|
+
const slice = keys.slice(0, maxKeys);
|
|
55
|
+
const suffix = keys.length > maxKeys ? ` (+${keys.length - maxKeys} more)` : '';
|
|
56
|
+
return `${slice.join(', ')}${suffix}`;
|
|
57
|
+
}
|
|
20
58
|
|
|
21
59
|
/**
|
|
22
60
|
* @param {'pass'|'fail'} status
|
|
@@ -28,38 +66,162 @@ function scenarioGlyph(status) {
|
|
|
28
66
|
|
|
29
67
|
/**
|
|
30
68
|
* @param {import('../api/types/governance-scenarios.types').GovernanceScenarioResult} scenario
|
|
31
|
-
* @param {boolean} verbose
|
|
32
69
|
*/
|
|
33
|
-
function
|
|
34
|
-
logger.log(` ${scenarioGlyph(scenario.status)} ${scenario.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
logger.log(metaGray(` Groups: ${scenario.subjectGroups.join(', ')}`));
|
|
70
|
+
function logGovernanceScenarioSubjectLines(scenario) {
|
|
71
|
+
logger.log(` ${scenarioGlyph(scenario.status)} ${scenario.id}`);
|
|
72
|
+
logger.log(metaGray(` Subject email: ${scenario.subjectEmail || '—'}`));
|
|
73
|
+
if (scenario.subjectDisplayName) {
|
|
74
|
+
logger.log(
|
|
75
|
+
metaGray(
|
|
76
|
+
` Subject: ${scenario.subjectDisplayName} (${scenario.subjectUserId || '—'})`
|
|
77
|
+
)
|
|
78
|
+
);
|
|
43
79
|
}
|
|
44
|
-
logger.log(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
80
|
+
logger.log(metaGray(` Verdict: ${scenario.verdict || '—'}`));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {import('../api/types/governance-scenarios.types').GovernanceScenarioResult} scenario
|
|
85
|
+
*/
|
|
86
|
+
function logGovernanceScenarioCounts(scenario) {
|
|
87
|
+
const visible = typeof scenario.visibleKeyCount === 'number' ? scenario.visibleKeyCount : 0;
|
|
88
|
+
const abac = typeof scenario.excludedAbac === 'number' ? scenario.excludedAbac : 0;
|
|
89
|
+
const filter = typeof scenario.excludedFilter === 'number' ? scenario.excludedFilter : 0;
|
|
90
|
+
logger.log(metaGray(` Visible keys: ${visible} allowed`));
|
|
91
|
+
logger.log(metaGray(` Declined: ${abac} by ABAC · ${filter} by filter`));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @param {import('../api/types/governance-scenarios.types').GovernanceScenarioResult} scenario
|
|
96
|
+
* @param {{ mustIncludeKeys: string[], mustExcludeKeys: string[] }} expect
|
|
97
|
+
*/
|
|
98
|
+
function logGovernanceScenarioPassSamples(expect) {
|
|
99
|
+
const allowed =
|
|
100
|
+
expect.mustIncludeKeys.length > 0 ? formatKeySample(expect.mustIncludeKeys) : '—';
|
|
101
|
+
const blocked =
|
|
102
|
+
expect.mustExcludeKeys.length > 0 ? formatKeySample(expect.mustExcludeKeys) : '—';
|
|
103
|
+
logger.log(metaGray(` Sample allowed: ${allowed}`));
|
|
104
|
+
logger.log(metaGray(` Sample blocked: ${blocked}`));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @param {import('../api/types/governance-scenarios.types').GovernanceScenarioResult} scenario
|
|
109
|
+
*/
|
|
110
|
+
function logGovernanceScenarioFailSamples(scenario) {
|
|
111
|
+
if (scenario.missingRequiredKeys?.length) {
|
|
51
112
|
logger.log(
|
|
52
|
-
metaGray(`
|
|
113
|
+
metaGray(` Missing keys: ${formatKeySample(scenario.missingRequiredKeys)}`)
|
|
53
114
|
);
|
|
54
115
|
}
|
|
55
|
-
if (scenario.
|
|
56
|
-
logger.log(
|
|
116
|
+
if (scenario.unexpectedVisibleKeys?.length) {
|
|
117
|
+
logger.log(
|
|
118
|
+
metaGray(` Unexpected: ${formatKeySample(scenario.unexpectedVisibleKeys)}`)
|
|
119
|
+
);
|
|
57
120
|
}
|
|
58
121
|
if (scenario.fixHint) {
|
|
59
|
-
logger.log(metaGray(` Fix:
|
|
122
|
+
logger.log(metaGray(` Fix: ${scenario.fixHint}`));
|
|
60
123
|
}
|
|
61
124
|
}
|
|
62
125
|
|
|
126
|
+
/**
|
|
127
|
+
* @param {import('../api/types/governance-scenarios.types').GovernanceScenarioResult} scenario
|
|
128
|
+
* @param {Map<string, { mustIncludeKeys: string[], mustExcludeKeys: string[] }>} expectMap
|
|
129
|
+
*/
|
|
130
|
+
function logGovernanceScenarioDetail(scenario, expectMap) {
|
|
131
|
+
const expect = expectMap.get(scenario.id) || {
|
|
132
|
+
mustIncludeKeys: [],
|
|
133
|
+
mustExcludeKeys: []
|
|
134
|
+
};
|
|
135
|
+
logGovernanceScenarioSubjectLines(scenario);
|
|
136
|
+
logGovernanceScenarioCounts(scenario);
|
|
137
|
+
if (scenario.status === 'pass') {
|
|
138
|
+
logGovernanceScenarioPassSamples(expect);
|
|
139
|
+
} else {
|
|
140
|
+
logGovernanceScenarioFailSamples(scenario);
|
|
141
|
+
}
|
|
142
|
+
if (scenario.subjectGroups?.length) {
|
|
143
|
+
logger.log(metaGray(` Groups: ${scenario.subjectGroups.join(', ')}`));
|
|
144
|
+
}
|
|
145
|
+
if (scenario.auditRef) {
|
|
146
|
+
logger.log(metaGray(` Audit: ${scenario.auditRef}`));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* One datasource block for verify-governance -v.
|
|
152
|
+
* @param {Object} row
|
|
153
|
+
* @param {string} row.datasourceKey
|
|
154
|
+
* @param {Object} [row.result]
|
|
155
|
+
* @param {Object} [row.packDocument]
|
|
156
|
+
* @param {string} [row.packPath]
|
|
157
|
+
* @param {string} [row.error]
|
|
158
|
+
*/
|
|
159
|
+
function displayGovernanceDatasourceVerbose(row) {
|
|
160
|
+
logger.log('');
|
|
161
|
+
logger.log(chalk.white(`Datasource: ${row.datasourceKey}`));
|
|
162
|
+
if (row.error) {
|
|
163
|
+
logger.log(formatBlockingError(row.error));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const run = row.result;
|
|
167
|
+
if (!run || !run.summary) {
|
|
168
|
+
logger.log(metaGray(' No scenario run result (pack missing or run skipped).'));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
logger.log(headerKeyValue('Pack:', run.packKey || '—'));
|
|
172
|
+
if (row.packPath) {
|
|
173
|
+
logger.log(metaGray(` File: ${row.packPath}`));
|
|
174
|
+
}
|
|
175
|
+
const summary = run.summary;
|
|
176
|
+
logger.log(
|
|
177
|
+
headerKeyValue('Scenarios:', `${summary.passed || 0}/${summary.total || 0} passed`)
|
|
178
|
+
);
|
|
179
|
+
const expectMap = buildScenarioExpectMap(row.packDocument);
|
|
180
|
+
for (const scenario of run.scenarios || []) {
|
|
181
|
+
logGovernanceScenarioDetail(scenario, expectMap);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Verbose (-v) scenario breakdown for verify-governance / governance verify.
|
|
187
|
+
* @param {Object} result
|
|
188
|
+
*/
|
|
189
|
+
function displayGovernanceVerboseDetails(result) {
|
|
190
|
+
if (!result) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
logger.log('');
|
|
194
|
+
logger.log(chalk.white('Scenario results'));
|
|
195
|
+
logger.log(metaGray(SEP));
|
|
196
|
+
logger.log(metaGray('Key sets only — no record payloads.'));
|
|
197
|
+
|
|
198
|
+
if (result.legacyResult && result.legacyResult.summary) {
|
|
199
|
+
const dsKey =
|
|
200
|
+
result.packDatasourceKey ||
|
|
201
|
+
primaryDatasourceFromPack(result.packDocument) ||
|
|
202
|
+
'scenario pack';
|
|
203
|
+
displayGovernanceDatasourceVerbose({
|
|
204
|
+
datasourceKey: dsKey,
|
|
205
|
+
result: result.legacyResult,
|
|
206
|
+
packDocument: result.packDocument,
|
|
207
|
+
packPath: result.packPath
|
|
208
|
+
});
|
|
209
|
+
logger.log('');
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const rows = result.datasourceRows || [];
|
|
214
|
+
if (rows.length === 0) {
|
|
215
|
+
logger.log(metaGray(' No datasource scenario packs were run.'));
|
|
216
|
+
logger.log('');
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
for (const row of rows) {
|
|
220
|
+
displayGovernanceDatasourceVerbose(row);
|
|
221
|
+
}
|
|
222
|
+
logger.log('');
|
|
223
|
+
}
|
|
224
|
+
|
|
63
225
|
/**
|
|
64
226
|
* @param {string} systemKey
|
|
65
227
|
* @param {import('../api/types/governance-scenarios.types').GovernanceScenariosRunResponse} result
|
|
@@ -82,8 +244,13 @@ function displayGovernanceRunTTY(systemKey, result, opts = {}) {
|
|
|
82
244
|
);
|
|
83
245
|
logger.log(metaGray(' Does not call vendor APIs (use test-e2e for connectivity).'));
|
|
84
246
|
logger.log('');
|
|
247
|
+
const expectMap = buildScenarioExpectMap(opts.packDocument);
|
|
85
248
|
for (const scenario of result.scenarios || []) {
|
|
86
|
-
|
|
249
|
+
if (opts.verbose === true) {
|
|
250
|
+
logGovernanceScenarioDetail(scenario, expectMap);
|
|
251
|
+
} else {
|
|
252
|
+
logger.log(` ${scenarioGlyph(scenario.status)} ${scenario.verdict}`);
|
|
253
|
+
}
|
|
87
254
|
}
|
|
88
255
|
logger.log('');
|
|
89
256
|
if (agg === 'ok') {
|
|
@@ -112,8 +279,31 @@ function exitCodeFromGovernanceSummary(summary) {
|
|
|
112
279
|
return 0;
|
|
113
280
|
}
|
|
114
281
|
|
|
282
|
+
/**
|
|
283
|
+
* @param {Object|null|undefined} packDocument
|
|
284
|
+
* @returns {string|null}
|
|
285
|
+
*/
|
|
286
|
+
function primaryDatasourceFromPack(packDocument) {
|
|
287
|
+
const scenarios = packDocument?.spec?.scenarios;
|
|
288
|
+
if (!Array.isArray(scenarios)) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
for (const scenario of scenarios) {
|
|
292
|
+
const keys = scenario?.search?.datasourceKeys;
|
|
293
|
+
if (Array.isArray(keys) && keys.length > 0 && typeof keys[0] === 'string') {
|
|
294
|
+
return keys[0];
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
|
|
115
300
|
module.exports = {
|
|
301
|
+
buildScenarioExpectMap,
|
|
302
|
+
formatKeySample,
|
|
303
|
+
displayGovernanceDatasourceVerbose,
|
|
304
|
+
displayGovernanceVerboseDetails,
|
|
116
305
|
displayGovernanceRunTTY,
|
|
117
306
|
printGovernanceRunJson,
|
|
118
|
-
exitCodeFromGovernanceSummary
|
|
307
|
+
exitCodeFromGovernanceSummary,
|
|
308
|
+
primaryDatasourceFromPack
|
|
119
309
|
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write admin-secrets.env from setup password bundles.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Apply dev/pro bundles to admin-secrets.env
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const fsRealSync = require('../internal/fs-real-sync');
|
|
12
|
+
const logger = require('../utils/logger');
|
|
13
|
+
const { applyPasswordBundleToAdminObj } = require('../core/admin-secrets-bundle');
|
|
14
|
+
|
|
15
|
+
const DEFAULT_ADMIN_OBJ = {
|
|
16
|
+
REDIS_HOST: 'local:redis:6379:0:',
|
|
17
|
+
REDIS_COMMANDER_USER: 'admin'
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {() => object} getCoreSecrets
|
|
22
|
+
* @param {string} adminSecretsPath
|
|
23
|
+
* @param {Object.<string, string>} merged
|
|
24
|
+
* @param {string|null} logMessage
|
|
25
|
+
*/
|
|
26
|
+
async function writeAdminSecretsFile(getCoreSecrets, adminSecretsPath, merged, logMessage) {
|
|
27
|
+
const { assertWritableSecretsPathForTests } = require('../utils/aifabrix-test-runtime-guard');
|
|
28
|
+
assertWritableSecretsPathForTests(adminSecretsPath);
|
|
29
|
+
const content = await getCoreSecrets().formatAdminSecretsContent(merged);
|
|
30
|
+
fsRealSync.writeFileSync(adminSecretsPath, content, { mode: 0o600 });
|
|
31
|
+
if (logMessage) {
|
|
32
|
+
logger.log(logMessage);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {Object} ctx
|
|
38
|
+
* @param {() => object} ctx.getCoreSecrets
|
|
39
|
+
* @param {(bundle: object) => Promise<void>} [ctx.syncAdminKvFromPasswordBundle]
|
|
40
|
+
* @param {(bundle: object) => Promise<void>} [ctx.syncRequiredKvFromPasswordBundle]
|
|
41
|
+
* @param {boolean} [ctx.syncAdminKv]
|
|
42
|
+
* @param {(dir: string) => void} ctx.logVolumeResetHint
|
|
43
|
+
* @param {string} ctx.infraDirForHint
|
|
44
|
+
* @param {string} ctx.adminSecretsPath
|
|
45
|
+
* @param {Object} ctx.adminObj
|
|
46
|
+
* @param {Object} ctx.bundle
|
|
47
|
+
* @param {string} [ctx.email]
|
|
48
|
+
*/
|
|
49
|
+
async function applyAdminSecretsFromBundle(ctx) {
|
|
50
|
+
const {
|
|
51
|
+
getCoreSecrets,
|
|
52
|
+
syncAdminKvFromPasswordBundle,
|
|
53
|
+
syncRequiredKvFromPasswordBundle,
|
|
54
|
+
syncAdminKv,
|
|
55
|
+
logVolumeResetHint,
|
|
56
|
+
infraDirForHint,
|
|
57
|
+
adminSecretsPath,
|
|
58
|
+
adminObj,
|
|
59
|
+
bundle,
|
|
60
|
+
email
|
|
61
|
+
} = ctx;
|
|
62
|
+
let merged = applyPasswordBundleToAdminObj({ ...DEFAULT_ADMIN_OBJ, ...adminObj }, bundle);
|
|
63
|
+
if (email && String(email).trim()) {
|
|
64
|
+
merged = { ...merged, PGADMIN_DEFAULT_EMAIL: String(email).trim() };
|
|
65
|
+
}
|
|
66
|
+
await writeAdminSecretsFile(
|
|
67
|
+
getCoreSecrets,
|
|
68
|
+
adminSecretsPath,
|
|
69
|
+
merged,
|
|
70
|
+
'Updated admin credentials in admin-secrets.env.'
|
|
71
|
+
);
|
|
72
|
+
if (syncAdminKv && typeof syncAdminKvFromPasswordBundle === 'function') {
|
|
73
|
+
await syncAdminKvFromPasswordBundle(bundle);
|
|
74
|
+
} else if (typeof syncRequiredKvFromPasswordBundle === 'function') {
|
|
75
|
+
await syncRequiredKvFromPasswordBundle(bundle);
|
|
76
|
+
}
|
|
77
|
+
logVolumeResetHint(infraDirForHint);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = {
|
|
81
|
+
DEFAULT_ADMIN_OBJ,
|
|
82
|
+
writeAdminSecretsFile,
|
|
83
|
+
applyAdminSecretsFromBundle
|
|
84
|
+
};
|