@aifabrix/builder 2.51.0 → 2.52.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/jest.isolated-projects.js +77 -1
- package/jest.projects.js +5 -426
- package/lib/api/assistants.api.js +67 -0
- package/lib/api/datasources-extended.api.js +6 -6
- package/lib/api/evidence-authoring-helpers.js +267 -0
- package/lib/api/evidence-authoring.api.js +337 -0
- package/lib/api/evidence.api.js +57 -1
- package/lib/api/index.js +24 -7
- package/lib/api/pipeline.api.js +43 -3
- package/lib/api/records-bulk.api.js +28 -3
- package/lib/api/types/evidence.types.js +156 -8
- package/lib/api/work.api.js +283 -0
- package/lib/app/run-container-start.js +4 -0
- package/lib/app/run-deploy-job.js +216 -0
- package/lib/app/run-env-compose.js +32 -0
- package/lib/app/run-env-recovery.js +35 -0
- package/lib/app/run-helpers.js +15 -9
- package/lib/app/run.js +18 -2
- package/lib/channels/add-channel.js +54 -23
- package/lib/channels/approval-guides/chatgpt.js +13 -9
- package/lib/channels/approval-guides/microsoft-copilot.js +7 -8
- package/lib/channels/channel-artifact-generator.js +14 -2
- package/lib/channels/channel-credential.js +3 -1
- package/lib/channels/channel-probe-evidence.js +79 -0
- package/lib/channels/channel-probe.js +265 -13
- package/lib/channels/channel-runtime-resolver.js +120 -29
- package/lib/channels/channel-status-display.js +44 -0
- package/lib/channels/channel-targets.js +25 -1
- package/lib/channels/chatgpt-runtime-contract.js +29 -0
- package/lib/channels/microsoft-copilot-package.js +280 -0
- package/lib/channels/runtime-tool-catalog.js +165 -0
- package/lib/cli/index.js +2 -0
- package/lib/cli/infra-guided-footers.js +1 -1
- package/lib/cli/infra-guided-public-url-warn.js +55 -0
- package/lib/cli/infra-guided.js +65 -56
- package/lib/cli/setup-app.help.js +4 -0
- package/lib/cli/setup-app.js +4 -0
- package/lib/cli/setup-app.test-commands.js +59 -28
- package/lib/cli/setup-external-system-help.js +8 -2
- package/lib/cli/setup-external-system.js +62 -12
- package/lib/commands/app-test.js +2 -14
- package/lib/commands/channel-add-setup.js +8 -2
- package/lib/commands/channel.js +16 -5
- package/lib/commands/datasource-load-export-cli.js +6 -1
- package/lib/commands/deploy-gate-failure-details.js +19 -17
- package/lib/commands/deploy-gate-orchestrator.js +3 -2
- package/lib/commands/dev-down.js +2 -6
- package/lib/commands/evidence-kind.js +65 -15
- package/lib/commands/governance-generate-external.js +56 -21
- package/lib/commands/governance-verify-external.js +2 -5
- package/lib/commands/lifecycle-external.js +21 -8
- package/lib/commands/repair-datasource-apply.js +10 -1
- package/lib/commands/repair-datasource-run.js +4 -2
- package/lib/commands/repair-datasource-test-payload.js +80 -19
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +42 -3
- package/lib/commands/repair-internal.js +9 -1
- package/lib/commands/repair-openapi-sync.js +34 -17
- package/lib/commands/role-assistant.js +371 -0
- package/lib/commands/test-governance-external.js +2 -5
- package/lib/commands/up-miso.js +61 -24
- package/lib/commands/upload-data-sync-finalize.js +25 -7
- package/lib/commands/upload-sidecar-followups.js +144 -47
- package/lib/commands/upload.js +43 -6
- package/lib/commands/verify-governance-combined-external.js +73 -9
- package/lib/commands/verify-governance-db.js +80 -25
- package/lib/commands/verify-governance-external.js +31 -10
- package/lib/commands/verify-operations-external.js +2 -5
- package/lib/commands/verify-operations-step-plan.js +31 -0
- package/lib/commands/verify-trust-command-action.js +2 -5
- package/lib/commands/wizard-core-helpers.js +7 -3
- package/lib/commands/wizard-core.js +78 -9
- package/lib/datasource/bulk-loader-run-batches.js +4 -2
- package/lib/datasource/bulk-loader-service.js +5 -1
- package/lib/datasource/datasource-identifier.js +4 -3
- package/lib/datasource/datasource-validate-summary.js +2 -2
- package/lib/datasource/integration-context.js +3 -3
- package/lib/datasource/resolve-app.js +90 -8
- package/lib/datasource/test-e2e.js +2 -2
- package/lib/datasource/unified-validation-run-body.js +15 -1
- package/lib/datasource/unified-validation-run-resolve.js +2 -2
- package/lib/datasource/validate.js +13 -6
- package/lib/external-system/deploy-helpers.js +39 -1
- package/lib/external-system/deploy.js +25 -11
- package/lib/external-system/download-helpers.js +111 -2
- package/lib/external-system/download-role-assistant.js +55 -0
- package/lib/external-system/download.js +45 -26
- package/lib/external-system/test-helpers.js +1 -1
- package/lib/external-system/test-system-level.js +21 -3
- package/lib/external-system/test.js +43 -7
- package/lib/generator/builders.js +12 -15
- package/lib/generator/wizard.js +51 -4
- package/lib/lifecycle/access-control-abac.js +121 -0
- package/lib/lifecycle/lifecycle-governance-options.js +4 -1
- package/lib/lifecycle/product-model.js +3 -2
- package/lib/lifecycle/report-display.js +14 -2
- package/lib/programmatic/capability-registry.js +20 -1
- package/lib/programmatic/command-options.js +1 -0
- package/lib/programmatic/index.js +4 -0
- package/lib/programmatic/manifest-patch-section.js +48 -9
- package/lib/programmatic/manifest-section-registry-data.js +3 -2
- package/lib/programmatic/openapi-apply-result-schemas.js +44 -0
- package/lib/programmatic/openapi-component-schemas.js +16 -1
- package/lib/programmatic/openapi-description-enricher.js +3 -1
- package/lib/programmatic/openapi-descriptions.js +55 -5
- package/lib/programmatic/openapi-evidence-schemas.js +161 -0
- package/lib/programmatic/openapi-manifest-schemas.js +6 -2
- package/lib/programmatic/openapi-operation-bindings.js +99 -0
- package/lib/programmatic/openapi-request-schemas.js +36 -1
- package/lib/programmatic/openapi-result-schemas.js +1 -1
- package/lib/programmatic/openapi-schema-descriptions-certify.js +5 -1
- package/lib/programmatic/openapi-schema-descriptions-core.js +1 -1
- package/lib/programmatic/openapi-schema-descriptions-evidence.js +156 -0
- package/lib/programmatic/openapi-schema-descriptions-manifest.js +4 -3
- package/lib/programmatic/openapi-schema-descriptions-operations.js +70 -0
- package/lib/programmatic/openapi-spec.js +47 -28
- package/lib/programmatic/orchestration-openapi-meta.js +5 -0
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +89 -2
- package/lib/programmatic/run-certify.js +15 -2
- package/lib/programmatic/run-deploy.js +74 -0
- package/lib/programmatic/run-evidence-authoring.js +80 -0
- package/lib/programmatic/run-protection.js +124 -0
- package/lib/programmatic/run-template-workspace.js +28 -1
- package/lib/programmatic/workspace-context.js +6 -0
- package/lib/protection/auth-context.js +48 -6
- package/lib/protection/paths.js +22 -0
- package/lib/protection/run-protection-create-helpers.js +22 -1
- package/lib/protection/run-protection-create.js +1 -1
- package/lib/protection/sync-after-upload.js +1 -1
- package/lib/role-assistant/evidence-sync.js +450 -0
- package/lib/role-assistant/github-workflow.js +96 -0
- package/lib/role-assistant/knowledge-markdown-frontmatter.js +75 -0
- package/lib/role-assistant/knowledge-sync.js +485 -0
- package/lib/role-assistant/settings.js +126 -0
- package/lib/role-assistant/test-cases-evaluate.js +170 -0
- package/lib/role-assistant/test-cases-honesty.js +184 -0
- package/lib/role-assistant/test-cases.js +364 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +221 -0
- package/lib/role-assistant/test-runner-workhub.js +399 -0
- package/lib/role-assistant/test-runner.js +500 -0
- package/lib/schema/application-schema.json +24 -28
- package/lib/schema/deployment-rules.yaml +1 -0
- package/lib/schema/external-datasource.schema.json +38 -4
- package/lib/schema/external-system.schema.json +4 -4
- package/lib/schema/role-assistant-settings.schema.json +108 -0
- package/lib/utils/api.js +52 -27
- package/lib/utils/app-path-resolve.js +72 -24
- package/lib/utils/authentication-shape.js +3 -1
- package/lib/utils/certify-external-workspace.js +40 -0
- package/lib/utils/deployment-validation.js +28 -3
- package/lib/utils/docker-run-ephemeral.js +115 -0
- package/lib/utils/enterprise-knowledge-paths.js +29 -12
- package/lib/utils/env-copy-keycloak.js +196 -0
- package/lib/utils/env-copy.js +34 -1
- package/lib/utils/external-system-readiness-compact-display.js +3 -0
- package/lib/utils/health-check-public-warn.js +31 -13
- package/lib/utils/health-check.js +11 -1
- package/lib/utils/help-builder.js +1 -0
- package/lib/utils/paths.js +80 -38
- package/lib/utils/pipeline-upload-auth-retry.js +15 -3
- package/lib/utils/role-assistant-paths.js +160 -0
- package/lib/utils/schema-loader.js +41 -0
- package/lib/utils/schema-resolver.js +36 -4
- package/lib/utils/token-manager.js +38 -29
- package/lib/utils/upload-sync-options.js +7 -4
- package/lib/utils/url-declarative-resolve-load-doc.js +38 -1
- package/lib/validation/external-manifest-validator.js +31 -8
- package/lib/validation/reserved-system-key-prefixes.js +56 -0
- package/lib/validation/validate-external-file.js +8 -1
- package/lib/validation/validate.js +54 -19
- package/package.json +2 -1
- package/scripts/export-builder-api-evidence.js +1 -1
- package/templates/applications/builder-api/application.yaml +3 -3
- package/templates/applications/dataplane/application.yaml +24 -17
- package/templates/applications/dataplane/env.template +2 -2
- package/templates/applications/dataplane/rbac.yaml +24 -10
- package/templates/applications/keycloak/application.yaml +2 -2
- package/templates/applications/keycloak/env.template +5 -2
- package/templates/applications/miso-controller/application.yaml +3 -3
- package/templates/applications/miso-controller/env.template +17 -2
- package/templates/channels/chatgpt/install.template.md.hbs +82 -26
- package/templates/channels/chatgpt/integration/README.md +11 -7
- package/templates/channels/chatgpt/integration/application.json +2 -2
- package/templates/channels/chatgpt/integration/chatgpt-system.json +3 -3
- package/templates/channels/chatgpt/integration/env.template +1 -1
- package/templates/channels/chatgpt/manifest.template.json.hbs +36 -5
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +28 -0
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +22 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +32 -22
- package/templates/channels/microsoft-copilot/integration/README.md +9 -7
- package/templates/channels/microsoft-copilot/integration/application.json +2 -2
- package/templates/channels/microsoft-copilot/integration/env.template +1 -1
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +7 -6
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -6
- package/templates/channels/slack/install.template.md.hbs +6 -1
- package/templates/python/docker-compose.hbs +10 -0
- package/templates/typescript/docker-compose.hbs +10 -0
- /package/.cursor/plans/{157.1-security-quality-violations-by-type.csv → Done/157.1-security-quality-violations-by-type.csv} +0 -0
|
@@ -12,22 +12,123 @@ const { unwrapPublicationResult, isPublicationUnchanged } = require('../utils/ex
|
|
|
12
12
|
const { logUploadReadinessSummary } = require('../utils/external-system-readiness-display');
|
|
13
13
|
const { isQuietMinimalSync } = require('../utils/upload-sync-options');
|
|
14
14
|
|
|
15
|
+
function buildRoleAssistantModel(payload) {
|
|
16
|
+
return {
|
|
17
|
+
application: payload?.application,
|
|
18
|
+
dataSources: payload?.dataSources || []
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function buildRoleAssistantSyncContext(ctx, model) {
|
|
23
|
+
// Controller deploy env (e.g. miso) ≠ role-assistant.yaml section (dev|tst|pro).
|
|
24
|
+
const { resolveRoleAssistantSettingsEnvKey } = require('../role-assistant/knowledge-sync');
|
|
25
|
+
const raEnv = resolveRoleAssistantSettingsEnvKey(
|
|
26
|
+
(ctx.options && (ctx.options.env || ctx.options.roleAssistantEnv)) || 'dev'
|
|
27
|
+
);
|
|
28
|
+
return {
|
|
29
|
+
systemKey: ctx.systemKey,
|
|
30
|
+
dataplaneUrl: ctx.dataplaneUrl,
|
|
31
|
+
authConfig: ctx.authConfig,
|
|
32
|
+
model,
|
|
33
|
+
environment: raEnv,
|
|
34
|
+
pathOptions: ctx.options.pathOptions || {},
|
|
35
|
+
dryRun: ctx.options.dryRun === true
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function runGovernanceSidecar(ctx, sidecar, quietSidecar) {
|
|
40
|
+
try {
|
|
41
|
+
const { uploadGovernanceScenarioPacks } = require('../lifecycle/scenario-upload');
|
|
42
|
+
const uploaded = await uploadGovernanceScenarioPacks(ctx.systemKey, ctx.dataplaneUrl, ctx.authConfig, {
|
|
43
|
+
silent: quietSidecar
|
|
44
|
+
});
|
|
45
|
+
sidecar.governance = { uploaded: Number(uploaded || 0) };
|
|
46
|
+
} catch (err) {
|
|
47
|
+
sidecar.governance = { skipped: true, reason: err.message || String(err) };
|
|
48
|
+
if (!quietSidecar) {
|
|
49
|
+
logger.log(formatWarningLine(`Governance scenario upload skipped: ${err.message}`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function runEvidenceSidecar(ctx, model, sidecar, quietSidecar) {
|
|
55
|
+
const { importRoleAssistantEvidence, logRoleAssistantEvidenceImportSummary } = require('../role-assistant/evidence-sync');
|
|
56
|
+
const result = await importRoleAssistantEvidence(buildRoleAssistantSyncContext(ctx, model));
|
|
57
|
+
sidecar.evidence = result;
|
|
58
|
+
if (!quietSidecar) {
|
|
59
|
+
logRoleAssistantEvidenceImportSummary(ctx.systemKey, result, { verbose: ctx.options.verbose === true });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function runKnowledgeSidecar(ctx, model, sidecar, quietSidecar) {
|
|
64
|
+
const {
|
|
65
|
+
importRoleAssistantKnowledge,
|
|
66
|
+
logKnowledgeImportSummary,
|
|
67
|
+
pushRoleAssistantDocumentStorageSettings,
|
|
68
|
+
logDocumentStorageSettingsPushSummary
|
|
69
|
+
} = require('../role-assistant/knowledge-sync');
|
|
70
|
+
const syncCtx = buildRoleAssistantSyncContext(ctx, model);
|
|
71
|
+
try {
|
|
72
|
+
const settingsResult = await pushRoleAssistantDocumentStorageSettings(syncCtx);
|
|
73
|
+
sidecar.documentStorageSettings = settingsResult;
|
|
74
|
+
if (!quietSidecar) {
|
|
75
|
+
logDocumentStorageSettingsPushSummary(ctx.systemKey, settingsResult, {
|
|
76
|
+
verbose: ctx.options.verbose === true
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
sidecar.documentStorageSettings = {
|
|
81
|
+
skipped: true,
|
|
82
|
+
reason: err.message || String(err)
|
|
83
|
+
};
|
|
84
|
+
if (!quietSidecar) {
|
|
85
|
+
logger.log(
|
|
86
|
+
formatWarningLine(
|
|
87
|
+
`Knowledge document storage settings update failed: ${err.message}`
|
|
88
|
+
)
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const result = await importRoleAssistantKnowledge(syncCtx);
|
|
95
|
+
sidecar.knowledge = result;
|
|
96
|
+
if (!quietSidecar) {
|
|
97
|
+
logKnowledgeImportSummary(ctx.systemKey, result, { verbose: ctx.options.verbose === true });
|
|
98
|
+
}
|
|
99
|
+
} catch (err) {
|
|
100
|
+
sidecar.knowledge = { skipped: true, reason: err.message || String(err) };
|
|
101
|
+
if (!quietSidecar) {
|
|
102
|
+
logger.log(formatWarningLine(`Role assistant knowledge sync skipped: ${err.message}`));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
15
107
|
/**
|
|
16
108
|
* Sidecar follow-ups that are independent of pipeline publish hash (scenario packs).
|
|
17
109
|
* @param {Object} ctx
|
|
18
110
|
* @returns {Promise<void>}
|
|
19
111
|
*/
|
|
20
112
|
async function runUploadSidecarFollowups(ctx) {
|
|
21
|
-
const
|
|
22
|
-
|
|
113
|
+
const sidecar = {
|
|
114
|
+
governance: null,
|
|
115
|
+
evidence: null,
|
|
116
|
+
knowledge: null,
|
|
117
|
+
documentStorageSettings: null
|
|
118
|
+
};
|
|
119
|
+
const quietSidecar = isQuietMinimalSync(ctx.options);
|
|
120
|
+
const model = buildRoleAssistantModel(ctx.payload);
|
|
121
|
+
await runGovernanceSidecar(ctx, sidecar, quietSidecar);
|
|
23
122
|
try {
|
|
24
|
-
|
|
25
|
-
await uploadGovernanceScenarioPacks(systemKey, dataplaneUrl, authConfig, { silent: quietSidecar });
|
|
123
|
+
await runEvidenceSidecar(ctx, model, sidecar, quietSidecar);
|
|
26
124
|
} catch (err) {
|
|
27
|
-
if (
|
|
28
|
-
|
|
125
|
+
if (err && err.evidenceSummary) {
|
|
126
|
+
sidecar.evidence = err.evidenceSummary;
|
|
29
127
|
}
|
|
128
|
+
throw err;
|
|
30
129
|
}
|
|
130
|
+
await runKnowledgeSidecar(ctx, model, sidecar, quietSidecar);
|
|
131
|
+
return sidecar;
|
|
31
132
|
}
|
|
32
133
|
|
|
33
134
|
/**
|
|
@@ -54,61 +155,57 @@ async function resolveUploadProbeData(ctx, maybeRunUploadProbeFn) {
|
|
|
54
155
|
return { probeData: null, compact };
|
|
55
156
|
}
|
|
56
157
|
|
|
158
|
+
function logUploadSummary(ctx, publication, probeData) {
|
|
159
|
+
if (ctx.options.suppressSummary === true) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
logUploadReadinessSummary({
|
|
163
|
+
environment: ctx.environment,
|
|
164
|
+
dataplaneUrl: ctx.dataplaneUrl,
|
|
165
|
+
systemKey: ctx.systemKey,
|
|
166
|
+
publication,
|
|
167
|
+
manifest: ctx.manifest,
|
|
168
|
+
minimal: !!ctx.options.minimal,
|
|
169
|
+
willProbe: false,
|
|
170
|
+
credentialPush: ctx.credentialPush,
|
|
171
|
+
configPush: ctx.configPush,
|
|
172
|
+
forcePublish: ctx.options.force === true,
|
|
173
|
+
probeData
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function runProbeAfterSummary(ctx, maybeRunUploadProbe, compact) {
|
|
178
|
+
if (ctx.options.probe && !compact) {
|
|
179
|
+
await maybeRunUploadProbe(ctx.dataplaneUrl, ctx.systemKey, ctx.authConfig, ctx.options.probeTimeout, {
|
|
180
|
+
compact: false
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function runSidecarAndWrap(ctx) {
|
|
186
|
+
const sidecar = await runUploadSidecarFollowups(ctx);
|
|
187
|
+
return { sidecar };
|
|
188
|
+
}
|
|
189
|
+
|
|
57
190
|
/**
|
|
58
191
|
* @param {Object} ctx
|
|
59
192
|
* @param {Function} maybeRunUploadProbe
|
|
60
193
|
* @returns {Promise<void>}
|
|
61
194
|
*/
|
|
62
195
|
async function handlePublicationAndFollowups(ctx, maybeRunUploadProbe) {
|
|
63
|
-
const
|
|
64
|
-
systemKey,
|
|
65
|
-
options,
|
|
66
|
-
manifest,
|
|
67
|
-
payload,
|
|
68
|
-
environment,
|
|
69
|
-
dataplaneUrl,
|
|
70
|
-
authConfig,
|
|
71
|
-
rawRes,
|
|
72
|
-
credentialPush,
|
|
73
|
-
configPush
|
|
74
|
-
} = ctx;
|
|
75
|
-
const publication = unwrapPublicationResult(rawRes);
|
|
196
|
+
const publication = unwrapPublicationResult(ctx.rawRes);
|
|
76
197
|
if (!publication) {
|
|
77
198
|
throw new Error(
|
|
78
199
|
'Unexpected response from dataplane upload: missing publication result (uploadId/system/datasources).'
|
|
79
200
|
);
|
|
80
201
|
}
|
|
81
202
|
if (isPublicationUnchanged(publication)) {
|
|
82
|
-
|
|
83
|
-
return;
|
|
203
|
+
return runSidecarAndWrap(ctx);
|
|
84
204
|
}
|
|
85
|
-
|
|
86
|
-
const suppressSummary = options.suppressSummary === true;
|
|
87
205
|
const { probeData, compact } = await resolveUploadProbeData(ctx, maybeRunUploadProbe);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
environment,
|
|
92
|
-
dataplaneUrl,
|
|
93
|
-
systemKey,
|
|
94
|
-
publication,
|
|
95
|
-
manifest,
|
|
96
|
-
minimal: !!options.minimal,
|
|
97
|
-
willProbe: false,
|
|
98
|
-
credentialPush,
|
|
99
|
-
configPush,
|
|
100
|
-
forcePublish: options.force === true,
|
|
101
|
-
probeData
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (options.probe && !compact) {
|
|
106
|
-
await maybeRunUploadProbe(dataplaneUrl, systemKey, authConfig, options.probeTimeout, {
|
|
107
|
-
compact: false
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
await runUploadSidecarFollowups({ systemKey, options, payload, dataplaneUrl, authConfig });
|
|
206
|
+
logUploadSummary(ctx, publication, probeData);
|
|
207
|
+
await runProbeAfterSummary(ctx, maybeRunUploadProbe, compact);
|
|
208
|
+
return runSidecarAndWrap(ctx);
|
|
112
209
|
}
|
|
113
210
|
|
|
114
211
|
module.exports = {
|
package/lib/commands/upload.js
CHANGED
|
@@ -47,6 +47,12 @@ const { syncDeployJsonFromSources } = require('../external-system/sync-deploy-ma
|
|
|
47
47
|
const { handlePublicationAndFollowups } = require('./upload-sidecar-followups');
|
|
48
48
|
const { finalizeUploadPublishResult, finishUnchangedUploadPublication } = require('./upload-data-sync-finalize');
|
|
49
49
|
const { pushAndLogCredentialSecrets } = require('./upload-credential-push-log');
|
|
50
|
+
const {
|
|
51
|
+
SYSTEM_KIND_DIGITAL_WORKER,
|
|
52
|
+
readRoleAssistantSettings,
|
|
53
|
+
resolveRoleAssistantSettingsVersion,
|
|
54
|
+
resolveRoleAssistantEnvironmentSettings
|
|
55
|
+
} = require('../role-assistant/settings');
|
|
50
56
|
|
|
51
57
|
/**
|
|
52
58
|
* Validates system-key format (same as download).
|
|
@@ -123,14 +129,24 @@ async function resolveDataplaneAndAuth(systemKey, opts = {}) {
|
|
|
123
129
|
* @param {string} dataplaneUrl - Dataplane base URL
|
|
124
130
|
* @param {Object} authConfig - Auth config
|
|
125
131
|
* @param {Object} payload - { version, application, dataSources, status: "draft" }
|
|
132
|
+
* @param {string} systemKey
|
|
133
|
+
* @param {Object} [options]
|
|
134
|
+
* @param {number|string} [options.timeoutMs]
|
|
126
135
|
* @returns {Promise<Object>} Raw API response envelope
|
|
127
136
|
*/
|
|
128
|
-
async function runUploadValidatePublish(
|
|
137
|
+
async function runUploadValidatePublish(
|
|
138
|
+
dataplaneUrl,
|
|
139
|
+
authConfig,
|
|
140
|
+
payload,
|
|
141
|
+
systemKey,
|
|
142
|
+
options = {}
|
|
143
|
+
) {
|
|
129
144
|
const res = await uploadApplicationViaPipelineWithAuthRetry(
|
|
130
145
|
dataplaneUrl,
|
|
131
146
|
authConfig,
|
|
132
147
|
payload,
|
|
133
|
-
systemKey
|
|
148
|
+
systemKey,
|
|
149
|
+
{ timeoutMs: options.timeoutMs }
|
|
134
150
|
);
|
|
135
151
|
if (res?.success === false) {
|
|
136
152
|
throw new Error(formatApiError(res, dataplaneUrl));
|
|
@@ -231,6 +247,14 @@ async function buildValidatedUploadManifestPayload(systemKey, opts = {}) {
|
|
|
231
247
|
force: opts.force === true,
|
|
232
248
|
status: opts.uploadStatus === 'published' ? 'published' : 'draft'
|
|
233
249
|
});
|
|
250
|
+
if (String(manifest?.system?.systemKind || '').trim() === SYSTEM_KIND_DIGITAL_WORKER) {
|
|
251
|
+
const settings = readRoleAssistantSettings(systemKey, { required: true, pathOptions });
|
|
252
|
+
resolveRoleAssistantEnvironmentSettings(settings, opts.env || 'dev', { required: true });
|
|
253
|
+
const settingsVersion = resolveRoleAssistantSettingsVersion(settings);
|
|
254
|
+
if (settingsVersion) {
|
|
255
|
+
payload.version = settingsVersion;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
234
258
|
await resolvePayloadConfiguration(systemKey, payload, pathOptions);
|
|
235
259
|
return { manifest, payload };
|
|
236
260
|
}
|
|
@@ -264,7 +288,10 @@ async function logAndSyncLocalOpenApiForUpload(systemKey, manifest, uploadContex
|
|
|
264
288
|
systemKey,
|
|
265
289
|
datasourceFiles,
|
|
266
290
|
dataplaneUrl: uploadContext.dataplaneUrl,
|
|
267
|
-
authConfig: uploadContext.authConfig
|
|
291
|
+
authConfig: uploadContext.authConfig,
|
|
292
|
+
// Always replace SpecFile rows keyed by openapi.documentKey so vendor/full
|
|
293
|
+
// specs are not left missing while only thin internal:* slices remain.
|
|
294
|
+
force: true
|
|
268
295
|
});
|
|
269
296
|
if (!uploadContext.quiet) {
|
|
270
297
|
for (const line of openapiSyncLines) {
|
|
@@ -293,7 +320,7 @@ async function completeUploadAfterPublish(systemKey, options, manifest, payload,
|
|
|
293
320
|
pathOptions: options.pathOptions,
|
|
294
321
|
quiet: quietCompact
|
|
295
322
|
});
|
|
296
|
-
await handlePublicationAndFollowups(
|
|
323
|
+
const followupResult = await handlePublicationAndFollowups(
|
|
297
324
|
{
|
|
298
325
|
systemKey,
|
|
299
326
|
options,
|
|
@@ -309,7 +336,13 @@ async function completeUploadAfterPublish(systemKey, options, manifest, payload,
|
|
|
309
336
|
maybeRunUploadProbe
|
|
310
337
|
);
|
|
311
338
|
return finalizeUploadPublishResult(
|
|
312
|
-
{
|
|
339
|
+
{
|
|
340
|
+
dataplaneUrl: ctx.dataplaneUrl,
|
|
341
|
+
authConfig: ctx.authConfig,
|
|
342
|
+
environment: ctx.environment,
|
|
343
|
+
uploadSkipped: false,
|
|
344
|
+
sidecar: followupResult?.sidecar || null
|
|
345
|
+
},
|
|
313
346
|
payload,
|
|
314
347
|
options
|
|
315
348
|
);
|
|
@@ -331,7 +364,10 @@ async function runUploadPublishAndSummary(systemKey, options, manifest, payload)
|
|
|
331
364
|
payload
|
|
332
365
|
);
|
|
333
366
|
const rawRes = await runWithUploadPipelineSpinner(
|
|
334
|
-
async() =>
|
|
367
|
+
async() =>
|
|
368
|
+
runUploadValidatePublish(dataplaneUrl, authConfig, payload, systemKey, {
|
|
369
|
+
timeoutMs: options.timeoutMs
|
|
370
|
+
}),
|
|
335
371
|
{
|
|
336
372
|
systemKey,
|
|
337
373
|
json: options.json === true,
|
|
@@ -367,6 +403,7 @@ async function runUploadPublishAndSummary(systemKey, options, manifest, payload)
|
|
|
367
403
|
* @param {boolean} [options.verbose] - Expanded summary and server-side pipeline validate warnings
|
|
368
404
|
* @param {boolean} [options.probe] - POST validation/run after publish
|
|
369
405
|
* @param {number} [options.probeTimeout] - Probe timeout ms (default 120000)
|
|
406
|
+
* @param {number} [options.timeoutMs] - Pipeline publish timeout ms (HTTP + dataplane; default 300000)
|
|
370
407
|
* @param {boolean} [options.minimal] - Short summary (default: compact unless --verbose)
|
|
371
408
|
* @returns {Promise<{ dataplaneUrl: string, authConfig: Object, environment: string }|void>}
|
|
372
409
|
* @throws {Error} If validation or API calls fail
|
|
@@ -10,6 +10,56 @@ const {
|
|
|
10
10
|
buildSubjectsFromOptions,
|
|
11
11
|
resolveGovernanceIntegrationContext
|
|
12
12
|
} = require('./governance-cli-shared');
|
|
13
|
+
const { VERDICT } = require('../lifecycle/product-model');
|
|
14
|
+
const {
|
|
15
|
+
allDatasourcesAbacNotApplicable,
|
|
16
|
+
filterAbacRequiredDatasourceKeys
|
|
17
|
+
} = require('../lifecycle/access-control-abac');
|
|
18
|
+
const { runSystemLifecycle } = require('../api/lifecycle.api');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} resolvedKey
|
|
22
|
+
* @param {string[]} keys
|
|
23
|
+
* @param {Object} [extra]
|
|
24
|
+
* @returns {Object}
|
|
25
|
+
*/
|
|
26
|
+
function buildNotApplicableGovernanceResult(resolvedKey, keys, extra = {}) {
|
|
27
|
+
return {
|
|
28
|
+
systemKey: resolvedKey,
|
|
29
|
+
command: 'verify-governance',
|
|
30
|
+
verdict: VERDICT.NOT_APPLICABLE,
|
|
31
|
+
policyCoveragePercent: 100,
|
|
32
|
+
dimensionCoveragePercent: 100,
|
|
33
|
+
enforcementScenarios: { passed: 0, total: 0 },
|
|
34
|
+
datasourceRows: keys.map(datasourceKey => ({
|
|
35
|
+
datasourceKey,
|
|
36
|
+
verdict: VERDICT.NOT_APPLICABLE
|
|
37
|
+
})),
|
|
38
|
+
...extra
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {string} dataplaneUrl
|
|
44
|
+
* @param {Object} authConfig
|
|
45
|
+
* @param {string} resolvedKey
|
|
46
|
+
* @param {string[]} keys
|
|
47
|
+
* @param {Object} [extra]
|
|
48
|
+
* @returns {Promise<Object>}
|
|
49
|
+
*/
|
|
50
|
+
async function closeAllGovernanceAsNotApplicable(
|
|
51
|
+
dataplaneUrl,
|
|
52
|
+
authConfig,
|
|
53
|
+
resolvedKey,
|
|
54
|
+
keys,
|
|
55
|
+
extra = {}
|
|
56
|
+
) {
|
|
57
|
+
await runSystemLifecycle(dataplaneUrl, authConfig, resolvedKey, {
|
|
58
|
+
steps: ['governance'],
|
|
59
|
+
datasourceKeys: keys
|
|
60
|
+
});
|
|
61
|
+
return buildNotApplicableGovernanceResult(resolvedKey, keys, extra);
|
|
62
|
+
}
|
|
13
63
|
|
|
14
64
|
/**
|
|
15
65
|
* @async
|
|
@@ -23,22 +73,32 @@ async function runVerifyGovernanceCombined(systemKey, options = {}) {
|
|
|
23
73
|
}
|
|
24
74
|
|
|
25
75
|
const subjects = buildSubjectsFromOptions(options);
|
|
76
|
+
const { resolvedKey, keys, authConfig, dataplaneUrl } =
|
|
77
|
+
await resolveGovernanceIntegrationContext(systemKey, options);
|
|
78
|
+
|
|
26
79
|
if (subjects.length === 0) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
80
|
+
if (!allDatasourcesAbacNotApplicable(resolvedKey, keys)) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
'At least one --subject-user-id or --subject-email is required for verify-governance'
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return closeAllGovernanceAsNotApplicable(dataplaneUrl, authConfig, resolvedKey, keys);
|
|
30
86
|
}
|
|
31
87
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
88
|
+
const requiredKeys = filterAbacRequiredDatasourceKeys(resolvedKey, keys);
|
|
89
|
+
if (requiredKeys.length === 0) {
|
|
90
|
+
return closeAllGovernanceAsNotApplicable(dataplaneUrl, authConfig, resolvedKey, keys, {
|
|
91
|
+
generated: 0,
|
|
92
|
+
generateResults: []
|
|
93
|
+
});
|
|
94
|
+
}
|
|
36
95
|
|
|
37
96
|
const pipelineOpts = {
|
|
38
97
|
...options,
|
|
39
98
|
noPublish: true,
|
|
40
99
|
authConfig,
|
|
41
|
-
dataplaneUrl
|
|
100
|
+
dataplaneUrl,
|
|
101
|
+
datasourceKeys: requiredKeys
|
|
42
102
|
};
|
|
43
103
|
|
|
44
104
|
const generateResult = await runGovernanceGenerateForExternalSystem(
|
|
@@ -46,7 +106,11 @@ async function runVerifyGovernanceCombined(systemKey, options = {}) {
|
|
|
46
106
|
pipelineOpts
|
|
47
107
|
);
|
|
48
108
|
|
|
49
|
-
|
|
109
|
+
// Verify all datasources so notApplicable keys close as NOT_APPLICABLE.
|
|
110
|
+
const verifyResult = await runVerifyGovernanceForExternalSystem(resolvedKey, {
|
|
111
|
+
...pipelineOpts,
|
|
112
|
+
datasourceKeys: keys
|
|
113
|
+
});
|
|
50
114
|
|
|
51
115
|
return {
|
|
52
116
|
...verifyResult,
|
|
@@ -27,6 +27,58 @@ function attachUploadAuthToOptions(options, uploadCtx) {
|
|
|
27
27
|
options.silentResolve = true;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @param {string} key
|
|
32
|
+
* @param {Object|null} config
|
|
33
|
+
* @returns {Object}
|
|
34
|
+
*/
|
|
35
|
+
function buildNotApplicableGovernanceRow(key, config) {
|
|
36
|
+
const {
|
|
37
|
+
parseAccessControlAbac
|
|
38
|
+
} = require('../lifecycle/access-control-abac');
|
|
39
|
+
const abac = parseAccessControlAbac(config);
|
|
40
|
+
return {
|
|
41
|
+
datasourceKey: key,
|
|
42
|
+
verdict: VERDICT.NOT_APPLICABLE,
|
|
43
|
+
scenarios: { passed: 0, total: 0 },
|
|
44
|
+
policyCoveragePercent: 100,
|
|
45
|
+
dimensionCoveragePercent: 100,
|
|
46
|
+
rationale: abac.rationale
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {string} key
|
|
52
|
+
* @param {Object} ctx
|
|
53
|
+
* @returns {Promise<Object|null>}
|
|
54
|
+
*/
|
|
55
|
+
async function runRequiredGovernanceDatasource(key, ctx) {
|
|
56
|
+
try {
|
|
57
|
+
const packRow = await getDatasourceGovernancePack(ctx.dataplaneUrl, ctx.authConfig, key);
|
|
58
|
+
if (!packRow || !packRow.pack) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const result = await runDatasourceGovernanceScenarios(ctx.dataplaneUrl, ctx.authConfig, key);
|
|
62
|
+
const summary = result.summary || {};
|
|
63
|
+
return {
|
|
64
|
+
datasourceKey: key,
|
|
65
|
+
verdict: summary.failed > 0 ? VERDICT.FAILED : VERDICT.VERIFIED,
|
|
66
|
+
scenarios: { passed: summary.passed || 0, total: summary.total || 0 },
|
|
67
|
+
policyCoveragePercent: result.policyCoveragePercent ?? 100,
|
|
68
|
+
dimensionCoveragePercent: result.dimensionCoveragePercent ?? 100,
|
|
69
|
+
packDocument: packRow.pack,
|
|
70
|
+
result
|
|
71
|
+
};
|
|
72
|
+
} catch (err) {
|
|
73
|
+
return {
|
|
74
|
+
datasourceKey: key,
|
|
75
|
+
verdict: VERDICT.FAILED,
|
|
76
|
+
error: err.message,
|
|
77
|
+
scenarios: { passed: 0, total: 0 }
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
30
82
|
/**
|
|
31
83
|
* @async
|
|
32
84
|
* @param {string[]} keys
|
|
@@ -35,35 +87,27 @@ function attachUploadAuthToOptions(options, uploadCtx) {
|
|
|
35
87
|
* @returns {Promise<Array>}
|
|
36
88
|
*/
|
|
37
89
|
async function runGovernanceForDatasourceKeys(keys, ctx, progress = {}) {
|
|
90
|
+
const {
|
|
91
|
+
filterAbacRequiredDatasourceKeys,
|
|
92
|
+
loadDatasourceConfigsByKey
|
|
93
|
+
} = require('../lifecycle/access-control-abac');
|
|
94
|
+
const configs = loadDatasourceConfigsByKey(ctx.systemKey || '');
|
|
95
|
+
const required = new Set(
|
|
96
|
+
filterAbacRequiredDatasourceKeys(ctx.systemKey || '', keys)
|
|
97
|
+
);
|
|
38
98
|
const rows = [];
|
|
39
99
|
for (let index = 0; index < keys.length; index += 1) {
|
|
40
100
|
const key = keys[index];
|
|
41
101
|
if (typeof progress.setLabel === 'function') {
|
|
42
102
|
progress.setLabel(`Running governance scenarios: ${key} (${index + 1}/${keys.length})`);
|
|
43
103
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
});
|
|
104
|
+
if (!required.has(key)) {
|
|
105
|
+
rows.push(buildNotApplicableGovernanceRow(key, configs.get(key) || null));
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const row = await runRequiredGovernanceDatasource(key, ctx);
|
|
109
|
+
if (row) {
|
|
110
|
+
rows.push(row);
|
|
67
111
|
}
|
|
68
112
|
}
|
|
69
113
|
return rows;
|
|
@@ -76,7 +120,12 @@ async function runGovernanceForDatasourceKeys(keys, ctx, progress = {}) {
|
|
|
76
120
|
* @returns {Promise<Object>}
|
|
77
121
|
*/
|
|
78
122
|
async function runVerifyGovernanceFromDbPacks(systemKey, options) {
|
|
79
|
-
const { systemKey: resolvedKey, keys } =
|
|
123
|
+
const { systemKey: resolvedKey, keys: discoveredKeys } =
|
|
124
|
+
resolveExternalIntegrationContext(systemKey);
|
|
125
|
+
const keys =
|
|
126
|
+
Array.isArray(options.datasourceKeys) && options.datasourceKeys.length
|
|
127
|
+
? options.datasourceKeys
|
|
128
|
+
: discoveredKeys;
|
|
80
129
|
if (keys.length === 0) {
|
|
81
130
|
return { resolvedKey, datasourceRows: [] };
|
|
82
131
|
}
|
|
@@ -87,10 +136,16 @@ async function runVerifyGovernanceFromDbPacks(systemKey, options) {
|
|
|
87
136
|
}
|
|
88
137
|
|
|
89
138
|
const { authConfig, dataplaneUrl } = await resolveIntegrationAuth(resolvedKey, options);
|
|
139
|
+
options.authConfig = authConfig;
|
|
140
|
+
options.dataplaneUrl = dataplaneUrl;
|
|
90
141
|
const datasourceRows = await runWithVerifyStepProgress(
|
|
91
142
|
'Running governance scenarios',
|
|
92
143
|
async(progress) =>
|
|
93
|
-
runGovernanceForDatasourceKeys(
|
|
144
|
+
runGovernanceForDatasourceKeys(
|
|
145
|
+
keys,
|
|
146
|
+
{ authConfig, dataplaneUrl, systemKey: resolvedKey },
|
|
147
|
+
progress
|
|
148
|
+
),
|
|
94
149
|
options
|
|
95
150
|
);
|
|
96
151
|
return { resolvedKey, datasourceRows };
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
const { runTestGovernanceForExternalSystem } = require('./test-governance-external');
|
|
10
10
|
const { runVerifyGovernanceFromDbPacks } = require('./verify-governance-db');
|
|
11
|
-
const { VERDICT
|
|
11
|
+
const { VERDICT } = require('../lifecycle/product-model');
|
|
12
12
|
const {
|
|
13
13
|
sumEnforcementScenarios,
|
|
14
14
|
aggregateCoverage,
|
|
@@ -20,14 +20,26 @@ const {
|
|
|
20
20
|
* @returns {{ passed: number, total: number }}
|
|
21
21
|
*/
|
|
22
22
|
function buildDbPackResult(resolvedKey, datasourceRows) {
|
|
23
|
-
const
|
|
23
|
+
const hasFailed = datasourceRows.some(r => r.verdict === VERDICT.FAILED);
|
|
24
|
+
const allNa =
|
|
25
|
+
datasourceRows.length > 0
|
|
26
|
+
&& datasourceRows.every(r => r.verdict === VERDICT.NOT_APPLICABLE);
|
|
27
|
+
const allClosed = datasourceRows.every(
|
|
28
|
+
r => r.verdict === VERDICT.VERIFIED || r.verdict === VERDICT.NOT_APPLICABLE
|
|
29
|
+
);
|
|
30
|
+
let verdict = VERDICT.FAILED;
|
|
31
|
+
if (allNa) {
|
|
32
|
+
verdict = VERDICT.NOT_APPLICABLE;
|
|
33
|
+
} else if (allClosed && !hasFailed) {
|
|
34
|
+
verdict = VERDICT.VERIFIED;
|
|
35
|
+
}
|
|
24
36
|
const coverage = aggregateCoverage(datasourceRows);
|
|
25
37
|
return {
|
|
26
38
|
systemKey: resolvedKey,
|
|
27
39
|
command: 'verify-governance',
|
|
28
|
-
verdict
|
|
29
|
-
policyCoveragePercent: coverage.policy ?? (
|
|
30
|
-
dimensionCoveragePercent: coverage.dimension ?? (
|
|
40
|
+
verdict,
|
|
41
|
+
policyCoveragePercent: coverage.policy ?? (allClosed ? 100 : 0),
|
|
42
|
+
dimensionCoveragePercent: coverage.dimension ?? (allClosed ? 100 : 0),
|
|
31
43
|
enforcementScenarios: sumEnforcementScenarios(datasourceRows),
|
|
32
44
|
datasourceRows
|
|
33
45
|
};
|
|
@@ -41,12 +53,9 @@ function buildDbPackResult(resolvedKey, datasourceRows) {
|
|
|
41
53
|
*/
|
|
42
54
|
async function runVerifyGovernanceForExternalSystem(systemKey, options = {}) {
|
|
43
55
|
const pathsUtil = require('../utils/paths');
|
|
56
|
+
const { assertCertifyExternalWorkspace } = require('../utils/certify-external-workspace');
|
|
44
57
|
const appType = await pathsUtil.detectAppType(systemKey).catch(() => null);
|
|
45
|
-
|
|
46
|
-
throw new Error(
|
|
47
|
-
'verify-governance applies to external integration folders only (integration/<systemKey>/).'
|
|
48
|
-
);
|
|
49
|
-
}
|
|
58
|
+
assertCertifyExternalWorkspace(appType && appType.baseDir, 'verify-governance');
|
|
50
59
|
|
|
51
60
|
if (options.pack) {
|
|
52
61
|
const runPayload = await runTestGovernanceForExternalSystem(systemKey, options);
|
|
@@ -66,6 +75,18 @@ async function runVerifyGovernanceForExternalSystem(systemKey, options = {}) {
|
|
|
66
75
|
};
|
|
67
76
|
}
|
|
68
77
|
|
|
78
|
+
const naKeys = datasourceRows
|
|
79
|
+
.filter(row => row.verdict === VERDICT.NOT_APPLICABLE)
|
|
80
|
+
.map(row => row.datasourceKey)
|
|
81
|
+
.filter(Boolean);
|
|
82
|
+
if (naKeys.length > 0 && options.authConfig && options.dataplaneUrl) {
|
|
83
|
+
const { runSystemLifecycle } = require('../api/lifecycle.api');
|
|
84
|
+
await runSystemLifecycle(options.dataplaneUrl, options.authConfig, resolvedKey, {
|
|
85
|
+
steps: ['governance'],
|
|
86
|
+
datasourceKeys: naKeys
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
69
90
|
return buildDbPackResult(resolvedKey, datasourceRows);
|
|
70
91
|
}
|
|
71
92
|
|
|
@@ -162,12 +162,9 @@ async function buildOperationsResult({
|
|
|
162
162
|
*/
|
|
163
163
|
async function assertIntegrationExternalSystem(systemKey) {
|
|
164
164
|
const pathsUtil = require('../utils/paths');
|
|
165
|
+
const { assertCertifyExternalWorkspace } = require('../utils/certify-external-workspace');
|
|
165
166
|
const appType = await pathsUtil.detectAppType(systemKey).catch(() => null);
|
|
166
|
-
|
|
167
|
-
throw new Error(
|
|
168
|
-
'verify-operations applies to external integration folders only (integration/<systemKey>/).'
|
|
169
|
-
);
|
|
170
|
-
}
|
|
167
|
+
assertCertifyExternalWorkspace(appType && appType.baseDir, 'verify-operations');
|
|
171
168
|
}
|
|
172
169
|
|
|
173
170
|
/**
|