@aifabrix/builder 2.45.0 → 2.45.5
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/docs-rules.mdc +3 -1
- 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/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
- package/jest.projects.js +44 -1
- package/lib/api/agent-metadata-validation.api.js +93 -0
- package/lib/api/audit-api-helpers.js +68 -0
- package/lib/api/audit.api.js +119 -0
- package/lib/api/auth-cache.api.js +44 -0
- package/lib/api/certificates.api.js +4 -4
- package/lib/api/credential.api.js +2 -2
- package/lib/api/dataplane-health.api.js +137 -0
- package/lib/api/dataplane-sync.api.js +27 -0
- package/lib/api/datasources-core.api.js +21 -18
- package/lib/api/datasources-extended.api.js +22 -22
- package/lib/api/dimensions.api.js +3 -0
- package/lib/api/external-systems.api.js +13 -13
- package/lib/api/governance-scenarios.api.js +39 -0
- package/lib/api/groups.api.js +79 -0
- package/lib/api/index.js +45 -2
- package/lib/api/pipeline.api.js +4 -4
- package/lib/api/protection.api.js +157 -0
- package/lib/api/records-bulk.api.js +30 -0
- package/lib/api/records-search-parse.js +49 -0
- package/lib/api/records-search.api.js +29 -0
- package/lib/api/types/agent-metadata-validation.types.js +67 -0
- package/lib/api/types/audit.types.js +72 -0
- package/lib/api/types/dataplane-health.types.js +27 -0
- package/lib/api/types/dimensions.types.js +2 -0
- package/lib/api/types/governance-scenarios.types.js +39 -0
- package/lib/api/types/protection.types.js +69 -0
- package/lib/api/types/records-bulk.types.js +35 -0
- package/lib/api/types/records-search.types.js +28 -0
- package/lib/api/user-groups.api.js +50 -0
- package/lib/api/users.api.js +95 -0
- package/lib/api/validation-run.api.js +3 -3
- package/lib/api/validation-runner.js +3 -3
- package/lib/api/wizard-platform.api.js +3 -3
- package/lib/api/wizard.api.js +21 -21
- package/lib/app/deploy.js +34 -19
- package/lib/cli/index.js +4 -2
- package/lib/cli/infra-guided.js +22 -3
- package/lib/cli/setup-app.help.js +50 -2
- package/lib/cli/setup-app.js +33 -24
- package/lib/cli/setup-app.test-commands.js +80 -21
- package/lib/cli/setup-auth.js +30 -3
- package/lib/cli/setup-external-system.js +37 -3
- package/lib/cli/setup-utility-help-after.js +45 -0
- package/lib/cli/setup-utility-resolve.js +2 -2
- package/lib/cli/setup-utility.js +99 -81
- package/lib/commands/auth-status-dataplane-version.js +231 -0
- package/lib/commands/auth-status-display.js +94 -0
- package/lib/commands/auth-status.js +70 -6
- package/lib/commands/credential-push.js +10 -5
- package/lib/commands/datasource-load-export-cli.js +178 -0
- package/lib/commands/datasource-test-trust-cli.js +114 -0
- package/lib/commands/datasource-unified-test-cli.js +25 -17
- package/lib/commands/datasource-unified-test-cli.options.js +18 -3
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
- package/lib/commands/datasource-verify-audit-cli.js +96 -0
- package/lib/commands/datasource.js +68 -1
- package/lib/commands/dimension-value.js +43 -13
- package/lib/commands/dimension.js +38 -7
- package/lib/commands/identity-apply-sync.js +131 -0
- package/lib/commands/identity-group-cli.js +146 -0
- package/lib/commands/identity-membership-role-cache.js +175 -0
- package/lib/commands/identity-shared.js +94 -0
- package/lib/commands/identity-user-cli.js +158 -0
- package/lib/commands/identity.js +43 -0
- package/lib/commands/login.js +46 -16
- package/lib/commands/protection-cli-leaves.js +286 -0
- package/lib/commands/protection.js +50 -0
- package/lib/commands/repair.js +13 -3
- package/lib/commands/test-e2e-external.js +40 -9
- package/lib/commands/test-governance-cli-options.js +47 -0
- package/lib/commands/test-governance-command-action.js +55 -0
- package/lib/commands/test-governance-external.js +88 -0
- package/lib/commands/test-trust-cli-options.js +32 -0
- package/lib/commands/test-trust-command-action.js +118 -0
- package/lib/commands/test-trust-external.js +127 -0
- package/lib/commands/upload.js +34 -13
- package/lib/commands/wizard-core.js +3 -0
- package/lib/core/config-device-dataplane.js +185 -0
- package/lib/datasource/agent-trust-debug-log.js +45 -0
- package/lib/datasource/agent-trust-fetch.js +115 -0
- package/lib/datasource/agent-trust-map.js +101 -0
- package/lib/datasource/agent-trust-mock.js +44 -0
- package/lib/datasource/agent-trust-run.js +93 -0
- package/lib/datasource/agent-trust-timeout.js +25 -0
- package/lib/datasource/audit-evidence-display.js +80 -0
- package/lib/datasource/audit-evidence-extract-debug.js +103 -0
- package/lib/datasource/audit-evidence-extract.js +177 -0
- package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
- package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
- package/lib/datasource/audit-evidence-poll.js +109 -0
- package/lib/datasource/audit-evidence-run.js +177 -0
- package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
- package/lib/datasource/audit-evidence-verify-matrix.js +177 -0
- package/lib/datasource/audit-evidence-verify.js +108 -0
- package/lib/datasource/bulk-loader-run-batches.js +88 -0
- package/lib/datasource/bulk-loader-service-retry.js +52 -0
- package/lib/datasource/bulk-loader-service.js +127 -0
- package/lib/datasource/capability/run-capability-dimension.js +2 -1
- package/lib/datasource/datasource-exporter-resolve.js +82 -0
- package/lib/datasource/datasource-exporter-service.js +144 -0
- package/lib/datasource/datasource-identifier.js +148 -0
- package/lib/datasource/datasource-load-export-context.js +92 -0
- package/lib/datasource/integration-context.js +6 -4
- package/lib/datasource/local-data-paths.js +145 -0
- package/lib/datasource/log-cleaner.js +241 -0
- package/lib/datasource/log-viewer.js +111 -6
- package/lib/datasource/record-file-parser.js +85 -0
- package/lib/datasource/record-mapper.js +129 -0
- package/lib/datasource/resolve-app.js +74 -55
- package/lib/datasource/test-e2e.js +26 -2
- package/lib/datasource/unified-validation-run-resolve.js +45 -12
- package/lib/datasource/unified-validation-run.js +43 -17
- package/lib/datasource/validate.js +37 -20
- package/lib/external-system/test-system-level.js +25 -4
- package/lib/external-system/test.js +3 -1
- package/lib/governance/governance-pack-loader.js +70 -0
- package/lib/governance/governance-run-display.js +119 -0
- package/lib/identity/identity-apply-core.js +108 -0
- package/lib/identity/identity-apply-phases.js +244 -0
- package/lib/identity/identity-apply-service.js +77 -0
- package/lib/identity/identity-csv-parser.js +114 -0
- package/lib/internal/fs-real-sync.js +29 -1
- package/lib/protection/auth-context.js +45 -0
- package/lib/protection/convert-batch.js +90 -0
- package/lib/protection/load.js +41 -0
- package/lib/protection/paths.js +158 -0
- package/lib/protection/preflight-datasource-ready.js +46 -0
- package/lib/protection/protection-create-probe-lines.js +142 -0
- package/lib/protection/protection-create-probes.js +95 -0
- package/lib/protection/protection-create-scaffold.js +281 -0
- package/lib/protection/protection-display-helpers.js +445 -0
- package/lib/protection/protection-display.js +215 -0
- package/lib/protection/protection-preset-registry.js +97 -0
- package/lib/protection/report-exit.js +62 -0
- package/lib/protection/resolve.js +202 -0
- package/lib/protection/run-commands-validate.js +130 -0
- package/lib/protection/run-commands.js +216 -0
- package/lib/protection/run-protection-create-helpers.js +134 -0
- package/lib/protection/run-protection-create-probes-flow.js +43 -0
- package/lib/protection/run-protection-create.js +191 -0
- package/lib/protection/scope.js +22 -0
- package/lib/protection/sync-after-upload.js +64 -0
- package/lib/protection/upload-batch.js +127 -0
- package/lib/protection/validate-batch.js +113 -0
- package/lib/protection/validate-local.js +65 -0
- package/lib/resolvers/dimension-file.js +29 -4
- package/lib/schema/external-datasource.schema.json +47 -13
- package/lib/schema/flag-map-validation-run.json +2 -2
- package/lib/schema/protection.schema.json +374 -0
- package/lib/schema/type/credential-field-registry.json +636 -0
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/agent-trust-run-display.js +231 -0
- package/lib/utils/agent-trust-run-exit.js +59 -0
- package/lib/utils/agent-trust-wait-ui.js +94 -0
- package/lib/utils/cli-exit-codes.js +30 -0
- package/lib/utils/cli-sync-options.js +33 -0
- package/lib/utils/credential-push-ui.js +90 -0
- package/lib/utils/dataplane-cli-version-gate.js +202 -0
- package/lib/utils/dataplane-cli-version-help.js +74 -0
- package/lib/utils/datasource-export-display.js +137 -0
- package/lib/utils/datasource-load-display.js +174 -0
- package/lib/utils/datasource-load-export-ui.js +120 -0
- package/lib/utils/datasource-test-run-capability-scope.js +3 -3
- package/lib/utils/datasource-test-run-display.js +3 -3
- package/lib/utils/datasource-test-run-tty-log.js +5 -1
- package/lib/utils/help-builder.js +30 -24
- package/lib/utils/manifest-source-emit.js +22 -0
- package/lib/utils/semver-compare.js +127 -0
- package/lib/utils/upload-pipeline-ui.js +91 -0
- package/lib/utils/validation-poll-ui.js +14 -7
- package/lib/validation/wizard-config-validator.js +58 -19
- package/package.json +1 -1
- package/templates/applications/dataplane/env.template +13 -1
- package/templates/applications/dataplane/rbac.yaml +4 -0
- package/templates/external-system/README.md.hbs +56 -8
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dataplane fetch paths for agent trust runs (POST validate / GET latest).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
runAgentMetadataValidation,
|
|
9
|
+
getLatestAgentMetadataValidation
|
|
10
|
+
} = require('../api/agent-metadata-validation.api');
|
|
11
|
+
const { parseTrustTimeoutMs } = require('./agent-trust-timeout');
|
|
12
|
+
const { isAgentTrustMockEnabled, buildMockTrustRun } = require('./agent-trust-mock');
|
|
13
|
+
const { mapRunResponseToTrustRun, mapLatestResultToTrustRun } = require('./agent-trust-map');
|
|
14
|
+
const {
|
|
15
|
+
runWithAgentTrustWaitSpinner,
|
|
16
|
+
logAgentTrustWaitHintOnce
|
|
17
|
+
} = require('../utils/agent-trust-wait-ui');
|
|
18
|
+
|
|
19
|
+
function unwrapApiData(response) {
|
|
20
|
+
if (response && response.data !== undefined) return response.data;
|
|
21
|
+
return response;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {Object} options
|
|
26
|
+
* @returns {boolean}
|
|
27
|
+
*/
|
|
28
|
+
function shouldPreferLatestRead(options = {}) {
|
|
29
|
+
if (options.revalidate === true) return false;
|
|
30
|
+
return options.summary === true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {Error} err
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
function isLatestNotFoundError(err) {
|
|
38
|
+
const code = err && (err.statusCode || err.status);
|
|
39
|
+
if (code === 404) return true;
|
|
40
|
+
const msg = err && err.message ? String(err.message) : '';
|
|
41
|
+
return /no agent metadata validation/i.test(msg);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @async
|
|
46
|
+
* @param {Object} params
|
|
47
|
+
* @returns {Promise<Object>}
|
|
48
|
+
*/
|
|
49
|
+
async function postValidateTrustRun(params) {
|
|
50
|
+
const { dataplaneUrl, datasourceKey, systemKey, authConfig, body, options } = params;
|
|
51
|
+
const timeoutMs = parseTrustTimeoutMs(options);
|
|
52
|
+
logAgentTrustWaitHintOnce(datasourceKey, timeoutMs);
|
|
53
|
+
const raw = await runWithAgentTrustWaitSpinner(
|
|
54
|
+
() =>
|
|
55
|
+
runAgentMetadataValidation(dataplaneUrl, datasourceKey, authConfig, body, { timeoutMs }),
|
|
56
|
+
{ datasourceKey, timeoutMs }
|
|
57
|
+
);
|
|
58
|
+
return mapRunResponseToTrustRun({
|
|
59
|
+
datasourceKey,
|
|
60
|
+
systemKey,
|
|
61
|
+
runResponse: unwrapApiData(raw)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @async
|
|
67
|
+
* @param {Object} params
|
|
68
|
+
* @returns {Promise<Object>}
|
|
69
|
+
*/
|
|
70
|
+
async function getLatestTrustRun(params) {
|
|
71
|
+
const { dataplaneUrl, datasourceKey, systemKey, authConfig, options } = params;
|
|
72
|
+
const timeoutMs = parseTrustTimeoutMs(options);
|
|
73
|
+
const raw = await getLatestAgentMetadataValidation(dataplaneUrl, datasourceKey, authConfig, {
|
|
74
|
+
timeoutMs
|
|
75
|
+
});
|
|
76
|
+
return mapLatestResultToTrustRun({
|
|
77
|
+
datasourceKey,
|
|
78
|
+
systemKey,
|
|
79
|
+
latestResult: unwrapApiData(raw)
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @async
|
|
85
|
+
* @param {Object} params
|
|
86
|
+
* @returns {Promise<Object>}
|
|
87
|
+
*/
|
|
88
|
+
async function fetchTrustRunFromDataplane(params) {
|
|
89
|
+
const { datasourceKey, systemKey, dataplaneUrl, authConfig, options } = params;
|
|
90
|
+
if (isAgentTrustMockEnabled()) {
|
|
91
|
+
return buildMockTrustRun(datasourceKey, systemKey);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const body = { forceRevalidate: options.revalidate === true };
|
|
95
|
+
if (options.peerDatasourceConfigs && typeof options.peerDatasourceConfigs === 'object') {
|
|
96
|
+
body.peerDatasourceConfigs = options.peerDatasourceConfigs;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!shouldPreferLatestRead(options)) {
|
|
100
|
+
return postValidateTrustRun({ dataplaneUrl, datasourceKey, systemKey, authConfig, body, options });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
return await getLatestTrustRun({ dataplaneUrl, datasourceKey, systemKey, authConfig, options });
|
|
105
|
+
} catch (err) {
|
|
106
|
+
if (!isLatestNotFoundError(err)) throw err;
|
|
107
|
+
return postValidateTrustRun({ dataplaneUrl, datasourceKey, systemKey, authConfig, body, options });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
module.exports = {
|
|
112
|
+
shouldPreferLatestRead,
|
|
113
|
+
fetchTrustRunFromDataplane,
|
|
114
|
+
isLatestNotFoundError
|
|
115
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Map dataplane agent metadata validation API payloads to CLI trust runs.
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {string} trustDecision
|
|
11
|
+
* @returns {'ok'|'warn'|'fail'}
|
|
12
|
+
*/
|
|
13
|
+
function trustDecisionToRowStatus(trustDecision) {
|
|
14
|
+
const td = String(trustDecision || '').trim();
|
|
15
|
+
if (td === 'trusted') return 'ok';
|
|
16
|
+
if (td === 'usableWithWarnings') return 'warn';
|
|
17
|
+
return 'fail';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {Object} result - AgentMetadataValidationResult from dataplane
|
|
22
|
+
* @returns {string[]}
|
|
23
|
+
*/
|
|
24
|
+
function highLevelWarningsFromResult(result) {
|
|
25
|
+
if (!result || !Array.isArray(result.findings)) return [];
|
|
26
|
+
return result.findings
|
|
27
|
+
.filter(f => f && (f.severity === 'warning' || f.severity === 'error'))
|
|
28
|
+
.slice(0, 8)
|
|
29
|
+
.map(f => {
|
|
30
|
+
const code = f.code ? String(f.code) : 'FINDING';
|
|
31
|
+
const msg = f.message ? String(f.message) : '';
|
|
32
|
+
return msg ? `${code} — ${msg}` : code;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {Object} params
|
|
38
|
+
* @param {string} params.datasourceKey
|
|
39
|
+
* @param {string} params.systemKey
|
|
40
|
+
* @param {Object} params.runResponse - POST run response body
|
|
41
|
+
* @returns {Object} AgentTrustRun-shaped object for CLI display/exit
|
|
42
|
+
*/
|
|
43
|
+
function mapRunResponseToTrustRun({ datasourceKey, systemKey, runResponse }) {
|
|
44
|
+
const body = runResponse && typeof runResponse === 'object' ? runResponse : {};
|
|
45
|
+
const result = body.result && typeof body.result === 'object' ? body.result : {};
|
|
46
|
+
const trustDecision = result.trustDecision || 'pending';
|
|
47
|
+
return {
|
|
48
|
+
datasourceKey,
|
|
49
|
+
systemKey,
|
|
50
|
+
status: trustDecisionToRowStatus(trustDecision),
|
|
51
|
+
trustDecision,
|
|
52
|
+
validationStatus: result.status || 'pending',
|
|
53
|
+
confidence: typeof result.confidence === 'number' ? result.confidence : 0,
|
|
54
|
+
summary: result.summary || '',
|
|
55
|
+
validatedAt: result.validatedAt || '',
|
|
56
|
+
inputHash: result.inputHash || '',
|
|
57
|
+
contractVersion: result.contractVersion || '',
|
|
58
|
+
cacheHit: body.reused === true,
|
|
59
|
+
highLevelWarnings: highLevelWarningsFromResult(result),
|
|
60
|
+
findings: Array.isArray(result.findings) ? result.findings : [],
|
|
61
|
+
observedBusinessModel: result.observedBusinessModel || null,
|
|
62
|
+
runId: body.id || null
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {Object} params
|
|
68
|
+
* @param {string} params.datasourceKey
|
|
69
|
+
* @param {string} params.systemKey
|
|
70
|
+
* @param {Object} params.latestResult - GET /agent-validation body
|
|
71
|
+
* @returns {Object}
|
|
72
|
+
*/
|
|
73
|
+
function mapLatestResultToTrustRun({ datasourceKey, systemKey, latestResult }) {
|
|
74
|
+
const result = latestResult && typeof latestResult === 'object' ? latestResult : {};
|
|
75
|
+
const trustDecision = result.trustDecision || 'pending';
|
|
76
|
+
return {
|
|
77
|
+
datasourceKey,
|
|
78
|
+
systemKey,
|
|
79
|
+
status: trustDecisionToRowStatus(trustDecision),
|
|
80
|
+
trustDecision,
|
|
81
|
+
validationStatus: result.status || 'pending',
|
|
82
|
+
confidence: typeof result.confidence === 'number' ? result.confidence : 0,
|
|
83
|
+
summary: result.summary || '',
|
|
84
|
+
validatedAt: result.validatedAt || '',
|
|
85
|
+
inputHash: result.inputHash || '',
|
|
86
|
+
contractVersion: result.contractVersion || '',
|
|
87
|
+
cacheHit: true,
|
|
88
|
+
highLevelWarnings: highLevelWarningsFromResult(result),
|
|
89
|
+
findings: Array.isArray(result.findings) ? result.findings : [],
|
|
90
|
+
observedBusinessModel: result.observedBusinessModel || null,
|
|
91
|
+
runId: null,
|
|
92
|
+
readLatest: true
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = {
|
|
97
|
+
trustDecisionToRowStatus,
|
|
98
|
+
highLevelWarningsFromResult,
|
|
99
|
+
mapRunResponseToTrustRun,
|
|
100
|
+
mapLatestResultToTrustRun
|
|
101
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dev-only mock trust runs when AIFABRIX_AGENT_TRUST_MOCK=1 (plan 143).
|
|
3
|
+
* Not documented in user-facing CLI docs; for local CLI development without dataplane 404.5.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @returns {boolean}
|
|
10
|
+
*/
|
|
11
|
+
function isAgentTrustMockEnabled() {
|
|
12
|
+
return String(process.env.AIFABRIX_AGENT_TRUST_MOCK || '').trim() === '1';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} datasourceKey
|
|
17
|
+
* @param {string} systemKey
|
|
18
|
+
* @returns {Object}
|
|
19
|
+
*/
|
|
20
|
+
function buildMockTrustRun(datasourceKey, systemKey) {
|
|
21
|
+
return {
|
|
22
|
+
datasourceKey,
|
|
23
|
+
systemKey,
|
|
24
|
+
status: 'warn',
|
|
25
|
+
trustDecision: 'usableWithWarnings',
|
|
26
|
+
validationStatus: 'warning',
|
|
27
|
+
confidence: 0.72,
|
|
28
|
+
summary: 'Mock trust run (AIFABRIX_AGENT_TRUST_MOCK=1)',
|
|
29
|
+
validatedAt: new Date().toISOString(),
|
|
30
|
+
inputHash: 'mock-input-hash',
|
|
31
|
+
contractVersion: '1.0.0',
|
|
32
|
+
cacheHit: false,
|
|
33
|
+
highLevelWarnings: ['MOCK_TRUST — set AIFABRIX_AGENT_TRUST_MOCK=0 for live dataplane validation'],
|
|
34
|
+
findings: [],
|
|
35
|
+
observedBusinessModel: null,
|
|
36
|
+
runId: 'mock-run-id',
|
|
37
|
+
mock: true
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
isAgentTrustMockEnabled,
|
|
43
|
+
buildMockTrustRun
|
|
44
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Run dataplane agent metadata validation for one datasource (404.5 / plan 143).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
const logger = require('../utils/logger');
|
|
11
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
12
|
+
const { getConfig } = require('../core/config');
|
|
13
|
+
const { setupIntegrationTestAuth } = require('../external-system/test-auth');
|
|
14
|
+
const { resolveAppKeyForDatasource } = require('./resolve-app');
|
|
15
|
+
const { getSystemKeyFromAppKey } = require('./integration-context');
|
|
16
|
+
const { requireBearerForDataplanePipeline } = require('../utils/token-manager');
|
|
17
|
+
const { fetchTrustRunFromDataplane } = require('./agent-trust-fetch');
|
|
18
|
+
|
|
19
|
+
async function maybeSyncBeforeTrust({ noSync, authConfig, systemKey }) {
|
|
20
|
+
if (noSync === true) return;
|
|
21
|
+
requireBearerForDataplanePipeline(authConfig);
|
|
22
|
+
logger.log(chalk.cyan('Syncing local config to dataplane…'));
|
|
23
|
+
const { uploadExternalSystem } = require('../commands/upload');
|
|
24
|
+
await uploadExternalSystem(systemKey, { minimal: true });
|
|
25
|
+
logger.log(formatSuccessLine('Sync complete'));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function buildTransportFailureTrustRun(datasourceKey, systemKey, err) {
|
|
29
|
+
return {
|
|
30
|
+
datasourceKey,
|
|
31
|
+
systemKey,
|
|
32
|
+
status: 'fail',
|
|
33
|
+
trustDecision: 'notTrusted',
|
|
34
|
+
validationStatus: 'failed',
|
|
35
|
+
confidence: 0,
|
|
36
|
+
summary: err && err.message ? String(err.message) : 'Request failed',
|
|
37
|
+
transportError: true
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @async
|
|
43
|
+
* @param {string} datasourceKey
|
|
44
|
+
* @param {Object} options
|
|
45
|
+
* @returns {Promise<{ trustRun: Object, apiError: Object|null }>}
|
|
46
|
+
*/
|
|
47
|
+
async function runDatasourceAgentTrust(datasourceKey, options = {}) {
|
|
48
|
+
if (!datasourceKey || typeof datasourceKey !== 'string') {
|
|
49
|
+
throw new Error('Datasource key is required');
|
|
50
|
+
}
|
|
51
|
+
const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
|
|
52
|
+
const systemKey = await getSystemKeyFromAppKey(appKey);
|
|
53
|
+
|
|
54
|
+
let authConfig = options.authConfig;
|
|
55
|
+
let dataplaneUrl = options.dataplaneUrl || options.dataplane;
|
|
56
|
+
if (!authConfig || !dataplaneUrl) {
|
|
57
|
+
const configObj = await getConfig();
|
|
58
|
+
const auth = await setupIntegrationTestAuth(
|
|
59
|
+
appKey,
|
|
60
|
+
{ environment: options.environment, dataplane: options.dataplane },
|
|
61
|
+
configObj
|
|
62
|
+
);
|
|
63
|
+
authConfig = auth.authConfig;
|
|
64
|
+
dataplaneUrl = auth.dataplaneUrl;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
await maybeSyncBeforeTrust({
|
|
68
|
+
noSync: options.noSync === true,
|
|
69
|
+
authConfig,
|
|
70
|
+
systemKey
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const trustRun = await fetchTrustRunFromDataplane({
|
|
75
|
+
datasourceKey,
|
|
76
|
+
systemKey,
|
|
77
|
+
dataplaneUrl,
|
|
78
|
+
authConfig,
|
|
79
|
+
options
|
|
80
|
+
});
|
|
81
|
+
return { trustRun, apiError: null };
|
|
82
|
+
} catch (err) {
|
|
83
|
+
return {
|
|
84
|
+
trustRun: buildTransportFailureTrustRun(datasourceKey, systemKey, err),
|
|
85
|
+
apiError: err
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = {
|
|
91
|
+
runDatasourceAgentTrust,
|
|
92
|
+
maybeSyncBeforeTrust
|
|
93
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview HTTP timeout parsing for agent trust CLI (plan 143).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_TRUST_TIMEOUT_MS = 120000;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {Object} [options]
|
|
11
|
+
* @returns {number}
|
|
12
|
+
*/
|
|
13
|
+
function parseTrustTimeoutMs(options = {}) {
|
|
14
|
+
const raw = options.timeout;
|
|
15
|
+
if (raw !== undefined && raw !== null && raw !== '') {
|
|
16
|
+
const n = parseInt(String(raw), 10);
|
|
17
|
+
if (Number.isFinite(n) && n > 0) return n;
|
|
18
|
+
}
|
|
19
|
+
return DEFAULT_TRUST_TIMEOUT_MS;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
DEFAULT_TRUST_TIMEOUT_MS,
|
|
24
|
+
parseTrustTimeoutMs
|
|
25
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview TTY and JSON output for audit evidence verification (407.3)
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
const logger = require('../utils/logger');
|
|
11
|
+
const {
|
|
12
|
+
sectionTitle,
|
|
13
|
+
formatSuccessLine,
|
|
14
|
+
formatBlockingError,
|
|
15
|
+
successGlyph,
|
|
16
|
+
failureGlyph
|
|
17
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
18
|
+
|
|
19
|
+
const SEP = '────────────────────────────────';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {'passed'|'failed'} status
|
|
23
|
+
* @returns {string}
|
|
24
|
+
*/
|
|
25
|
+
function rowGlyph(status) {
|
|
26
|
+
return status === 'passed' ? successGlyph() : failureGlyph();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {import('../api/types/audit.types').AuditEvidenceVerification} result
|
|
31
|
+
* @param {boolean} [verbose]
|
|
32
|
+
*/
|
|
33
|
+
function displayAuditEvidenceMatrixTTY(result, verbose = false) {
|
|
34
|
+
logger.log(SEP);
|
|
35
|
+
logger.log(sectionTitle('Audit evidence matrix'));
|
|
36
|
+
logger.log(chalk.gray(` Datasource: ${result.datasourceKey}`));
|
|
37
|
+
if (result.correlationId) {
|
|
38
|
+
logger.log(chalk.gray(` Correlation: ${result.correlationId}`));
|
|
39
|
+
}
|
|
40
|
+
if (verbose && result.executionIds.length) {
|
|
41
|
+
logger.log(chalk.gray(` Execution ids: ${result.executionIds.length}`));
|
|
42
|
+
}
|
|
43
|
+
logger.log('');
|
|
44
|
+
for (const row of result.matrix || []) {
|
|
45
|
+
logger.log(` ${rowGlyph(row.status)} Row ${row.row}: ${row.detail}`);
|
|
46
|
+
if (verbose && row.code) {
|
|
47
|
+
logger.log(chalk.gray(` code: ${row.code}`));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
logger.log('');
|
|
51
|
+
if (result.status === 'passed') {
|
|
52
|
+
logger.log(formatSuccessLine('Audit evidence verification passed'));
|
|
53
|
+
} else {
|
|
54
|
+
const failed = (result.matrix || []).filter(r => r.status === 'failed').length;
|
|
55
|
+
logger.log(formatBlockingError(`Audit evidence verification failed (${failed} row(s))`));
|
|
56
|
+
}
|
|
57
|
+
logger.log(SEP);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {import('../api/types/audit.types').AuditEvidenceVerification} result
|
|
62
|
+
*/
|
|
63
|
+
function printAuditEvidenceVerificationJson(result) {
|
|
64
|
+
logger.log(
|
|
65
|
+
JSON.stringify({
|
|
66
|
+
auditEvidenceVerification: {
|
|
67
|
+
status: result.status,
|
|
68
|
+
datasourceKey: result.datasourceKey,
|
|
69
|
+
correlationId: result.correlationId,
|
|
70
|
+
executionIds: result.executionIds,
|
|
71
|
+
matrix: result.matrix
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
displayAuditEvidenceMatrixTTY,
|
|
79
|
+
printAuditEvidenceVerificationJson
|
|
80
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Extract execution ids from DatasourceTestRun debug / async E2E payloads
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {Array<*>} ids
|
|
11
|
+
* @returns {string[]}
|
|
12
|
+
*/
|
|
13
|
+
function dedupeIds(ids) {
|
|
14
|
+
if (!Array.isArray(ids)) return [];
|
|
15
|
+
const out = [];
|
|
16
|
+
const seen = new Set();
|
|
17
|
+
for (const raw of ids) {
|
|
18
|
+
const id = raw !== null && raw !== undefined ? String(raw).trim() : '';
|
|
19
|
+
if (!id || seen.has(id)) continue;
|
|
20
|
+
seen.add(id);
|
|
21
|
+
out.push(id);
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {*} node
|
|
28
|
+
* @param {string[]} out
|
|
29
|
+
*/
|
|
30
|
+
function collectExecutionIdFields(node, out) {
|
|
31
|
+
if (!node || typeof node !== 'object') return;
|
|
32
|
+
if (typeof node.executionId === 'string' && node.executionId.trim()) {
|
|
33
|
+
out.push(node.executionId.trim());
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(node.jobs)) {
|
|
36
|
+
for (const job of node.jobs) collectExecutionIdFields(job, out);
|
|
37
|
+
}
|
|
38
|
+
if (Array.isArray(node.datasources)) {
|
|
39
|
+
for (const ds of node.datasources) collectExecutionIdFields(ds, out);
|
|
40
|
+
}
|
|
41
|
+
if (node.audit && typeof node.audit === 'object') {
|
|
42
|
+
collectExecutionIdFields(node.audit, out);
|
|
43
|
+
}
|
|
44
|
+
if (node.evidence && typeof node.evidence === 'object') {
|
|
45
|
+
collectExecutionIdFields(node.evidence, out);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {Object|null|undefined} envelope
|
|
51
|
+
* @returns {string[]}
|
|
52
|
+
*/
|
|
53
|
+
function executionIdsFromDebugEnvelope(envelope) {
|
|
54
|
+
const dbg = envelope && envelope.debug;
|
|
55
|
+
if (!dbg || typeof dbg !== 'object') return [];
|
|
56
|
+
const found = [];
|
|
57
|
+
if (dbg.executionIds) {
|
|
58
|
+
found.push(...(Array.isArray(dbg.executionIds) ? dbg.executionIds : [dbg.executionIds]));
|
|
59
|
+
}
|
|
60
|
+
const asyncDbg = dbg.e2eAsyncDebug;
|
|
61
|
+
if (asyncDbg && Array.isArray(asyncDbg.stepDebug)) {
|
|
62
|
+
for (const step of asyncDbg.stepDebug) {
|
|
63
|
+
if (step && step.evidence) collectExecutionIdFields(step.evidence, found);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return dedupeIds(found);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* CIP operation names from capacity step (insert, update, list, …).
|
|
71
|
+
* @param {Object|null|undefined} envelope
|
|
72
|
+
* @returns {string[]}
|
|
73
|
+
*/
|
|
74
|
+
function cipOperationsFromDebugEnvelope(envelope) {
|
|
75
|
+
const dbg = envelope && envelope.debug;
|
|
76
|
+
const asyncDbg = dbg && dbg.e2eAsyncDebug;
|
|
77
|
+
if (!asyncDbg || !Array.isArray(asyncDbg.stepDebug)) return [];
|
|
78
|
+
const capStep = asyncDbg.stepDebug.find(s => s && s.name === 'capacity');
|
|
79
|
+
if (!capStep || !capStep.evidence) return [];
|
|
80
|
+
const ops = new Set();
|
|
81
|
+
const details = capStep.evidence.datasources;
|
|
82
|
+
if (!Array.isArray(details)) return [];
|
|
83
|
+
for (const ds of details) {
|
|
84
|
+
if (!ds || !Array.isArray(ds.capabilityDetails)) continue;
|
|
85
|
+
for (const item of ds.capabilityDetails) {
|
|
86
|
+
const key = item && item.key ? String(item.key) : '';
|
|
87
|
+
const m = key.match(/^capacity:([a-zA-Z]+)/);
|
|
88
|
+
if (m && m[1]) {
|
|
89
|
+
let op = m[1] === 'updateBasic' ? 'updatebasic' : m[1].toLowerCase();
|
|
90
|
+
if (op === 'create') op = 'insert';
|
|
91
|
+
ops.add(op);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return [...ops];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = {
|
|
99
|
+
dedupeIds,
|
|
100
|
+
executionIdsFromDebugEnvelope,
|
|
101
|
+
cipOperationsFromDebugEnvelope,
|
|
102
|
+
collectExecutionIdFields
|
|
103
|
+
};
|