@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
package/lib/cli/infra-guided.js
CHANGED
|
@@ -23,6 +23,9 @@ const { handleLogin } = require('../commands/login');
|
|
|
23
23
|
const healthCheck = require('../utils/health-check');
|
|
24
24
|
const { prepareUrlsLocalRegistryForUpPlatform } = require('../commands/up-common');
|
|
25
25
|
const { assertDevInfraUp } = require('../commands/dev-infra-gate');
|
|
26
|
+
const {
|
|
27
|
+
emitSystemBuilderAppManifestLineIfTTY
|
|
28
|
+
} = require('../utils/manifest-source-emit');
|
|
26
29
|
|
|
27
30
|
const SEPARATOR = '────────────────────────────────────────';
|
|
28
31
|
|
|
@@ -67,22 +70,23 @@ async function hasErrorLogs(appName, opts = {}) {
|
|
|
67
70
|
|
|
68
71
|
async function validateAppErrorLogs(appNames) {
|
|
69
72
|
const names = Array.isArray(appNames) ? appNames : [];
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return { name, hasErrors: false };
|
|
73
|
+
const bad = [];
|
|
74
|
+
for (const name of names) {
|
|
75
|
+
try {
|
|
76
|
+
const hasErrors = await hasErrorLogs(name, { tailLines: 300 });
|
|
77
|
+
if (hasErrors) {
|
|
78
|
+
bad.push(name);
|
|
77
79
|
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
} catch {
|
|
81
|
+
// ignore per-app log failures
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (bad.length === 0) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
83
87
|
logger.log(chalk.yellow('⚠ Some services reported error logs'));
|
|
84
|
-
for (const
|
|
85
|
-
logger.log(chalk.gray(` Run: aifabrix logs ${
|
|
88
|
+
for (const name of bad) {
|
|
89
|
+
logger.log(chalk.gray(` Run: aifabrix logs ${name} -l error`));
|
|
86
90
|
}
|
|
87
91
|
logger.log('');
|
|
88
92
|
}
|
|
@@ -158,7 +162,7 @@ async function computeAppBaseUrl(appName) {
|
|
|
158
162
|
return joinUrlPath(publicBase, mount);
|
|
159
163
|
}
|
|
160
164
|
|
|
161
|
-
// No Traefik front-door routing: publicBase
|
|
165
|
+
// No Traefik front-door routing: publicBase is localhost + published port unless Traefik/proxy opts into remote.
|
|
162
166
|
return String(publicBase).replace(/\/+$/, '');
|
|
163
167
|
}
|
|
164
168
|
|
|
@@ -226,7 +230,9 @@ async function getInfraHostAndPorts() {
|
|
|
226
230
|
const developerId = await config.getDeveloperId();
|
|
227
231
|
const idNum = typeof developerId === 'string' ? parseInt(developerId, 10) : developerId;
|
|
228
232
|
const ports = devConfig.getDevPorts(idNum);
|
|
229
|
-
const
|
|
233
|
+
const cfg = await config.getConfig();
|
|
234
|
+
const traefikOn = Boolean(cfg && cfg.traefik === true);
|
|
235
|
+
const remoteServer = traefikOn ? await config.getRemoteServer() : null;
|
|
230
236
|
const host = resolveInfraHost(remoteServer);
|
|
231
237
|
return { idNum, ports, host };
|
|
232
238
|
}
|
|
@@ -308,11 +314,13 @@ async function runGuidedUpDataplane(options, handleUpDataplane) {
|
|
|
308
314
|
await runGuidedAuthStep(handleLogin);
|
|
309
315
|
|
|
310
316
|
logger.log('');
|
|
317
|
+
emitSystemBuilderAppManifestLineIfTTY(logger, 'dataplane');
|
|
311
318
|
const dpSpin = startSpinner('Starting Dataplane...');
|
|
312
319
|
await withMutedLogger(() =>
|
|
313
320
|
handleUpDataplane({ ...options, platformInstall: true, skipInfraCheck: true })
|
|
314
321
|
);
|
|
315
322
|
stopSpinnerSuccess(dpSpin, 'Dataplane ready');
|
|
323
|
+
await refreshDataplaneVersionAfterPlatformInstall();
|
|
316
324
|
await validateAppErrorLogs(['dataplane']);
|
|
317
325
|
await logDataplaneReadyFooter();
|
|
318
326
|
}
|
|
@@ -346,6 +354,7 @@ function logGuidedPlatformSetupHeader() {
|
|
|
346
354
|
logger.log('');
|
|
347
355
|
logger.log(title('AI Fabrix Platform Setup'));
|
|
348
356
|
logger.log(SEPARATOR);
|
|
357
|
+
logger.log(chalk.gray('This may take a few minutes...'));
|
|
349
358
|
logger.log('');
|
|
350
359
|
}
|
|
351
360
|
|
|
@@ -353,43 +362,68 @@ async function runGuidedAuthStep(handleLogin) {
|
|
|
353
362
|
const spin = startSpinner('Authenticating...');
|
|
354
363
|
try {
|
|
355
364
|
const controllerUrl = await resolveControllerUrl();
|
|
356
|
-
await handleLogin({
|
|
365
|
+
await handleLogin({
|
|
366
|
+
method: 'device',
|
|
367
|
+
controller: controllerUrl,
|
|
368
|
+
environment: 'dev',
|
|
369
|
+
compact: true,
|
|
370
|
+
// Dataplane is not up yet during guided platform/dataplane install; refresh after it starts.
|
|
371
|
+
skipDataplaneVersionRefresh: true
|
|
372
|
+
});
|
|
357
373
|
} catch (authErr) {
|
|
358
374
|
if (spin) spin.fail('Authentication failed');
|
|
359
375
|
logger.error(formatBlockingError('Authentication failed'));
|
|
360
376
|
logger.log(chalk.gray('\nRun:\n af login\n\nThen retry:\n af up-platform\n'));
|
|
361
377
|
throw authErr;
|
|
362
378
|
}
|
|
363
|
-
// Compact device-login
|
|
364
|
-
|
|
379
|
+
// Compact device-login prints "Authentication successful"; close the step spinner cleanly.
|
|
380
|
+
stopSpinnerSuccess(spin, 'Authenticated');
|
|
365
381
|
}
|
|
366
382
|
|
|
367
|
-
async function
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
383
|
+
async function refreshDataplaneVersionAfterPlatformInstall() {
|
|
384
|
+
try {
|
|
385
|
+
const { tryRefreshDataplaneVersionAfterLogin } = require('../commands/auth-status-dataplane-version');
|
|
386
|
+
const controllerUrl = await resolveControllerUrl();
|
|
387
|
+
await tryRefreshDataplaneVersionAfterLogin(controllerUrl, {});
|
|
388
|
+
} catch {
|
|
389
|
+
// best-effort only
|
|
371
390
|
}
|
|
391
|
+
}
|
|
372
392
|
|
|
373
|
-
|
|
374
|
-
|
|
393
|
+
async function runGuidedKeycloakAndMisoControllerPhase(options, handleUpMiso) {
|
|
394
|
+
emitSystemBuilderAppManifestLineIfTTY(logger, 'keycloak');
|
|
375
395
|
const kcSpin = startSpinner('Starting Keycloak...');
|
|
376
396
|
await withMutedLogger(() => handleUpMiso({ ...options, platformInstall: true }));
|
|
377
397
|
stopSpinnerSuccess(kcSpin, 'Keycloak ready');
|
|
378
398
|
logger.log('');
|
|
379
|
-
|
|
399
|
+
emitSystemBuilderAppManifestLineIfTTY(logger, 'miso-controller');
|
|
380
400
|
const mcSpin = startSpinner('Starting Miso Controller...');
|
|
381
401
|
await waitForAppReady('miso-controller', { timeoutSeconds: 120 });
|
|
382
402
|
stopSpinnerSuccess(mcSpin, 'Miso Controller ready');
|
|
383
403
|
logger.log('');
|
|
404
|
+
}
|
|
384
405
|
|
|
385
|
-
|
|
386
|
-
|
|
406
|
+
async function runGuidedDataplaneInstallPhase(options, handleUpDataplane) {
|
|
387
407
|
logger.log('');
|
|
408
|
+
emitSystemBuilderAppManifestLineIfTTY(logger, 'dataplane');
|
|
388
409
|
const dpSpin = startSpinner('Starting Dataplane...');
|
|
389
410
|
await withMutedLogger(() =>
|
|
390
411
|
handleUpDataplane({ ...options, platformInstall: true, skipInfraCheck: true })
|
|
391
412
|
);
|
|
392
413
|
stopSpinnerSuccess(dpSpin, 'Dataplane ready');
|
|
414
|
+
await refreshDataplaneVersionAfterPlatformInstall();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
async function runGuidedUpPlatform(options, handleUpMiso, handleUpDataplane, handleLogin, forceCleanSummary = null) {
|
|
418
|
+
logGuidedPlatformSetupHeader();
|
|
419
|
+
if (forceCleanSummary && forceCleanSummary.forceSummary) {
|
|
420
|
+
logUpPlatformForceCleanSummary(forceCleanSummary.forceSummary, forceCleanSummary.cleanedApps);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
await withMutedLogger(() => prepareUrlsLocalRegistryForUpPlatform());
|
|
424
|
+
await runGuidedKeycloakAndMisoControllerPhase(options, handleUpMiso);
|
|
425
|
+
await runGuidedAuthStep(handleLogin);
|
|
426
|
+
await runGuidedDataplaneInstallPhase(options, handleUpDataplane);
|
|
393
427
|
await validateAppErrorLogs(['miso-controller', 'dataplane']);
|
|
394
428
|
await logPlatformReadyFooter();
|
|
395
429
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared completion hook for infra/platform CLI commands (installation.log).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview installation.log CLI helper
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 2.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const config = require('../core/config');
|
|
12
|
+
const installationLog = require('../utils/installation-log');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {Object} params
|
|
16
|
+
* @param {string} params.command
|
|
17
|
+
* @param {Object} params.options
|
|
18
|
+
* @param {Date} params.startedAt
|
|
19
|
+
* @param {'success'|'failure'} params.outcome
|
|
20
|
+
* @param {Error} [params.error]
|
|
21
|
+
* @param {string[]} [params.platformAppList]
|
|
22
|
+
* @param {Object} [params.cleanup]
|
|
23
|
+
* @param {boolean} [params.upPlatformForce]
|
|
24
|
+
* @param {boolean} [params.omitInfraSection]
|
|
25
|
+
* @returns {Promise<void>}
|
|
26
|
+
*/
|
|
27
|
+
async function recordInfraInstallationCommand(params) {
|
|
28
|
+
const {
|
|
29
|
+
command,
|
|
30
|
+
options,
|
|
31
|
+
startedAt,
|
|
32
|
+
outcome,
|
|
33
|
+
error,
|
|
34
|
+
platformAppList,
|
|
35
|
+
cleanup,
|
|
36
|
+
upPlatformForce,
|
|
37
|
+
omitInfraSection
|
|
38
|
+
} = params;
|
|
39
|
+
|
|
40
|
+
const completedAt = new Date();
|
|
41
|
+
let cfg = {};
|
|
42
|
+
try {
|
|
43
|
+
cfg = await config.getConfig();
|
|
44
|
+
} catch {
|
|
45
|
+
cfg = {};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
await installationLog.appendInstallationRecord({
|
|
50
|
+
command,
|
|
51
|
+
outcome,
|
|
52
|
+
startedAt,
|
|
53
|
+
completedAt,
|
|
54
|
+
options,
|
|
55
|
+
infra: !omitInfraSection && cfg ? { cfg, options } : undefined,
|
|
56
|
+
platformAppList,
|
|
57
|
+
cleanup,
|
|
58
|
+
upPlatformForce: upPlatformForce === true,
|
|
59
|
+
configExtra: {
|
|
60
|
+
controllerUrl: await installationLog.resolveControllerUrlForLog(),
|
|
61
|
+
adminEmail: await installationLog.resolveAdminEmailPresence()
|
|
62
|
+
},
|
|
63
|
+
error,
|
|
64
|
+
errorCode: error && error.code ? String(error.code) : undefined
|
|
65
|
+
});
|
|
66
|
+
} catch {
|
|
67
|
+
// never block CLI on log failure
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
recordInfraInstallationCommand
|
|
73
|
+
};
|
|
@@ -56,12 +56,60 @@ Examples:
|
|
|
56
56
|
Notes:
|
|
57
57
|
- To run E2E for one datasource, use:
|
|
58
58
|
aifabrix datasource test-e2e <datasourceKey>
|
|
59
|
-
- External integration: local system and datasource files are published to the dataplane before E2E (same as upload). Use --no-sync to exercise only config already deployed.
|
|
59
|
+
- External integration: local system and datasource files are published to the dataplane before E2E (same as upload). Use --no-sync to exercise only config already deployed.
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
const IDENTITY_HELP_AFTER = `
|
|
63
|
+
Examples:
|
|
64
|
+
# Bulk seed from demo users.csv (test-protection prefix) + sync + cache purge
|
|
65
|
+
$ aifabrix identity apply --file ./users.csv --filter-prefix test-protection -e dev --sync --purge-cache
|
|
66
|
+
$ aifabrix identity sync -e dev --purge-cache
|
|
67
|
+
$ aifabrix identity cache clear
|
|
68
|
+
|
|
69
|
+
# Single user / group
|
|
70
|
+
$ aifabrix identity user create --email alice@example.com --first-name Alice --last-name HR
|
|
71
|
+
$ aifabrix identity group create --name test-protection-sales-fi --description "Sales Finland"
|
|
72
|
+
|
|
73
|
+
Notes:
|
|
74
|
+
- Requires aifabrix login (controller token). See docs/commands/identity-management.md.
|
|
75
|
+
- Prefer identity apply over SQL in tests/fixtures/protection/optional-dev-identity-dataplane.sql.
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
const TEST_GOVERNANCE_HELP_AFTER = `
|
|
79
|
+
Examples:
|
|
80
|
+
# External system — ABAC visibility acceptance (governance scenario pack)
|
|
81
|
+
$ aifabrix test-governance test-protection
|
|
82
|
+
$ aifabrix test-governance test-protection --pack scenarios/test-protection-v1.yaml
|
|
83
|
+
$ aifabrix test-governance test-protection -v --no-sync
|
|
84
|
+
$ aifabrix test-governance test-protection --scenario country-isolation-maria-fi --json
|
|
85
|
+
|
|
86
|
+
Notes:
|
|
87
|
+
- Separate from test-e2e (vendor connectivity). Does not call external vendor APIs.
|
|
88
|
+
- Load baseline fixtures first (datasource load, protection upload) — not auto-run by this command.
|
|
89
|
+
- Default pack: integration/<systemKey>/scenarios/default.yaml or <systemKey>-v1.yaml
|
|
90
|
+
- Requires governance:evaluate on the operator token (see permissions.md).
|
|
91
|
+
`;
|
|
92
|
+
|
|
93
|
+
const TEST_TRUST_HELP_AFTER = `
|
|
94
|
+
Examples:
|
|
95
|
+
# External system — semantic trust for every datasource (dataplane 404.5)
|
|
96
|
+
$ aifabrix test-trust hubspot
|
|
97
|
+
$ aifabrix test-trust hubspot -v --revalidate
|
|
98
|
+
$ aifabrix test-trust hubspot --no-sync
|
|
99
|
+
$ aifabrix test-trust hubspot --summary --timeout 120000
|
|
100
|
+
|
|
101
|
+
Notes:
|
|
102
|
+
- For one datasource: aifabrix datasource test-trust <datasourceKey>
|
|
103
|
+
- Does not call external APIs (use test-e2e for live proof).
|
|
104
|
+
- Local integration files are published before run unless --no-sync.
|
|
60
105
|
`;
|
|
61
106
|
|
|
62
107
|
module.exports = {
|
|
63
108
|
TEST_HELP_AFTER,
|
|
64
109
|
TEST_INTEGRATION_HELP_AFTER,
|
|
65
|
-
TEST_E2E_HELP_AFTER
|
|
110
|
+
TEST_E2E_HELP_AFTER,
|
|
111
|
+
TEST_TRUST_HELP_AFTER,
|
|
112
|
+
TEST_GOVERNANCE_HELP_AFTER,
|
|
113
|
+
IDENTITY_HELP_AFTER
|
|
66
114
|
};
|
|
67
115
|
|
package/lib/cli/setup-app.js
CHANGED
|
@@ -16,14 +16,23 @@ const { setupInstallTestE2eLintCommands } = require('./setup-app.test-commands')
|
|
|
16
16
|
|
|
17
17
|
const CREATE_HELP_AFTER = `
|
|
18
18
|
Examples:
|
|
19
|
+
# Builder app → builder/<appKey>/
|
|
19
20
|
$ aifabrix create myapi --type webapp -l typescript
|
|
20
|
-
$ aifabrix create
|
|
21
|
+
$ aifabrix create mysvc --type api -l python
|
|
22
|
+
|
|
23
|
+
# External system → integration/<systemKey>/ (default --type external)
|
|
24
|
+
$ aifabrix create hubspot --wizard
|
|
25
|
+
$ aifabrix create mycrm --type external --display-name "My CRM" --description "..." \\
|
|
26
|
+
--system-type openapi --auth-type oauth2 --entity-type recordStorage --datasources 1
|
|
27
|
+
|
|
28
|
+
Positional: appKey for builder types; systemKey for --type external (folder under integration/).
|
|
29
|
+
Prefer aifabrix wizard [systemKey] for guided external setup.
|
|
21
30
|
`;
|
|
22
31
|
|
|
23
32
|
const DEPLOY_HELP_AFTER = `
|
|
24
33
|
Examples:
|
|
25
|
-
$ aifabrix deploy myapp
|
|
26
|
-
$ aifabrix deploy
|
|
34
|
+
$ aifabrix deploy myapp # builder appKey → builder/myapp/
|
|
35
|
+
$ aifabrix deploy hubspot --local # systemKey → integration/hubspot/
|
|
27
36
|
`;
|
|
28
37
|
|
|
29
38
|
const PUSH_HELP_AFTER = `
|
|
@@ -133,8 +142,8 @@ async function handleCreateCommand(appName, options) {
|
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
function setupCreateCommand(program) {
|
|
136
|
-
program.command('create <
|
|
137
|
-
.description('
|
|
145
|
+
program.command('create <appKey|systemKey>')
|
|
146
|
+
.description('Create builder app (builder/<appKey>/) or external system (integration/<systemKey>/; --type, flags, or --wizard)')
|
|
138
147
|
.addHelpText('after', CREATE_HELP_AFTER)
|
|
139
148
|
.option('-p, --port <port>', 'Application port', '3000')
|
|
140
149
|
.option('-d, --database', 'Requires database')
|
|
@@ -148,7 +157,7 @@ function setupCreateCommand(program) {
|
|
|
148
157
|
.option('-g, --github', 'Generate GitHub Actions workflows')
|
|
149
158
|
.option('--github-steps <steps>', 'Extra GitHub workflow steps (comma-separated, e.g., npm,test)')
|
|
150
159
|
.option('--main-branch <branch>', 'Main branch name for workflows', 'main')
|
|
151
|
-
.option('--wizard', '
|
|
160
|
+
.option('--wizard', 'Run wizard for external system (systemKey → integration/<systemKey>/; same as aifabrix wizard)')
|
|
152
161
|
.option('--display-name <name>', 'External system display name')
|
|
153
162
|
.option('--description <desc>', 'External system description')
|
|
154
163
|
.option('--system-type <type>', 'External system type (openapi, mcp, custom)')
|
|
@@ -207,15 +216,25 @@ Examples:
|
|
|
207
216
|
$ aifabrix run myapp --env tst
|
|
208
217
|
$ aifabrix run myapp --tag v1.0.0
|
|
209
218
|
$ aifabrix run myapp --base
|
|
210
|
-
$ aifabrix run myapp --reload
|
|
211
|
-
|
|
212
|
-
|
|
219
|
+
$ aifabrix run myapp --reload
|
|
220
|
+
$ aifabrix run myapp --no-proxy # same as --proxy false: localhost for Docker declarative public URLs; saves applications.<app>.proxy: false`;
|
|
221
|
+
program.command('run <appKey>')
|
|
222
|
+
.description('Run builder app by appKey locally or on remote Docker host')
|
|
213
223
|
.option('-p, --port <port>', 'Override local port')
|
|
214
224
|
.option('-d, --debug', 'Enable debug output with detailed container information')
|
|
215
225
|
.option('-t, --tag <tag>', 'Image tag to run (e.g. v1.0.0); overrides application.yaml image.tag')
|
|
216
226
|
.option('-e, --env <env>', 'Environment: dev (default), tst, or pro', 'dev')
|
|
217
227
|
.option('--base', 'Use manifest base image only (skip local developer-scoped tag preference)')
|
|
218
228
|
.option('--reload', 'In dev: mount workspace into container (Mutagen only if docker-endpoint is a remote host)')
|
|
229
|
+
.option(
|
|
230
|
+
'--proxy',
|
|
231
|
+
'Use Traefik/front-door public URL hints when infra has Traefik and application.yaml enables frontDoorRouting (default: on)',
|
|
232
|
+
true
|
|
233
|
+
)
|
|
234
|
+
.option(
|
|
235
|
+
'--no-proxy',
|
|
236
|
+
'Docker declarative public url://* use localhost + published port (saves applications.<app>.proxy: false); overrides --proxy'
|
|
237
|
+
)
|
|
219
238
|
.addHelpText('after', runHelp)
|
|
220
239
|
.action(async(appName, options) => {
|
|
221
240
|
try {
|
|
@@ -228,8 +247,8 @@ Examples:
|
|
|
228
247
|
}
|
|
229
248
|
|
|
230
249
|
function setupBuildRunLogsDownCommands(program) {
|
|
231
|
-
program.command('build <
|
|
232
|
-
.description('Build Docker image (auto-detect runtime)')
|
|
250
|
+
program.command('build <appKey>')
|
|
251
|
+
.description('Build Docker image for builder appKey (auto-detect runtime)')
|
|
233
252
|
.option('-l, --language <lang>', 'Override language detection')
|
|
234
253
|
.option('-f, --force-template', 'Force rebuild from template')
|
|
235
254
|
.option('--no-cache', 'Full Docker rebuild (disable layer cache); use after Dockerfile or context fixes')
|
|
@@ -247,8 +266,8 @@ function setupBuildRunLogsDownCommands(program) {
|
|
|
247
266
|
|
|
248
267
|
registerRunCommand(program);
|
|
249
268
|
|
|
250
|
-
program.command('logs <
|
|
251
|
-
.description('Tail
|
|
269
|
+
program.command('logs <appKey>')
|
|
270
|
+
.description('Tail container logs for appKey (optional env summary; secrets masked)')
|
|
252
271
|
.option('-f', 'Follow log stream')
|
|
253
272
|
.option('-t, --tail <lines>', 'Number of lines (default: 100); 0 = full list', '100')
|
|
254
273
|
.option('-l, --level <level>', 'Show only logs at this level or above (debug|info|warn|error)')
|
|
@@ -265,8 +284,8 @@ function setupBuildRunLogsDownCommands(program) {
|
|
|
265
284
|
}
|
|
266
285
|
});
|
|
267
286
|
|
|
268
|
-
program.command('down-app <
|
|
269
|
-
.description('Stop and remove
|
|
287
|
+
program.command('down-app <appKey>')
|
|
288
|
+
.description('Stop and remove container for appKey (--volumes removes data volume)')
|
|
270
289
|
.option('--volumes', 'Remove application Docker volume')
|
|
271
290
|
.action(async(appName, options) => {
|
|
272
291
|
try {
|
|
@@ -280,8 +299,8 @@ function setupBuildRunLogsDownCommands(program) {
|
|
|
280
299
|
}
|
|
281
300
|
|
|
282
301
|
function setupShellTestStopCommands(program) {
|
|
283
|
-
program.command('stop <
|
|
284
|
-
.description('Alias for down-app: stop and remove container')
|
|
302
|
+
program.command('stop <appKey>')
|
|
303
|
+
.description('Alias for down-app: stop and remove container for appKey')
|
|
285
304
|
.option('--volumes', 'Remove application Docker volume')
|
|
286
305
|
.action(async(appName, options) => {
|
|
287
306
|
try {
|
|
@@ -293,8 +312,8 @@ function setupShellTestStopCommands(program) {
|
|
|
293
312
|
}
|
|
294
313
|
});
|
|
295
314
|
|
|
296
|
-
program.command('shell <
|
|
297
|
-
.description('Interactive shell in
|
|
315
|
+
program.command('shell <appKey>')
|
|
316
|
+
.description('Interactive shell in container for builder appKey')
|
|
298
317
|
.option('--env <env>', 'Environment (dev|tst); dev uses running container', 'dev')
|
|
299
318
|
.action(async(appName, options) => {
|
|
300
319
|
try {
|
|
@@ -308,8 +327,8 @@ function setupShellTestStopCommands(program) {
|
|
|
308
327
|
}
|
|
309
328
|
|
|
310
329
|
function setupDockerfileGenerateCommand(program) {
|
|
311
|
-
program.command('dockerfile <
|
|
312
|
-
.description('Generate Dockerfile from detected runtime')
|
|
330
|
+
program.command('dockerfile <appKey>')
|
|
331
|
+
.description('Generate Dockerfile for builder appKey from detected runtime')
|
|
313
332
|
.option('-l, --language <lang>', 'Override language detection')
|
|
314
333
|
.option('-f, --force', 'Overwrite existing Dockerfile')
|
|
315
334
|
.action(async(appName, options) => {
|
|
@@ -325,8 +344,8 @@ function setupDockerfileGenerateCommand(program) {
|
|
|
325
344
|
}
|
|
326
345
|
|
|
327
346
|
function setupPushDeployDockerfileCommands(program) {
|
|
328
|
-
program.command('push <
|
|
329
|
-
.description('Push image to Azure Container Registry')
|
|
347
|
+
program.command('push <appKey>')
|
|
348
|
+
.description('Push builder appKey image to Azure Container Registry')
|
|
330
349
|
.addHelpText('after', PUSH_HELP_AFTER)
|
|
331
350
|
.option('-r, --registry <registry>', 'ACR registry URL (overrides application.yaml)')
|
|
332
351
|
.option('-t, --tag <tag>', 'Image tag(s) - comma-separated for multiple (default: latest)')
|
|
@@ -339,8 +358,8 @@ function setupPushDeployDockerfileCommands(program) {
|
|
|
339
358
|
}
|
|
340
359
|
});
|
|
341
360
|
|
|
342
|
-
program.command('deploy <
|
|
343
|
-
.description('Deploy via Miso Controller (Azure or --local)')
|
|
361
|
+
program.command('deploy <appKey|systemKey>')
|
|
362
|
+
.description('Deploy builder app or external system via Miso Controller (Azure or --local)')
|
|
344
363
|
.addHelpText('after', DEPLOY_HELP_AFTER)
|
|
345
364
|
.option('--local', 'Send manifest to controller then run app locally (app: same as aifabrix run <app>; external: restart dataplane)')
|
|
346
365
|
.option('--client-id <id>', 'Client ID (overrides config)')
|
|
@@ -8,11 +8,16 @@ const chalk = require('chalk');
|
|
|
8
8
|
const logger = require('../utils/logger');
|
|
9
9
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
10
10
|
const { cliOptsSkipCertSync } = require('../certification/cli-cert-sync-skip');
|
|
11
|
-
const {
|
|
11
|
+
const {
|
|
12
|
+
TEST_HELP_AFTER,
|
|
13
|
+
TEST_E2E_HELP_AFTER,
|
|
14
|
+
TEST_TRUST_HELP_AFTER,
|
|
15
|
+
TEST_GOVERNANCE_HELP_AFTER
|
|
16
|
+
} = require('./setup-app.help');
|
|
12
17
|
|
|
13
18
|
function setupTestCommand(program) {
|
|
14
|
-
program.command('test <
|
|
15
|
-
.description('Tests: builder in container; external = local validation')
|
|
19
|
+
program.command('test <appKey|systemKey>')
|
|
20
|
+
.description('Tests: builder appKey in container; external systemKey = local validation')
|
|
16
21
|
.option('-e, --env <env>', 'For builder app: dev (running container) or tst (ephemeral)', 'dev')
|
|
17
22
|
.option('-v, --verbose', 'Verbose output')
|
|
18
23
|
.option('-d, --debug', 'Write debug log to integration/<systemKey>/logs/ (external only)')
|
|
@@ -84,14 +89,16 @@ function firstIssuanceFailureHintFromE2eResults(results) {
|
|
|
84
89
|
* @param {Object} options
|
|
85
90
|
* @returns {Promise<void>}
|
|
86
91
|
*/
|
|
87
|
-
async function runExternalIntegrationE2EAndCertSync(appName, options) {
|
|
92
|
+
async function runExternalIntegrationE2EAndCertSync(appName, options, cmd) {
|
|
93
|
+
const { cliOptsSkipSync } = require('../utils/cli-sync-options');
|
|
88
94
|
const { runTestE2EForExternalSystem } = require('../commands/test-e2e-external');
|
|
95
|
+
const noSync = cliOptsSkipSync(options, cmd);
|
|
89
96
|
const { success, results } = await runTestE2EForExternalSystem(appName, {
|
|
90
97
|
env: options.env,
|
|
91
98
|
debug: options.debug,
|
|
92
99
|
verbose: options.verbose,
|
|
93
100
|
async: options.async !== false,
|
|
94
|
-
noSync
|
|
101
|
+
noSync
|
|
95
102
|
});
|
|
96
103
|
const { displayIntegrationTestResults } = require('../utils/external-system-display');
|
|
97
104
|
const datasourceResults = results.map(r => ({
|
|
@@ -118,17 +125,19 @@ async function runExternalIntegrationE2EAndCertSync(appName, options) {
|
|
|
118
125
|
await trySyncCertificationFromDataplaneForExternalApp(appName, 'test-e2e', { issuanceFailureHint });
|
|
119
126
|
}
|
|
120
127
|
|
|
121
|
-
async function runTestE2ECommand(appName, options) {
|
|
128
|
+
async function runTestE2ECommand(appName, options, cmd) {
|
|
129
|
+
const { cliOptsSkipSync } = require('../utils/cli-sync-options');
|
|
130
|
+
const noSync = cliOptsSkipSync(options, cmd);
|
|
122
131
|
const pathsUtil = require('../utils/paths');
|
|
123
132
|
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
124
|
-
if (
|
|
133
|
+
if (noSync && appType && appType.baseDir === 'builder') {
|
|
125
134
|
throw new Error(
|
|
126
135
|
'Option --no-sync applies only to external integration E2E (integration/<systemKey>/). ' +
|
|
127
136
|
'Remove --no-sync for builder app E2E.'
|
|
128
137
|
);
|
|
129
138
|
}
|
|
130
139
|
if (appType && appType.baseDir === 'integration') {
|
|
131
|
-
await runExternalIntegrationE2EAndCertSync(appName, options);
|
|
140
|
+
await runExternalIntegrationE2EAndCertSync(appName, options, cmd);
|
|
132
141
|
return;
|
|
133
142
|
}
|
|
134
143
|
const { runAppTestE2e } = require('../commands/app-test');
|
|
@@ -136,8 +145,8 @@ async function runTestE2ECommand(appName, options) {
|
|
|
136
145
|
}
|
|
137
146
|
|
|
138
147
|
function setupInstallCommand(program) {
|
|
139
|
-
program.command('install <
|
|
140
|
-
.description('Install deps in container (builder
|
|
148
|
+
program.command('install <appKey>')
|
|
149
|
+
.description('Install deps in container (builder appKey only)')
|
|
141
150
|
.option('--env <env>', 'dev (running container) or tst (ephemeral with .env)', 'dev')
|
|
142
151
|
.action(async(appName, options) => {
|
|
143
152
|
try {
|
|
@@ -145,7 +154,7 @@ function setupInstallCommand(program) {
|
|
|
145
154
|
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
146
155
|
if (appType && appType.baseDir === 'integration') {
|
|
147
156
|
logger.log(
|
|
148
|
-
chalk.gray('Install is for builder
|
|
157
|
+
chalk.gray('Install is for builder appKey only. Use aifabrix shell <appKey> for builder apps or External Systems commands for integrations.')
|
|
149
158
|
);
|
|
150
159
|
return;
|
|
151
160
|
}
|
|
@@ -159,15 +168,11 @@ function setupInstallCommand(program) {
|
|
|
159
168
|
}
|
|
160
169
|
|
|
161
170
|
function setupTestE2eCommand(program) {
|
|
162
|
-
program.command('test-e2e <
|
|
163
|
-
.description('E2E: builder in container; external = all datasources via dataplane')
|
|
171
|
+
program.command('test-e2e <appKey|systemKey>')
|
|
172
|
+
.description('E2E: builder appKey in container; external systemKey = all datasources via dataplane')
|
|
164
173
|
.option('-e, --env <env>', 'Environment: dev, tst, or pro (builder: dev/tst for container)', 'dev')
|
|
165
174
|
.option('-v, --verbose', 'Show detailed step output and poll progress')
|
|
166
175
|
.option('-d, --debug', 'Include debug output and write log to integration/<systemKey>/logs/')
|
|
167
|
-
.option(
|
|
168
|
-
'--sync',
|
|
169
|
-
'(Deprecated; no-op.) Local integration files are published before E2E by default; use --no-sync to skip.'
|
|
170
|
-
)
|
|
171
176
|
.option(
|
|
172
177
|
'--no-sync',
|
|
173
178
|
'Skip publishing local integration files; E2E uses the system config already on the dataplane (external integration only)'
|
|
@@ -188,7 +193,7 @@ function setupTestE2eCommand(program) {
|
|
|
188
193
|
env: envExplicit ? options.env : undefined,
|
|
189
194
|
async: true // system-level command surface omits --no-async; always poll for completeness
|
|
190
195
|
};
|
|
191
|
-
await runTestE2ECommand(appName, externalOpts);
|
|
196
|
+
await runTestE2ECommand(appName, externalOpts, cmd);
|
|
192
197
|
} catch (error) {
|
|
193
198
|
handleCommandError(error, 'test-e2e');
|
|
194
199
|
process.exit(1);
|
|
@@ -197,15 +202,15 @@ function setupTestE2eCommand(program) {
|
|
|
197
202
|
}
|
|
198
203
|
|
|
199
204
|
function setupLintCommand(program) {
|
|
200
|
-
program.command('lint <
|
|
201
|
-
.description('Lint in container (builder
|
|
205
|
+
program.command('lint <appKey>')
|
|
206
|
+
.description('Lint in container (builder appKey only)')
|
|
202
207
|
.option('--env <env>', 'dev (running container) or tst (ephemeral with .env)', 'dev')
|
|
203
208
|
.action(async(appName, options) => {
|
|
204
209
|
try {
|
|
205
210
|
const pathsUtil = require('../utils/paths');
|
|
206
211
|
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
207
212
|
if (appType && appType.baseDir === 'integration') {
|
|
208
|
-
logger.log(chalk.gray('lint is for builder
|
|
213
|
+
logger.log(chalk.gray('lint is for builder appKey only. Use aifabrix shell <appKey> then make lint or pnpm lint.'));
|
|
209
214
|
return;
|
|
210
215
|
}
|
|
211
216
|
const { runAppLint } = require('../commands/app-test');
|
|
@@ -217,10 +222,64 @@ function setupLintCommand(program) {
|
|
|
217
222
|
});
|
|
218
223
|
}
|
|
219
224
|
|
|
225
|
+
function collectScenarioId(value, previous) {
|
|
226
|
+
return previous.concat([value]);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function setupTestGovernanceCommand(program) {
|
|
230
|
+
const { testGovernanceCommandHandler } = require('../commands/test-governance-command-action');
|
|
231
|
+
program
|
|
232
|
+
.command('test-governance <appKey|systemKey>')
|
|
233
|
+
.description(
|
|
234
|
+
'Governance scenario acceptance: ABAC visibility via governed search (key sets only)'
|
|
235
|
+
)
|
|
236
|
+
.option('-e, --env <env>', 'Environment: dev, tst, or pro', 'dev')
|
|
237
|
+
.option('--pack <path>', 'Scenario pack YAML (default: scenarios/default.yaml or <systemKey>-v1.yaml)')
|
|
238
|
+
.option('-a, --app <path>', 'Integration folder override')
|
|
239
|
+
.option(
|
|
240
|
+
'--scenario <id>',
|
|
241
|
+
'Run subset of scenario ids (repeatable)',
|
|
242
|
+
collectScenarioId,
|
|
243
|
+
[]
|
|
244
|
+
)
|
|
245
|
+
.option('--no-sync', 'Skip publishing local integration files before run')
|
|
246
|
+
.option('-v, --verbose', 'Per-scenario verdict lines with subject and counts')
|
|
247
|
+
.option('--json', 'Machine-readable redacted result (same allowlist as API)')
|
|
248
|
+
.addHelpText('after', TEST_GOVERNANCE_HELP_AFTER)
|
|
249
|
+
.action((appName, options, cmd) => testGovernanceCommandHandler(appName, options, cmd));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function setupTestTrustCommand(program) {
|
|
253
|
+
const { testTrustCommandHandler } = require('../commands/test-trust-command-action');
|
|
254
|
+
program
|
|
255
|
+
.command('test-trust <appKey|systemKey>')
|
|
256
|
+
.description(
|
|
257
|
+
'Semantic agent metadata validation for external system (all datasources via dataplane 404.5)'
|
|
258
|
+
)
|
|
259
|
+
.option('-e, --env <env>', 'Environment: dev, tst, or pro', 'dev')
|
|
260
|
+
.option('-v, --verbose', 'Show findings and observed business model')
|
|
261
|
+
.option('-d, --debug', 'Write debug log under integration/<systemKey>/logs/')
|
|
262
|
+
.option('--no-sync', 'Skip publishing local integration files before validate')
|
|
263
|
+
.option('--revalidate', 'Force new validation for each datasource')
|
|
264
|
+
.option(
|
|
265
|
+
'--timeout <ms>',
|
|
266
|
+
'HTTP timeout for validate/latest requests (ms)',
|
|
267
|
+
'120000'
|
|
268
|
+
)
|
|
269
|
+
.option('--strict', 'Exit 1 unless every datasource is trusted')
|
|
270
|
+
.option('--warnings-as-errors', 'Exit 1 when any datasource is usableWithWarnings')
|
|
271
|
+
.option('--json', 'Print JSON array of trust runs')
|
|
272
|
+
.option('--summary', 'One line per datasource')
|
|
273
|
+
.addHelpText('after', TEST_TRUST_HELP_AFTER)
|
|
274
|
+
.action((appName, options, cmd) => testTrustCommandHandler(appName, options, cmd));
|
|
275
|
+
}
|
|
276
|
+
|
|
220
277
|
function setupInstallTestE2eLintCommands(program) {
|
|
221
278
|
setupInstallCommand(program);
|
|
222
279
|
setupTestCommand(program);
|
|
223
280
|
setupTestE2eCommand(program);
|
|
281
|
+
setupTestGovernanceCommand(program);
|
|
282
|
+
setupTestTrustCommand(program);
|
|
224
283
|
setupLintCommand(program);
|
|
225
284
|
}
|
|
226
285
|
|