@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
package/lib/cli/setup-utility.js
CHANGED
|
@@ -15,40 +15,7 @@ const logger = require('../utils/logger');
|
|
|
15
15
|
const { handleCommandError, logOfflinePathWhenType } = require('../utils/cli-utils');
|
|
16
16
|
const { detectAppType, getDeployJsonPath, getResolveAppPath } = require('../utils/paths');
|
|
17
17
|
const { setupResolveCommand } = require('./setup-utility-resolve');
|
|
18
|
-
|
|
19
|
-
const JSON_HELP_AFTER = `
|
|
20
|
-
Example:
|
|
21
|
-
$ aifabrix json myapp
|
|
22
|
-
Generates *-deploy.json (or application-schema.json) for commit before deploy.
|
|
23
|
-
`;
|
|
24
|
-
|
|
25
|
-
const VALIDATE_HELP_AFTER = `
|
|
26
|
-
Examples:
|
|
27
|
-
$ aifabrix validate myapp
|
|
28
|
-
$ aifabrix validate myapp --cert-sync
|
|
29
|
-
$ aifabrix validate --integration
|
|
30
|
-
$ aifabrix validate --builder
|
|
31
|
-
`;
|
|
32
|
-
|
|
33
|
-
const REPAIR_HELP_AFTER = `
|
|
34
|
-
Examples:
|
|
35
|
-
$ aifabrix repair hubspot-demo
|
|
36
|
-
Align manifest, system/datasource files, RBAC extract, env.template, and deploy JSON under integration/<systemKey>/.
|
|
37
|
-
|
|
38
|
-
$ aifabrix repair hubspot-demo --dry-run
|
|
39
|
-
Show what would change without writing files.
|
|
40
|
-
|
|
41
|
-
$ aifabrix repair hubspot-demo --auth oauth2
|
|
42
|
-
Set authentication method; updates the system file and env.template (oauth2, aad, apikey, basic, ā¦).
|
|
43
|
-
|
|
44
|
-
$ aifabrix repair hubspot-demo --rbac --expose --sync --test
|
|
45
|
-
Optional datasource fixes: RBAC roles/permissions, exposed.schema from attributes, default sync block, testPayload stubs.
|
|
46
|
-
|
|
47
|
-
$ aifabrix repair hubspot-demo --doc
|
|
48
|
-
Regenerate README.md from the current deployment manifest only (other drift fixes unchanged).
|
|
49
|
-
|
|
50
|
-
Before overwriting files, repair writes timestamped backups under integration/<systemKey>/backup/ (same as datasource capability copy). Use --no-backup to skip.
|
|
51
|
-
`;
|
|
18
|
+
const { JSON_HELP_AFTER, VALIDATE_HELP_AFTER, REPAIR_HELP_AFTER } = require('./setup-utility-help-after');
|
|
52
19
|
|
|
53
20
|
/**
|
|
54
21
|
* Resolve app path and type for split-json (integration first, then builder).
|
|
@@ -122,7 +89,7 @@ function logSplitJsonResult(result) {
|
|
|
122
89
|
}
|
|
123
90
|
|
|
124
91
|
function setupJsonCommand(program) {
|
|
125
|
-
program.command('json <
|
|
92
|
+
program.command('json <appKey|systemKey>')
|
|
126
93
|
.description('Write deployment JSON to disk for version control')
|
|
127
94
|
.addHelpText('after', JSON_HELP_AFTER)
|
|
128
95
|
.action(async(appName, options) => {
|
|
@@ -156,7 +123,7 @@ function setupJsonCommand(program) {
|
|
|
156
123
|
}
|
|
157
124
|
|
|
158
125
|
function setupSplitJsonCommand(program) {
|
|
159
|
-
program.command('split-json <
|
|
126
|
+
program.command('split-json <appKey|systemKey>')
|
|
160
127
|
.description('Split deploy JSON into env.template, application.yaml, rbac, README, ā¦')
|
|
161
128
|
.option('-o, --output <dir>', 'Output directory for component files (defaults to same directory as JSON)')
|
|
162
129
|
.action(async(appName, options) => {
|
|
@@ -263,32 +230,54 @@ function setupRepairCommand(program) {
|
|
|
263
230
|
});
|
|
264
231
|
}
|
|
265
232
|
|
|
233
|
+
async function resolveConvertTargetFormat(options) {
|
|
234
|
+
const config = require('../core/config');
|
|
235
|
+
const effectiveFormat = options.format || (await config.getFormat());
|
|
236
|
+
if (!effectiveFormat) {
|
|
237
|
+
throw new Error(
|
|
238
|
+
'Option --format is required and must be \'json\' or \'yaml\' (or set default with aifabrix dev set-format)'
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
const normalized = effectiveFormat.trim().toLowerCase();
|
|
242
|
+
if (normalized !== 'json' && normalized !== 'yaml') {
|
|
243
|
+
throw new Error('Option --format must be \'json\' or \'yaml\'');
|
|
244
|
+
}
|
|
245
|
+
return normalized;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function logConvertCommandResults(converted, deleted) {
|
|
249
|
+
logger.log(formatSuccessParagraph('Convert complete.'));
|
|
250
|
+
converted.forEach((p) => logger.log(` ⢠${p}`));
|
|
251
|
+
if (deleted.length > 0) {
|
|
252
|
+
logger.log(chalk.gray(' Removed old files:'));
|
|
253
|
+
deleted.forEach((p) => logger.log(chalk.gray(` ${p}`)));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async function runConvertCommandForApp(appName, options) {
|
|
258
|
+
const normalized = await resolveConvertTargetFormat(options);
|
|
259
|
+
const { isProtectionScope } = require('../protection/scope');
|
|
260
|
+
if (isProtectionScope(appName)) {
|
|
261
|
+
const { runConvertProtectionBatch } = require('../protection/convert-batch');
|
|
262
|
+
const { converted, deleted } = await runConvertProtectionBatch(normalized, {
|
|
263
|
+
force: options.force
|
|
264
|
+
});
|
|
265
|
+
logConvertCommandResults(converted, deleted);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const { runConvert } = require('../commands/convert');
|
|
269
|
+
const { converted, deleted } = await runConvert(appName, { format: normalized, force: options.force });
|
|
270
|
+
logConvertCommandResults(converted, deleted);
|
|
271
|
+
}
|
|
272
|
+
|
|
266
273
|
function setupConvertCommand(program) {
|
|
267
|
-
program.command('convert <
|
|
268
|
-
.description('Convert
|
|
274
|
+
program.command('convert <appKey|systemKey>')
|
|
275
|
+
.description('Convert config files between JSON and YAML (builder/<appKey>/ or integration/<systemKey>/)')
|
|
269
276
|
.option('--format <format>', 'Target format: json | yaml (required unless config format is set)')
|
|
270
277
|
.option('-f, --force', 'Skip confirmation prompt')
|
|
271
278
|
.action(async(appName, options) => {
|
|
272
279
|
try {
|
|
273
|
-
|
|
274
|
-
const effectiveFormat = options.format || (await config.getFormat());
|
|
275
|
-
if (!effectiveFormat) {
|
|
276
|
-
throw new Error(
|
|
277
|
-
'Option --format is required and must be \'json\' or \'yaml\' (or set default with aifabrix dev set-format)'
|
|
278
|
-
);
|
|
279
|
-
}
|
|
280
|
-
const normalized = effectiveFormat.trim().toLowerCase();
|
|
281
|
-
if (normalized !== 'json' && normalized !== 'yaml') {
|
|
282
|
-
throw new Error('Option --format must be \'json\' or \'yaml\'');
|
|
283
|
-
}
|
|
284
|
-
const { runConvert } = require('../commands/convert');
|
|
285
|
-
const { converted, deleted } = await runConvert(appName, { format: normalized, force: options.force });
|
|
286
|
-
logger.log(formatSuccessParagraph('Convert complete.'));
|
|
287
|
-
converted.forEach(p => logger.log(` ⢠${p}`));
|
|
288
|
-
if (deleted.length > 0) {
|
|
289
|
-
logger.log(chalk.gray(' Removed old files:'));
|
|
290
|
-
deleted.forEach(p => logger.log(chalk.gray(` ${p}`)));
|
|
291
|
-
}
|
|
280
|
+
await runConvertCommandForApp(appName, options);
|
|
292
281
|
} catch (error) {
|
|
293
282
|
handleCommandError(error, 'convert');
|
|
294
283
|
process.exit(1);
|
|
@@ -297,8 +286,8 @@ function setupConvertCommand(program) {
|
|
|
297
286
|
}
|
|
298
287
|
|
|
299
288
|
function setupShowCommand(program) {
|
|
300
|
-
program.command('show <
|
|
301
|
-
.description('Show app from local tree (default) or controller (--online)')
|
|
289
|
+
program.command('show <appKey|systemKey>')
|
|
290
|
+
.description('Show builder app or external system from local tree (default) or controller (--online)')
|
|
302
291
|
.option('--online', 'Fetch application data from the controller')
|
|
303
292
|
.option('--json', 'Output as JSON')
|
|
304
293
|
.option(
|
|
@@ -368,51 +357,80 @@ async function runValidateBatchBranch(validate, opts) {
|
|
|
368
357
|
return true;
|
|
369
358
|
}
|
|
370
359
|
|
|
360
|
+
async function runProtectionValidateBranch(appOrFile, opts) {
|
|
361
|
+
const { validateProtectionBatchCommand } = require('../protection/validate-batch');
|
|
362
|
+
const code = await validateProtectionBatchCommand(
|
|
363
|
+
{
|
|
364
|
+
env: opts.env,
|
|
365
|
+
json: (opts.format || '').toLowerCase() === 'json',
|
|
366
|
+
warningsAsErrors: opts.warningsAsErrors === true,
|
|
367
|
+
simulate: opts.simulate === true,
|
|
368
|
+
verbose: opts.verbose === true
|
|
369
|
+
},
|
|
370
|
+
logger
|
|
371
|
+
);
|
|
372
|
+
if (code !== 0) {
|
|
373
|
+
process.exit(code);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function buildValidateJsonPayload(result, appOrFile) {
|
|
378
|
+
let payload = result;
|
|
379
|
+
try {
|
|
380
|
+
if (result?.appPath && appOrFile && typeof appOrFile === 'string') {
|
|
381
|
+
if (!(fs.existsSync(appOrFile) && fs.statSync(appOrFile).isFile())) {
|
|
382
|
+
const { getManifestSourcePayload } = require('../utils/manifest-source-emit');
|
|
383
|
+
payload = { ...result, manifestSource: getManifestSourcePayload(appOrFile, result.appPath) };
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
} catch {
|
|
387
|
+
/* keep plain result */
|
|
388
|
+
}
|
|
389
|
+
return payload;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function displaySingleValidateResult(appOrFile, result, outFormat, validate) {
|
|
393
|
+
emitManifestAfterValidateIfApplicable(appOrFile, result, outFormat);
|
|
394
|
+
if (outFormat === 'json') {
|
|
395
|
+
logger.log(JSON.stringify(buildValidateJsonPayload(result, appOrFile), null, 2));
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
validate.displayValidationResults(result);
|
|
399
|
+
}
|
|
400
|
+
|
|
371
401
|
async function runValidateCommand(appOrFile, options) {
|
|
372
402
|
const validate = require('../validation/validate');
|
|
373
403
|
const opts = options.opts ? options.opts() : options;
|
|
404
|
+
const { isProtectionScope } = require('../protection/scope');
|
|
405
|
+
if (isProtectionScope(appOrFile)) {
|
|
406
|
+
await runProtectionValidateBranch(appOrFile, opts);
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
374
409
|
if (await runValidateBatchBranch(validate, opts)) {
|
|
375
410
|
return;
|
|
376
411
|
}
|
|
377
|
-
|
|
378
412
|
const outFormat = (opts.format || 'default').toLowerCase();
|
|
379
|
-
|
|
380
413
|
if (!appOrFile || typeof appOrFile !== 'string') {
|
|
381
414
|
logger.log(chalk.red('App name or file path is required, or use --integration / --builder'));
|
|
382
415
|
process.exit(1);
|
|
383
416
|
}
|
|
384
|
-
|
|
385
417
|
const result = await validate.validateAppOrFile(appOrFile, {
|
|
386
418
|
...opts,
|
|
387
419
|
certSync: opts.certSync === true
|
|
388
420
|
});
|
|
389
|
-
|
|
390
|
-
if (outFormat === 'json') {
|
|
391
|
-
let payload = result;
|
|
392
|
-
try {
|
|
393
|
-
if (result?.appPath && appOrFile && typeof appOrFile === 'string') {
|
|
394
|
-
if (!(fs.existsSync(appOrFile) && fs.statSync(appOrFile).isFile())) {
|
|
395
|
-
const { getManifestSourcePayload } = require('../utils/manifest-source-emit');
|
|
396
|
-
payload = { ...result, manifestSource: getManifestSourcePayload(appOrFile, result.appPath) };
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
} catch {
|
|
400
|
-
/* keep plain result */
|
|
401
|
-
}
|
|
402
|
-
logger.log(JSON.stringify(payload, null, 2));
|
|
403
|
-
} else {
|
|
404
|
-
validate.displayValidationResults(result);
|
|
405
|
-
}
|
|
421
|
+
displaySingleValidateResult(appOrFile, result, outFormat, validate);
|
|
406
422
|
if (!result.valid) process.exit(1);
|
|
407
423
|
}
|
|
408
424
|
|
|
409
425
|
function setupValidateDiffCommands(program) {
|
|
410
|
-
program.command('validate [
|
|
411
|
-
.description('Validate
|
|
426
|
+
program.command('validate [appKey|systemKey|file]')
|
|
427
|
+
.description('Validate appKey, systemKey, file path, .protection batch, or all under integration/ and builder/')
|
|
412
428
|
.addHelpText('after', VALIDATE_HELP_AFTER)
|
|
413
429
|
.option('--format <format>', 'Output format: json | default (human-readable)')
|
|
414
430
|
.option('--integration', 'Validate all applications under integration/')
|
|
415
431
|
.option('--builder', 'Validate all applications under builder/')
|
|
432
|
+
.option('--warnings-as-errors', 'For .protection: pass strict=true to dataplane validate')
|
|
433
|
+
.option('--simulate', 'For .protection: run simulate after validate')
|
|
416
434
|
.option(
|
|
417
435
|
'--cert-sync',
|
|
418
436
|
'After successful validation of an external integration, refresh the system file certification block from the dataplane (requires login)'
|
|
@@ -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
|
|