@aifabrix/builder 2.45.0 → 2.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/cli-layout.mdc +2 -0
- package/.cursor/rules/cli-product-neutral.mdc +43 -0
- package/.cursor/rules/docs-rules.mdc +3 -1
- package/.cursor/rules/project-rules.mdc +1 -0
- package/README.md +43 -17
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
- package/jest.config.default.js +2 -1
- package/jest.config.isolated.js +2 -1
- package/jest.global-live-fabrix-hooks.js +36 -0
- package/jest.isolated-projects.js +130 -0
- package/jest.projects.js +69 -121
- package/lib/api/agent-metadata-validation.api.js +93 -0
- package/lib/api/api-response-errors.js +124 -0
- package/lib/api/audit-api-helpers.js +68 -0
- package/lib/api/audit.api.js +119 -0
- package/lib/api/auth-cache.api.js +44 -0
- package/lib/api/certificates.api.js +4 -4
- package/lib/api/credential.api.js +2 -2
- package/lib/api/dataplane-health.api.js +137 -0
- package/lib/api/dataplane-sync.api.js +27 -0
- package/lib/api/datasources-core.api.js +21 -18
- package/lib/api/datasources-extended.api.js +22 -22
- package/lib/api/dimensions.api.js +3 -0
- package/lib/api/external-systems.api.js +13 -13
- package/lib/api/governance-scenario-pack.api.js +159 -0
- package/lib/api/governance-scenarios.api.js +39 -0
- package/lib/api/groups.api.js +79 -0
- package/lib/api/index.js +88 -5
- package/lib/api/lifecycle.api.js +77 -0
- package/lib/api/pipeline.api.js +7 -5
- package/lib/api/protection.api.js +157 -0
- package/lib/api/records-bulk.api.js +43 -0
- package/lib/api/records-search-parse.js +49 -0
- package/lib/api/records-search.api.js +29 -0
- package/lib/api/types/agent-metadata-validation.types.js +67 -0
- package/lib/api/types/audit.types.js +72 -0
- package/lib/api/types/dataplane-health.types.js +27 -0
- package/lib/api/types/dimensions.types.js +2 -0
- package/lib/api/types/governance-scenarios.types.js +39 -0
- package/lib/api/types/protection.types.js +69 -0
- package/lib/api/types/records-bulk.types.js +35 -0
- package/lib/api/types/records-search.types.js +28 -0
- package/lib/api/user-groups.api.js +50 -0
- package/lib/api/users.api.js +95 -0
- package/lib/api/validation-run.api.js +3 -3
- package/lib/api/validation-runner.js +5 -3
- package/lib/api/wizard-platform.api.js +3 -3
- package/lib/api/wizard.api.js +21 -21
- package/lib/app/deploy-config.js +4 -1
- package/lib/app/deploy.js +34 -19
- package/lib/app/down.js +20 -1
- package/lib/app/push.js +4 -5
- package/lib/app/register.js +7 -4
- package/lib/app/run-env-compose.js +84 -30
- package/lib/build/index.js +5 -0
- package/lib/certification/sync-system-certification.js +13 -6
- package/lib/cli/index.js +8 -2
- package/lib/cli/infra-guided-auth.js +109 -0
- package/lib/cli/infra-guided.js +91 -69
- package/lib/cli/setup-app.help.js +19 -2
- package/lib/cli/setup-app.js +58 -23
- package/lib/cli/setup-app.test-commands.js +28 -21
- package/lib/cli/setup-auth.js +55 -3
- package/lib/cli/setup-certification-commands.js +147 -0
- package/lib/cli/setup-certification.help.js +141 -0
- package/lib/cli/setup-environment.js +19 -2
- package/lib/cli/setup-external-system-help.js +62 -0
- package/lib/cli/setup-external-system.js +62 -6
- package/lib/cli/setup-infra.js +9 -1
- package/lib/cli/setup-platform.js +6 -1
- package/lib/cli/setup-secrets.js +33 -1
- package/lib/cli/setup-utility-help-after.js +65 -0
- package/lib/cli/setup-utility-repair.js +198 -0
- package/lib/cli/setup-utility-resolve.js +42 -6
- package/lib/cli/setup-utility-validate.js +197 -0
- package/lib/cli/setup-utility.js +41 -258
- package/lib/commands/auth-status-client-tokens.js +214 -0
- package/lib/commands/auth-status-dataplane-version.js +269 -0
- package/lib/commands/auth-status-display.js +94 -0
- package/lib/commands/auth-status.js +111 -53
- package/lib/commands/credential-push.js +10 -5
- package/lib/commands/datasource-load-export-cli.js +178 -0
- package/lib/commands/datasource-test-trust-cli.js +118 -0
- package/lib/commands/datasource-unified-test-cli.js +31 -20
- package/lib/commands/datasource-unified-test-cli.options.js +22 -3
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
- package/lib/commands/datasource-verify-audit-cli.js +96 -0
- package/lib/commands/datasource.js +68 -1
- package/lib/commands/dev-show-display.js +8 -1
- package/lib/commands/dimension-value.js +43 -13
- package/lib/commands/dimension.js +38 -7
- package/lib/commands/governance-cli-shared.js +94 -0
- package/lib/commands/governance-command-action.js +132 -0
- package/lib/commands/governance-download-external.js +34 -0
- package/lib/commands/governance-generate-external.js +71 -0
- package/lib/commands/governance-upload-external.js +36 -0
- package/lib/commands/governance-verify-external.js +64 -0
- package/lib/commands/governance.js +144 -0
- package/lib/commands/identity-apply-sync.js +131 -0
- package/lib/commands/identity-group-cli.js +146 -0
- package/lib/commands/identity-membership-role-cache.js +175 -0
- package/lib/commands/identity-shared.js +94 -0
- package/lib/commands/identity-user-cli.js +158 -0
- package/lib/commands/identity.js +43 -0
- package/lib/commands/lifecycle-command-action.js +123 -0
- package/lib/commands/lifecycle-external.js +268 -0
- package/lib/commands/login.js +56 -17
- package/lib/commands/protection-cli-leaves.js +286 -0
- package/lib/commands/protection.js +50 -0
- package/lib/commands/repair-auth-apply.js +127 -0
- package/lib/commands/repair-changed-files.js +41 -0
- package/lib/commands/repair-datasource-keys.js +4 -1
- package/lib/commands/repair-datasource-run.js +59 -0
- package/lib/commands/repair-datasource-test-payload.js +259 -0
- package/lib/commands/repair-datasource.js +1 -51
- package/lib/commands/repair-env-template.js +64 -13
- package/lib/commands/repair-external-run.js +216 -0
- package/lib/commands/repair-openapi-sync.js +23 -0
- package/lib/commands/repair-persist.js +4 -0
- package/lib/commands/repair-rbac.js +52 -1
- package/lib/commands/repair-steps.js +145 -0
- package/lib/commands/repair.js +29 -286
- package/lib/commands/secrets-get.js +184 -0
- package/lib/commands/secrets-remove-all.js +3 -1
- package/lib/commands/setup-image-refresh.js +146 -0
- package/lib/commands/setup-modes.js +158 -162
- package/lib/commands/setup-platform-auth.js +76 -0
- package/lib/commands/setup-prompts-admin.js +244 -0
- package/lib/commands/setup-prompts-platform-mode.js +67 -0
- package/lib/commands/setup-prompts-validators.js +36 -0
- package/lib/commands/setup-prompts.js +24 -76
- package/lib/commands/setup-run-context.js +45 -0
- package/lib/commands/setup-spinners.js +39 -0
- package/lib/commands/setup.js +27 -5
- package/lib/commands/teardown.js +39 -0
- package/lib/commands/test-e2e-external.js +61 -14
- package/lib/commands/test-governance-cli-options.js +47 -0
- package/lib/commands/test-governance-external.js +67 -0
- package/lib/commands/test-trust-cli-options.js +32 -0
- package/lib/commands/test-trust-external.js +126 -0
- package/lib/commands/up-common.js +25 -13
- package/lib/commands/up-dataplane.js +50 -13
- package/lib/commands/upload-publish-context.js +75 -0
- package/lib/commands/upload-sidecar-followups.js +89 -0
- package/lib/commands/upload.js +108 -105
- package/lib/commands/verify-governance-combined-external.js +61 -0
- package/lib/commands/verify-governance-command-action.js +64 -0
- package/lib/commands/verify-governance-db.js +102 -0
- package/lib/commands/verify-governance-external.js +77 -0
- package/lib/commands/verify-governance-result-builders.js +71 -0
- package/lib/commands/verify-operations-command-action.js +68 -0
- package/lib/commands/verify-operations-external.js +268 -0
- package/lib/commands/verify-operations-persist.js +75 -0
- package/lib/commands/verify-operations-step-plan.js +68 -0
- package/lib/commands/verify-operations-steps.js +111 -0
- package/lib/commands/verify-trust-command-action.js +70 -0
- package/lib/commands/verify-trust-external.js +67 -0
- package/lib/commands/wizard-config-normalizer.js +43 -23
- package/lib/commands/wizard-core.js +5 -0
- package/lib/core/admin-password-generator.js +38 -0
- package/lib/core/admin-secrets-bundle.js +111 -0
- package/lib/core/admin-secrets-env-overlay.js +62 -0
- package/lib/core/admin-secrets.js +32 -4
- package/lib/core/config-attach-extensions.js +3 -0
- package/lib/core/config-device-dataplane.js +185 -0
- package/lib/core/config-platform-controller.js +44 -0
- package/lib/core/config-setup-installation-profile.js +42 -0
- package/lib/core/config-setup-platform-mode.js +46 -0
- package/lib/core/config.js +46 -36
- package/lib/core/secrets-admin-env.js +6 -2
- package/lib/core/secrets-ensure.js +4 -0
- package/lib/core/secrets-env-content.js +54 -48
- package/lib/core/secrets-env-write.js +10 -1
- package/lib/core/secrets-infra-placeholder-sync.js +2 -0
- package/lib/core/setup-installation-profile.js +43 -0
- package/lib/core/setup-platform-mode.js +55 -0
- package/lib/datasource/agent-trust-debug-log.js +45 -0
- package/lib/datasource/agent-trust-fetch.js +115 -0
- package/lib/datasource/agent-trust-map.js +101 -0
- package/lib/datasource/agent-trust-mock.js +44 -0
- package/lib/datasource/agent-trust-run.js +95 -0
- package/lib/datasource/agent-trust-timeout.js +25 -0
- package/lib/datasource/audit-evidence-display.js +80 -0
- package/lib/datasource/audit-evidence-extract-debug.js +115 -0
- package/lib/datasource/audit-evidence-extract.js +180 -0
- package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
- package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
- package/lib/datasource/audit-evidence-poll.js +109 -0
- package/lib/datasource/audit-evidence-run.js +177 -0
- package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
- package/lib/datasource/audit-evidence-verify-matrix.js +205 -0
- package/lib/datasource/audit-evidence-verify.js +108 -0
- package/lib/datasource/bulk-loader-run-batches.js +100 -0
- package/lib/datasource/bulk-loader-service-retry.js +52 -0
- package/lib/datasource/bulk-loader-service.js +127 -0
- package/lib/datasource/capability/run-capability-dimension.js +2 -1
- package/lib/datasource/datasource-exporter-resolve.js +82 -0
- package/lib/datasource/datasource-exporter-service.js +144 -0
- package/lib/datasource/datasource-identifier.js +148 -0
- package/lib/datasource/datasource-load-export-context.js +95 -0
- package/lib/datasource/integration-context.js +6 -4
- package/lib/datasource/local-data-paths.js +145 -0
- package/lib/datasource/log-cleaner.js +241 -0
- package/lib/datasource/log-viewer.js +111 -6
- package/lib/datasource/record-file-parser.js +85 -0
- package/lib/datasource/record-mapper.js +129 -0
- package/lib/datasource/resolve-app.js +74 -55
- package/lib/datasource/test-e2e.js +29 -2
- package/lib/datasource/unified-validation-run-body.js +3 -1
- package/lib/datasource/unified-validation-run-resolve.js +45 -12
- package/lib/datasource/unified-validation-run.js +47 -18
- package/lib/datasource/validate.js +37 -20
- package/lib/deployment/environment-poll-status.js +138 -0
- package/lib/deployment/environment.js +42 -34
- package/lib/external-system/download.js +21 -20
- package/lib/external-system/generator.js +5 -1
- package/lib/external-system/integration-auth-context.js +45 -0
- package/lib/external-system/test-auth.js +12 -5
- package/lib/external-system/test-system-level.js +25 -4
- package/lib/external-system/test.js +9 -7
- package/lib/generator/external-controller-manifest.js +15 -0
- package/lib/governance/governance-cli-errors.js +96 -0
- package/lib/governance/governance-download-display.js +38 -0
- package/lib/governance/governance-pack-loader.js +70 -0
- package/lib/governance/governance-run-display.js +309 -0
- package/lib/identity/identity-apply-core.js +108 -0
- package/lib/identity/identity-apply-phases.js +244 -0
- package/lib/identity/identity-apply-service.js +77 -0
- package/lib/identity/identity-csv-parser.js +114 -0
- package/lib/infrastructure/admin-secrets-apply.js +84 -0
- package/lib/infrastructure/admin-secrets-ensure.js +130 -0
- package/lib/infrastructure/admin-secrets-resolve.js +95 -0
- package/lib/infrastructure/admin-secrets-sync.js +91 -0
- package/lib/infrastructure/helpers.js +23 -129
- package/lib/infrastructure/index.js +5 -6
- package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
- package/lib/internal/fs-real-sync.js +29 -1
- package/lib/lifecycle/certification-progress.js +231 -0
- package/lib/lifecycle/dataplane-ui-url.js +145 -0
- package/lib/lifecycle/exit-codes.js +24 -0
- package/lib/lifecycle/json-envelope.js +25 -0
- package/lib/lifecycle/lifecycle-governance-options.js +51 -0
- package/lib/lifecycle/logger-quiet.js +29 -0
- package/lib/lifecycle/open-api-published.js +59 -0
- package/lib/lifecycle/operations-readiness-metrics.js +101 -0
- package/lib/lifecycle/product-model.js +196 -0
- package/lib/lifecycle/report-display.js +471 -0
- package/lib/lifecycle/scenario-upload.js +191 -0
- package/lib/lifecycle/verify-step-progress.js +87 -0
- package/lib/parameters/infra-kv-discovery.js +27 -2
- package/lib/protection/auth-context.js +51 -0
- package/lib/protection/convert-batch.js +90 -0
- package/lib/protection/load.js +41 -0
- package/lib/protection/paths.js +158 -0
- package/lib/protection/preflight-datasource-ready.js +46 -0
- package/lib/protection/protection-create-probe-lines.js +142 -0
- package/lib/protection/protection-create-probes.js +95 -0
- package/lib/protection/protection-create-scaffold.js +281 -0
- package/lib/protection/protection-display-helpers.js +445 -0
- package/lib/protection/protection-display.js +215 -0
- package/lib/protection/protection-preset-registry.js +97 -0
- package/lib/protection/report-exit.js +62 -0
- package/lib/protection/resolve.js +202 -0
- package/lib/protection/run-commands-validate.js +130 -0
- package/lib/protection/run-commands.js +216 -0
- package/lib/protection/run-protection-create-helpers.js +134 -0
- package/lib/protection/run-protection-create-probes-flow.js +43 -0
- package/lib/protection/run-protection-create.js +191 -0
- package/lib/protection/scope.js +22 -0
- package/lib/protection/sync-after-upload.js +64 -0
- package/lib/protection/upload-batch.js +127 -0
- package/lib/protection/validate-batch.js +113 -0
- package/lib/protection/validate-local.js +65 -0
- package/lib/resolvers/dimension-file.js +29 -4
- package/lib/schema/application-schema.json +1 -1
- package/lib/schema/datasource-test-run.schema.json +89 -6
- package/lib/schema/external-datasource.schema.json +2636 -2588
- package/lib/schema/external-system.schema.json +1089 -761
- package/lib/schema/flag-map-validation-run.json +2 -2
- package/lib/schema/infra.parameter.yaml +45 -0
- package/lib/schema/protection.schema.json +374 -0
- package/lib/schema/type/credential-field-registry.json +642 -0
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/agent-trust-run-display.js +231 -0
- package/lib/utils/agent-trust-run-exit.js +59 -0
- package/lib/utils/agent-trust-wait-ui.js +94 -0
- package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
- package/lib/utils/api.js +55 -31
- package/lib/utils/app-relative-path-env.js +112 -0
- package/lib/utils/cli-exit-codes.js +30 -0
- package/lib/utils/cli-secrets-error-format.js +83 -21
- package/lib/utils/cli-sync-options.js +33 -0
- package/lib/utils/cli-utils.js +16 -4
- package/lib/utils/compose-generate-docker-compose.js +4 -0
- package/lib/utils/compose-traefik-ingress-base.js +16 -1
- package/lib/utils/config-secrets-path.js +46 -0
- package/lib/utils/controller-url.js +88 -1
- package/lib/utils/credential-push-ui.js +90 -0
- package/lib/utils/credential-secrets-env.js +137 -9
- package/lib/utils/dataplane-cli-version-gate.js +202 -0
- package/lib/utils/dataplane-cli-version-help.js +74 -0
- package/lib/utils/dataplane-resolver.js +129 -2
- package/lib/utils/datasource-export-display.js +137 -0
- package/lib/utils/datasource-load-display.js +174 -0
- package/lib/utils/datasource-load-export-ui.js +120 -0
- package/lib/utils/datasource-test-run-capability-scope.js +3 -3
- package/lib/utils/datasource-test-run-display.js +3 -3
- package/lib/utils/datasource-test-run-tty-log.js +5 -1
- package/lib/utils/declarative-url-ports.js +3 -3
- package/lib/utils/deployment-auth-mode.js +41 -0
- package/lib/utils/developer-volume-id.js +33 -0
- package/lib/utils/env-copy.js +14 -9
- package/lib/utils/env-kv-orphan-lines.js +43 -0
- package/lib/utils/error-formatters/network-errors.js +13 -4
- package/lib/utils/external-env-template.js +1 -0
- package/lib/utils/external-system-readiness-core.js +10 -0
- package/lib/utils/external-system-readiness-display.js +80 -23
- package/lib/utils/health-check.js +4 -1
- package/lib/utils/help-builder.js +35 -26
- package/lib/utils/keycloak-realm-ready.js +101 -0
- package/lib/utils/load-cip-capacity-display-config.js +61 -15
- package/lib/utils/manifest-source-emit.js +24 -0
- package/lib/utils/pipeline-upload-auth-retry.js +82 -0
- package/lib/utils/platform-controller-url.js +156 -0
- package/lib/utils/postgres-platform-bootstrap.js +199 -0
- package/lib/utils/postgres-wipe.js +9 -2
- package/lib/utils/resolve-env-mode.js +47 -0
- package/lib/utils/secrets-generator.js +31 -25
- package/lib/utils/secrets-missing-error.js +164 -0
- package/lib/utils/semver-compare.js +127 -0
- package/lib/utils/service-url-label.js +81 -0
- package/lib/utils/setup-quiet-output.js +25 -0
- package/lib/utils/template-helpers.js +15 -0
- package/lib/utils/token-manager-client-credentials.js +201 -0
- package/lib/utils/token-manager-messages.js +8 -0
- package/lib/utils/token-manager-refresh.js +12 -2
- package/lib/utils/token-manager.js +86 -105
- package/lib/utils/upload-pipeline-ui.js +98 -0
- package/lib/utils/upload-sync-options.js +42 -0
- package/lib/utils/url-declarative-public-base.js +21 -3
- package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
- package/lib/utils/validation-poll-ui.js +22 -7
- package/lib/utils/validation-run-stage.js +45 -0
- package/lib/validation/wizard-config-validator.js +58 -19
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +2 -1
- package/templates/applications/dataplane/env.template +36 -1
- package/templates/applications/dataplane/rbac.yaml +4 -0
- package/templates/applications/miso-controller/env.template +16 -0
- package/templates/external-system/README.md.hbs +116 -11
- package/templates/python/docker-compose.hbs +19 -18
- package/templates/typescript/docker-compose.hbs +18 -17
|
@@ -11,14 +11,30 @@
|
|
|
11
11
|
const chalk = require('chalk');
|
|
12
12
|
const { failureGlyph, successGlyph } = require('../utils/cli-test-layout-chalk');
|
|
13
13
|
const logger = require('../utils/logger');
|
|
14
|
-
const config = require('../core/config');
|
|
15
|
-
const { getConfig } = config;
|
|
16
14
|
const { getOrRefreshDeviceToken } = require('../utils/token-manager');
|
|
17
15
|
const { getAuthUser } = require('../api/auth.api');
|
|
18
16
|
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
19
17
|
const { findDataplaneServiceAppKey } = require('./wizard-dataplane');
|
|
20
18
|
const { getDataplaneUrl } = require('../datasource/deploy');
|
|
21
19
|
const { checkDataplaneHealth } = require('../utils/dataplane-health');
|
|
20
|
+
const {
|
|
21
|
+
displayDataplaneVersionSection,
|
|
22
|
+
displayCliUpgradeRequired
|
|
23
|
+
} = require('./auth-status-display');
|
|
24
|
+
const {
|
|
25
|
+
refreshDataplaneVersionInfo,
|
|
26
|
+
loadCachedVersionInfo
|
|
27
|
+
} = require('./auth-status-dataplane-version');
|
|
28
|
+
const {
|
|
29
|
+
EXIT_NOT_AUTHENTICATED,
|
|
30
|
+
EXIT_CLI_VERSION_INCOMPATIBLE,
|
|
31
|
+
EXIT_OK
|
|
32
|
+
} = require('../utils/cli-exit-codes');
|
|
33
|
+
const {
|
|
34
|
+
refreshExpiredClientTokensWherePossible,
|
|
35
|
+
displayStoredClientTokensSection,
|
|
36
|
+
tryResolveClientTokenAuth
|
|
37
|
+
} = require('./auth-status-client-tokens');
|
|
22
38
|
|
|
23
39
|
/**
|
|
24
40
|
* Format expiration date for display
|
|
@@ -81,22 +97,6 @@ async function checkDeviceToken(controllerUrl) {
|
|
|
81
97
|
}
|
|
82
98
|
}
|
|
83
99
|
|
|
84
|
-
/**
|
|
85
|
-
* Decrypt token if encrypted
|
|
86
|
-
* @async
|
|
87
|
-
* @param {string} token - Token to decrypt
|
|
88
|
-
* @returns {Promise<string>} Decrypted token
|
|
89
|
-
*/
|
|
90
|
-
async function decryptTokenIfNeeded(token) {
|
|
91
|
-
const { decryptToken, isTokenEncrypted } = require('../utils/token-encryption');
|
|
92
|
-
const encryptionKey = await config.getSecretsEncryptionKey();
|
|
93
|
-
|
|
94
|
-
if (encryptionKey && isTokenEncrypted(token)) {
|
|
95
|
-
return await decryptToken(token, encryptionKey);
|
|
96
|
-
}
|
|
97
|
-
return token;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
100
|
/**
|
|
101
101
|
* Validate client token and return result
|
|
102
102
|
* @async
|
|
@@ -143,29 +143,14 @@ async function validateClientToken(token, controllerUrl, environment, appName, e
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
/**
|
|
146
|
-
* Check and validate client token
|
|
146
|
+
* Check and validate client token (refreshes when expired if client credentials exist).
|
|
147
147
|
* @async
|
|
148
148
|
* @param {string} controllerUrl - Controller URL
|
|
149
149
|
* @param {string} environment - Environment key
|
|
150
150
|
* @returns {Promise<Object|null>} Token validation result or null
|
|
151
151
|
*/
|
|
152
152
|
async function checkClientToken(controllerUrl, environment) {
|
|
153
|
-
|
|
154
|
-
const environments = configData.environments || {};
|
|
155
|
-
const envConfig = environments[environment];
|
|
156
|
-
|
|
157
|
-
if (!envConfig || !envConfig.clients) {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
for (const [appName, tokenData] of Object.entries(envConfig.clients)) {
|
|
162
|
-
if (tokenData.controller === controllerUrl && tokenData.token) {
|
|
163
|
-
const token = await decryptTokenIfNeeded(tokenData.token);
|
|
164
|
-
return await validateClientToken(token, controllerUrl, environment, appName, tokenData.expiresAt);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return null;
|
|
153
|
+
return tryResolveClientTokenAuth(controllerUrl, environment, validateClientToken);
|
|
169
154
|
}
|
|
170
155
|
|
|
171
156
|
/**
|
|
@@ -290,6 +275,10 @@ function displayOpenApiDocs(controllerUrl, dataplaneUrl) {
|
|
|
290
275
|
* @param {Object} [dataplaneInfo] - Optional dataplane URL and health
|
|
291
276
|
* @param {string|null} [dataplaneInfo.url] - Dataplane URL
|
|
292
277
|
* @param {boolean} [dataplaneInfo.connected] - Whether dataplane is reachable
|
|
278
|
+
* @param {string|undefined} [dataplaneInfo.dataplaneVersion]
|
|
279
|
+
* @param {string|undefined} [dataplaneInfo.minBuilderCliVersion]
|
|
280
|
+
* @param {string} [dataplaneInfo.cliVersion]
|
|
281
|
+
* @param {boolean} [dataplaneInfo.compatible]
|
|
293
282
|
*/
|
|
294
283
|
function displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo) {
|
|
295
284
|
logger.log(chalk.bold('\n🔐 Authentication Status\n'));
|
|
@@ -308,45 +297,109 @@ function displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo) {
|
|
|
308
297
|
|
|
309
298
|
if (tokenInfo.authenticated && dataplaneInfo) {
|
|
310
299
|
displayDataplaneSection(dataplaneInfo.url, dataplaneInfo.connected);
|
|
300
|
+
displayDataplaneVersionSection({
|
|
301
|
+
connected: dataplaneInfo.connected,
|
|
302
|
+
dataplaneVersion: dataplaneInfo.dataplaneVersion,
|
|
303
|
+
minBuilderCliVersion: dataplaneInfo.minBuilderCliVersion,
|
|
304
|
+
cliVersion: dataplaneInfo.cliVersion,
|
|
305
|
+
compatible: dataplaneInfo.compatible
|
|
306
|
+
});
|
|
307
|
+
if (dataplaneInfo.minBuilderCliVersion && dataplaneInfo.compatible === false) {
|
|
308
|
+
displayCliUpgradeRequired({
|
|
309
|
+
required: dataplaneInfo.minBuilderCliVersion,
|
|
310
|
+
installed: dataplaneInfo.cliVersion
|
|
311
|
+
});
|
|
312
|
+
}
|
|
311
313
|
}
|
|
312
314
|
|
|
313
315
|
logger.log('');
|
|
314
316
|
}
|
|
315
317
|
|
|
318
|
+
/**
|
|
319
|
+
* Resolve the dataplane block for auth status (URL, reachability, versions,
|
|
320
|
+
* compatibility). Returns null when no dataplane is discovered.
|
|
321
|
+
*
|
|
322
|
+
* @async
|
|
323
|
+
* @function buildDataplaneInfo
|
|
324
|
+
* @param {string} controllerUrl
|
|
325
|
+
* @param {string} environment
|
|
326
|
+
* @param {Object} authConfig - Bearer auth config built from a valid token
|
|
327
|
+
* @returns {Promise<Object|null>}
|
|
328
|
+
*/
|
|
329
|
+
async function buildDataplaneInfo(controllerUrl, environment, authConfig) {
|
|
330
|
+
const dataplaneUrl = await resolveDataplaneUrlSilent(controllerUrl, environment, authConfig);
|
|
331
|
+
if (!dataplaneUrl) {
|
|
332
|
+
return { url: null, connected: false };
|
|
333
|
+
}
|
|
334
|
+
const connected = await checkDataplaneHealth(dataplaneUrl, 5000);
|
|
335
|
+
const versionInfo = connected
|
|
336
|
+
? await refreshDataplaneVersionInfo(controllerUrl, dataplaneUrl)
|
|
337
|
+
: await loadCachedVersionInfo(controllerUrl);
|
|
338
|
+
return {
|
|
339
|
+
url: dataplaneUrl,
|
|
340
|
+
connected,
|
|
341
|
+
dataplaneVersion: versionInfo.dataplaneVersion,
|
|
342
|
+
minBuilderCliVersion: versionInfo.minBuilderCliVersion,
|
|
343
|
+
cliVersion: versionInfo.cliVersion,
|
|
344
|
+
compatible: versionInfo.compatible
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
316
348
|
/**
|
|
317
349
|
* Handle auth status command
|
|
318
350
|
* Controller and environment come from config.yaml (set via aifabrix login or aifabrix auth config).
|
|
319
351
|
* @async
|
|
320
352
|
* @function handleAuthStatus
|
|
321
353
|
* @param {Object} options - Command options
|
|
322
|
-
* @param {boolean} [options.validate] - If true, exit with code 1 when not authenticated
|
|
354
|
+
* @param {boolean} [options.validate] - If true, exit with code 1 when not authenticated, or code 3 when CLI is older than dataplane minimum
|
|
323
355
|
* @returns {Promise<void>} Resolves when status is displayed
|
|
324
356
|
*/
|
|
357
|
+
/**
|
|
358
|
+
* Prefer a working device token; fall back to environment client credentials when the
|
|
359
|
+
* stored device token is expired or rejected (common in long-lived dev VMs).
|
|
360
|
+
*
|
|
361
|
+
* @async
|
|
362
|
+
* @param {string} controllerUrl
|
|
363
|
+
* @param {string} environment
|
|
364
|
+
* @returns {Promise<Object|null>}
|
|
365
|
+
*/
|
|
366
|
+
async function resolveAuthenticatedTokenInfo(controllerUrl, environment) {
|
|
367
|
+
const deviceResult = await checkDeviceToken(controllerUrl);
|
|
368
|
+
if (deviceResult && deviceResult.authenticated) {
|
|
369
|
+
return deviceResult;
|
|
370
|
+
}
|
|
371
|
+
const clientResult = await checkClientToken(controllerUrl, environment);
|
|
372
|
+
if (clientResult && clientResult.authenticated) {
|
|
373
|
+
return clientResult;
|
|
374
|
+
}
|
|
375
|
+
return deviceResult || clientResult || null;
|
|
376
|
+
}
|
|
377
|
+
|
|
325
378
|
async function handleAuthStatus(options = {}) {
|
|
326
379
|
const { resolveEnvironment } = require('../core/config');
|
|
327
380
|
const controllerUrl = await resolveControllerUrl();
|
|
328
381
|
const environment = await resolveEnvironment();
|
|
329
382
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
// If no device token, check client token
|
|
334
|
-
if (!tokenInfo) {
|
|
335
|
-
tokenInfo = await checkClientToken(controllerUrl, environment);
|
|
336
|
-
}
|
|
383
|
+
const refreshedCount = await refreshExpiredClientTokensWherePossible(environment, controllerUrl);
|
|
384
|
+
const tokenInfo = await resolveAuthenticatedTokenInfo(controllerUrl, environment);
|
|
337
385
|
|
|
338
386
|
let dataplaneInfo = null;
|
|
339
387
|
if (tokenInfo && tokenInfo.authenticated && tokenInfo.token) {
|
|
340
388
|
const authConfig = { type: 'bearer', token: tokenInfo.token };
|
|
341
|
-
|
|
342
|
-
const connected = dataplaneUrl ? await checkDataplaneHealth(dataplaneUrl, 5000) : false;
|
|
343
|
-
dataplaneInfo = { url: dataplaneUrl, connected };
|
|
389
|
+
dataplaneInfo = await buildDataplaneInfo(controllerUrl, environment, authConfig);
|
|
344
390
|
}
|
|
345
391
|
|
|
346
392
|
displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo);
|
|
393
|
+
await displayStoredClientTokensSection(environment, controllerUrl, refreshedCount);
|
|
347
394
|
|
|
348
|
-
if (options.validate
|
|
349
|
-
|
|
395
|
+
if (options.validate) {
|
|
396
|
+
if (!tokenInfo || !tokenInfo.authenticated) {
|
|
397
|
+
process.exit(EXIT_NOT_AUTHENTICATED);
|
|
398
|
+
}
|
|
399
|
+
if (dataplaneInfo && dataplaneInfo.minBuilderCliVersion && dataplaneInfo.compatible === false) {
|
|
400
|
+
process.exit(EXIT_CLI_VERSION_INCOMPATIBLE);
|
|
401
|
+
}
|
|
402
|
+
process.exit(EXIT_OK);
|
|
350
403
|
}
|
|
351
404
|
}
|
|
352
405
|
|
|
@@ -363,10 +416,7 @@ async function getValidatedAuthContext() {
|
|
|
363
416
|
const controllerUrl = await resolveControllerUrl();
|
|
364
417
|
const environment = await resolveEnvironment();
|
|
365
418
|
|
|
366
|
-
|
|
367
|
-
if (!tokenInfo) {
|
|
368
|
-
tokenInfo = await checkClientToken(controllerUrl, environment);
|
|
369
|
-
}
|
|
419
|
+
const tokenInfo = await resolveAuthenticatedTokenInfo(controllerUrl, environment);
|
|
370
420
|
|
|
371
421
|
if (!tokenInfo || !tokenInfo.authenticated || !tokenInfo.token) {
|
|
372
422
|
throw new Error('Not authenticated. Run "aifabrix login" or configure client credentials.');
|
|
@@ -378,4 +428,12 @@ async function getValidatedAuthContext() {
|
|
|
378
428
|
return { controllerUrl, environment, authConfig, dataplaneUrl };
|
|
379
429
|
}
|
|
380
430
|
|
|
381
|
-
module.exports = {
|
|
431
|
+
module.exports = {
|
|
432
|
+
handleAuthStatus,
|
|
433
|
+
getValidatedAuthContext,
|
|
434
|
+
resolveAuthenticatedTokenInfo,
|
|
435
|
+
checkDeviceToken,
|
|
436
|
+
checkClientToken,
|
|
437
|
+
refreshExpiredClientTokensWherePossible,
|
|
438
|
+
displayStoredClientTokensSection
|
|
439
|
+
};
|
|
@@ -16,6 +16,7 @@ const { getDeploymentAuth, requireBearerForDataplanePipeline } = require('../uti
|
|
|
16
16
|
const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
|
|
17
17
|
const { getIntegrationPath } = require('../utils/paths');
|
|
18
18
|
const { pushCredentialSecrets } = require('../utils/credential-secrets-env');
|
|
19
|
+
const { runWithCredentialPushSpinner } = require('../utils/credential-push-ui');
|
|
19
20
|
const { generateControllerManifest } = require('../generator/external-controller-manifest');
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -84,11 +85,15 @@ async function runCredentialPush(systemKey) {
|
|
|
84
85
|
const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig);
|
|
85
86
|
|
|
86
87
|
const payload = await buildPayload(systemKey);
|
|
87
|
-
const pushResult = await
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
const pushResult = await runWithCredentialPushSpinner(
|
|
89
|
+
() =>
|
|
90
|
+
pushCredentialSecrets(dataplaneUrl, authConfig, {
|
|
91
|
+
envFilePath,
|
|
92
|
+
appName: systemKey,
|
|
93
|
+
payload
|
|
94
|
+
}),
|
|
95
|
+
{ systemKey }
|
|
96
|
+
);
|
|
92
97
|
|
|
93
98
|
logPushResult(pushResult);
|
|
94
99
|
return { pushed: pushResult.pushed || 0 };
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CLI for `datasource load` and `datasource export` (plan 144)
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const logger = require('../utils/logger');
|
|
10
|
+
const { formatBlockingError } = require('../utils/cli-test-layout-chalk');
|
|
11
|
+
const { runDatasourceLoad } = require('../datasource/bulk-loader-service');
|
|
12
|
+
const { runDatasourceExport } = require('../datasource/datasource-exporter-service');
|
|
13
|
+
const { displayDatasourceLoadTTY } = require('../utils/datasource-load-display');
|
|
14
|
+
const { displayDatasourceExportTTY } = require('../utils/datasource-export-display');
|
|
15
|
+
|
|
16
|
+
function loadHelpAfter() {
|
|
17
|
+
return `
|
|
18
|
+
Examples:
|
|
19
|
+
$ aifabrix datasource load hubspot-test-datasource-company
|
|
20
|
+
$ aifabrix datasource load hubspot-test-company --file ./fixtures/rows.ndjson -v
|
|
21
|
+
$ aifabrix datasource load hubspot-test-company --dry-run
|
|
22
|
+
$ af ds load hubspot-test-company --batch-size 50 --sync-type incremental
|
|
23
|
+
|
|
24
|
+
Notes:
|
|
25
|
+
- Imports local JSON/NDJSON via dataplane bulk record sync (not direct DB).
|
|
26
|
+
- Default file: integration/.data/<systemKey>-data-<entity>.json or .ndjson
|
|
27
|
+
- External integration folders only (integration/<systemKey>/).
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function exportHelpAfter() {
|
|
32
|
+
return `
|
|
33
|
+
Examples:
|
|
34
|
+
$ aifabrix datasource export hubspot-test-datasource-company
|
|
35
|
+
$ aifabrix datasource export hubspot-test-company --format ndjson --limit 500
|
|
36
|
+
$ aifabrix datasource export hubspot-test-company --filter '{"status":{"eq":"active"}}' -v
|
|
37
|
+
$ af ds export hubspot-test-company --fields email,name --strict
|
|
38
|
+
|
|
39
|
+
Notes:
|
|
40
|
+
- Exports governed records search results (ABAC applied), not a raw DB dump.
|
|
41
|
+
- Default output: integration/.data/<systemKey>-data-<entity>.json or .ndjson
|
|
42
|
+
- Maximum 10000 rows per run (dataplane search limit).
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {Object} result
|
|
48
|
+
* @returns {number}
|
|
49
|
+
*/
|
|
50
|
+
function computeLoadExitCode(result) {
|
|
51
|
+
if (result.dryRun) {
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
return (result.totals.failedCount || 0) > 0 ? 1 : 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {Object} result
|
|
59
|
+
* @param {Object} options
|
|
60
|
+
* @returns {number}
|
|
61
|
+
*/
|
|
62
|
+
function computeExportExitCode(result, options) {
|
|
63
|
+
if (options.strict === true && result.recordCount === 0) {
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function datasourceLoadAction(datasourceKey, options) {
|
|
70
|
+
try {
|
|
71
|
+
const result = await runDatasourceLoad(datasourceKey, {
|
|
72
|
+
app: options.app,
|
|
73
|
+
env: options.env,
|
|
74
|
+
file: options.file,
|
|
75
|
+
verbose: options.verbose,
|
|
76
|
+
dryRun: options.dryRun,
|
|
77
|
+
batchSize: options.batchSize,
|
|
78
|
+
syncType: options.syncType,
|
|
79
|
+
format: options.format
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (options.json) {
|
|
83
|
+
const { context: _ctx, ...payload } = result;
|
|
84
|
+
logger.log(JSON.stringify(payload, null, 2));
|
|
85
|
+
} else {
|
|
86
|
+
displayDatasourceLoadTTY(result, { environment: options.env, verbose: options.verbose });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
process.exit(computeLoadExitCode(result));
|
|
90
|
+
} catch (err) {
|
|
91
|
+
logger.error(formatBlockingError(`Load failed: ${err.message}`));
|
|
92
|
+
const code = err.message && /auth|login|token|version|unreachable/i.test(err.message) ? 3 : 1;
|
|
93
|
+
process.exit(code);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function datasourceExportAction(datasourceKey, options) {
|
|
98
|
+
try {
|
|
99
|
+
const result = await runDatasourceExport(datasourceKey, {
|
|
100
|
+
app: options.app,
|
|
101
|
+
env: options.env,
|
|
102
|
+
file: options.file,
|
|
103
|
+
verbose: options.verbose,
|
|
104
|
+
format: options.format,
|
|
105
|
+
filter: options.filter,
|
|
106
|
+
fields: options.fields,
|
|
107
|
+
limit: options.limit,
|
|
108
|
+
intent: options.intent,
|
|
109
|
+
strict: options.strict
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
if (options.json) {
|
|
113
|
+
const { context: _ctx, ...payload } = result;
|
|
114
|
+
logger.log(JSON.stringify(payload, null, 2));
|
|
115
|
+
} else {
|
|
116
|
+
displayDatasourceExportTTY(result, { environment: options.env, verbose: options.verbose });
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
process.exit(computeExportExitCode(result, options));
|
|
120
|
+
} catch (err) {
|
|
121
|
+
logger.error(formatBlockingError(`Export failed: ${err.message}`));
|
|
122
|
+
const code = err.message && /auth|login|token|version|unreachable/i.test(err.message) ? 3 : 1;
|
|
123
|
+
process.exit(code);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @param {import('commander').Command} datasource
|
|
129
|
+
*/
|
|
130
|
+
function setupDatasourceLoadExportCommands(datasource) {
|
|
131
|
+
datasource
|
|
132
|
+
.command('load <datasourceKey>')
|
|
133
|
+
.description('Import local JSON/NDJSON records via dataplane bulk sync')
|
|
134
|
+
.option('-a, --app <app>', 'Integration folder name')
|
|
135
|
+
.option('-e, --env <env>', 'Environment: dev, tst, or pro')
|
|
136
|
+
.option('--file <path>', 'Input file (default: integration/.data/...)')
|
|
137
|
+
.option('--format <json|ndjson>', 'File format when extension is ambiguous')
|
|
138
|
+
.option('--batch-size <n>', 'Records per bulk request', '100')
|
|
139
|
+
.option(
|
|
140
|
+
'--sync-type <incremental|bulk|validate>',
|
|
141
|
+
'Dataplane syncType',
|
|
142
|
+
'incremental'
|
|
143
|
+
)
|
|
144
|
+
.option('--dry-run', 'Parse and validate only; no upload')
|
|
145
|
+
.option('-v, --verbose', 'Per-batch progress')
|
|
146
|
+
.option('--json', 'Machine-readable result JSON')
|
|
147
|
+
.addHelpText('after', loadHelpAfter())
|
|
148
|
+
.action(datasourceLoadAction);
|
|
149
|
+
|
|
150
|
+
datasource
|
|
151
|
+
.command('export <datasourceKey>')
|
|
152
|
+
.description('Export governed records to local JSON/NDJSON via records search')
|
|
153
|
+
.option('-a, --app <app>', 'Integration folder name')
|
|
154
|
+
.option('-e, --env <env>', 'Environment: dev, tst, or pro')
|
|
155
|
+
.option('--file <path>', 'Output file (default: integration/.data/...)')
|
|
156
|
+
.option('--format <json|ndjson>', 'Output format')
|
|
157
|
+
.option('--filter <json>', 'Records search filters (JSON object)')
|
|
158
|
+
.option('--fields <csv>', 'Project metadata keys in export rows')
|
|
159
|
+
.option('--limit <n>', 'Max records (1–10000)', '1000')
|
|
160
|
+
.option(
|
|
161
|
+
'--intent <retrieval|grounding|analytics|validation>',
|
|
162
|
+
'Search intent',
|
|
163
|
+
'validation'
|
|
164
|
+
)
|
|
165
|
+
.option('--strict', 'Exit 1 when zero rows are exported')
|
|
166
|
+
.option('-v, --verbose', 'Search stats and file size')
|
|
167
|
+
.option('--json', 'Machine-readable result JSON')
|
|
168
|
+
.addHelpText('after', exportHelpAfter())
|
|
169
|
+
.action(datasourceExportAction);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module.exports = {
|
|
173
|
+
setupDatasourceLoadExportCommands,
|
|
174
|
+
datasourceLoadAction,
|
|
175
|
+
datasourceExportAction,
|
|
176
|
+
computeLoadExitCode,
|
|
177
|
+
computeExportExitCode
|
|
178
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CLI wiring for `datasource verify-trust` (404.5 / plan 143).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const logger = require('../utils/logger');
|
|
10
|
+
const { formatBlockingError } = require('../utils/cli-test-layout-chalk');
|
|
11
|
+
const { runDatasourceAgentTrust } = require('../datasource/agent-trust-run');
|
|
12
|
+
const { writeTrustDebugLogAndPrint } = require('../datasource/agent-trust-debug-log');
|
|
13
|
+
const { displayAgentTrustRunTTY } = require('../utils/agent-trust-run-display');
|
|
14
|
+
const { computeExitCodeFromTrustRun } = require('../utils/agent-trust-run-exit');
|
|
15
|
+
const { attachDatasourceTestCommonOptions } = require('./datasource-unified-test-cli.options');
|
|
16
|
+
const { cliOptsSkipSync } = require('../utils/cli-sync-options');
|
|
17
|
+
|
|
18
|
+
function datasourceVerifyTrustHelpAfter() {
|
|
19
|
+
return `
|
|
20
|
+
Examples:
|
|
21
|
+
$ aifabrix datasource verify-trust hubspot-companies
|
|
22
|
+
$ aifabrix datasource verify-trust hubspot-companies --app test-e2e-hubspot -v
|
|
23
|
+
$ aifabrix datasource verify-trust hubspot-companies --revalidate --strict
|
|
24
|
+
$ aifabrix verify-trust test-e2e-hubspot
|
|
25
|
+
|
|
26
|
+
Notes:
|
|
27
|
+
- Semantic trust only (agent metadata validation). For live API proof use test-e2e.
|
|
28
|
+
- Local files are published before run unless --no-sync.
|
|
29
|
+
- With --debug, JSON is saved under integration/<app>/logs/ (verify-trust-<key>-*.json). View with: aifabrix datasource log-trust <key>
|
|
30
|
+
`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function runDatasourceVerifyTrustOnce(datasourceKey, options) {
|
|
34
|
+
const { trustRun, apiError } = await runDatasourceAgentTrust(datasourceKey, {
|
|
35
|
+
app: options.app,
|
|
36
|
+
environment: options.env,
|
|
37
|
+
noSync: options.noSync === true,
|
|
38
|
+
force: options.force === true,
|
|
39
|
+
revalidate: options.revalidate === true,
|
|
40
|
+
summary: options.summary === true,
|
|
41
|
+
timeout: options.timeout
|
|
42
|
+
});
|
|
43
|
+
return { trustRun, apiError };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function finalizeDatasourceVerifyTrust(datasourceKey, options, result) {
|
|
47
|
+
const displayOpts = {
|
|
48
|
+
json: options.json,
|
|
49
|
+
verbose: options.verbose,
|
|
50
|
+
environment: options.env,
|
|
51
|
+
noSync: options.noSync === true,
|
|
52
|
+
strict: options.strict === true
|
|
53
|
+
};
|
|
54
|
+
if (options.json) {
|
|
55
|
+
logger.log(JSON.stringify(result.trustRun, null, 2));
|
|
56
|
+
} else if (options.summary) {
|
|
57
|
+
const tr = result.trustRun;
|
|
58
|
+
logger.log(
|
|
59
|
+
`${tr.datasourceKey}: ${tr.trustDecision} (${tr.validationStatus}, ${Math.round((tr.confidence || 0) * 100)}%)`
|
|
60
|
+
);
|
|
61
|
+
} else {
|
|
62
|
+
displayAgentTrustRunTTY(result.trustRun, displayOpts);
|
|
63
|
+
}
|
|
64
|
+
const exitOpts = {
|
|
65
|
+
warningsAsErrors: options.warningsAsErrors === true,
|
|
66
|
+
strict: options.strict === true
|
|
67
|
+
};
|
|
68
|
+
return computeExitCodeFromTrustRun(result.trustRun, exitOpts);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function datasourceVerifyTrustAction(datasourceKey, options, cmd) {
|
|
72
|
+
try {
|
|
73
|
+
const merged = { ...options, noSync: cliOptsSkipSync(options, cmd) };
|
|
74
|
+
const result = await runDatasourceVerifyTrustOnce(datasourceKey, merged);
|
|
75
|
+
const { resolveAppKeyForDatasource } = require('../datasource/resolve-app');
|
|
76
|
+
const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
|
|
77
|
+
if (options.debug) {
|
|
78
|
+
await writeTrustDebugLogAndPrint(appKey, datasourceKey, {
|
|
79
|
+
request: { datasourceKey, revalidate: options.revalidate === true },
|
|
80
|
+
response: result.trustRun,
|
|
81
|
+
error: result.apiError ? result.apiError.message : null
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
const exitCode = await finalizeDatasourceVerifyTrust(datasourceKey, merged, result);
|
|
85
|
+
process.exit(exitCode);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
logger.error(formatBlockingError('Agent trust validation failed:'), err.message);
|
|
88
|
+
process.exit(3);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function attachDatasourceTrustOptions(cmd) {
|
|
93
|
+
attachDatasourceTestCommonOptions(cmd, {
|
|
94
|
+
includeNoAsync: false,
|
|
95
|
+
includePayload: false,
|
|
96
|
+
timeoutHelp: 'HTTP timeout for validate request (ms)',
|
|
97
|
+
timeoutDefault: '120000'
|
|
98
|
+
});
|
|
99
|
+
cmd
|
|
100
|
+
.option('--no-sync', 'Skip publishing local integration files before validate')
|
|
101
|
+
.option('--revalidate', 'Force new validation (ignore inputHash cache)')
|
|
102
|
+
.option('--strict', 'Exit 1 unless trustDecision is trusted');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function setupDatasourceVerifyTrustCommand(datasource) {
|
|
106
|
+
const cmd = datasource
|
|
107
|
+
.command('verify-trust <datasourceKey>')
|
|
108
|
+
.description('Semantic agent metadata validation for one datasource');
|
|
109
|
+
attachDatasourceTrustOptions(cmd);
|
|
110
|
+
cmd.addHelpText('after', datasourceVerifyTrustHelpAfter()).action(datasourceVerifyTrustAction);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = {
|
|
114
|
+
setupDatasourceVerifyTrustCommand,
|
|
115
|
+
runDatasourceVerifyTrustOnce,
|
|
116
|
+
finalizeDatasourceVerifyTrust,
|
|
117
|
+
datasourceVerifyTrustAction
|
|
118
|
+
};
|
|
@@ -28,6 +28,7 @@ const {
|
|
|
28
28
|
finalizeDatasourceTestE2ELegacyPath,
|
|
29
29
|
displayDatasourceTestE2EEnvelopeResults
|
|
30
30
|
} = require('./datasource-unified-test-e2e-cli-helpers');
|
|
31
|
+
const { maybeVerifyAuditAfterE2E } = require('../datasource/audit-evidence-run');
|
|
31
32
|
const {
|
|
32
33
|
datasourceTestHelpAfter,
|
|
33
34
|
datasourceTestIntegrationHelpAfter,
|
|
@@ -76,7 +77,8 @@ function buildDatasourceTestRunOpts(options) {
|
|
|
76
77
|
timeout: options.timeout,
|
|
77
78
|
async: options.async !== false,
|
|
78
79
|
noAsync: options.async === false,
|
|
79
|
-
sync: options.sync === true
|
|
80
|
+
sync: options.sync === true,
|
|
81
|
+
force: options.force === true
|
|
80
82
|
};
|
|
81
83
|
}
|
|
82
84
|
|
|
@@ -173,7 +175,8 @@ function buildIntegrationTestOpts(options) {
|
|
|
173
175
|
debug: options.debug,
|
|
174
176
|
verbose: options.verbose,
|
|
175
177
|
timeout: options.timeout,
|
|
176
|
-
sync: options.sync === true
|
|
178
|
+
sync: options.sync === true,
|
|
179
|
+
force: options.force === true
|
|
177
180
|
};
|
|
178
181
|
}
|
|
179
182
|
|
|
@@ -333,8 +336,9 @@ async function runDatasourceTestE2ECliOnce(datasourceKey, options) {
|
|
|
333
336
|
minProcessed: options.minProcessed,
|
|
334
337
|
minRecordCount: options.minRecordCount,
|
|
335
338
|
timeout: options.timeout,
|
|
336
|
-
capabilityKey: options.
|
|
337
|
-
sync: options.sync === true
|
|
339
|
+
capabilityKey: options.capabilityKey,
|
|
340
|
+
sync: options.sync === true,
|
|
341
|
+
force: options.force === true
|
|
338
342
|
});
|
|
339
343
|
const unifiedModes =
|
|
340
344
|
options.json || options.summary || options.warningsAsErrors || options.requireCert;
|
|
@@ -352,7 +356,7 @@ async function runDatasourceTestE2ECliOnce(datasourceKey, options) {
|
|
|
352
356
|
warningsAsErrors: options.warningsAsErrors,
|
|
353
357
|
requireCert: options.requireCert,
|
|
354
358
|
debug: options.debug,
|
|
355
|
-
requestedCapabilityKey: options.
|
|
359
|
+
requestedCapabilityKey: options.capabilityKey,
|
|
356
360
|
strictCapabilityScope: options.strictCapabilityScope === true
|
|
357
361
|
}
|
|
358
362
|
);
|
|
@@ -370,24 +374,24 @@ async function runDatasourceTestE2ECliOnce(datasourceKey, options) {
|
|
|
370
374
|
|
|
371
375
|
async function runDatasourceTestE2ECliAction(datasourceKey, options) {
|
|
372
376
|
const { exitCode, envelope } = await runDatasourceTestE2ECliOnce(datasourceKey, options);
|
|
373
|
-
await
|
|
374
|
-
|
|
377
|
+
const finalExit = await maybeVerifyAuditAfterE2E(exitCode, datasourceKey, envelope, options);
|
|
378
|
+
await afterUnifiedValidationCertSync(
|
|
379
|
+
finalExit,
|
|
380
|
+
datasourceKey,
|
|
381
|
+
options,
|
|
382
|
+
'datasource test-e2e',
|
|
383
|
+
envelope
|
|
384
|
+
);
|
|
385
|
+
process.exit(finalExit);
|
|
375
386
|
}
|
|
376
387
|
|
|
377
388
|
async function e2eTestCommandAction(datasourceKey, capabilityKey, options) {
|
|
378
389
|
const optObj = options && typeof options === 'object' ? options : {};
|
|
379
390
|
const capFromArg = typeof capabilityKey === 'string' ? capabilityKey.trim() : '';
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
:
|
|
383
|
-
|
|
384
|
-
if (capFromArg && capFromFlag && capFromArg !== capFromFlag) {
|
|
385
|
-
logger.warn(
|
|
386
|
-
chalk.yellow('⚠ Capability mismatch:'),
|
|
387
|
-
`using positional '${capFromArg}' instead of --capability '${capFromFlag}'.`
|
|
388
|
-
);
|
|
389
|
-
}
|
|
390
|
-
const mergedOptions = { ...optObj, capability: requestedCapability || undefined };
|
|
391
|
+
const mergedOptions = {
|
|
392
|
+
...optObj,
|
|
393
|
+
capabilityKey: capFromArg || undefined
|
|
394
|
+
};
|
|
391
395
|
try {
|
|
392
396
|
if (mergedOptions.watch) {
|
|
393
397
|
const { appKey } = await resolveAppKeyForDatasource(datasourceKey, mergedOptions.app);
|
|
@@ -400,14 +404,20 @@ async function e2eTestCommandAction(datasourceKey, capabilityKey, options) {
|
|
|
400
404
|
runOnce: async() => {
|
|
401
405
|
try {
|
|
402
406
|
const r = await runDatasourceTestE2ECliOnce(datasourceKey, mergedOptions);
|
|
403
|
-
await
|
|
407
|
+
const finalExit = await maybeVerifyAuditAfterE2E(
|
|
404
408
|
r.exitCode,
|
|
405
409
|
datasourceKey,
|
|
410
|
+
r.envelope,
|
|
411
|
+
mergedOptions
|
|
412
|
+
);
|
|
413
|
+
await afterUnifiedValidationCertSync(
|
|
414
|
+
finalExit,
|
|
415
|
+
datasourceKey,
|
|
406
416
|
mergedOptions,
|
|
407
417
|
'datasource test-e2e (watch)',
|
|
408
418
|
r.envelope
|
|
409
419
|
);
|
|
410
|
-
return r;
|
|
420
|
+
return { exitCode: finalExit, envelope: r.envelope };
|
|
411
421
|
} catch (err) {
|
|
412
422
|
logger.error(formatBlockingError('E2E test failed:'), err.message);
|
|
413
423
|
return { exitCode: 3, envelope: null };
|
|
@@ -459,5 +469,6 @@ module.exports = {
|
|
|
459
469
|
runIntegrationOnceForWatch,
|
|
460
470
|
integrationTestCommandAction,
|
|
461
471
|
runDatasourceTestE2ECliOnce,
|
|
472
|
+
maybeVerifyAuditAfterE2E,
|
|
462
473
|
e2eTestCommandAction
|
|
463
474
|
};
|