@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,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Upload sidecar follow-ups (governance packs, certification sync).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const logger = require('../utils/logger');
|
|
10
|
+
const { formatWarningLine } = require('../utils/cli-test-layout-chalk');
|
|
11
|
+
const { unwrapPublicationResult, isPublicationUnchanged } = require('../utils/external-system-readiness-core');
|
|
12
|
+
const { logUploadReadinessSummary } = require('../utils/external-system-readiness-display');
|
|
13
|
+
const { maybeSyncSystemCertificationFromDataplane } = require('../certification/sync-system-certification');
|
|
14
|
+
const { cliOptsSkipCertSync } = require('../certification/cli-cert-sync-skip');
|
|
15
|
+
const { isQuietMinimalSync } = require('../utils/upload-sync-options');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Sidecar follow-ups that are independent of pipeline publish hash (scenario packs, cert sync).
|
|
19
|
+
* @param {Object} ctx
|
|
20
|
+
* @returns {Promise<void>}
|
|
21
|
+
*/
|
|
22
|
+
async function runUploadSidecarFollowups(ctx) {
|
|
23
|
+
const { systemKey, options, payload, dataplaneUrl, authConfig } = ctx;
|
|
24
|
+
const quietSidecar = isQuietMinimalSync(options);
|
|
25
|
+
const dsKeys = (payload.dataSources || []).map((ds) => ds && ds.key).filter(Boolean);
|
|
26
|
+
try {
|
|
27
|
+
const { uploadGovernanceScenarioPacks } = require('../lifecycle/scenario-upload');
|
|
28
|
+
await uploadGovernanceScenarioPacks(systemKey, dataplaneUrl, authConfig, { silent: quietSidecar });
|
|
29
|
+
} catch (err) {
|
|
30
|
+
if (!quietSidecar) {
|
|
31
|
+
logger.log(formatWarningLine(`Governance scenario upload skipped: ${err.message}`));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
await maybeSyncSystemCertificationFromDataplane({
|
|
35
|
+
label: 'upload',
|
|
36
|
+
noCertSync: cliOptsSkipCertSync(options),
|
|
37
|
+
systemKey,
|
|
38
|
+
dataplaneUrl,
|
|
39
|
+
authConfig,
|
|
40
|
+
datasourceKeys: dsKeys,
|
|
41
|
+
silent: quietSidecar
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {Object} ctx
|
|
47
|
+
* @param {Function} maybeRunUploadProbe
|
|
48
|
+
* @returns {Promise<void>}
|
|
49
|
+
*/
|
|
50
|
+
async function handlePublicationAndFollowups(ctx, maybeRunUploadProbe) {
|
|
51
|
+
const {
|
|
52
|
+
systemKey,
|
|
53
|
+
options,
|
|
54
|
+
manifest,
|
|
55
|
+
payload,
|
|
56
|
+
environment,
|
|
57
|
+
dataplaneUrl,
|
|
58
|
+
authConfig,
|
|
59
|
+
rawRes
|
|
60
|
+
} = ctx;
|
|
61
|
+
const publication = unwrapPublicationResult(rawRes);
|
|
62
|
+
if (!publication) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
'Unexpected response from dataplane upload: missing publication result (uploadId/system/datasources).'
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
if (isPublicationUnchanged(publication)) {
|
|
68
|
+
await runUploadSidecarFollowups({ systemKey, options, payload, dataplaneUrl, authConfig });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
logUploadReadinessSummary({
|
|
72
|
+
environment,
|
|
73
|
+
dataplaneUrl,
|
|
74
|
+
systemKey,
|
|
75
|
+
publication,
|
|
76
|
+
manifest,
|
|
77
|
+
minimal: !!options.minimal,
|
|
78
|
+
willProbe: !!options.probe
|
|
79
|
+
});
|
|
80
|
+
if (options.probe) {
|
|
81
|
+
await maybeRunUploadProbe(dataplaneUrl, systemKey, authConfig, options.probeTimeout);
|
|
82
|
+
}
|
|
83
|
+
await runUploadSidecarFollowups({ systemKey, options, payload, dataplaneUrl, authConfig });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
module.exports = {
|
|
87
|
+
runUploadSidecarFollowups,
|
|
88
|
+
handlePublicationAndFollowups
|
|
89
|
+
};
|
package/lib/commands/upload.js
CHANGED
|
@@ -21,7 +21,7 @@ const logger = require('../utils/logger');
|
|
|
21
21
|
|
|
22
22
|
const SEP = chalk.gray('────────────────────────────────────────');
|
|
23
23
|
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
24
|
-
const { getDeploymentAuth
|
|
24
|
+
const { getDeploymentAuth } = require('../utils/token-manager');
|
|
25
25
|
const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
|
|
26
26
|
const { getIntegrationPath } = require('../utils/paths');
|
|
27
27
|
const { pushCredentialSecrets } = require('../utils/credential-secrets-env');
|
|
@@ -36,22 +36,24 @@ const { validateExternalSystemComplete } = require('../validation/validate');
|
|
|
36
36
|
const { displayValidationResults } = require('../validation/validate-display');
|
|
37
37
|
const { generateControllerManifest } = require('../generator/external-controller-manifest');
|
|
38
38
|
const {
|
|
39
|
-
uploadApplicationViaPipeline,
|
|
40
39
|
validatePipelineConfig,
|
|
41
40
|
testSystemViaPipeline
|
|
42
41
|
} = require('../api/pipeline.api');
|
|
42
|
+
const { uploadApplicationViaPipelineWithAuthRetry } = require('../utils/pipeline-upload-auth-retry');
|
|
43
43
|
const { formatApiError } = require('../utils/api-error-handler');
|
|
44
|
-
const {
|
|
45
|
-
const { unwrapPublicationResult, unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
44
|
+
const { unwrapPublicationResult, unwrapApiData, isPublicationUnchanged } = require('../utils/external-system-readiness-core');
|
|
46
45
|
const {
|
|
47
|
-
logUploadReadinessSummary,
|
|
48
46
|
logServerValidationWarnings,
|
|
49
47
|
logProbeRuntimeBlock
|
|
50
48
|
} = require('../utils/external-system-readiness-display');
|
|
51
|
-
const { maybeSyncSystemCertificationFromDataplane } = require('../certification/sync-system-certification');
|
|
52
|
-
const { cliOptsSkipCertSync } = require('../certification/cli-cert-sync-skip');
|
|
53
49
|
const { maybeSyncOpenApiFilesForMcp } = require('./repair-openapi-sync');
|
|
54
|
-
const {
|
|
50
|
+
const { resolveUploadPublishContext } = require('./upload-publish-context');
|
|
51
|
+
const { syncDeployJsonFromSources } = require('../external-system/sync-deploy-manifest');
|
|
52
|
+
const { isQuietMinimalSync } = require('../utils/upload-sync-options');
|
|
53
|
+
const {
|
|
54
|
+
runUploadSidecarFollowups,
|
|
55
|
+
handlePublicationAndFollowups
|
|
56
|
+
} = require('./upload-sidecar-followups');
|
|
55
57
|
|
|
56
58
|
/**
|
|
57
59
|
* Validates system-key format (same as download).
|
|
@@ -73,13 +75,22 @@ function validateSystemKeyFormat(systemKey) {
|
|
|
73
75
|
* @param {Object} manifest - Controller manifest from generateControllerManifest
|
|
74
76
|
* @returns {Object} { version, application, dataSources, status: "draft" }
|
|
75
77
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
/**
|
|
79
|
+
* @param {Object} manifest - Controller manifest from generateControllerManifest
|
|
80
|
+
* @param {{ force?: boolean }} [opts]
|
|
81
|
+
* @returns {Object}
|
|
82
|
+
*/
|
|
83
|
+
function buildUploadPayload(manifest, opts = {}) {
|
|
84
|
+
const payload = {
|
|
78
85
|
version: manifest.version || '1.0.0',
|
|
79
86
|
application: manifest.system,
|
|
80
87
|
dataSources: manifest.dataSources || [],
|
|
81
88
|
status: 'draft'
|
|
82
89
|
};
|
|
90
|
+
if (opts.force === true) {
|
|
91
|
+
payload.force = true;
|
|
92
|
+
}
|
|
93
|
+
return payload;
|
|
83
94
|
}
|
|
84
95
|
|
|
85
96
|
/**
|
|
@@ -113,11 +124,15 @@ async function resolveDataplaneAndAuth(systemKey, opts = {}) {
|
|
|
113
124
|
* @param {Object} payload - { version, application, dataSources, status: "draft" }
|
|
114
125
|
* @returns {Promise<Object>} Raw API response envelope
|
|
115
126
|
*/
|
|
116
|
-
async function runUploadValidatePublish(dataplaneUrl, authConfig, payload) {
|
|
117
|
-
const res = await
|
|
127
|
+
async function runUploadValidatePublish(dataplaneUrl, authConfig, payload, systemKey) {
|
|
128
|
+
const res = await uploadApplicationViaPipelineWithAuthRetry(
|
|
129
|
+
dataplaneUrl,
|
|
130
|
+
authConfig,
|
|
131
|
+
payload,
|
|
132
|
+
systemKey
|
|
133
|
+
);
|
|
118
134
|
if (res?.success === false) {
|
|
119
|
-
|
|
120
|
-
throw new Error(msg);
|
|
135
|
+
throw new Error(formatApiError(res, dataplaneUrl));
|
|
121
136
|
}
|
|
122
137
|
return res;
|
|
123
138
|
}
|
|
@@ -269,18 +284,22 @@ async function maybeRunUploadProbe(dataplaneUrl, systemKey, authConfig, probeTim
|
|
|
269
284
|
|
|
270
285
|
/**
|
|
271
286
|
* Local validation, manifest, payload, and configuration resolution.
|
|
272
|
-
*
|
|
287
|
+
* Regenerates integration/<systemKey>/<systemKey>-deploy.json from sources (same as `aifabrix json`).
|
|
273
288
|
*
|
|
274
289
|
* @param {string} systemKey
|
|
275
290
|
* @param {{ dryRun?: boolean }} [_opts] - Reserved for callers (e.g. dry-run); manifest is always built from current disk files
|
|
276
291
|
* @returns {Promise<{ manifest: Object, payload: Object }>}
|
|
277
292
|
*/
|
|
278
|
-
async function buildValidatedUploadManifestPayload(systemKey,
|
|
293
|
+
async function buildValidatedUploadManifestPayload(systemKey, opts = {}) {
|
|
294
|
+
const quiet = opts.minimal === true || opts.quiet === true;
|
|
279
295
|
const validationResult = await validateExternalSystemComplete(systemKey, { type: 'external' });
|
|
280
296
|
throwIfValidationFailed(validationResult);
|
|
281
|
-
|
|
297
|
+
if (!quiet) {
|
|
298
|
+
logger.log(formatSuccessLine('Local validation passed'));
|
|
299
|
+
}
|
|
300
|
+
await syncDeployJsonFromSources(systemKey, { quiet });
|
|
282
301
|
const manifest = await generateControllerManifest(systemKey, { type: 'external' });
|
|
283
|
-
const payload = buildUploadPayload(manifest);
|
|
302
|
+
const payload = buildUploadPayload(manifest, { force: opts.force === true });
|
|
284
303
|
await resolvePayloadConfiguration(systemKey, payload);
|
|
285
304
|
return { manifest, payload };
|
|
286
305
|
}
|
|
@@ -311,58 +330,6 @@ async function logAndSyncLocalOpenApiForUpload(systemKey, manifest) {
|
|
|
311
330
|
}
|
|
312
331
|
}
|
|
313
332
|
|
|
314
|
-
/**
|
|
315
|
-
* @param {Object} ctx
|
|
316
|
-
* @param {string} ctx.systemKey
|
|
317
|
-
* @param {Object} ctx.options
|
|
318
|
-
* @param {Object} ctx.manifest
|
|
319
|
-
* @param {Object} ctx.payload
|
|
320
|
-
* @param {string} ctx.environment
|
|
321
|
-
* @param {string} ctx.dataplaneUrl
|
|
322
|
-
* @param {Object} ctx.authConfig
|
|
323
|
-
* @param {Object} ctx.rawRes
|
|
324
|
-
* @returns {Promise<void>}
|
|
325
|
-
*/
|
|
326
|
-
async function handlePublicationAndFollowups(ctx) {
|
|
327
|
-
const {
|
|
328
|
-
systemKey,
|
|
329
|
-
options,
|
|
330
|
-
manifest,
|
|
331
|
-
payload,
|
|
332
|
-
environment,
|
|
333
|
-
dataplaneUrl,
|
|
334
|
-
authConfig,
|
|
335
|
-
rawRes
|
|
336
|
-
} = ctx;
|
|
337
|
-
const publication = unwrapPublicationResult(rawRes);
|
|
338
|
-
if (!publication) {
|
|
339
|
-
throw new Error(
|
|
340
|
-
'Unexpected response from dataplane upload: missing publication result (uploadId/system/datasources).'
|
|
341
|
-
);
|
|
342
|
-
}
|
|
343
|
-
logUploadReadinessSummary({
|
|
344
|
-
environment,
|
|
345
|
-
dataplaneUrl,
|
|
346
|
-
systemKey,
|
|
347
|
-
publication,
|
|
348
|
-
manifest,
|
|
349
|
-
minimal: !!options.minimal,
|
|
350
|
-
willProbe: !!options.probe
|
|
351
|
-
});
|
|
352
|
-
if (options.probe) {
|
|
353
|
-
await maybeRunUploadProbe(dataplaneUrl, systemKey, authConfig, options.probeTimeout);
|
|
354
|
-
}
|
|
355
|
-
const dsKeys = (payload.dataSources || []).map((ds) => ds && ds.key).filter(Boolean);
|
|
356
|
-
await maybeSyncSystemCertificationFromDataplane({
|
|
357
|
-
label: 'upload',
|
|
358
|
-
noCertSync: cliOptsSkipCertSync(options),
|
|
359
|
-
systemKey,
|
|
360
|
-
dataplaneUrl,
|
|
361
|
-
authConfig,
|
|
362
|
-
datasourceKeys: dsKeys
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
|
|
366
333
|
/**
|
|
367
334
|
* Upload path after dry-run check.
|
|
368
335
|
* @param {string} systemKey
|
|
@@ -371,45 +338,55 @@ async function handlePublicationAndFollowups(ctx) {
|
|
|
371
338
|
* @param {Object} payload
|
|
372
339
|
*/
|
|
373
340
|
async function runUploadPublishAndSummary(systemKey, options, manifest, payload) {
|
|
374
|
-
const { dataplaneUrl, authConfig, environment } = await
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
341
|
+
const { dataplaneUrl, authConfig, environment } = await resolveUploadPublishContext(
|
|
342
|
+
resolveDataplaneAndAuth,
|
|
343
|
+
maybeRunVerboseServerValidation,
|
|
344
|
+
systemKey,
|
|
345
|
+
options,
|
|
346
|
+
payload
|
|
347
|
+
);
|
|
348
|
+
const rawRes = await runWithUploadPipelineSpinner(
|
|
349
|
+
async() => runUploadValidatePublish(dataplaneUrl, authConfig, payload, systemKey),
|
|
350
|
+
{
|
|
351
|
+
systemKey,
|
|
352
|
+
json: options.json === true,
|
|
353
|
+
syncMode: options.syncMode === true,
|
|
354
|
+
suppressPipelineSpinner: options.suppressPipelineSpinner === true
|
|
355
|
+
}
|
|
356
|
+
);
|
|
357
|
+
const publication = unwrapPublicationResult(rawRes);
|
|
358
|
+
if (isPublicationUnchanged(publication)) {
|
|
359
|
+
if (!isQuietMinimalSync(options)) {
|
|
360
|
+
logger.log(formatSuccessLine('Config unchanged on dataplane — upload skipped.'));
|
|
361
|
+
}
|
|
362
|
+
await runUploadSidecarFollowups({
|
|
363
|
+
systemKey,
|
|
364
|
+
options,
|
|
365
|
+
payload,
|
|
366
|
+
dataplaneUrl,
|
|
367
|
+
authConfig
|
|
368
|
+
});
|
|
369
|
+
return { dataplaneUrl, authConfig, environment, uploadSkipped: true };
|
|
389
370
|
}
|
|
371
|
+
|
|
390
372
|
await pushAndLogCredentialSecrets(dataplaneUrl, authConfig, systemKey, payload, {
|
|
391
373
|
json: options.json === true
|
|
392
374
|
});
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
375
|
+
await logAndSyncLocalOpenApiForUpload(systemKey, manifest);
|
|
376
|
+
await handlePublicationAndFollowups(
|
|
377
|
+
{
|
|
378
|
+
systemKey,
|
|
379
|
+
options,
|
|
380
|
+
manifest,
|
|
381
|
+
payload,
|
|
382
|
+
environment,
|
|
383
|
+
dataplaneUrl,
|
|
384
|
+
authConfig,
|
|
385
|
+
rawRes
|
|
399
386
|
},
|
|
400
|
-
|
|
387
|
+
maybeRunUploadProbe
|
|
401
388
|
);
|
|
402
|
-
|
|
403
|
-
systemKey,
|
|
404
|
-
options,
|
|
405
|
-
manifest,
|
|
406
|
-
payload,
|
|
407
|
-
environment,
|
|
408
|
-
dataplaneUrl,
|
|
409
|
-
authConfig,
|
|
410
|
-
rawRes
|
|
411
|
-
});
|
|
412
|
-
return { dataplaneUrl, authConfig, environment };
|
|
389
|
+
return { dataplaneUrl, authConfig, environment, uploadSkipped: false };
|
|
413
390
|
}
|
|
414
391
|
|
|
415
392
|
/**
|
|
@@ -426,12 +403,17 @@ async function runUploadPublishAndSummary(systemKey, options, manifest, payload)
|
|
|
426
403
|
*/
|
|
427
404
|
async function uploadExternalSystem(systemKey, options = {}) {
|
|
428
405
|
validateSystemKeyFormat(systemKey);
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
406
|
+
const minimal = options.minimal === true;
|
|
407
|
+
if (!minimal) {
|
|
408
|
+
logger.log('');
|
|
409
|
+
logger.log(sectionTitle('Upload external system'));
|
|
410
|
+
logger.log(SEP);
|
|
411
|
+
logger.log(headerKeyValue('System:', systemKey));
|
|
412
|
+
}
|
|
433
413
|
const { manifest, payload } = await buildValidatedUploadManifestPayload(systemKey, {
|
|
434
|
-
dryRun: !!options.dryRun
|
|
414
|
+
dryRun: !!options.dryRun,
|
|
415
|
+
force: options.force === true,
|
|
416
|
+
minimal
|
|
435
417
|
});
|
|
436
418
|
if (options.dryRun) {
|
|
437
419
|
logger.log(chalk.yellow('Dry run: would upload payload (no API calls).'));
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview verify-governance — sync, generate, verify (424.0 dataplane-first).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const { runGovernanceGenerateForExternalSystem } = require('./governance-generate-external');
|
|
8
|
+
const { runVerifyGovernanceForExternalSystem } = require('./verify-governance-external');
|
|
9
|
+
const {
|
|
10
|
+
buildSubjectsFromOptions,
|
|
11
|
+
resolveGovernanceIntegrationContext
|
|
12
|
+
} = require('./governance-cli-shared');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @async
|
|
16
|
+
* @param {string} systemKey
|
|
17
|
+
* @param {Object} options
|
|
18
|
+
* @returns {Promise<Object>}
|
|
19
|
+
*/
|
|
20
|
+
async function runVerifyGovernanceCombined(systemKey, options = {}) {
|
|
21
|
+
if (options.pack) {
|
|
22
|
+
return runVerifyGovernanceForExternalSystem(systemKey, options);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const subjects = buildSubjectsFromOptions(options);
|
|
26
|
+
if (subjects.length === 0) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
'At least one --subject-user-id or --subject-email is required for verify-governance'
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const { resolvedKey, authConfig, dataplaneUrl } = await resolveGovernanceIntegrationContext(
|
|
33
|
+
systemKey,
|
|
34
|
+
options
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const pipelineOpts = {
|
|
38
|
+
...options,
|
|
39
|
+
noSync: true,
|
|
40
|
+
authConfig,
|
|
41
|
+
dataplaneUrl
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const generateResult = await runGovernanceGenerateForExternalSystem(
|
|
45
|
+
resolvedKey,
|
|
46
|
+
pipelineOpts
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const verifyResult = await runVerifyGovernanceForExternalSystem(resolvedKey, pipelineOpts);
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
...verifyResult,
|
|
53
|
+
command: 'verify-governance',
|
|
54
|
+
generated: generateResult.generated,
|
|
55
|
+
generateResults: generateResult.results
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = {
|
|
60
|
+
runVerifyGovernanceCombined
|
|
61
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CLI action for `aifabrix verify-governance` (plan 150.0 / 424.0).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const logger = require('../utils/logger');
|
|
8
|
+
const { handleCommandError } = require('../utils/cli-utils');
|
|
9
|
+
const { runVerifyGovernanceCombined } = require('./verify-governance-combined-external');
|
|
10
|
+
const { normalizeTestGovernanceCliOptions } = require('./test-governance-cli-options');
|
|
11
|
+
const { displayVerifyGovernanceTTY } = require('../lifecycle/report-display');
|
|
12
|
+
const { exitCodeFromVerdict } = require('../lifecycle/exit-codes');
|
|
13
|
+
const { buildJsonEnvelope } = require('../lifecycle/json-envelope');
|
|
14
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {Object} options
|
|
18
|
+
* @param {import('commander').Command} [cmd]
|
|
19
|
+
* @returns {Object}
|
|
20
|
+
*/
|
|
21
|
+
function normalizeVerifyGovernanceCliOptions(options, cmd) {
|
|
22
|
+
const base = normalizeTestGovernanceCliOptions(options, cmd);
|
|
23
|
+
return {
|
|
24
|
+
...base,
|
|
25
|
+
certificationProfile: options.certificationProfile || 'bronze',
|
|
26
|
+
subjectUserIds: options.subjectUserId || [],
|
|
27
|
+
subjectEmails: options.subjectEmail || [],
|
|
28
|
+
maxSamplesPerPartition: options.maxSamplesPerPartition
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function runVerifyGovernanceCommandAction(appName, options, cmd) {
|
|
33
|
+
const opts = normalizeVerifyGovernanceCliOptions(options, cmd);
|
|
34
|
+
const result = await runVerifyGovernanceCombined(appName, opts);
|
|
35
|
+
|
|
36
|
+
if (opts.json) {
|
|
37
|
+
logger.log(JSON.stringify(buildJsonEnvelope(result, opts.verbose), null, 2));
|
|
38
|
+
} else {
|
|
39
|
+
if (opts.verbose && !opts.pack && typeof result.generated === 'number' && result.generated > 0) {
|
|
40
|
+
logger.log(formatSuccessLine(`Generated packs for ${result.generated} datasource(s)`));
|
|
41
|
+
}
|
|
42
|
+
displayVerifyGovernanceTTY(result.systemKey, result, { details: opts.verbose });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const exitCode = exitCodeFromVerdict(result.verdict);
|
|
46
|
+
if (exitCode !== 0) {
|
|
47
|
+
process.exit(exitCode);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function verifyGovernanceCommandHandler(appName, options, cmd) {
|
|
52
|
+
try {
|
|
53
|
+
await runVerifyGovernanceCommandAction(appName, options, cmd);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
handleCommandError(error, 'verify-governance');
|
|
56
|
+
process.exit(3);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
runVerifyGovernanceCommandAction,
|
|
62
|
+
verifyGovernanceCommandHandler,
|
|
63
|
+
normalizeVerifyGovernanceCliOptions
|
|
64
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview verify-governance DB pack path (plan 150.0).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
resolveExternalIntegrationContext,
|
|
9
|
+
syncLocalIfRequested
|
|
10
|
+
} = require('./test-e2e-external');
|
|
11
|
+
const { runDatasourceGovernanceScenarios, getDatasourceGovernancePack } = require('../api/governance-scenario-pack.api');
|
|
12
|
+
const { resolveIntegrationAuth } = require('../external-system/integration-auth-context');
|
|
13
|
+
const { cliOptsSkipSync } = require('../utils/cli-sync-options');
|
|
14
|
+
const { VERDICT } = require('../lifecycle/product-model');
|
|
15
|
+
const { runWithVerifyStepProgress } = require('../lifecycle/verify-step-progress');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {Object} options
|
|
19
|
+
* @param {Object|null} uploadCtx
|
|
20
|
+
*/
|
|
21
|
+
function attachUploadAuthToOptions(options, uploadCtx) {
|
|
22
|
+
if (!uploadCtx?.authConfig || !uploadCtx?.dataplaneUrl) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
options.authConfig = uploadCtx.authConfig;
|
|
26
|
+
options.dataplaneUrl = uploadCtx.dataplaneUrl;
|
|
27
|
+
options.silentResolve = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @async
|
|
32
|
+
* @param {string[]} keys
|
|
33
|
+
* @param {Object} ctx
|
|
34
|
+
* @param {{ setLabel?: (label: string) => void }} [progress]
|
|
35
|
+
* @returns {Promise<Array>}
|
|
36
|
+
*/
|
|
37
|
+
async function runGovernanceForDatasourceKeys(keys, ctx, progress = {}) {
|
|
38
|
+
const rows = [];
|
|
39
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
40
|
+
const key = keys[index];
|
|
41
|
+
if (typeof progress.setLabel === 'function') {
|
|
42
|
+
progress.setLabel(`Running governance scenarios: ${key} (${index + 1}/${keys.length})`);
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const packRow = await getDatasourceGovernancePack(ctx.dataplaneUrl, ctx.authConfig, key);
|
|
46
|
+
if (!packRow || !packRow.pack) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const result = await runDatasourceGovernanceScenarios(ctx.dataplaneUrl, ctx.authConfig, key);
|
|
50
|
+
const summary = result.summary || {};
|
|
51
|
+
rows.push({
|
|
52
|
+
datasourceKey: key,
|
|
53
|
+
verdict: summary.failed > 0 ? VERDICT.FAILED : VERDICT.VERIFIED,
|
|
54
|
+
scenarios: { passed: summary.passed || 0, total: summary.total || 0 },
|
|
55
|
+
policyCoveragePercent: result.policyCoveragePercent ?? 100,
|
|
56
|
+
dimensionCoveragePercent: result.dimensionCoveragePercent ?? 100,
|
|
57
|
+
packDocument: packRow.pack,
|
|
58
|
+
result
|
|
59
|
+
});
|
|
60
|
+
} catch (err) {
|
|
61
|
+
rows.push({
|
|
62
|
+
datasourceKey: key,
|
|
63
|
+
verdict: VERDICT.FAILED,
|
|
64
|
+
error: err.message,
|
|
65
|
+
scenarios: { passed: 0, total: 0 }
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return rows;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @async
|
|
74
|
+
* @param {string} systemKey
|
|
75
|
+
* @param {Object} options
|
|
76
|
+
* @returns {Promise<Object>}
|
|
77
|
+
*/
|
|
78
|
+
async function runVerifyGovernanceFromDbPacks(systemKey, options) {
|
|
79
|
+
const { systemKey: resolvedKey, keys } = resolveExternalIntegrationContext(systemKey);
|
|
80
|
+
if (keys.length === 0) {
|
|
81
|
+
return { resolvedKey, datasourceRows: [] };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!cliOptsSkipSync(options)) {
|
|
85
|
+
const uploadCtx = await syncLocalIfRequested(resolvedKey, options);
|
|
86
|
+
attachUploadAuthToOptions(options, uploadCtx);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const { authConfig, dataplaneUrl } = await resolveIntegrationAuth(resolvedKey, options);
|
|
90
|
+
const datasourceRows = await runWithVerifyStepProgress(
|
|
91
|
+
'Running governance scenarios',
|
|
92
|
+
async(progress) =>
|
|
93
|
+
runGovernanceForDatasourceKeys(keys, { authConfig, dataplaneUrl }, progress),
|
|
94
|
+
options
|
|
95
|
+
);
|
|
96
|
+
return { resolvedKey, datasourceRows };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = {
|
|
100
|
+
runGovernanceForDatasourceKeys,
|
|
101
|
+
runVerifyGovernanceFromDbPacks
|
|
102
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview verify-governance orchestration — DB scenario packs per datasource (plan 150.0).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { runTestGovernanceForExternalSystem } = require('./test-governance-external');
|
|
10
|
+
const { runVerifyGovernanceFromDbPacks } = require('./verify-governance-db');
|
|
11
|
+
const { VERDICT, verdictFromPassed } = require('../lifecycle/product-model');
|
|
12
|
+
const {
|
|
13
|
+
sumEnforcementScenarios,
|
|
14
|
+
aggregateCoverage,
|
|
15
|
+
buildPackOverrideResult
|
|
16
|
+
} = require('./verify-governance-result-builders');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {Array<Object>} rows
|
|
20
|
+
* @returns {{ passed: number, total: number }}
|
|
21
|
+
*/
|
|
22
|
+
function buildDbPackResult(resolvedKey, datasourceRows) {
|
|
23
|
+
const allVerified = datasourceRows.every(r => r.verdict === VERDICT.VERIFIED);
|
|
24
|
+
const coverage = aggregateCoverage(datasourceRows);
|
|
25
|
+
return {
|
|
26
|
+
systemKey: resolvedKey,
|
|
27
|
+
command: 'verify-governance',
|
|
28
|
+
verdict: verdictFromPassed(allVerified),
|
|
29
|
+
policyCoveragePercent: coverage.policy ?? (allVerified ? 100 : 0),
|
|
30
|
+
dimensionCoveragePercent: coverage.dimension ?? (allVerified ? 100 : 0),
|
|
31
|
+
enforcementScenarios: sumEnforcementScenarios(datasourceRows),
|
|
32
|
+
datasourceRows
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @async
|
|
38
|
+
* @param {string} systemKey
|
|
39
|
+
* @param {Object} options
|
|
40
|
+
* @returns {Promise<Object>}
|
|
41
|
+
*/
|
|
42
|
+
async function runVerifyGovernanceForExternalSystem(systemKey, options = {}) {
|
|
43
|
+
const pathsUtil = require('../utils/paths');
|
|
44
|
+
const appType = await pathsUtil.detectAppType(systemKey).catch(() => null);
|
|
45
|
+
if (!appType || appType.baseDir !== 'integration') {
|
|
46
|
+
throw new Error(
|
|
47
|
+
'verify-governance applies to external integration folders only (integration/<systemKey>/).'
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (options.pack) {
|
|
52
|
+
const runPayload = await runTestGovernanceForExternalSystem(systemKey, options);
|
|
53
|
+
return buildPackOverrideResult(systemKey, runPayload);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const { resolvedKey, datasourceRows } = await runVerifyGovernanceFromDbPacks(systemKey, options);
|
|
57
|
+
if (datasourceRows.length === 0) {
|
|
58
|
+
return {
|
|
59
|
+
systemKey: resolvedKey,
|
|
60
|
+
command: 'verify-governance',
|
|
61
|
+
verdict: VERDICT.FAILED,
|
|
62
|
+
policyCoveragePercent: 0,
|
|
63
|
+
dimensionCoveragePercent: 0,
|
|
64
|
+
enforcementScenarios: { passed: 0, total: 0 },
|
|
65
|
+
datasourceRows: []
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return buildDbPackResult(resolvedKey, datasourceRows);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = {
|
|
73
|
+
runVerifyGovernanceForExternalSystem,
|
|
74
|
+
buildPackOverrideResult,
|
|
75
|
+
sumEnforcementScenarios,
|
|
76
|
+
aggregateCoverage
|
|
77
|
+
};
|