@aifabrix/builder 2.44.6 ā 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/cli-layout.mdc +7 -3
- 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 +100 -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/app/helpers.js +3 -3
- package/lib/app/index.js +3 -3
- package/lib/app/register.js +7 -6
- package/lib/app/restart-display.js +52 -21
- package/lib/app/rotate-secret.js +7 -6
- package/lib/app/run-helpers.js +15 -8
- package/lib/app/run.js +57 -9
- package/lib/app/show-display.js +7 -0
- package/lib/app/show.js +87 -5
- package/lib/build/index.js +9 -5
- package/lib/cli/index.js +4 -2
- package/lib/cli/infra-guided.js +62 -28
- package/lib/cli/installation-log-command.js +73 -0
- package/lib/cli/setup-app.help.js +50 -2
- package/lib/cli/setup-app.js +44 -25
- package/lib/cli/setup-app.test-commands.js +80 -21
- package/lib/cli/setup-auth.js +124 -52
- package/lib/cli/setup-external-system.js +37 -3
- package/lib/cli/setup-infra-up-dataplane-action.js +111 -0
- package/lib/cli/setup-infra-up-platform-action.js +131 -0
- package/lib/cli/setup-infra.js +60 -119
- package/lib/cli/setup-platform.js +1 -1
- package/lib/cli/setup-utility-help-after.js +45 -0
- package/lib/cli/setup-utility-resolve.js +132 -0
- package/lib/cli/setup-utility.js +148 -116
- package/lib/commands/app-logs.js +81 -33
- package/lib/commands/auth-config.js +116 -18
- 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/setup-modes.js +19 -6
- package/lib/commands/setup-prompts.js +41 -8
- package/lib/commands/setup.js +114 -9
- package/lib/commands/teardown.js +54 -5
- 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/up-common.js +48 -14
- package/lib/commands/up-dataplane.js +21 -18
- package/lib/commands/up-miso.js +12 -8
- package/lib/commands/upload.js +38 -15
- package/lib/commands/wizard-core.js +3 -0
- package/lib/core/audit-logger.js +1 -34
- package/lib/core/config-admin-email.js +56 -0
- package/lib/core/config-device-dataplane.js +185 -0
- package/lib/core/config-normalize.js +60 -0
- package/lib/core/config-registered-controller-urls.js +54 -0
- package/lib/core/config.js +33 -50
- package/lib/core/secrets-ensure-infra.js +1 -1
- package/lib/core/secrets-env-content.js +86 -90
- package/lib/core/secrets-env-declarative-expand.js +170 -0
- package/lib/core/secrets-env-write.js +2 -0
- package/lib/core/secrets-load.js +106 -102
- 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/deploy.js +5 -1
- 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/internal/node-fs.js +2 -0
- 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/application-schema.json +4 -0
- package/lib/schema/external-datasource.schema.json +47 -13
- package/lib/schema/flag-map-validation-run.json +2 -2
- package/lib/schema/infra.parameter.yaml +10 -0
- 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/app-config-resolver.js +24 -1
- package/lib/utils/applications-config-defaults.js +206 -0
- package/lib/utils/auth-config-validator.js +2 -12
- package/lib/utils/bash-secret-env.js +1 -1
- package/lib/utils/cli-exit-codes.js +30 -0
- package/lib/utils/cli-sync-options.js +33 -0
- package/lib/utils/compose-generate-docker-compose.js +111 -6
- package/lib/utils/compose-generator.js +17 -8
- package/lib/utils/controller-url.js +50 -7
- 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/env-copy.js +99 -14
- package/lib/utils/env-template.js +5 -1
- package/lib/utils/health-check-url.js +18 -15
- package/lib/utils/health-check.js +7 -5
- package/lib/utils/help-builder.js +30 -24
- package/lib/utils/infra-optional-service-flags.js +69 -0
- package/lib/utils/installation-log-core.js +282 -0
- package/lib/utils/installation-log-record.js +237 -0
- package/lib/utils/installation-log.js +123 -0
- package/lib/utils/log-redaction.js +105 -0
- package/lib/utils/manifest-location.js +164 -0
- package/lib/utils/manifest-source-emit.js +184 -0
- package/lib/utils/paths.js +238 -89
- package/lib/utils/remote-secrets-loader.js +7 -1
- package/lib/utils/run-cli-flags.js +29 -0
- package/lib/utils/secrets-canonical.js +10 -3
- package/lib/utils/secrets-path.js +3 -4
- package/lib/utils/secrets-utils.js +20 -10
- package/lib/utils/semver-compare.js +127 -0
- package/lib/utils/system-builder-root.js +10 -2
- package/lib/utils/upload-pipeline-ui.js +91 -0
- package/lib/utils/url-declarative-public-base.js +80 -12
- package/lib/utils/url-declarative-resolve-build-urls.js +238 -0
- package/lib/utils/url-declarative-resolve-build.js +24 -393
- package/lib/utils/url-declarative-resolve-expand-token.js +189 -0
- package/lib/utils/url-declarative-resolve-load-doc.js +12 -3
- package/lib/utils/url-declarative-resolve-surface-state.js +102 -0
- package/lib/utils/url-declarative-resolve.js +47 -7
- package/lib/utils/url-declarative-runtime-base-path.js +21 -1
- package/lib/utils/urls-local-registry-scan.js +103 -0
- package/lib/utils/urls-local-registry.js +161 -90
- package/lib/utils/validation-poll-ui.js +14 -7
- package/lib/validation/wizard-config-validator.js +58 -19
- package/package.json +3 -1
- package/templates/applications/dataplane/application.yaml +4 -0
- package/templates/applications/dataplane/env.template +13 -1
- package/templates/applications/dataplane/rbac.yaml +4 -0
- package/templates/applications/miso-controller/application.yaml +2 -0
- package/templates/applications/miso-controller/env.template +27 -29
- package/templates/external-system/README.md.hbs +56 -8
- package/.npmrc.token +0 -1
|
@@ -8,53 +8,144 @@
|
|
|
8
8
|
* @version 2.0.0
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
const chalk = require('chalk');
|
|
11
12
|
const { formatBlockingError, formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
12
13
|
const {
|
|
13
14
|
setControllerUrl,
|
|
14
15
|
setCurrentEnvironment,
|
|
15
|
-
getControllerUrl
|
|
16
|
+
getControllerUrl,
|
|
17
|
+
getRegisteredControllerUrls,
|
|
18
|
+
getConfig
|
|
16
19
|
} = require('../core/config');
|
|
17
20
|
const {
|
|
18
21
|
validateControllerUrl,
|
|
19
22
|
validateEnvironment,
|
|
20
23
|
checkUserLoggedIn
|
|
21
24
|
} = require('../utils/auth-config-validator');
|
|
22
|
-
const {
|
|
25
|
+
const { hasStoredDeviceTokenForController } = require('../utils/controller-url');
|
|
23
26
|
const logger = require('../utils/logger');
|
|
24
27
|
|
|
28
|
+
/**
|
|
29
|
+
* True when user ran --set-controller with no URL (pick from config.yaml).
|
|
30
|
+
* @param {unknown} setController - Commander option value
|
|
31
|
+
* @returns {boolean}
|
|
32
|
+
*/
|
|
33
|
+
function isInteractiveControllerPick(setController) {
|
|
34
|
+
return (
|
|
35
|
+
setController === true ||
|
|
36
|
+
(typeof setController === 'string' && setController.trim() === '')
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* True when a non-empty controller URL string was passed.
|
|
42
|
+
* @param {unknown} setController - Commander option value
|
|
43
|
+
* @returns {boolean}
|
|
44
|
+
*/
|
|
45
|
+
function hasExplicitControllerUrl(setController) {
|
|
46
|
+
return typeof setController === 'string' && setController.trim() !== '';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Normalize controller URL for equality checks (trailing slashes).
|
|
51
|
+
* @param {string|null|undefined} url - URL or empty
|
|
52
|
+
* @returns {string}
|
|
53
|
+
*/
|
|
54
|
+
function normalizeForCompare(url) {
|
|
55
|
+
if (!url || typeof url !== 'string') return '';
|
|
56
|
+
return url.trim().replace(/\/+$/, '');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function throwNoRegisteredControllers() {
|
|
60
|
+
const msg =
|
|
61
|
+
'No controllers are registered in config. Run "aifabrix login" first, or set a controller with "aifabrix auth --set-controller <url>".';
|
|
62
|
+
logger.error(formatBlockingError(msg));
|
|
63
|
+
throw new Error(msg);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function throwNonInteractiveControllerPick() {
|
|
67
|
+
const msg =
|
|
68
|
+
'Cannot choose a controller without a URL in non-interactive mode. Run: aifabrix auth --set-controller <url>';
|
|
69
|
+
logger.error(formatBlockingError(msg));
|
|
70
|
+
throw new Error(msg);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Pick default controller from URLs in config (`controller` + `device` keys), or set the only one.
|
|
75
|
+
* @async
|
|
76
|
+
* @returns {Promise<void>}
|
|
77
|
+
*/
|
|
78
|
+
async function handleSelectRegisteredController() {
|
|
79
|
+
const urls = await getRegisteredControllerUrls();
|
|
80
|
+
|
|
81
|
+
if (urls.length === 0) {
|
|
82
|
+
throwNoRegisteredControllers();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!process.stdin.isTTY) {
|
|
86
|
+
throwNonInteractiveControllerPick();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (urls.length === 1) {
|
|
90
|
+
const sole = urls[0];
|
|
91
|
+
const current = await getControllerUrl();
|
|
92
|
+
if (normalizeForCompare(current) === normalizeForCompare(sole)) {
|
|
93
|
+
logger.log(formatSuccessLine(`Default controller is already set to ${sole}.`));
|
|
94
|
+
logger.log(
|
|
95
|
+
chalk.white('To add another controller, run: aifabrix auth --set-controller <url>')
|
|
96
|
+
);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
await handleSetController(sole);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const inquirer = require('inquirer');
|
|
104
|
+
const { controllerUrl } = await inquirer.prompt([
|
|
105
|
+
{
|
|
106
|
+
type: 'list',
|
|
107
|
+
name: 'controllerUrl',
|
|
108
|
+
message: 'Select default controller:',
|
|
109
|
+
choices: urls
|
|
110
|
+
}
|
|
111
|
+
]);
|
|
112
|
+
await handleSetController(controllerUrl);
|
|
113
|
+
}
|
|
114
|
+
|
|
25
115
|
/**
|
|
26
116
|
* Handle set-controller command
|
|
27
|
-
* Allows setting the default controller when no
|
|
28
|
-
*
|
|
117
|
+
* Allows setting the default controller when there are no device tokens, or when a token exists
|
|
118
|
+
* for the target URL (including switching among multiple logged-in controllers). If device tokens
|
|
119
|
+
* exist only for other controller URLs, throws with a clear message.
|
|
29
120
|
*
|
|
30
121
|
* @async
|
|
31
122
|
* @function handleSetController
|
|
32
123
|
* @param {string} url - Controller URL to set
|
|
33
124
|
* @returns {Promise<void>}
|
|
34
|
-
* @throws {Error} If validation fails or credentials exist for
|
|
125
|
+
* @throws {Error} If validation fails or credentials exist only for other controllers
|
|
35
126
|
*/
|
|
36
127
|
async function handleSetController(url) {
|
|
37
128
|
try {
|
|
38
129
|
validateControllerUrl(url);
|
|
39
130
|
const normalizedUrl = url.trim().replace(/\/+$/, '');
|
|
40
131
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
132
|
+
const userConfig = await getConfig();
|
|
133
|
+
const device =
|
|
134
|
+
userConfig.device && typeof userConfig.device === 'object' ? userConfig.device : {};
|
|
135
|
+
const deviceKeys = Object.keys(device);
|
|
136
|
+
const hasTokenForTarget = await hasStoredDeviceTokenForController(normalizedUrl);
|
|
48
137
|
|
|
49
|
-
|
|
50
|
-
if (normalizedLoggedIn === normalizedUrl) {
|
|
138
|
+
if (deviceKeys.length === 0 || hasTokenForTarget) {
|
|
51
139
|
await setControllerUrl(url);
|
|
52
140
|
logger.log(formatSuccessLine(`Controller URL set to: ${url}`));
|
|
53
141
|
return;
|
|
54
142
|
}
|
|
55
143
|
|
|
144
|
+
const otherKey =
|
|
145
|
+
deviceKeys.find((k) => normalizeForCompare(k) !== normalizeForCompare(normalizedUrl)) ||
|
|
146
|
+
deviceKeys[0];
|
|
56
147
|
throw new Error(
|
|
57
|
-
`You have credentials for another controller (${
|
|
148
|
+
`You have credentials for another controller (${otherKey.trim().replace(/\/+$/, '')}).\n` +
|
|
58
149
|
'To use a different controller either run "aifabrix login" with that controller, or run "aifabrix logout" first to clear credentials, then set the new controller with "aifabrix auth --set-controller <url>".'
|
|
59
150
|
);
|
|
60
151
|
} catch (error) {
|
|
@@ -107,20 +198,27 @@ async function handleSetEnvironment(environment) {
|
|
|
107
198
|
* @async
|
|
108
199
|
* @function handleAuthConfig
|
|
109
200
|
* @param {Object} options - Command options
|
|
110
|
-
* @param {string} [options.setController] - Controller URL
|
|
201
|
+
* @param {string|boolean} [options.setController] - Controller URL, or true when flag has no value
|
|
111
202
|
* @param {string} [options.setEnvironment] - Environment to set
|
|
112
203
|
* @returns {Promise<void>}
|
|
113
204
|
* @throws {Error} If command fails
|
|
114
205
|
*/
|
|
115
206
|
async function handleAuthConfig(options) {
|
|
116
|
-
|
|
207
|
+
const pick = isInteractiveControllerPick(options.setController);
|
|
208
|
+
const hasUrl = hasExplicitControllerUrl(options.setController);
|
|
209
|
+
|
|
210
|
+
if (!pick && !hasUrl && !options.setEnvironment) {
|
|
117
211
|
throw new Error(
|
|
118
212
|
'No action specified. Use "aifabrix auth --set-controller <url>" or "aifabrix auth --set-environment <env>".'
|
|
119
213
|
);
|
|
120
214
|
}
|
|
121
|
-
|
|
215
|
+
|
|
216
|
+
if (pick) {
|
|
217
|
+
await handleSelectRegisteredController();
|
|
218
|
+
} else if (hasUrl) {
|
|
122
219
|
await handleSetController(options.setController);
|
|
123
220
|
}
|
|
221
|
+
|
|
124
222
|
if (options.setEnvironment) {
|
|
125
223
|
await handleSetEnvironment(options.setEnvironment);
|
|
126
224
|
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth-status dataplane version refresh + compatibility resolution (plan 142.0).
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `auth-status.js` to keep that file under the 500-line limit
|
|
5
|
+
* (`.cursor/rules/project-rules.mdc ā File and Function Size Limits`). The
|
|
6
|
+
* helpers here are pure-ish (only depend on the dataplane health API and the
|
|
7
|
+
* `device.<controllerUrl>` cache module) so they are easy to mock in unit
|
|
8
|
+
* tests.
|
|
9
|
+
*
|
|
10
|
+
* @fileoverview Resolve dataplane version + Builder CLI compatibility for auth status
|
|
11
|
+
* @author AI Fabrix Team
|
|
12
|
+
* @version 2.0.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const { fetchDataplaneGeneralHealth } = require('../api/dataplane-health.api');
|
|
18
|
+
const {
|
|
19
|
+
updateDeviceDataplaneVersions,
|
|
20
|
+
getDeviceDataplaneVersions
|
|
21
|
+
} = require('../core/config-device-dataplane');
|
|
22
|
+
const {
|
|
23
|
+
getInstalledCliVersion
|
|
24
|
+
} = require('../utils/dataplane-cli-version-gate');
|
|
25
|
+
const { isAtLeast, isValidSemver } = require('../utils/semver-compare');
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Per plan 142.0: invalid semver from the dataplane is logged but does **not**
|
|
29
|
+
* block the CLI; missing min version means no enforcement.
|
|
30
|
+
*
|
|
31
|
+
* @param {string} cliVersion
|
|
32
|
+
* @param {string|undefined} minBuilderCliVersion
|
|
33
|
+
* @returns {boolean}
|
|
34
|
+
*/
|
|
35
|
+
function computeCompatibility(cliVersion, minBuilderCliVersion) {
|
|
36
|
+
if (!minBuilderCliVersion) return true;
|
|
37
|
+
if (!isValidSemver(minBuilderCliVersion) || !isValidSemver(cliVersion)) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return isAtLeast(cliVersion, minBuilderCliVersion);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Read `device.<controllerUrl>` cache without throwing.
|
|
45
|
+
* @private
|
|
46
|
+
* @async
|
|
47
|
+
* @param {string} controllerUrl
|
|
48
|
+
* @returns {Promise<Object|null>}
|
|
49
|
+
*/
|
|
50
|
+
async function safeReadCache(controllerUrl) {
|
|
51
|
+
if (!controllerUrl) return null;
|
|
52
|
+
try {
|
|
53
|
+
return await getDeviceDataplaneVersions(controllerUrl);
|
|
54
|
+
} catch (_error) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Refresh dataplane health, persist `device.<controllerUrl>` version cache,
|
|
61
|
+
* and derive the compatibility verdict against the installed Builder CLI.
|
|
62
|
+
* Falls back to the cached entry when the live probe fails so `auth status`
|
|
63
|
+
* still shows the last-known values offline.
|
|
64
|
+
*
|
|
65
|
+
* @async
|
|
66
|
+
* @param {string} controllerUrl - Controller URL (cache key)
|
|
67
|
+
* @param {string} dataplaneUrl - Dataplane base URL for the health probe
|
|
68
|
+
* @returns {Promise<{
|
|
69
|
+
* dataplaneVersion: string|undefined,
|
|
70
|
+
* minBuilderCliVersion: string|undefined,
|
|
71
|
+
* cliVersion: string,
|
|
72
|
+
* compatible: boolean
|
|
73
|
+
* }>}
|
|
74
|
+
*/
|
|
75
|
+
async function refreshDataplaneVersionInfo(controllerUrl, dataplaneUrl) {
|
|
76
|
+
const cliVersion = getInstalledCliVersion();
|
|
77
|
+
let dataplaneVersion;
|
|
78
|
+
let minBuilderCliVersion;
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const snapshot = await fetchDataplaneGeneralHealth(dataplaneUrl);
|
|
82
|
+
if (snapshot) {
|
|
83
|
+
dataplaneVersion = snapshot.version;
|
|
84
|
+
minBuilderCliVersion = snapshot.minBuilderCliVersion;
|
|
85
|
+
try {
|
|
86
|
+
await updateDeviceDataplaneVersions(controllerUrl, {
|
|
87
|
+
version: dataplaneVersion,
|
|
88
|
+
minBuilderCliVersion: minBuilderCliVersion || null
|
|
89
|
+
});
|
|
90
|
+
} catch (_persistError) {
|
|
91
|
+
// cache write failure must not break the display
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} catch (_fetchError) {
|
|
95
|
+
// ignore ā fall through to cached values
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!dataplaneVersion && !minBuilderCliVersion) {
|
|
99
|
+
const cached = await safeReadCache(controllerUrl);
|
|
100
|
+
if (cached) {
|
|
101
|
+
dataplaneVersion = cached.version;
|
|
102
|
+
minBuilderCliVersion = cached.minBuilderCliVersion;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const compatible = computeCompatibility(cliVersion, minBuilderCliVersion);
|
|
107
|
+
return { dataplaneVersion, minBuilderCliVersion, cliVersion, compatible };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Load cached versions only (no live probe). Used when the dataplane is
|
|
112
|
+
* unreachable so `auth status` can still surface a known compatibility floor.
|
|
113
|
+
*
|
|
114
|
+
* @async
|
|
115
|
+
* @param {string} controllerUrl
|
|
116
|
+
* @returns {Promise<{
|
|
117
|
+
* dataplaneVersion: string|undefined,
|
|
118
|
+
* minBuilderCliVersion: string|undefined,
|
|
119
|
+
* cliVersion: string,
|
|
120
|
+
* compatible: boolean
|
|
121
|
+
* }>}
|
|
122
|
+
*/
|
|
123
|
+
async function loadCachedVersionInfo(controllerUrl) {
|
|
124
|
+
const cliVersion = getInstalledCliVersion();
|
|
125
|
+
const cached = await safeReadCache(controllerUrl);
|
|
126
|
+
const dataplaneVersion = cached ? cached.version : undefined;
|
|
127
|
+
const minBuilderCliVersion = cached ? cached.minBuilderCliVersion : undefined;
|
|
128
|
+
return {
|
|
129
|
+
dataplaneVersion,
|
|
130
|
+
minBuilderCliVersion,
|
|
131
|
+
cliVersion,
|
|
132
|
+
compatible: computeCompatibility(cliVersion, minBuilderCliVersion)
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Resolve bearer auth after login (device token preferred, else client app token).
|
|
138
|
+
* @private
|
|
139
|
+
* @async
|
|
140
|
+
* @param {string} controllerUrl
|
|
141
|
+
* @param {string} environment
|
|
142
|
+
* @param {Object} loginOptions
|
|
143
|
+
* @returns {Promise<Object|null>}
|
|
144
|
+
*/
|
|
145
|
+
async function resolveAuthConfigAfterLogin(controllerUrl, environment, loginOptions) {
|
|
146
|
+
const { getOrRefreshDeviceToken, getDeploymentAuth } = require('../utils/token-manager');
|
|
147
|
+
const device = await getOrRefreshDeviceToken(controllerUrl);
|
|
148
|
+
if (device && device.token) {
|
|
149
|
+
return { type: 'bearer', token: device.token };
|
|
150
|
+
}
|
|
151
|
+
if (!loginOptions.app) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
return await getDeploymentAuth(controllerUrl, environment, loginOptions.app);
|
|
156
|
+
} catch (_authError) {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Resolve dataplane URL after login (mirrors auth-status silent resolver).
|
|
163
|
+
* @private
|
|
164
|
+
* @async
|
|
165
|
+
* @param {string} controllerUrl
|
|
166
|
+
* @param {string} environment
|
|
167
|
+
* @param {Object} authConfig
|
|
168
|
+
* @returns {Promise<string|null>}
|
|
169
|
+
*/
|
|
170
|
+
async function resolveDataplaneUrlAfterLogin(controllerUrl, environment, authConfig) {
|
|
171
|
+
const { findDataplaneServiceAppKey } = require('./wizard-dataplane');
|
|
172
|
+
const { getDataplaneUrl } = require('../datasource/deploy');
|
|
173
|
+
try {
|
|
174
|
+
const dataplaneAppKey = await findDataplaneServiceAppKey(
|
|
175
|
+
controllerUrl,
|
|
176
|
+
environment,
|
|
177
|
+
authConfig
|
|
178
|
+
);
|
|
179
|
+
if (dataplaneAppKey) {
|
|
180
|
+
return await getDataplaneUrl(controllerUrl, dataplaneAppKey, environment, authConfig);
|
|
181
|
+
}
|
|
182
|
+
return await getDataplaneUrl(controllerUrl, 'dataplane', environment, authConfig);
|
|
183
|
+
} catch (_resolveError) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Best-effort health refresh after login when dataplane URL is discoverable.
|
|
190
|
+
* Never throws ā cache failures must not block login success.
|
|
191
|
+
*
|
|
192
|
+
* @async
|
|
193
|
+
* @param {string} controllerUrl - Controller URL (device cache key)
|
|
194
|
+
* @param {Object} [loginOptions]
|
|
195
|
+
* @param {string} [loginOptions.app] - App name (credentials login) for client-token auth
|
|
196
|
+
* @returns {Promise<void>}
|
|
197
|
+
*/
|
|
198
|
+
async function tryRefreshDataplaneVersionAfterLogin(controllerUrl, loginOptions = {}) {
|
|
199
|
+
if (!controllerUrl || typeof controllerUrl !== 'string') {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
const { resolveEnvironment } = require('../core/config');
|
|
204
|
+
const environment = await resolveEnvironment();
|
|
205
|
+
const authConfig = await resolveAuthConfigAfterLogin(
|
|
206
|
+
controllerUrl,
|
|
207
|
+
environment,
|
|
208
|
+
loginOptions
|
|
209
|
+
);
|
|
210
|
+
if (!authConfig) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const dataplaneUrl = await resolveDataplaneUrlAfterLogin(
|
|
214
|
+
controllerUrl,
|
|
215
|
+
environment,
|
|
216
|
+
authConfig
|
|
217
|
+
);
|
|
218
|
+
if (dataplaneUrl) {
|
|
219
|
+
await refreshDataplaneVersionInfo(controllerUrl, dataplaneUrl);
|
|
220
|
+
}
|
|
221
|
+
} catch (_error) {
|
|
222
|
+
// best-effort only
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
module.exports = {
|
|
227
|
+
refreshDataplaneVersionInfo,
|
|
228
|
+
loadCachedVersionInfo,
|
|
229
|
+
computeCompatibility,
|
|
230
|
+
tryRefreshDataplaneVersionAfterLogin
|
|
231
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth-status dataplane version block + blocking upgrade UX (plan 142.0).
|
|
3
|
+
*
|
|
4
|
+
* Kept in a separate module so `auth-status.js` stays under the 500-line
|
|
5
|
+
* limit and so the same display helpers can be reused by future dataplane
|
|
6
|
+
* gate surfaces (`upload`, `wizard`, `deploy`, ā¦).
|
|
7
|
+
*
|
|
8
|
+
* @fileoverview TTY rendering for dataplane / Builder CLI compatibility
|
|
9
|
+
* @author AI Fabrix Team
|
|
10
|
+
* @version 2.0.0
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const chalk = require('chalk');
|
|
16
|
+
const logger = require('../utils/logger');
|
|
17
|
+
const {
|
|
18
|
+
successGlyph,
|
|
19
|
+
failureGlyph
|
|
20
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
21
|
+
const {
|
|
22
|
+
formatCliVersionGateError
|
|
23
|
+
} = require('../utils/dataplane-cli-version-help');
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Format a single key/value version line indented under the dataplane block.
|
|
27
|
+
* @private
|
|
28
|
+
* @param {string} label
|
|
29
|
+
* @param {string|undefined|null} value
|
|
30
|
+
* @returns {string}
|
|
31
|
+
*/
|
|
32
|
+
function versionLine(label, value) {
|
|
33
|
+
const display = value && String(value).trim() ? chalk.cyan(value) : chalk.gray('ā');
|
|
34
|
+
return ` ${label}: ${display}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Render the dataplane version subsection on `aifabrix auth status`.
|
|
39
|
+
*
|
|
40
|
+
* Designed to be called immediately after the existing connection/status line,
|
|
41
|
+
* so the output reads as a single grouped block per layout.md §HEADER BLOCK.
|
|
42
|
+
*
|
|
43
|
+
* @param {Object} params
|
|
44
|
+
* @param {boolean} params.connected - Whether dataplane reachability probe passed
|
|
45
|
+
* @param {string|undefined} params.dataplaneVersion - From `device.<controllerUrl>.dataplane-version`
|
|
46
|
+
* @param {string|undefined} params.minBuilderCliVersion - From `device.<controllerUrl>.dataplane-min-cli-version`
|
|
47
|
+
* @param {string} params.cliVersion - Installed Builder CLI version
|
|
48
|
+
* @param {boolean} params.compatible - true when CLI ā„ minimum (or no minimum enforced)
|
|
49
|
+
* @returns {void}
|
|
50
|
+
*/
|
|
51
|
+
function displayDataplaneVersionSection({
|
|
52
|
+
connected,
|
|
53
|
+
dataplaneVersion,
|
|
54
|
+
minBuilderCliVersion,
|
|
55
|
+
cliVersion,
|
|
56
|
+
compatible
|
|
57
|
+
}) {
|
|
58
|
+
if (!connected && !dataplaneVersion) {
|
|
59
|
+
// Nothing to add ā keep auth status quiet when the dataplane probe failed
|
|
60
|
+
// and no cached version is known (the reachability line already told the user).
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
logger.log(versionLine('Dataplane version', dataplaneVersion));
|
|
64
|
+
logger.log(versionLine('Min Builder CLI', minBuilderCliVersion));
|
|
65
|
+
logger.log(versionLine('This CLI', cliVersion));
|
|
66
|
+
if (!minBuilderCliVersion) {
|
|
67
|
+
logger.log(` Compatibility: ${chalk.gray('Not enforced')}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (compatible) {
|
|
71
|
+
logger.log(` Compatibility: ${successGlyph()} ${chalk.green('OK')}`);
|
|
72
|
+
} else {
|
|
73
|
+
logger.log(` Compatibility: ${failureGlyph()} ${chalk.red('Upgrade required')}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Render the blocking upgrade block (red ā + Next actions) under the
|
|
79
|
+
* dataplane subsection when the CLI is incompatible.
|
|
80
|
+
*
|
|
81
|
+
* @param {Object} params
|
|
82
|
+
* @param {string} params.required - Required minimum semver
|
|
83
|
+
* @param {string} params.installed - Currently installed semver
|
|
84
|
+
* @returns {void}
|
|
85
|
+
*/
|
|
86
|
+
function displayCliUpgradeRequired({ required, installed }) {
|
|
87
|
+
logger.log('');
|
|
88
|
+
logger.log(formatCliVersionGateError(required, installed));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = {
|
|
92
|
+
displayDataplaneVersionSection,
|
|
93
|
+
displayCliUpgradeRequired
|
|
94
|
+
};
|
|
@@ -19,6 +19,19 @@ const { resolveControllerUrl } = require('../utils/controller-url');
|
|
|
19
19
|
const { findDataplaneServiceAppKey } = require('./wizard-dataplane');
|
|
20
20
|
const { getDataplaneUrl } = require('../datasource/deploy');
|
|
21
21
|
const { checkDataplaneHealth } = require('../utils/dataplane-health');
|
|
22
|
+
const {
|
|
23
|
+
displayDataplaneVersionSection,
|
|
24
|
+
displayCliUpgradeRequired
|
|
25
|
+
} = require('./auth-status-display');
|
|
26
|
+
const {
|
|
27
|
+
refreshDataplaneVersionInfo,
|
|
28
|
+
loadCachedVersionInfo
|
|
29
|
+
} = require('./auth-status-dataplane-version');
|
|
30
|
+
const {
|
|
31
|
+
EXIT_NOT_AUTHENTICATED,
|
|
32
|
+
EXIT_CLI_VERSION_INCOMPATIBLE,
|
|
33
|
+
EXIT_OK
|
|
34
|
+
} = require('../utils/cli-exit-codes');
|
|
22
35
|
|
|
23
36
|
/**
|
|
24
37
|
* Format expiration date for display
|
|
@@ -290,6 +303,10 @@ function displayOpenApiDocs(controllerUrl, dataplaneUrl) {
|
|
|
290
303
|
* @param {Object} [dataplaneInfo] - Optional dataplane URL and health
|
|
291
304
|
* @param {string|null} [dataplaneInfo.url] - Dataplane URL
|
|
292
305
|
* @param {boolean} [dataplaneInfo.connected] - Whether dataplane is reachable
|
|
306
|
+
* @param {string|undefined} [dataplaneInfo.dataplaneVersion]
|
|
307
|
+
* @param {string|undefined} [dataplaneInfo.minBuilderCliVersion]
|
|
308
|
+
* @param {string} [dataplaneInfo.cliVersion]
|
|
309
|
+
* @param {boolean} [dataplaneInfo.compatible]
|
|
293
310
|
*/
|
|
294
311
|
function displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo) {
|
|
295
312
|
logger.log(chalk.bold('\nš Authentication Status\n'));
|
|
@@ -308,18 +325,61 @@ function displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo) {
|
|
|
308
325
|
|
|
309
326
|
if (tokenInfo.authenticated && dataplaneInfo) {
|
|
310
327
|
displayDataplaneSection(dataplaneInfo.url, dataplaneInfo.connected);
|
|
328
|
+
displayDataplaneVersionSection({
|
|
329
|
+
connected: dataplaneInfo.connected,
|
|
330
|
+
dataplaneVersion: dataplaneInfo.dataplaneVersion,
|
|
331
|
+
minBuilderCliVersion: dataplaneInfo.minBuilderCliVersion,
|
|
332
|
+
cliVersion: dataplaneInfo.cliVersion,
|
|
333
|
+
compatible: dataplaneInfo.compatible
|
|
334
|
+
});
|
|
335
|
+
if (dataplaneInfo.minBuilderCliVersion && dataplaneInfo.compatible === false) {
|
|
336
|
+
displayCliUpgradeRequired({
|
|
337
|
+
required: dataplaneInfo.minBuilderCliVersion,
|
|
338
|
+
installed: dataplaneInfo.cliVersion
|
|
339
|
+
});
|
|
340
|
+
}
|
|
311
341
|
}
|
|
312
342
|
|
|
313
343
|
logger.log('');
|
|
314
344
|
}
|
|
315
345
|
|
|
346
|
+
/**
|
|
347
|
+
* Resolve the dataplane block for auth status (URL, reachability, versions,
|
|
348
|
+
* compatibility). Returns null when no dataplane is discovered.
|
|
349
|
+
*
|
|
350
|
+
* @async
|
|
351
|
+
* @function buildDataplaneInfo
|
|
352
|
+
* @param {string} controllerUrl
|
|
353
|
+
* @param {string} environment
|
|
354
|
+
* @param {Object} authConfig - Bearer auth config built from a valid token
|
|
355
|
+
* @returns {Promise<Object|null>}
|
|
356
|
+
*/
|
|
357
|
+
async function buildDataplaneInfo(controllerUrl, environment, authConfig) {
|
|
358
|
+
const dataplaneUrl = await resolveDataplaneUrlSilent(controllerUrl, environment, authConfig);
|
|
359
|
+
if (!dataplaneUrl) {
|
|
360
|
+
return { url: null, connected: false };
|
|
361
|
+
}
|
|
362
|
+
const connected = await checkDataplaneHealth(dataplaneUrl, 5000);
|
|
363
|
+
const versionInfo = connected
|
|
364
|
+
? await refreshDataplaneVersionInfo(controllerUrl, dataplaneUrl)
|
|
365
|
+
: await loadCachedVersionInfo(controllerUrl);
|
|
366
|
+
return {
|
|
367
|
+
url: dataplaneUrl,
|
|
368
|
+
connected,
|
|
369
|
+
dataplaneVersion: versionInfo.dataplaneVersion,
|
|
370
|
+
minBuilderCliVersion: versionInfo.minBuilderCliVersion,
|
|
371
|
+
cliVersion: versionInfo.cliVersion,
|
|
372
|
+
compatible: versionInfo.compatible
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
316
376
|
/**
|
|
317
377
|
* Handle auth status command
|
|
318
378
|
* Controller and environment come from config.yaml (set via aifabrix login or aifabrix auth config).
|
|
319
379
|
* @async
|
|
320
380
|
* @function handleAuthStatus
|
|
321
381
|
* @param {Object} options - Command options
|
|
322
|
-
* @param {boolean} [options.validate] - If true, exit with code 1 when not authenticated
|
|
382
|
+
* @param {boolean} [options.validate] - If true, exit with code 1 when not authenticated, or code 3 when CLI is older than dataplane minimum
|
|
323
383
|
* @returns {Promise<void>} Resolves when status is displayed
|
|
324
384
|
*/
|
|
325
385
|
async function handleAuthStatus(options = {}) {
|
|
@@ -338,15 +398,19 @@ async function handleAuthStatus(options = {}) {
|
|
|
338
398
|
let dataplaneInfo = null;
|
|
339
399
|
if (tokenInfo && tokenInfo.authenticated && tokenInfo.token) {
|
|
340
400
|
const authConfig = { type: 'bearer', token: tokenInfo.token };
|
|
341
|
-
|
|
342
|
-
const connected = dataplaneUrl ? await checkDataplaneHealth(dataplaneUrl, 5000) : false;
|
|
343
|
-
dataplaneInfo = { url: dataplaneUrl, connected };
|
|
401
|
+
dataplaneInfo = await buildDataplaneInfo(controllerUrl, environment, authConfig);
|
|
344
402
|
}
|
|
345
403
|
|
|
346
404
|
displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo);
|
|
347
405
|
|
|
348
|
-
if (options.validate
|
|
349
|
-
|
|
406
|
+
if (options.validate) {
|
|
407
|
+
if (!tokenInfo || !tokenInfo.authenticated) {
|
|
408
|
+
process.exit(EXIT_NOT_AUTHENTICATED);
|
|
409
|
+
}
|
|
410
|
+
if (dataplaneInfo && dataplaneInfo.minBuilderCliVersion && dataplaneInfo.compatible === false) {
|
|
411
|
+
process.exit(EXIT_CLI_VERSION_INCOMPATIBLE);
|
|
412
|
+
}
|
|
413
|
+
process.exit(EXIT_OK);
|
|
350
414
|
}
|
|
351
415
|
}
|
|
352
416
|
|
|
@@ -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 };
|