@aifabrix/builder 2.44.4 → 2.44.6
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 +1 -1
- package/.cursor/rules/project-rules.mdc +1 -1
- package/.npmrc.token +1 -1
- package/README.md +15 -23
- package/integration/hubspot-test/README.md +2 -0
- package/integration/hubspot-test/test.js +5 -3
- package/jest.projects.js +68 -17
- package/lib/api/controller-health.api.js +49 -0
- package/lib/api/dimension-values.api.js +82 -0
- package/lib/api/dimensions.api.js +114 -0
- package/lib/api/external-systems.api.js +1 -0
- package/lib/api/integration-clients.api.js +168 -0
- package/lib/api/types/dimension-values.types.js +28 -0
- package/lib/api/types/dimensions.types.js +31 -0
- package/lib/api/types/integration-clients.types.js +45 -0
- package/lib/api/types/wizard.types.js +2 -1
- package/lib/api/validation-runner.js +46 -25
- package/lib/app/deploy-config.js +11 -1
- package/lib/app/deploy-status-display.js +3 -3
- package/lib/app/deploy.js +36 -14
- package/lib/app/display.js +15 -11
- package/lib/app/push.js +46 -23
- package/lib/app/register.js +1 -1
- package/lib/app/restart-display.js +95 -0
- package/lib/app/rotate-secret.js +1 -1
- package/lib/app/run-container-start.js +12 -6
- package/lib/app/run-env-compose.js +30 -1
- package/lib/app/run-helpers.js +44 -12
- package/lib/app/run-reload-sync.js +148 -0
- package/lib/app/run-resolve-image.js +51 -1
- package/lib/app/run.js +99 -73
- package/lib/build/index.js +75 -45
- package/lib/cli/doctor-check.js +117 -0
- package/lib/cli/index.js +8 -2
- package/lib/cli/infra-guided.js +445 -0
- package/lib/cli/setup-app.help.js +1 -1
- package/lib/cli/setup-app.js +20 -2
- package/lib/cli/setup-app.test-commands.js +9 -5
- package/lib/cli/setup-auth.js +26 -0
- package/lib/cli/setup-dev-path-commands.js +50 -3
- package/lib/cli/setup-infra.js +138 -61
- package/lib/cli/setup-integration-client.js +182 -0
- package/lib/cli/setup-parameters.js +21 -2
- package/lib/cli/setup-platform.js +102 -0
- package/lib/cli/setup-secrets.js +18 -6
- package/lib/cli/setup-utility.js +97 -33
- package/lib/commands/datasource-capability-dimension-cli.js +128 -0
- package/lib/commands/datasource-capability-output.js +29 -0
- package/lib/commands/datasource-capability-relate-cli.js +140 -0
- package/lib/commands/datasource-capability.js +411 -0
- package/lib/commands/datasource-unified-test-cli.options.js +1 -1
- package/lib/commands/datasource.js +53 -13
- package/lib/commands/dev-down.js +3 -3
- package/lib/commands/dev-infra-gate.js +32 -0
- package/lib/commands/dev-init.js +13 -7
- package/lib/commands/dimension-value.js +179 -0
- package/lib/commands/dimension.js +330 -0
- package/lib/commands/integration-client.js +430 -0
- package/lib/commands/login-device.js +65 -30
- package/lib/commands/login.js +21 -10
- package/lib/commands/parameters-validate.js +78 -13
- package/lib/commands/repair-datasource-auto-rbac.js +166 -0
- package/lib/commands/repair-datasource-keys.js +10 -5
- package/lib/commands/repair-datasource.js +19 -7
- package/lib/commands/repair-env-template.js +4 -1
- package/lib/commands/repair-openapi-sync.js +172 -0
- package/lib/commands/repair-persist.js +102 -0
- package/lib/commands/repair-rbac-extract.js +27 -0
- package/lib/commands/repair-rbac-migrate.js +186 -0
- package/lib/commands/repair-rbac.js +225 -19
- package/lib/commands/repair-system-alignment.js +246 -0
- package/lib/commands/repair-system-permissions.js +168 -0
- package/lib/commands/repair.js +120 -354
- package/lib/commands/secure.js +1 -1
- package/lib/commands/setup-modes.js +455 -0
- package/lib/commands/setup-prompts.js +388 -0
- package/lib/commands/setup.js +149 -0
- package/lib/commands/teardown.js +228 -0
- package/lib/commands/test-e2e-external.js +4 -3
- package/lib/commands/up-common.js +97 -12
- package/lib/commands/up-dataplane.js +33 -11
- package/lib/commands/up-miso.js +7 -11
- package/lib/commands/upload.js +109 -23
- package/lib/commands/wizard-core-helpers.js +14 -11
- package/lib/commands/wizard-core.js +58 -15
- package/lib/commands/wizard-dataplane.js +2 -2
- package/lib/commands/wizard-entity-selection.js +72 -14
- package/lib/commands/wizard-headless.js +7 -3
- package/lib/commands/wizard-helpers.js +13 -1
- package/lib/commands/wizard.js +210 -61
- package/lib/constants/infra-compose-service-names.js +40 -0
- package/lib/core/env-reader.js +16 -3
- package/lib/core/secrets-admin-env.js +101 -0
- package/lib/core/secrets-ensure-infra.js +34 -1
- package/lib/core/secrets-ensure.js +88 -66
- package/lib/core/secrets-env-content.js +432 -0
- package/lib/core/secrets-env-write.js +27 -1
- package/lib/core/secrets-load.js +248 -0
- package/lib/core/secrets-names.js +32 -0
- package/lib/core/secrets.js +17 -757
- package/lib/datasource/capability/basic-exposure.js +76 -0
- package/lib/datasource/capability/capability-diff-slice.js +41 -0
- package/lib/datasource/capability/capability-key.js +34 -0
- package/lib/datasource/capability/capability-resolve.js +172 -0
- package/lib/datasource/capability/capability-storage-keys.js +22 -0
- package/lib/datasource/capability/copy-operations.js +348 -0
- package/lib/datasource/capability/copy-test-payload.js +139 -0
- package/lib/datasource/capability/create-operations.js +235 -0
- package/lib/datasource/capability/dimension-operations.js +151 -0
- package/lib/datasource/capability/dimension-validate.js +219 -0
- package/lib/datasource/capability/json-pointer.js +31 -0
- package/lib/datasource/capability/reference-rewrite.js +51 -0
- package/lib/datasource/capability/relate-operations.js +325 -0
- package/lib/datasource/capability/relate-validate.js +219 -0
- package/lib/datasource/capability/remove-operations.js +275 -0
- package/lib/datasource/capability/run-capability-copy.js +152 -0
- package/lib/datasource/capability/run-capability-diff.js +135 -0
- package/lib/datasource/capability/run-capability-dimension.js +291 -0
- package/lib/datasource/capability/run-capability-edit.js +377 -0
- package/lib/datasource/capability/run-capability-relate.js +193 -0
- package/lib/datasource/capability/run-capability-remove.js +105 -0
- package/lib/datasource/capability/templates/minimal-fetch.json +18 -0
- package/lib/datasource/capability/validate-capability-slice.js +35 -0
- package/lib/datasource/list.js +136 -23
- package/lib/datasource/log-viewer.js +2 -4
- package/lib/datasource/unified-validation-run.js +51 -16
- package/lib/datasource/validate.js +53 -1
- package/lib/deployment/deploy-poll-ui.js +60 -0
- package/lib/deployment/deployer-status.js +29 -3
- package/lib/deployment/deployer.js +48 -30
- package/lib/deployment/environment.js +7 -2
- package/lib/deployment/poll-interval.js +72 -0
- package/lib/deployment/push.js +11 -9
- package/lib/external-system/deploy.js +4 -1
- package/lib/external-system/download.js +61 -32
- package/lib/external-system/sync-deploy-manifest.js +33 -0
- package/lib/generator/wizard-prompts.js +7 -1
- package/lib/generator/wizard.js +34 -0
- package/lib/infrastructure/index.js +49 -19
- package/lib/infrastructure/orphan-infra-docker-teardown.js +177 -0
- package/lib/parameters/infra-kv-discovery.js +29 -4
- package/lib/parameters/infra-parameter-catalog.js +6 -3
- package/lib/parameters/infra-parameter-validate.js +67 -19
- package/lib/resolvers/datasource-resolver.js +53 -0
- package/lib/resolvers/dimension-file.js +52 -0
- package/lib/resolvers/manifest-resolver.js +133 -0
- package/lib/schema/external-datasource.schema.json +183 -53
- package/lib/schema/external-system.schema.json +23 -10
- package/lib/schema/infra.parameter.yaml +26 -11
- package/lib/schema/wizard-config.schema.json +2 -2
- package/lib/utils/aifabrix-config-dir-walk.js +40 -0
- package/lib/utils/aifabrix-runtime-config-dir.js +26 -3
- package/lib/utils/app-run-containers.js +2 -2
- package/lib/utils/bash-secret-env.js +59 -0
- package/lib/utils/cli-secrets-error-format.js +78 -0
- package/lib/utils/cli-test-layout-chalk.js +31 -9
- package/lib/utils/cli-utils.js +4 -36
- package/lib/utils/datasource-test-run-display.js +8 -0
- package/lib/utils/dev-hosts-helper.js +3 -2
- package/lib/utils/dev-init-ssh-merge.js +2 -1
- package/lib/utils/docker-build.js +17 -9
- package/lib/utils/docker-reload-mount.js +127 -0
- package/lib/utils/external-readme.js +117 -4
- package/lib/utils/external-system-local-test-tty.js +3 -2
- package/lib/utils/external-system-readiness-core.js +45 -12
- package/lib/utils/external-system-readiness-deploy-display.js +3 -3
- package/lib/utils/external-system-readiness-display-internals.js +33 -3
- package/lib/utils/external-system-readiness-display.js +10 -1
- package/lib/utils/file-upload.js +40 -3
- package/lib/utils/health-check-db-init.js +107 -0
- package/lib/utils/health-check-public-warn.js +69 -0
- package/lib/utils/health-check-url.js +19 -4
- package/lib/utils/health-check.js +135 -105
- package/lib/utils/help-builder.js +5 -1
- package/lib/utils/image-name.js +34 -7
- package/lib/utils/integration-file-backup.js +74 -0
- package/lib/utils/mutagen-install.js +30 -3
- package/lib/utils/paths.js +108 -25
- package/lib/utils/postgres-wipe.js +212 -0
- package/lib/utils/register-aifabrix-shell-env.js +15 -0
- package/lib/utils/remote-dev-auth.js +21 -5
- package/lib/utils/remote-docker-env.js +9 -1
- package/lib/utils/remote-secrets-loader.js +42 -3
- package/lib/utils/resolve-docker-image-ref.js +9 -3
- package/lib/utils/secrets-ancestor-paths.js +47 -0
- package/lib/utils/secrets-helpers.js +17 -10
- package/lib/utils/secrets-kv-refs.js +42 -0
- package/lib/utils/secrets-kv-scope.js +19 -2
- package/lib/utils/secrets-materialize-local.js +134 -0
- package/lib/utils/secrets-path.js +24 -10
- package/lib/utils/secrets-utils.js +2 -2
- package/lib/utils/system-builder-root.js +34 -0
- package/lib/utils/url-declarative-resolve-build.js +6 -1
- package/lib/utils/url-declarative-runtime-base-path.js +32 -0
- package/lib/utils/url-declarative-vdir-inactive-env.js +2 -1
- package/lib/utils/urls-local-registry.js +73 -20
- package/lib/utils/validation-poll-ui.js +81 -0
- package/lib/utils/validation-run-poll.js +29 -5
- package/lib/utils/with-muted-logger.js +53 -0
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +1 -1
- package/templates/applications/dataplane/rbac.yaml +10 -10
- package/templates/applications/keycloak/env.template +8 -6
- package/templates/applications/miso-controller/application.yaml +7 -0
- package/templates/applications/miso-controller/env.template +7 -7
- package/templates/applications/miso-controller/rbac.yaml +9 -9
- package/templates/external-system/README.md.hbs +89 -102
- package/.nyc_output/55e9d034-ddab-4579-a706-e02a91d75c91.json +0 -1
- package/.nyc_output/processinfo/55e9d034-ddab-4579-a706-e02a91d75c91.json +0 -1
- package/.nyc_output/processinfo/index.json +0 -1
- package/lib/api/service-users.api.js +0 -150
- package/lib/api/types/service-users.types.js +0 -65
- package/lib/cli/setup-service-user.js +0 -187
- package/lib/commands/service-user.js +0 -429
package/lib/cli/setup-infra.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {
|
|
2
|
+
formatProgress,
|
|
3
|
+
formatSuccessLine,
|
|
4
|
+
sectionTitle,
|
|
5
|
+
headerKeyValue
|
|
6
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
2
7
|
/**
|
|
3
8
|
* CLI infrastructure command setup (up-infra, up-platform, up-miso, up-dataplane, down-infra, doctor, status, restart).
|
|
4
9
|
*
|
|
@@ -10,7 +15,6 @@ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
|
10
15
|
const chalk = require('chalk');
|
|
11
16
|
const infra = require('../infrastructure');
|
|
12
17
|
const appLib = require('../app');
|
|
13
|
-
const validator = require('../validation/validator');
|
|
14
18
|
const config = require('../core/config');
|
|
15
19
|
const logger = require('../utils/logger');
|
|
16
20
|
const { handleCommandError, isAuthenticationError } = require('../utils/cli-utils');
|
|
@@ -18,19 +22,29 @@ const { resolveControllerUrl } = require('../utils/controller-url');
|
|
|
18
22
|
const { handleLogin } = require('../commands/login');
|
|
19
23
|
const { handleUpMiso } = require('../commands/up-miso');
|
|
20
24
|
const { handleUpDataplane } = require('../commands/up-dataplane');
|
|
21
|
-
const {
|
|
25
|
+
const {
|
|
26
|
+
applyUpPlatformForceConfig,
|
|
27
|
+
cleanBuilderAppDirs,
|
|
28
|
+
prepareUrlsLocalRegistryForUpPlatform
|
|
29
|
+
} = require('../commands/up-common');
|
|
30
|
+
const { runGuidedUpInfra, runGuidedUpMiso, runGuidedUpDataplane, runGuidedUpPlatform, runGuidedDownInfra } = require('./infra-guided');
|
|
22
31
|
const {
|
|
23
32
|
loadInfraStatusSummary,
|
|
24
33
|
formatInfraStatusTitleLine,
|
|
25
34
|
logInfraStatusConfigurationSummary,
|
|
26
35
|
logPaddedFieldRow
|
|
27
36
|
} = require('../utils/infra-status-display');
|
|
37
|
+
const { runDoctorCheck } = require('./doctor-check');
|
|
38
|
+
const {
|
|
39
|
+
getRestartableInfraServiceNames,
|
|
40
|
+
buildRestartInfraHelpLines
|
|
41
|
+
} = require('../constants/infra-compose-service-names');
|
|
28
42
|
|
|
29
43
|
const UP_INFRA_HELP_AFTER = `
|
|
30
44
|
Typical sequence:
|
|
31
45
|
$ aifabrix up-infra
|
|
32
46
|
$ aifabrix up-platform
|
|
33
|
-
Or: aifabrix up-miso, then aifabrix up-dataplane (login required for dataplane)
|
|
47
|
+
Or: aifabrix up-infra, aifabrix up-miso, then aifabrix up-dataplane (login required for dataplane)
|
|
34
48
|
|
|
35
49
|
Full bootstrap example (Traefik, TLS flag, pgAdmin, catalog overrides — matches shipped defaults in infra.parameter.yaml):
|
|
36
50
|
$ aifabrix up-infra --traefik --tls --adminPassword admin123 --adminEmail admin@aifabrix.dev --userPassword user123 --pgAdmin
|
|
@@ -59,16 +73,14 @@ async function persistTlsEnabledFlag(cfg, value) {
|
|
|
59
73
|
await config.saveConfig(cfg);
|
|
60
74
|
const tlsStr = value ? 'true' : 'false';
|
|
61
75
|
const httpStr = value ? 'false' : 'true';
|
|
62
|
-
logger.log(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
)
|
|
71
|
-
);
|
|
76
|
+
logger.log(formatSuccessLine(
|
|
77
|
+
`TLS mode ${value ? 'enabled' : 'disabled'} and saved to config (` +
|
|
78
|
+
'${TLS_ENABLED}=' +
|
|
79
|
+
tlsStr +
|
|
80
|
+
', ${HTTP_ENABLED}=' +
|
|
81
|
+
httpStr +
|
|
82
|
+
' when generating deployment JSON)'
|
|
83
|
+
));
|
|
72
84
|
}
|
|
73
85
|
|
|
74
86
|
/**
|
|
@@ -152,11 +164,27 @@ async function runUpInfraCommand(options) {
|
|
|
152
164
|
});
|
|
153
165
|
}
|
|
154
166
|
|
|
167
|
+
async function maybeHandleUpPlatformAuthRetry(error, options) {
|
|
168
|
+
if (!isAuthenticationError(error)) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
const controllerUrl = error.controllerUrl || await resolveControllerUrl();
|
|
172
|
+
if (!options.verbose) {
|
|
173
|
+
logger.log(formatProgress('Authenticating...'));
|
|
174
|
+
} else {
|
|
175
|
+
logger.log(chalk.blue('\nAuthentication required. Running aifabrix login...\n'));
|
|
176
|
+
}
|
|
177
|
+
await handleLogin({ method: 'device', controller: controllerUrl, compact: !options.verbose });
|
|
178
|
+
await handleUpDataplane(options);
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
|
|
155
182
|
function setupUpInfraCommand(program) {
|
|
156
183
|
program.command('up-infra')
|
|
157
184
|
.description('Start Postgres, Redis; optional pgAdmin, Redis Commander, Traefik')
|
|
158
185
|
.addHelpText('after', UP_INFRA_HELP_AFTER)
|
|
159
186
|
.option('-d, --developer <id>', 'Set developer ID and start infrastructure')
|
|
187
|
+
.option('--verbose', 'Show full orchestration output (default is guided summary)')
|
|
160
188
|
.option('--adminPassword <password>', 'Override {{adminPassword}} defaults (Postgres, pgAdmin, Redis Commander, catalog literals)')
|
|
161
189
|
.option('--adminEmail <email>', 'Override {{adminEmail}} default (e.g. pgAdmin login email)')
|
|
162
190
|
.option('--userPassword <password>', 'Override {{userPassword}} default (e.g. Keycloak default user password)')
|
|
@@ -170,6 +198,11 @@ function setupUpInfraCommand(program) {
|
|
|
170
198
|
.option('--no-tls', 'Disable TLS mode (${TLS_ENABLED}=false, ${HTTP_ENABLED}=true)')
|
|
171
199
|
.action(async(options) => {
|
|
172
200
|
try {
|
|
201
|
+
if (!options.verbose) {
|
|
202
|
+
await runGuidedUpInfra(options, runUpInfraCommand);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
173
206
|
await runUpInfraCommand(options);
|
|
174
207
|
} catch (error) {
|
|
175
208
|
handleCommandError(error, 'up-infra');
|
|
@@ -184,26 +217,47 @@ function setupUpPlatformCommand(program) {
|
|
|
184
217
|
.option('-r, --registry <url>', 'Override registry for all apps (e.g. myacr.azurecr.io)')
|
|
185
218
|
.option('--registry-mode <mode>', 'Override registry mode (acr|external)')
|
|
186
219
|
.option('-i, --image <key>=<value>', 'Override image (e.g. keycloak=myreg/k:v1, miso-controller=myreg/m:v1, dataplane=myreg/d:v1); can be repeated', (v, prev) => (prev || []).concat([v]))
|
|
187
|
-
.option('
|
|
220
|
+
.option('--base', 'Resolve platform images from manifest only (default: true)', true)
|
|
221
|
+
.option('--verbose', 'Show full orchestration output (default is guided installer)')
|
|
222
|
+
.option(
|
|
223
|
+
'-f, --force',
|
|
224
|
+
'Reset CLI auth (clear all device/client tokens, set environment to dev, set default controller URL from developer-id), clean builder/keycloak, builder/miso-controller, builder/dataplane, then re-fetch from templates'
|
|
225
|
+
)
|
|
188
226
|
.action(async(options) => {
|
|
189
227
|
try {
|
|
228
|
+
let platformForceCleanSummary = null;
|
|
190
229
|
if (options.force) {
|
|
191
|
-
await
|
|
230
|
+
const forceSummary = await applyUpPlatformForceConfig({ silent: !options.verbose });
|
|
231
|
+
const cleanedApps = await cleanBuilderAppDirs(['keycloak', 'miso-controller', 'dataplane'], {
|
|
232
|
+
silent: !options.verbose
|
|
233
|
+
});
|
|
234
|
+
if (!options.verbose) {
|
|
235
|
+
platformForceCleanSummary = { forceSummary, cleanedApps };
|
|
236
|
+
}
|
|
192
237
|
}
|
|
238
|
+
|
|
239
|
+
if (!options.verbose) {
|
|
240
|
+
await runGuidedUpPlatform(
|
|
241
|
+
options,
|
|
242
|
+
handleUpMiso,
|
|
243
|
+
handleUpDataplane,
|
|
244
|
+
handleLogin,
|
|
245
|
+
platformForceCleanSummary
|
|
246
|
+
);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
await prepareUrlsLocalRegistryForUpPlatform();
|
|
193
251
|
await handleUpMiso(options);
|
|
194
252
|
await handleUpDataplane(options);
|
|
195
253
|
} catch (error) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
logger.log(chalk.blue('\nAuthentication required. Running aifabrix login...\n'));
|
|
199
|
-
try {
|
|
200
|
-
await handleLogin({ method: 'device', controller: controllerUrl });
|
|
201
|
-
await handleUpDataplane(options);
|
|
254
|
+
try {
|
|
255
|
+
if (await maybeHandleUpPlatformAuthRetry(error, options)) {
|
|
202
256
|
return;
|
|
203
|
-
} catch (loginOrRetryError) {
|
|
204
|
-
handleCommandError(loginOrRetryError, 'up-platform');
|
|
205
|
-
process.exit(1);
|
|
206
257
|
}
|
|
258
|
+
} catch (loginOrRetryError) {
|
|
259
|
+
handleCommandError(loginOrRetryError, 'up-platform');
|
|
260
|
+
process.exit(1);
|
|
207
261
|
}
|
|
208
262
|
handleCommandError(error, 'up-platform');
|
|
209
263
|
process.exit(1);
|
|
@@ -217,12 +271,19 @@ function setupUpMisoCommand(program) {
|
|
|
217
271
|
.option('-r, --registry <url>', 'Override registry for all apps (e.g. myacr.azurecr.io)')
|
|
218
272
|
.option('--registry-mode <mode>', 'Override registry mode (acr|external)')
|
|
219
273
|
.option('-i, --image <key>=<value>', 'Override image (e.g. keycloak=myreg/k:v1, miso-controller=myreg/m:v1); can be repeated', (v, prev) => (prev || []).concat([v]))
|
|
274
|
+
.option('--base', 'Resolve platform images from manifest only (default: true)', true)
|
|
220
275
|
.option('-f, --force', 'Clean builder/keycloak and builder/miso-controller and re-fetch from templates')
|
|
276
|
+
.option('--verbose', 'Show full orchestration output (default is guided summary)')
|
|
221
277
|
.action(async(options) => {
|
|
222
278
|
try {
|
|
223
279
|
if (options.force) {
|
|
224
280
|
await cleanBuilderAppDirs(['keycloak', 'miso-controller']);
|
|
225
281
|
}
|
|
282
|
+
if (!options.verbose) {
|
|
283
|
+
await runGuidedUpMiso(options, handleUpMiso);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
226
287
|
await handleUpMiso(options);
|
|
227
288
|
} catch (error) {
|
|
228
289
|
handleCommandError(error, 'up-miso');
|
|
@@ -233,23 +294,34 @@ function setupUpMisoCommand(program) {
|
|
|
233
294
|
|
|
234
295
|
function setupUpDataplaneCommand(program) {
|
|
235
296
|
program.command('up-dataplane')
|
|
236
|
-
.description('Register, deploy, run dataplane locally (dev env; login required)')
|
|
297
|
+
.description('Register, deploy, run dataplane locally (dev env; needs up-infra; login required)')
|
|
237
298
|
.option('-r, --registry <url>', 'Override registry for dataplane image')
|
|
238
299
|
.option('--registry-mode <mode>', 'Override registry mode (acr|external)')
|
|
239
300
|
.option('-i, --image <ref>', 'Override dataplane image reference (e.g. myreg/dataplane:latest)')
|
|
301
|
+
.option('--base', 'Resolve dataplane image from manifest only when running locally (default: true)', true)
|
|
240
302
|
.option('-f, --force', 'Clean builder/dataplane and re-fetch from templates')
|
|
303
|
+
.option('--verbose', 'Show full orchestration output (default is guided summary)')
|
|
241
304
|
.action(async(options) => {
|
|
242
305
|
try {
|
|
243
306
|
if (options.force) {
|
|
244
307
|
await cleanBuilderAppDirs(['dataplane']);
|
|
245
308
|
}
|
|
309
|
+
if (!options.verbose) {
|
|
310
|
+
await runGuidedUpDataplane(options, handleUpDataplane);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
|
|
246
314
|
await handleUpDataplane(options);
|
|
247
315
|
} catch (error) {
|
|
248
316
|
if (isAuthenticationError(error)) {
|
|
249
317
|
const controllerUrl = error.controllerUrl || await resolveControllerUrl();
|
|
250
|
-
|
|
318
|
+
if (!options.verbose) {
|
|
319
|
+
logger.log(formatProgress('Authenticating...'));
|
|
320
|
+
} else {
|
|
321
|
+
logger.log(chalk.blue('\nAuthentication required. Running aifabrix login...\n'));
|
|
322
|
+
}
|
|
251
323
|
try {
|
|
252
|
-
await handleLogin({ method: 'device', controller: controllerUrl });
|
|
324
|
+
await handleLogin({ method: 'device', controller: controllerUrl, compact: !options.verbose });
|
|
253
325
|
await handleUpDataplane(options);
|
|
254
326
|
return;
|
|
255
327
|
} catch (loginOrRetryError) {
|
|
@@ -267,8 +339,14 @@ function setupDownInfraCommand(program) {
|
|
|
267
339
|
program.command('down-infra [service|app]')
|
|
268
340
|
.description('Stop all infra, or stop one app; use -v to remove volumes')
|
|
269
341
|
.option('-v, --volumes', 'Remove volumes (deletes all data)')
|
|
342
|
+
.option('--verbose', 'Show full orchestration output (default is guided summary)')
|
|
270
343
|
.action(async(appName, options) => {
|
|
271
344
|
try {
|
|
345
|
+
if (!options.verbose) {
|
|
346
|
+
await runGuidedDownInfra(appName, options, infra, appLib);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
272
350
|
if (typeof appName === 'string' && appName.trim().length > 0) {
|
|
273
351
|
await appLib.downApp(appName, { volumes: !!options.volumes });
|
|
274
352
|
} else {
|
|
@@ -287,33 +365,7 @@ function setupDoctorCommand(program) {
|
|
|
287
365
|
.description('Check Docker, ports, secrets, and infra health')
|
|
288
366
|
.action(async() => {
|
|
289
367
|
try {
|
|
290
|
-
|
|
291
|
-
logger.log('\n🔍 AI Fabrix Environment Check\n');
|
|
292
|
-
logger.log(`Docker: ${result.docker === 'ok' ? '✔ Running' : '✖ Not available'}`);
|
|
293
|
-
logger.log(`Ports: ${result.ports === 'ok' ? '✔ Available' : '⚠ Some ports in use'}`);
|
|
294
|
-
logger.log(`Secrets: ${result.secrets === 'ok' ? '✔ Configured' : '✖ Missing'}`);
|
|
295
|
-
if (result.recommendations.length > 0) {
|
|
296
|
-
logger.log('\n📋 Recommendations:');
|
|
297
|
-
result.recommendations.forEach(rec => logger.log(` • ${rec}`));
|
|
298
|
-
}
|
|
299
|
-
if (result.docker === 'ok') {
|
|
300
|
-
try {
|
|
301
|
-
const cfg = await config.getConfig();
|
|
302
|
-
const health = await infra.checkInfraHealth(null, {
|
|
303
|
-
pgadmin: cfg.pgadmin !== false,
|
|
304
|
-
redisCommander: cfg.redisCommander !== false,
|
|
305
|
-
traefik: !!cfg.traefik
|
|
306
|
-
});
|
|
307
|
-
logger.log('\n🏥 Infrastructure Health:');
|
|
308
|
-
Object.entries(health).forEach(([service, status]) => {
|
|
309
|
-
const icon = status === 'healthy' ? '✔' : status === 'unknown' ? '❓' : '✖';
|
|
310
|
-
logger.log(` ${icon} ${service}: ${status}`);
|
|
311
|
-
});
|
|
312
|
-
} catch (error) {
|
|
313
|
-
logger.log('\n🏥 Infrastructure: Not running');
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
logger.log('');
|
|
368
|
+
await runDoctorCheck();
|
|
317
369
|
} catch (error) {
|
|
318
370
|
handleCommandError(error, 'doctor');
|
|
319
371
|
process.exit(1);
|
|
@@ -361,19 +413,44 @@ function setupStatusCommand(program) {
|
|
|
361
413
|
});
|
|
362
414
|
}
|
|
363
415
|
|
|
364
|
-
const
|
|
416
|
+
const RESTART_INFRA_SERVICE_NAMES = getRestartableInfraServiceNames();
|
|
417
|
+
|
|
418
|
+
const RESTART_COMMAND_HELP_AFTER = `
|
|
419
|
+
Infra — use these exact Docker Compose service names:
|
|
420
|
+
${buildRestartInfraHelpLines()}
|
|
421
|
+
|
|
422
|
+
Optional services (pgadmin, redis-commander, traefik) only exist if you enabled them when running up-infra.
|
|
423
|
+
|
|
424
|
+
Builder apps (examples):
|
|
425
|
+
keycloak, miso-controller, dataplane
|
|
426
|
+
|
|
427
|
+
Examples:
|
|
428
|
+
$ aifabrix restart postgres
|
|
429
|
+
$ aifabrix restart traefik
|
|
430
|
+
$ aifabrix restart miso-controller
|
|
431
|
+
`;
|
|
365
432
|
|
|
366
433
|
function setupRestartCommand(program) {
|
|
367
434
|
program.command('restart <service|app>')
|
|
368
|
-
.description(
|
|
435
|
+
.description(
|
|
436
|
+
'Restart one infra compose service (postgres, redis, pgadmin, redis-commander, traefik) or a builder app container'
|
|
437
|
+
)
|
|
438
|
+
.addHelpText('after', RESTART_COMMAND_HELP_AFTER)
|
|
369
439
|
.action(async(service) => {
|
|
370
440
|
try {
|
|
371
|
-
if (
|
|
372
|
-
|
|
373
|
-
logger.log(
|
|
441
|
+
if (RESTART_INFRA_SERVICE_NAMES.includes(service)) {
|
|
442
|
+
logger.log('');
|
|
443
|
+
logger.log(sectionTitle('Restart'));
|
|
444
|
+
logger.log(headerKeyValue('Infra service:', service));
|
|
445
|
+
logger.log(formatProgress(`Restarting ${service}…`));
|
|
446
|
+
await infra.restartService(service, { suppressProgressLog: true });
|
|
447
|
+
logger.log(formatSuccessLine(`${service} restarted successfully`));
|
|
374
448
|
} else {
|
|
449
|
+
logger.log('');
|
|
450
|
+
logger.log(sectionTitle('Restart'));
|
|
451
|
+
logger.log(headerKeyValue('Application:', service));
|
|
375
452
|
await appLib.restartApp(service);
|
|
376
|
-
logger.log(
|
|
453
|
+
logger.log(formatSuccessLine(`${service} restarted successfully`));
|
|
377
454
|
}
|
|
378
455
|
} catch (error) {
|
|
379
456
|
handleCommandError(error, 'restart');
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI integration-client command setup (Controller OAuth / API clients).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Integration client CLI definitions
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 2.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { handleCommandError } = require('../utils/cli-utils');
|
|
10
|
+
const {
|
|
11
|
+
runIntegrationClientCreate,
|
|
12
|
+
runIntegrationClientList,
|
|
13
|
+
runIntegrationClientRotateSecret,
|
|
14
|
+
runIntegrationClientDelete,
|
|
15
|
+
runIntegrationClientUpdateGroups,
|
|
16
|
+
runIntegrationClientUpdateRedirectUris
|
|
17
|
+
} = require('../commands/integration-client');
|
|
18
|
+
|
|
19
|
+
const HELP_AFTER = `
|
|
20
|
+
Integration clients are machine identities for integrations, CI, Postman OAuth2, or API access.
|
|
21
|
+
Use: list (integration-client:read), create (integration-client:create), rotate-secret,
|
|
22
|
+
update-groups, update-redirect-uris (integration-client:update), delete (integration-client:delete).
|
|
23
|
+
The controller returns a one-time clientSecret on create and rotate-secret—save it immediately;
|
|
24
|
+
it cannot be retrieved again.
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
$ aifabrix integration-client create --key postman --display-name "Postman client" \\
|
|
28
|
+
--redirect-uris https://oauth.pstmn.io/v1/callback --group-names AI-Fabrix-Platform-Admins
|
|
29
|
+
$ aifabrix integration-client list
|
|
30
|
+
$ aifabrix integration-client rotate-secret --id <uuid>
|
|
31
|
+
$ aifabrix integration-client delete --id <uuid>
|
|
32
|
+
$ aifabrix integration-client update-groups --id <uuid> --group-names Group1,Group2
|
|
33
|
+
$ aifabrix integration-client update-redirect-uris --id <uuid> --redirect-uris https://app.example.com/callback
|
|
34
|
+
|
|
35
|
+
Run "aifabrix login" first.`;
|
|
36
|
+
|
|
37
|
+
function parseOptionalInt(val) {
|
|
38
|
+
return (val !== undefined && val !== null) ? parseInt(val, 10) : undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function addCreateCommand(integrationClient) {
|
|
42
|
+
integrationClient.command('create')
|
|
43
|
+
.description('Create an integration client and receive a one-time clientSecret (save it now; it will not be shown again)')
|
|
44
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
45
|
+
.option('-k, --key <key>', 'Stable key (lowercase alphanumeric and hyphens; required)')
|
|
46
|
+
.option('-n, --display-name <name>', 'Display name (required)')
|
|
47
|
+
.option('--keycloak-client-id <id>', 'Optional fixed Keycloak client id (when omitted, the server assigns one)')
|
|
48
|
+
.option('--redirect-uris <uris>', 'Comma-separated OAuth2 redirect URIs (required)')
|
|
49
|
+
.option('--group-names <names>', 'Comma-separated group names (optional; omit for OAuth-only clients)')
|
|
50
|
+
.option('-d, --description <description>', 'Optional description')
|
|
51
|
+
.action(async(options) => {
|
|
52
|
+
try {
|
|
53
|
+
await runIntegrationClientCreate({
|
|
54
|
+
controller: options.controller,
|
|
55
|
+
key: options.key,
|
|
56
|
+
displayName: options.displayName,
|
|
57
|
+
keycloakClientId: options.keycloakClientId,
|
|
58
|
+
redirectUris: options.redirectUris,
|
|
59
|
+
groupNames: options.groupNames,
|
|
60
|
+
description: options.description
|
|
61
|
+
});
|
|
62
|
+
} catch (error) {
|
|
63
|
+
handleCommandError(error, 'integration-client create');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function addListCommand(integrationClient) {
|
|
70
|
+
integrationClient.command('list')
|
|
71
|
+
.description('List integration clients (supports pagination and search)')
|
|
72
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
73
|
+
.option('--page <n>', 'Page number')
|
|
74
|
+
.option('--page-size <n>', 'Items per page')
|
|
75
|
+
.option('--search <term>', 'Search term')
|
|
76
|
+
.option('--sort <field>', 'Sort field/direction')
|
|
77
|
+
.option('--filter <expr>', 'Filter expression')
|
|
78
|
+
.action(async(options) => {
|
|
79
|
+
try {
|
|
80
|
+
await runIntegrationClientList({
|
|
81
|
+
controller: options.controller,
|
|
82
|
+
page: parseOptionalInt(options.page),
|
|
83
|
+
pageSize: parseOptionalInt(options.pageSize),
|
|
84
|
+
search: options.search,
|
|
85
|
+
sort: options.sort,
|
|
86
|
+
filter: options.filter
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
handleCommandError(error, 'integration-client list');
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function addRotateSecretCommand(integrationClient) {
|
|
96
|
+
integrationClient.command('rotate-secret')
|
|
97
|
+
.description('Rotate (regenerate) secret for an integration client; new secret shown once only')
|
|
98
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
99
|
+
.option('--id <uuid>', 'Integration client ID (required)')
|
|
100
|
+
.action(async(options) => {
|
|
101
|
+
try {
|
|
102
|
+
await runIntegrationClientRotateSecret({ controller: options.controller, id: options.id });
|
|
103
|
+
} catch (error) {
|
|
104
|
+
handleCommandError(error, 'integration-client rotate-secret');
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function addDeleteCommand(integrationClient) {
|
|
111
|
+
integrationClient.command('delete')
|
|
112
|
+
.description('Delete (deactivate) an integration client')
|
|
113
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
114
|
+
.option('--id <uuid>', 'Integration client ID (required)')
|
|
115
|
+
.action(async(options) => {
|
|
116
|
+
try {
|
|
117
|
+
await runIntegrationClientDelete({ controller: options.controller, id: options.id });
|
|
118
|
+
} catch (error) {
|
|
119
|
+
handleCommandError(error, 'integration-client delete');
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function addUpdateGroupsCommand(integrationClient) {
|
|
126
|
+
integrationClient.command('update-groups')
|
|
127
|
+
.description('Update group assignments for an integration client')
|
|
128
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
129
|
+
.option('--id <uuid>', 'Integration client ID (required)')
|
|
130
|
+
.option('--group-names <names>', 'Comma-separated group names (required)')
|
|
131
|
+
.action(async(options) => {
|
|
132
|
+
try {
|
|
133
|
+
await runIntegrationClientUpdateGroups({
|
|
134
|
+
controller: options.controller,
|
|
135
|
+
id: options.id,
|
|
136
|
+
groupNames: options.groupNames
|
|
137
|
+
});
|
|
138
|
+
} catch (error) {
|
|
139
|
+
handleCommandError(error, 'integration-client update-groups');
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function addUpdateRedirectUrisCommand(integrationClient) {
|
|
146
|
+
integrationClient.command('update-redirect-uris')
|
|
147
|
+
.description('Update redirect URIs for an integration client (min 1)')
|
|
148
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
149
|
+
.option('--id <uuid>', 'Integration client ID (required)')
|
|
150
|
+
.option('--redirect-uris <uris>', 'Comma-separated redirect URIs (required, min 1)')
|
|
151
|
+
.action(async(options) => {
|
|
152
|
+
try {
|
|
153
|
+
await runIntegrationClientUpdateRedirectUris({
|
|
154
|
+
controller: options.controller,
|
|
155
|
+
id: options.id,
|
|
156
|
+
redirectUris: options.redirectUris
|
|
157
|
+
});
|
|
158
|
+
} catch (error) {
|
|
159
|
+
handleCommandError(error, 'integration-client update-redirect-uris');
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Registers integration-client commands
|
|
167
|
+
* @param {Command} program - Commander program instance
|
|
168
|
+
*/
|
|
169
|
+
function setupIntegrationClientCommands(program) {
|
|
170
|
+
const integrationClient = program
|
|
171
|
+
.command('integration-client')
|
|
172
|
+
.description('OAuth integration clients on Controller (integrations, CI, API access)')
|
|
173
|
+
.addHelpText('after', HELP_AFTER);
|
|
174
|
+
addCreateCommand(integrationClient);
|
|
175
|
+
addListCommand(integrationClient);
|
|
176
|
+
addRotateSecretCommand(integrationClient);
|
|
177
|
+
addDeleteCommand(integrationClient);
|
|
178
|
+
addUpdateGroupsCommand(integrationClient);
|
|
179
|
+
addUpdateRedirectUrisCommand(integrationClient);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
module.exports = { setupIntegrationClientCommands };
|
|
@@ -17,11 +17,30 @@ function setupParametersCommands(program) {
|
|
|
17
17
|
|
|
18
18
|
parameters
|
|
19
19
|
.command('validate')
|
|
20
|
-
.description(
|
|
20
|
+
.description(
|
|
21
|
+
'Validate builder/*/env.template kv:// references against infra.parameter.yaml'
|
|
22
|
+
)
|
|
21
23
|
.option('--catalog <path>', 'Override path to infra.parameter.yaml')
|
|
24
|
+
.option('--verbose', 'Print scanned files and scan summary')
|
|
25
|
+
.addHelpText(
|
|
26
|
+
'after',
|
|
27
|
+
`
|
|
28
|
+
Examples:
|
|
29
|
+
aifabrix parameters validate
|
|
30
|
+
aifabrix parameters validate --verbose
|
|
31
|
+
aifabrix parameters validate --catalog ./lib/schema/infra.parameter.yaml
|
|
32
|
+
|
|
33
|
+
Notes:
|
|
34
|
+
- Scans builder/* apps only (integration/* is intentionally skipped).
|
|
35
|
+
- Extracts kv://KEY references from env.template and checks KEY coverage in the catalog.
|
|
36
|
+
`
|
|
37
|
+
)
|
|
22
38
|
.action(async(opts) => {
|
|
23
39
|
try {
|
|
24
|
-
const result = await handleParametersValidate({
|
|
40
|
+
const result = await handleParametersValidate({
|
|
41
|
+
catalogPath: opts.catalog,
|
|
42
|
+
verbose: Boolean(opts.verbose)
|
|
43
|
+
});
|
|
25
44
|
if (!result.valid) process.exit(1);
|
|
26
45
|
} catch (error) {
|
|
27
46
|
handleCommandError(error, 'parameters validate');
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI registration for `aifabrix setup` and `aifabrix teardown`.
|
|
3
|
+
*
|
|
4
|
+
* `setup` is the one-shot platform installer. When no infrastructure is
|
|
5
|
+
* detected it runs a small wizard (admin email/password, AI tool keys) and
|
|
6
|
+
* then `up-infra` + `up-platform`. When infra is already up, it offers a
|
|
7
|
+
* mode menu (re-install, wipe data, clean install files, update images).
|
|
8
|
+
*
|
|
9
|
+
* `teardown` is the symmetrical inverse of `setup`: `down-infra -v` plus a
|
|
10
|
+
* full clean of the AI Fabrix system directory (everything except
|
|
11
|
+
* `config.yaml`).
|
|
12
|
+
*
|
|
13
|
+
* @fileoverview CLI command setup for setup/teardown
|
|
14
|
+
* @author AI Fabrix Team
|
|
15
|
+
* @version 2.0.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
'use strict';
|
|
19
|
+
|
|
20
|
+
const { handleCommandError } = require('../utils/cli-utils');
|
|
21
|
+
const { handleSetup } = require('../commands/setup');
|
|
22
|
+
const { handleTeardown } = require('../commands/teardown');
|
|
23
|
+
|
|
24
|
+
const SETUP_HELP_AFTER = `
|
|
25
|
+
What this command does:
|
|
26
|
+
- With no infra running: prompts for admin email/password (used for Postgres, pgAdmin, Keycloak), prompts for an AI tool (OpenAI or Azure OpenAI) only when keys are not already set, then runs up-infra and up-platform.
|
|
27
|
+
- With infra running: shows a mode menu:
|
|
28
|
+
1) Re-install — stop infra and remove all volumes, then up-infra + up-platform --force.
|
|
29
|
+
2) Wipe data — drop every database and DB user, then up-infra + up-platform --force.
|
|
30
|
+
3) Clean installation files — remove user-local secrets, then up-infra + up-platform --force.
|
|
31
|
+
4) Update images — pull the latest infra and platform images, then up-infra + up-platform.
|
|
32
|
+
|
|
33
|
+
AI tool keys are read from the user-local file (~/.aifabrix/secrets.local.yaml) merged with the shared aifabrix-secrets file. If either source already provides keys, the AI tool prompt is skipped.
|
|
34
|
+
|
|
35
|
+
Use 'aifabrix teardown' to fully remove the local installation.
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
const TEARDOWN_HELP_AFTER = `
|
|
39
|
+
What this command does:
|
|
40
|
+
- Runs down-infra -v (stops all infra + apps, removes every Docker volume).
|
|
41
|
+
- Removes every file and subfolder inside ~/.aifabrix/ EXCEPT config.yaml.
|
|
42
|
+
This includes secrets.local.yaml, admin-secrets.env, auth/token files,
|
|
43
|
+
and infra-dev*/ directories.
|
|
44
|
+
|
|
45
|
+
This is the symmetrical inverse of 'aifabrix setup'. Use --yes / -y to skip the confirmation prompt in CI.
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Register the setup command on the Commander program.
|
|
50
|
+
* @param {import('commander').Command} program
|
|
51
|
+
*/
|
|
52
|
+
function registerSetup(program) {
|
|
53
|
+
program
|
|
54
|
+
.command('setup')
|
|
55
|
+
.description('Install or refresh the full AI Fabrix platform (infra + miso + dataplane)')
|
|
56
|
+
.option('-d, --developer <id>', 'Pin developer ID before fresh install (fresh path only; ignored when infra is already up)')
|
|
57
|
+
.option('-y, --yes', 'Skip destructive confirmation prompts (re-install, wipe data, teardown)')
|
|
58
|
+
.addHelpText('after', SETUP_HELP_AFTER)
|
|
59
|
+
.action(async(options) => {
|
|
60
|
+
try {
|
|
61
|
+
await handleSetup(options || {});
|
|
62
|
+
} catch (error) {
|
|
63
|
+
handleCommandError(error, 'setup');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Register the teardown command on the Commander program.
|
|
71
|
+
* @param {import('commander').Command} program
|
|
72
|
+
*/
|
|
73
|
+
function registerTeardown(program) {
|
|
74
|
+
program
|
|
75
|
+
.command('teardown')
|
|
76
|
+
.description('Tear down local AI Fabrix infra and clean ~/.aifabrix/ except config.yaml')
|
|
77
|
+
.option('-y, --yes', 'Skip the confirmation prompt')
|
|
78
|
+
.addHelpText('after', TEARDOWN_HELP_AFTER)
|
|
79
|
+
.action(async(options) => {
|
|
80
|
+
try {
|
|
81
|
+
await handleTeardown(options || {});
|
|
82
|
+
} catch (error) {
|
|
83
|
+
handleCommandError(error, 'teardown');
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Register all setup-platform commands on the Commander program.
|
|
91
|
+
* @param {import('commander').Command} program
|
|
92
|
+
*/
|
|
93
|
+
function setupPlatformCommands(program) {
|
|
94
|
+
registerSetup(program);
|
|
95
|
+
registerTeardown(program);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = {
|
|
99
|
+
setupPlatformCommands,
|
|
100
|
+
registerSetup,
|
|
101
|
+
registerTeardown
|
|
102
|
+
};
|