@aifabrix/builder 2.43.0 → 2.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/anchor-docs.mdc +15 -0
- package/README.md +1 -1
- package/anchor-docs/README.md +10 -0
- package/anchor-docs/_TEMPLATE +24 -0
- package/bin/aifabrix.js +13 -4
- package/integration/hubspot-test/README.md +31 -0
- package/integration/hubspot-test/create-hubspot.js +5 -5
- package/integration/hubspot-test/hubspot-test-datasource-company.json +58 -462
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +61 -555
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +63 -506
- package/integration/hubspot-test/hubspot-test-datasource-users.json +42 -83
- package/integration/hubspot-test/hubspot-test-deploy.json +3 -3
- package/integration/hubspot-test/test-dataplane-down-tests.js +1 -7
- package/integration/hubspot-test/test-dataplane-down.js +3 -3
- package/integration/hubspot-test/test.js +35 -43
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
- package/integration/roundtrip-test-local/README.md +144 -0
- package/integration/roundtrip-test-local/application.yaml +13 -0
- package/integration/roundtrip-test-local/env.template +15 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
- package/integration/roundtrip-test-local2/README.md +144 -0
- package/integration/roundtrip-test-local2/application.yaml +13 -0
- package/integration/roundtrip-test-local2/env.template +15 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
- package/integration/test/wizard.yaml +8 -0
- package/jest.config.default.js +10 -0
- package/jest.config.integration.fixtures.js +22 -0
- package/jest.config.integration.js +21 -18
- package/jest.config.isolated.js +10 -0
- package/jest.projects.js +288 -0
- package/lib/api/datasources-core.api.js +3 -3
- package/lib/api/dev-mtls-request.js +110 -0
- package/lib/api/dev-server-https.js +145 -0
- package/lib/api/dev.api.js +133 -144
- package/lib/api/index.js +0 -1
- package/lib/api/pipeline.api.js +67 -20
- package/lib/api/types/dev.types.js +4 -3
- package/lib/api/types/pipeline.types.js +8 -5
- package/lib/api/types/validation-run.types.js +56 -0
- package/lib/api/validation-run.api.js +99 -0
- package/lib/api/validation-runner.js +99 -0
- package/lib/app/config.js +1 -1
- package/lib/app/deploy-status-display.js +2 -2
- package/lib/app/deploy.js +7 -6
- package/lib/app/display.js +2 -1
- package/lib/app/dockerfile.js +3 -2
- package/lib/app/down.js +2 -1
- package/lib/app/helpers.js +6 -5
- package/lib/app/index.js +27 -8
- package/lib/app/list.js +7 -6
- package/lib/app/push.js +4 -3
- package/lib/app/register.js +16 -7
- package/lib/app/rotate-secret.js +14 -13
- package/lib/app/run-container-start.js +184 -0
- package/lib/app/run-docker-fallback.js +108 -0
- package/lib/app/run-env-compose.js +30 -42
- package/lib/app/run-helpers.js +49 -126
- package/lib/app/run-infra-requirements.js +30 -0
- package/lib/app/run-resolve-image.js +21 -0
- package/lib/app/run.js +74 -21
- package/lib/app/show-display.js +1 -1
- package/lib/app/show.js +1 -1
- package/lib/build/index.js +13 -10
- package/lib/cli/index.js +2 -0
- package/lib/cli/setup-app.help.js +67 -0
- package/lib/cli/setup-app.js +57 -121
- package/lib/cli/setup-app.test-commands.js +179 -0
- package/lib/cli/setup-auth.js +19 -5
- package/lib/cli/setup-credential-deployment.js +22 -8
- package/lib/cli/setup-dev-path-commands.js +124 -0
- package/lib/cli/setup-dev.js +170 -113
- package/lib/cli/setup-environment.js +7 -1
- package/lib/cli/setup-external-system.js +62 -22
- package/lib/cli/setup-infra.js +126 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +106 -8
- package/lib/cli/setup-service-user.js +1 -1
- package/lib/cli/setup-utility.js +36 -20
- package/lib/commands/app-down.js +5 -7
- package/lib/commands/app-install.js +14 -7
- package/lib/commands/app-logs.js +13 -10
- package/lib/commands/app-shell.js +4 -1
- package/lib/commands/app-test.js +25 -19
- package/lib/commands/app.js +22 -10
- package/lib/commands/auth-config.js +6 -6
- package/lib/commands/auth-status.js +4 -3
- package/lib/commands/credential-env.js +4 -3
- package/lib/commands/credential-list.js +5 -4
- package/lib/commands/credential-push.js +4 -3
- package/lib/commands/datasource-unified-test-cli.js +495 -0
- package/lib/commands/datasource-unified-test-cli.options.js +149 -0
- package/lib/commands/datasource-validation-cli.js +129 -0
- package/lib/commands/datasource.js +105 -98
- package/lib/commands/deployment-list.js +6 -5
- package/lib/commands/dev-cli-handlers.js +122 -18
- package/lib/commands/dev-down.js +4 -3
- package/lib/commands/dev-init.js +231 -116
- package/lib/commands/dev-show-display.js +473 -0
- package/lib/commands/login-credentials.js +3 -2
- package/lib/commands/login-device.js +4 -3
- package/lib/commands/login.js +5 -4
- package/lib/commands/logout.js +8 -7
- package/lib/commands/parameters-validate.js +54 -0
- package/lib/commands/repair-datasource.js +314 -68
- package/lib/commands/repair-env-template.js +2 -2
- package/lib/commands/repair.js +21 -3
- package/lib/commands/secrets-list.js +23 -12
- package/lib/commands/secrets-remove-all.js +220 -0
- package/lib/commands/secrets-remove.js +21 -12
- package/lib/commands/secrets-set.js +21 -12
- package/lib/commands/secrets-validate.js +4 -4
- package/lib/commands/secure.js +10 -9
- package/lib/commands/service-user.js +26 -25
- package/lib/commands/test-e2e-external.js +27 -1
- package/lib/commands/up-common.js +3 -2
- package/lib/commands/up-dataplane.js +29 -16
- package/lib/commands/up-miso.js +19 -29
- package/lib/commands/upload.js +138 -39
- package/lib/commands/wizard-core-helpers.js +1 -1
- package/lib/commands/wizard-dataplane.js +4 -3
- package/lib/commands/wizard-helpers.js +3 -3
- package/lib/commands/wizard.js +2 -2
- package/lib/core/admin-secrets.js +14 -5
- package/lib/core/audit-logger.js +12 -4
- package/lib/core/config-attach-extensions.js +46 -0
- package/lib/core/config-runtime-paths.js +29 -0
- package/lib/core/config.js +55 -56
- package/lib/core/diff.js +3 -2
- package/lib/core/ensure-encryption-key.js +1 -1
- package/lib/core/secrets-ensure-infra.js +77 -0
- package/lib/core/secrets-ensure.js +120 -64
- package/lib/core/secrets-env-write.js +35 -7
- package/lib/core/secrets-infra-placeholder-sync.js +61 -0
- package/lib/core/secrets.js +200 -37
- package/lib/core/templates-env.js +4 -3
- package/lib/datasource/abac-validator.js +1 -10
- package/lib/datasource/deploy.js +75 -53
- package/lib/datasource/field-reference-validator.js +9 -6
- package/lib/datasource/integration-context.js +63 -0
- package/lib/datasource/list.js +8 -7
- package/lib/datasource/log-viewer.js +84 -53
- package/lib/datasource/resolve-app.js +4 -4
- package/lib/datasource/test-e2e.js +95 -146
- package/lib/datasource/test-integration.js +114 -122
- package/lib/datasource/unified-validation-run-body.js +65 -0
- package/lib/datasource/unified-validation-run-post.js +23 -0
- package/lib/datasource/unified-validation-run-resolve.js +43 -0
- package/lib/datasource/unified-validation-run.js +92 -0
- package/lib/datasource/validate.js +157 -13
- package/lib/deployment/deployer.js +4 -3
- package/lib/deployment/environment.js +7 -6
- package/lib/deployment/push.js +17 -8
- package/lib/external-system/delete.js +4 -3
- package/lib/external-system/deploy.js +131 -53
- package/lib/external-system/download-helpers.js +1 -1
- package/lib/external-system/download.js +7 -6
- package/lib/external-system/generator.js +92 -6
- package/lib/external-system/integration-test-dispatch.js +26 -0
- package/lib/external-system/test-execution.js +5 -1
- package/lib/external-system/test-helpers.js +0 -4
- package/lib/external-system/test-system-level-helpers.js +110 -0
- package/lib/external-system/test-system-level.js +83 -44
- package/lib/external-system/test.js +59 -8
- package/lib/generator/builders.js +23 -11
- package/lib/generator/deploy-manifest-azure-kv.js +81 -0
- package/lib/generator/external.js +16 -4
- package/lib/generator/helpers.js +58 -3
- package/lib/generator/index.js +4 -0
- package/lib/generator/split-readme.js +12 -7
- package/lib/generator/split-variables.js +2 -1
- package/lib/generator/split.js +1 -1
- package/lib/generator/wizard-readme.js +3 -3
- package/lib/generator/wizard.js +8 -8
- package/lib/infrastructure/compose.js +60 -6
- package/lib/infrastructure/helpers.js +201 -29
- package/lib/infrastructure/index.js +28 -17
- package/lib/infrastructure/services.js +21 -15
- package/lib/internal/fs-real-sync.js +104 -0
- package/lib/internal/node-fs.js +98 -0
- package/lib/parameters/database-secret-values.js +173 -0
- package/lib/parameters/infra-kv-discovery.js +121 -0
- package/lib/parameters/infra-parameter-catalog.js +458 -0
- package/lib/parameters/infra-parameter-validate.js +64 -0
- package/lib/schema/application-schema.json +37 -17
- package/lib/schema/datasource-test-run.schema.json +493 -0
- package/lib/schema/deployment-rules.yaml +102 -63
- package/lib/schema/external-datasource.schema.json +1200 -442
- package/lib/schema/external-system.schema.json +181 -5
- package/lib/schema/flag-map-validation-run.json +31 -0
- package/lib/schema/infra-parameter.schema.json +106 -0
- package/lib/schema/infra.parameter.yaml +421 -0
- package/lib/schema/type/credential-auth-templates.json +40 -0
- package/lib/schema/type/document-storage.json +213 -0
- package/lib/schema/type/message-service.json +123 -0
- package/lib/schema/type/vector-store.json +88 -0
- package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
- package/lib/utils/api-error-handler.js +2 -2
- package/lib/utils/api.js +49 -14
- package/lib/utils/app-register-api.js +3 -2
- package/lib/utils/app-register-auth.js +1 -1
- package/lib/utils/app-register-config.js +4 -4
- package/lib/utils/app-register-display.js +3 -2
- package/lib/utils/app-register-validator.js +3 -2
- package/lib/utils/app-run-containers.js +26 -22
- package/lib/utils/app-scoped-config.js +31 -0
- package/lib/utils/app-service-env-from-builder.js +164 -0
- package/lib/utils/build-copy.js +1 -1
- package/lib/utils/build-helpers.js +20 -20
- package/lib/utils/build-resolve-image.js +165 -0
- package/lib/utils/cli-layout-chalk.js +8 -0
- package/lib/utils/cli-test-layout-chalk.js +267 -0
- package/lib/utils/cli-utils.js +88 -11
- package/lib/utils/compose-db-passwords.js +138 -0
- package/lib/utils/compose-generate-docker-compose.js +216 -0
- package/lib/utils/compose-generator.js +197 -291
- package/lib/utils/compose-miso-env.js +18 -0
- package/lib/utils/compose-traefik-ingress-base.js +158 -0
- package/lib/utils/config-paths.js +166 -7
- package/lib/utils/config-scoped-resources-preference.js +41 -0
- package/lib/utils/controller-deployment-outcome.js +68 -0
- package/lib/utils/credential-display.js +2 -2
- package/lib/utils/dataplane-pipeline-warning.js +4 -3
- package/lib/utils/datasource-test-run-capability-scope.js +43 -0
- package/lib/utils/datasource-test-run-debug-display.js +137 -0
- package/lib/utils/datasource-test-run-debug-slice.js +93 -0
- package/lib/utils/datasource-test-run-display.js +442 -0
- package/lib/utils/datasource-test-run-exit.js +58 -0
- package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
- package/lib/utils/datasource-test-run-report-version.js +51 -0
- package/lib/utils/datasource-test-run-schema-sync.js +59 -0
- package/lib/utils/datasource-test-run-tty-log.js +81 -0
- package/lib/utils/datasource-validation-watch.js +266 -0
- package/lib/utils/declarative-url-ports.js +47 -0
- package/lib/utils/derive-env-key-from-client-id.js +41 -0
- package/lib/utils/dev-ca-install.js +185 -23
- package/lib/utils/dev-cert-helper.js +266 -17
- package/lib/utils/dev-hosts-helper.js +307 -0
- package/lib/utils/dev-init-cert-hints.js +37 -0
- package/lib/utils/dev-init-health-messages.js +52 -0
- package/lib/utils/dev-init-resolve.js +86 -0
- package/lib/utils/dev-init-ssh-merge.js +65 -0
- package/lib/utils/dev-ssh-config-helper.js +196 -0
- package/lib/utils/dev-user-groups.js +93 -0
- package/lib/utils/docker-build.js +42 -17
- package/lib/utils/docker-exec.js +28 -0
- package/lib/utils/docker-manifest-public-port.js +116 -0
- package/lib/utils/docker-not-running-hint.js +52 -0
- package/lib/utils/docker.js +98 -11
- package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
- package/lib/utils/env-config-loader.js +10 -91
- package/lib/utils/env-copy.js +19 -10
- package/lib/utils/env-map.js +35 -8
- package/lib/utils/env-template.js +2 -2
- package/lib/utils/environment-scoped-resources.js +144 -0
- package/lib/utils/error-formatter.js +92 -13
- package/lib/utils/error-formatters/http-status-errors.js +6 -5
- package/lib/utils/error-formatters/network-errors.js +2 -1
- package/lib/utils/error-formatters/permission-errors.js +2 -1
- package/lib/utils/error-formatters/validation-errors.js +2 -1
- package/lib/utils/external-readme.js +8 -1
- package/lib/utils/external-system-display.js +234 -136
- package/lib/utils/external-system-local-test-tty.js +389 -0
- package/lib/utils/external-system-readiness-core.js +377 -0
- package/lib/utils/external-system-readiness-deploy-display.js +270 -0
- package/lib/utils/external-system-readiness-display-internals.js +150 -0
- package/lib/utils/external-system-readiness-display.js +186 -0
- package/lib/utils/external-system-test-helpers.js +24 -6
- package/lib/utils/external-system-validators.js +30 -12
- package/lib/utils/health-check-url.js +119 -0
- package/lib/utils/health-check.js +59 -25
- package/lib/utils/help-builder.js +11 -8
- package/lib/utils/image-version.js +4 -8
- package/lib/utils/infra-containers.js +4 -7
- package/lib/utils/infra-env-defaults.js +162 -0
- package/lib/utils/infra-status-display.js +167 -0
- package/lib/utils/infra-status.js +16 -8
- package/lib/utils/local-secrets.js +3 -4
- package/lib/utils/paths.js +134 -47
- package/lib/utils/port-resolver.js +10 -23
- package/lib/utils/redis-env-scope.js +62 -0
- package/lib/utils/register-aifabrix-shell-env.js +204 -0
- package/lib/utils/remote-builder-validation.js +99 -0
- package/lib/utils/remote-dev-auth.js +117 -21
- package/lib/utils/remote-docker-env.js +67 -15
- package/lib/utils/remote-secrets-loader.js +13 -4
- package/lib/utils/resolve-docker-image-ref.js +124 -0
- package/lib/utils/schema-loader.js +22 -9
- package/lib/utils/secrets-bash-kv.js +25 -0
- package/lib/utils/secrets-generator.js +169 -49
- package/lib/utils/secrets-helpers.js +70 -59
- package/lib/utils/secrets-kv-scope.js +60 -0
- package/lib/utils/secrets-utils.js +32 -38
- package/lib/utils/secrets-validation.js +3 -1
- package/lib/utils/secrets-yaml-preserve.js +109 -0
- package/lib/utils/ssh-key-helper.js +4 -2
- package/lib/utils/template-helpers.js +2 -2
- package/lib/utils/test-log-writer.js +3 -3
- package/lib/utils/token-manager.js +1 -2
- package/lib/utils/url-declarative-public-base.js +188 -0
- package/lib/utils/url-declarative-resolve-build.js +493 -0
- package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
- package/lib/utils/url-declarative-resolve.js +220 -0
- package/lib/utils/url-declarative-token-parse.js +74 -0
- package/lib/utils/url-declarative-url-flags.js +50 -0
- package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
- package/lib/utils/url-public-path-prefix.js +34 -0
- package/lib/utils/urls-local-registry.js +220 -0
- package/lib/utils/validation-report-tty-kit.js +77 -0
- package/lib/utils/validation-run-poll.js +89 -0
- package/lib/utils/validation-run-post-retry.js +73 -0
- package/lib/utils/validation-run-request.js +98 -0
- package/lib/utils/variable-transformer.js +21 -4
- package/lib/utils/yaml-preserve.js +33 -14
- package/lib/validation/datasource-warnings.js +56 -0
- package/lib/validation/env-template-auth.js +1 -1
- package/lib/validation/external-manifest-validator.js +27 -7
- package/lib/validation/validate-display.js +37 -31
- package/lib/validation/validate.js +4 -13
- package/lib/validation/validator-unresolved-placeholders.js +98 -0
- package/lib/validation/validator.js +22 -65
- package/lib/validation/wizard-config-validator.js +2 -1
- package/package.json +7 -3
- package/scripts/check-datasource-test-run-schema-sync.js +34 -0
- package/scripts/diagnose-cli.js +150 -0
- package/scripts/install-local.js +304 -55
- package/templates/README.md +15 -2
- package/templates/applications/dataplane/application.yaml +52 -2
- package/templates/applications/dataplane/env.template +75 -17
- package/templates/applications/dataplane/rbac.yaml +8 -0
- package/templates/applications/keycloak/application.yaml +9 -1
- package/templates/applications/keycloak/env.template +15 -6
- package/templates/applications/miso-controller/application.yaml +10 -2
- package/templates/applications/miso-controller/env.template +42 -12
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/external-system/README.md.hbs +20 -7
- package/templates/external-system/deploy.js.hbs +5 -5
- package/templates/external-system/external-datasource.yaml.hbs +197 -118
- package/templates/infra/compose.yaml.hbs +20 -4
- package/templates/python/docker-compose.hbs +16 -0
- package/templates/typescript/docker-compose.hbs +16 -0
- package/lib/api/external-test.api.js +0 -111
- package/lib/schema/env-config.yaml +0 -60
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* CLI external system command setup (download, upload, delete, test-integration).
|
|
3
3
|
*
|
|
4
4
|
* Registers these commands on the Commander program:
|
|
5
|
-
* - download <
|
|
6
|
-
* - upload <
|
|
7
|
-
* - delete <
|
|
5
|
+
* - download <systemKey> – Download external system from dataplane to integration/<systemKey>/
|
|
6
|
+
* - upload <systemKey> – Upload publishes to dataplane and registers the app with the controller (draft)
|
|
7
|
+
* - delete <systemKey> – Delete external system and associated datasources from dataplane
|
|
8
8
|
* - test-integration <app> – Run integration tests (builder: in container; external: via dataplane pipeline)
|
|
9
9
|
*
|
|
10
10
|
* @fileoverview External system command definitions for AI Fabrix Builder CLI
|
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
18
|
+
const { TEST_INTEGRATION_HELP_AFTER } = require('./setup-app.help');
|
|
18
19
|
|
|
19
20
|
function setupDownloadCommand(program) {
|
|
20
|
-
program.command('download <
|
|
21
|
-
.description('
|
|
21
|
+
program.command('download <systemKey>')
|
|
22
|
+
.description('Pull external system from dataplane into integration/<key>/')
|
|
22
23
|
.option('--format <format>', 'Output format: json | yaml (default: yaml or config format)')
|
|
23
24
|
.option('--dry-run', 'Show what would be downloaded without actually downloading')
|
|
24
25
|
.option('--force', 'Overwrite existing README.md without prompting')
|
|
@@ -39,13 +40,24 @@ function setupDownloadCommand(program) {
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
function setupUploadCommand(program) {
|
|
42
|
-
program.command('upload <
|
|
43
|
-
.description('
|
|
43
|
+
program.command('upload <systemKey>')
|
|
44
|
+
.description('Validate, publish to dataplane, and register with controller (draft application)')
|
|
44
45
|
.option('--dry-run', 'Validate and build payload only; no API calls')
|
|
46
|
+
.option('-v, --verbose', 'Run server-side pipeline validate and print warnings before publish')
|
|
47
|
+
.option('--probe', 'After publish, run dataplane runtime checks (validation/run); slower')
|
|
48
|
+
.option('--minimal', 'Print only a short readiness summary after upload')
|
|
49
|
+
.option('--probe-timeout <ms>', 'Timeout for --probe (default: 120000)', '120000')
|
|
45
50
|
.action(async(systemKey, options) => {
|
|
46
51
|
try {
|
|
47
52
|
const upload = require('../commands/upload');
|
|
48
|
-
|
|
53
|
+
const probeTimeout =
|
|
54
|
+
options.probeTimeout === undefined || options.probeTimeout === null
|
|
55
|
+
? 120000
|
|
56
|
+
: Number(options.probeTimeout);
|
|
57
|
+
await upload.uploadExternalSystem(systemKey, {
|
|
58
|
+
...options,
|
|
59
|
+
probeTimeout: Number.isFinite(probeTimeout) ? probeTimeout : 120000
|
|
60
|
+
});
|
|
49
61
|
} catch (error) {
|
|
50
62
|
handleCommandError(error, 'upload');
|
|
51
63
|
process.exit(1);
|
|
@@ -54,9 +66,9 @@ function setupUploadCommand(program) {
|
|
|
54
66
|
}
|
|
55
67
|
|
|
56
68
|
function setupDeleteCommand(program) {
|
|
57
|
-
program.command('delete <
|
|
58
|
-
.description('
|
|
59
|
-
.option('--type <type>', 'Application type (default: external; use "external" to target integration/<
|
|
69
|
+
program.command('delete <systemKey>')
|
|
70
|
+
.description('Remove external system and its datasources from dataplane')
|
|
71
|
+
.option('--type <type>', 'Application type (default: external; use "external" to target integration/<systemKey>)')
|
|
60
72
|
.option('--yes', 'Skip confirmation prompt')
|
|
61
73
|
.option('--force', 'Skip confirmation prompt (alias for --yes)')
|
|
62
74
|
.action(async(systemKey, options) => {
|
|
@@ -111,9 +123,15 @@ async function tryBuilderTestIntegration(appName, options) {
|
|
|
111
123
|
*/
|
|
112
124
|
async function runExternalSystemTestIntegration(appName, options) {
|
|
113
125
|
const test = require('../external-system/test');
|
|
114
|
-
const opts = {
|
|
126
|
+
const opts = {
|
|
127
|
+
...options,
|
|
128
|
+
environment: options.env || options.environment,
|
|
129
|
+
debug: options.debug,
|
|
130
|
+
perDatasource: options.perDatasource,
|
|
131
|
+
sync: options.sync === true
|
|
132
|
+
};
|
|
115
133
|
const results = await test.testExternalSystemIntegration(appName, opts);
|
|
116
|
-
test.displayIntegrationTestResults(results, options.verbose);
|
|
134
|
+
test.displayIntegrationTestResults(results, options.verbose, { debug: options.debug, runType: 'integration' });
|
|
117
135
|
if (!results.success) process.exit(1);
|
|
118
136
|
}
|
|
119
137
|
|
|
@@ -126,6 +144,12 @@ async function runExternalSystemTestIntegration(appName, options) {
|
|
|
126
144
|
async function runTestIntegrationCommand(appName, options) {
|
|
127
145
|
const pathsUtil = require('../utils/paths');
|
|
128
146
|
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
147
|
+
if (options.sync === true && appType && appType.baseDir === 'builder') {
|
|
148
|
+
throw new Error(
|
|
149
|
+
'Option --sync applies only to external integration tests (integration/<systemKey>/). ' +
|
|
150
|
+
'For a builder app use aifabrix upload <systemKey> from the integration folder, or run test-integration without --sync.'
|
|
151
|
+
);
|
|
152
|
+
}
|
|
129
153
|
if (appType && appType.baseDir === 'builder') {
|
|
130
154
|
const { runAppTestIntegration } = require('../commands/app-test');
|
|
131
155
|
const opts = { env: options.env || options.environment || 'dev' };
|
|
@@ -133,23 +157,39 @@ async function runTestIntegrationCommand(appName, options) {
|
|
|
133
157
|
return;
|
|
134
158
|
}
|
|
135
159
|
const ranBuilder = await tryBuilderTestIntegration(appName, options);
|
|
136
|
-
if (ranBuilder)
|
|
160
|
+
if (ranBuilder) {
|
|
161
|
+
if (options.sync === true) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
'Option --sync applies only when test-integration runs against an external integration folder on the dataplane. ' +
|
|
164
|
+
'This run used a builder-style path instead. Remove --sync or use an integration/<systemKey>/ app.'
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
137
169
|
await runExternalSystemTestIntegration(appName, options);
|
|
138
170
|
}
|
|
139
171
|
|
|
140
172
|
function setupExternalSystemTestCommands(program) {
|
|
141
173
|
// 'test <app>' is registered in setup-app.js and dispatches by app type (builder vs external)
|
|
142
174
|
program.command('test-integration <app>')
|
|
143
|
-
.description('
|
|
144
|
-
.option('-
|
|
145
|
-
.option('-p, --payload <file>', 'Path to custom test payload file')
|
|
146
|
-
.option('-e, --env <env>', 'Environment: dev, tst, or pro (default: from aifabrix auth config)')
|
|
175
|
+
.description('Integration tests: builder in container; external via dataplane')
|
|
176
|
+
.option('-e, --env <env>', 'Environment: dev, tst, or pro (builder: dev/tst for container)', 'dev')
|
|
147
177
|
.option('-v, --verbose', 'Show detailed test output')
|
|
148
|
-
.option('--debug', 'Include debug output and write log to integration/<
|
|
149
|
-
.option(
|
|
150
|
-
|
|
178
|
+
.option('-d, --debug', 'Include debug output and write log to integration/<systemKey>/logs/')
|
|
179
|
+
.option(
|
|
180
|
+
'--sync',
|
|
181
|
+
'Publish local system and datasource files to the dataplane before running tests (same as aifabrix upload <systemKey>)'
|
|
182
|
+
)
|
|
183
|
+
.addHelpText('after', TEST_INTEGRATION_HELP_AFTER)
|
|
184
|
+
.action(async(appName, options, cmd) => {
|
|
151
185
|
try {
|
|
152
|
-
|
|
186
|
+
const rawArgs = Array.isArray(cmd?.rawArgs) ? cmd.rawArgs : [];
|
|
187
|
+
const envExplicit = rawArgs.includes('-e') || rawArgs.includes('--env');
|
|
188
|
+
const opts = {
|
|
189
|
+
...options,
|
|
190
|
+
env: envExplicit ? options.env : undefined
|
|
191
|
+
};
|
|
192
|
+
await runTestIntegrationCommand(appName, opts);
|
|
153
193
|
} catch (error) {
|
|
154
194
|
handleCommandError(error, 'test-integration');
|
|
155
195
|
process.exit(1);
|
package/lib/cli/setup-infra.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* CLI infrastructure command setup (up-infra, up-platform, up-miso, up-dataplane, down-infra, doctor, status, restart).
|
|
3
4
|
*
|
|
@@ -18,6 +19,22 @@ const { handleLogin } = require('../commands/login');
|
|
|
18
19
|
const { handleUpMiso } = require('../commands/up-miso');
|
|
19
20
|
const { handleUpDataplane } = require('../commands/up-dataplane');
|
|
20
21
|
const { cleanBuilderAppDirs } = require('../commands/up-common');
|
|
22
|
+
const {
|
|
23
|
+
loadInfraStatusSummary,
|
|
24
|
+
formatInfraStatusTitleLine,
|
|
25
|
+
logInfraStatusConfigurationSummary,
|
|
26
|
+
logPaddedFieldRow
|
|
27
|
+
} = require('../utils/infra-status-display');
|
|
28
|
+
|
|
29
|
+
const UP_INFRA_HELP_AFTER = `
|
|
30
|
+
Typical sequence:
|
|
31
|
+
$ aifabrix up-infra
|
|
32
|
+
$ aifabrix up-platform
|
|
33
|
+
Or: aifabrix up-miso, then aifabrix up-dataplane (login required for dataplane)
|
|
34
|
+
|
|
35
|
+
Full bootstrap example (Traefik, TLS flag, pgAdmin, catalog overrides — matches shipped defaults in infra.parameter.yaml):
|
|
36
|
+
$ aifabrix up-infra --traefik --tls --adminPassword admin123 --adminEmail admin@aifabrix.dev --userPassword user123 --pgAdmin
|
|
37
|
+
`;
|
|
21
38
|
|
|
22
39
|
/**
|
|
23
40
|
* Persists optional service flag to config when explicitly set.
|
|
@@ -29,7 +46,29 @@ const { cleanBuilderAppDirs } = require('../commands/up-common');
|
|
|
29
46
|
async function persistOptionalServiceFlag(cfg, key, value, label) {
|
|
30
47
|
cfg[key] = value;
|
|
31
48
|
await config.saveConfig(cfg);
|
|
32
|
-
logger.log(
|
|
49
|
+
logger.log(formatSuccessLine(`${label} ${value ? 'enabled' : 'disabled'} and saved to config`));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Persists TLS mode for ${TLS_ENABLED} / ${HTTP_ENABLED} in application.yaml / deployment manifest interpolation.
|
|
54
|
+
* @param {Object} cfg - Config object (mutated)
|
|
55
|
+
* @param {boolean} value - Whether TLS mode is on
|
|
56
|
+
*/
|
|
57
|
+
async function persistTlsEnabledFlag(cfg, value) {
|
|
58
|
+
cfg.tlsEnabled = value;
|
|
59
|
+
await config.saveConfig(cfg);
|
|
60
|
+
const tlsStr = value ? 'true' : 'false';
|
|
61
|
+
const httpStr = value ? 'false' : 'true';
|
|
62
|
+
logger.log(
|
|
63
|
+
chalk.green(
|
|
64
|
+
`✔ TLS mode ${value ? 'enabled' : 'disabled'} and saved to config (` +
|
|
65
|
+
'${TLS_ENABLED}=' +
|
|
66
|
+
tlsStr +
|
|
67
|
+
', ${HTTP_ENABLED}=' +
|
|
68
|
+
httpStr +
|
|
69
|
+
' when generating deployment JSON)'
|
|
70
|
+
)
|
|
71
|
+
);
|
|
33
72
|
}
|
|
34
73
|
|
|
35
74
|
/**
|
|
@@ -46,24 +85,26 @@ function resolveFlag(optValue, cfgValue, defaultWhenUndef = true) {
|
|
|
46
85
|
}
|
|
47
86
|
|
|
48
87
|
/**
|
|
49
|
-
*
|
|
50
|
-
* @
|
|
51
|
-
* @returns {Promise<void>}
|
|
88
|
+
* @param {Object} options - Commander options
|
|
89
|
+
* @returns {Promise<number|null>} Developer ID or null
|
|
52
90
|
*/
|
|
53
|
-
async function
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
if (isNaN(id) || id < 0) {
|
|
59
|
-
throw new Error('Developer ID must be a non-negative number (0 = default infra, > 0 = developer-specific)');
|
|
60
|
-
}
|
|
61
|
-
await config.setDeveloperId(id);
|
|
62
|
-
process.env.AIFABRIX_DEVELOPERID = id.toString();
|
|
63
|
-
developerId = id;
|
|
64
|
-
logger.log(chalk.green(`✓ Developer ID set to ${id}`));
|
|
91
|
+
async function applyDeveloperIdFromUpInfra(options) {
|
|
92
|
+
if (!options.developer) return null;
|
|
93
|
+
const id = parseInt(options.developer, 10);
|
|
94
|
+
if (isNaN(id) || id < 0) {
|
|
95
|
+
throw new Error('Developer ID must be a non-negative number (0 = default infra, > 0 = developer-specific)');
|
|
65
96
|
}
|
|
66
|
-
|
|
97
|
+
await config.setDeveloperId(id);
|
|
98
|
+
process.env.AIFABRIX_DEVELOPERID = id.toString();
|
|
99
|
+
logger.log(formatSuccessLine(`Developer ID set to ${id}`));
|
|
100
|
+
return id;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param {Object} options
|
|
105
|
+
* @param {Object} cfg - Mutable config from getConfig()
|
|
106
|
+
*/
|
|
107
|
+
async function persistOptionalInfraFlagsFromCli(options, cfg) {
|
|
67
108
|
const flagSpecs = [
|
|
68
109
|
{ opt: options.traefik, key: 'traefik', label: 'Traefik' },
|
|
69
110
|
{ opt: options.pgAdmin, key: 'pgadmin', label: 'pgAdmin' },
|
|
@@ -74,25 +115,59 @@ async function runUpInfraCommand(options) {
|
|
|
74
115
|
await persistOptionalServiceFlag(cfg, key, opt, label);
|
|
75
116
|
}
|
|
76
117
|
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @param {Object} options
|
|
122
|
+
* @param {Object} cfg
|
|
123
|
+
*/
|
|
124
|
+
async function maybePersistTlsFromUpInfra(options, cfg) {
|
|
125
|
+
// Commander maps --no-tls to options.tls === false (not a separate notls flag).
|
|
126
|
+
if (options.tls === true) await persistTlsEnabledFlag(cfg, true);
|
|
127
|
+
else if (options.tls === false) await persistTlsEnabledFlag(cfg, false);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Runs the up-infra command: resolves developer ID, traefik, pgAdmin, redisAdmin, and starts infra.
|
|
132
|
+
* @param {Object} options - Commander options (developer, traefik, pgAdmin, redisAdmin)
|
|
133
|
+
* @returns {Promise<void>}
|
|
134
|
+
*/
|
|
135
|
+
async function runUpInfraCommand(options) {
|
|
136
|
+
await config.ensureSecretsEncryptionKey();
|
|
137
|
+
const developerId = await applyDeveloperIdFromUpInfra(options);
|
|
138
|
+
const cfg = await config.getConfig();
|
|
139
|
+
await persistOptionalInfraFlagsFromCli(options, cfg);
|
|
140
|
+
await maybePersistTlsFromUpInfra(options, cfg);
|
|
141
|
+
const adminPass = options.adminPassword || options.adminPwd;
|
|
142
|
+
const tlsEnabledEffective = cfg.tlsEnabled === true;
|
|
77
143
|
await infra.startInfra(developerId, {
|
|
78
144
|
traefik: resolveFlag(options.traefik, cfg.traefik, false),
|
|
79
145
|
pgadmin: resolveFlag(options.pgAdmin, cfg.pgadmin, true),
|
|
80
146
|
redisCommander: resolveFlag(options.redisAdmin, cfg.redisCommander, true),
|
|
81
|
-
|
|
147
|
+
adminPassword: adminPass,
|
|
148
|
+
adminPwd: adminPass,
|
|
149
|
+
adminEmail: options.adminEmail,
|
|
150
|
+
userPassword: options.userPassword,
|
|
151
|
+
tlsEnabled: tlsEnabledEffective
|
|
82
152
|
});
|
|
83
153
|
}
|
|
84
154
|
|
|
85
155
|
function setupUpInfraCommand(program) {
|
|
86
156
|
program.command('up-infra')
|
|
87
|
-
.description('Start
|
|
157
|
+
.description('Start Postgres, Redis; optional pgAdmin, Redis Commander, Traefik')
|
|
158
|
+
.addHelpText('after', UP_INFRA_HELP_AFTER)
|
|
88
159
|
.option('-d, --developer <id>', 'Set developer ID and start infrastructure')
|
|
89
|
-
.option('--
|
|
160
|
+
.option('--adminPassword <password>', 'Override {{adminPassword}} defaults (Postgres, pgAdmin, Redis Commander, catalog literals)')
|
|
161
|
+
.option('--adminEmail <email>', 'Override {{adminEmail}} default (e.g. pgAdmin login email)')
|
|
162
|
+
.option('--userPassword <password>', 'Override {{userPassword}} default (e.g. Keycloak default user password)')
|
|
90
163
|
.option('--pgAdmin', 'Include pgAdmin web UI and save to config')
|
|
91
164
|
.option('--no-pgAdmin', 'Exclude pgAdmin and save to config')
|
|
92
165
|
.option('--redisAdmin', 'Include Redis Commander web UI and save to config')
|
|
93
166
|
.option('--no-redisAdmin', 'Exclude Redis Commander and save to config')
|
|
94
167
|
.option('--traefik', 'Include Traefik reverse proxy and save to config')
|
|
95
168
|
.option('--no-traefik', 'Exclude Traefik and save to config')
|
|
169
|
+
.option('--tls', 'Enable TLS mode; save tlsEnabled (${TLS_ENABLED}=true, ${HTTP_ENABLED}=false in application.yaml)')
|
|
170
|
+
.option('--no-tls', 'Disable TLS mode (${TLS_ENABLED}=false, ${HTTP_ENABLED}=true)')
|
|
96
171
|
.action(async(options) => {
|
|
97
172
|
try {
|
|
98
173
|
await runUpInfraCommand(options);
|
|
@@ -105,7 +180,7 @@ function setupUpInfraCommand(program) {
|
|
|
105
180
|
|
|
106
181
|
function setupUpPlatformCommand(program) {
|
|
107
182
|
program.command('up-platform')
|
|
108
|
-
.description('Start
|
|
183
|
+
.description('Start Keycloak, Miso Controller, dataplane from images (needs up-infra)')
|
|
109
184
|
.option('-r, --registry <url>', 'Override registry for all apps (e.g. myacr.azurecr.io)')
|
|
110
185
|
.option('--registry-mode <mode>', 'Override registry mode (acr|external)')
|
|
111
186
|
.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]))
|
|
@@ -138,7 +213,7 @@ function setupUpPlatformCommand(program) {
|
|
|
138
213
|
|
|
139
214
|
function setupUpMisoCommand(program) {
|
|
140
215
|
program.command('up-miso')
|
|
141
|
-
.description('
|
|
216
|
+
.description('Start Keycloak + Miso Controller from images only (no dataplane; needs up-infra)')
|
|
142
217
|
.option('-r, --registry <url>', 'Override registry for all apps (e.g. myacr.azurecr.io)')
|
|
143
218
|
.option('--registry-mode <mode>', 'Override registry mode (acr|external)')
|
|
144
219
|
.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]))
|
|
@@ -158,7 +233,7 @@ function setupUpMisoCommand(program) {
|
|
|
158
233
|
|
|
159
234
|
function setupUpDataplaneCommand(program) {
|
|
160
235
|
program.command('up-dataplane')
|
|
161
|
-
.description('Register, deploy,
|
|
236
|
+
.description('Register, deploy, run dataplane locally (dev env; login required)')
|
|
162
237
|
.option('-r, --registry <url>', 'Override registry for dataplane image')
|
|
163
238
|
.option('--registry-mode <mode>', 'Override registry mode (acr|external)')
|
|
164
239
|
.option('-i, --image <ref>', 'Override dataplane image reference (e.g. myreg/dataplane:latest)')
|
|
@@ -189,8 +264,8 @@ function setupUpDataplaneCommand(program) {
|
|
|
189
264
|
}
|
|
190
265
|
|
|
191
266
|
function setupDownInfraCommand(program) {
|
|
192
|
-
program.command('down-infra [app]')
|
|
193
|
-
.description('Stop
|
|
267
|
+
program.command('down-infra [service|app]')
|
|
268
|
+
.description('Stop all infra, or stop one app; use -v to remove volumes')
|
|
194
269
|
.option('-v, --volumes', 'Remove volumes (deletes all data)')
|
|
195
270
|
.action(async(appName, options) => {
|
|
196
271
|
try {
|
|
@@ -209,14 +284,14 @@ function setupDownInfraCommand(program) {
|
|
|
209
284
|
|
|
210
285
|
function setupDoctorCommand(program) {
|
|
211
286
|
program.command('doctor')
|
|
212
|
-
.description('Check
|
|
287
|
+
.description('Check Docker, ports, secrets, and infra health')
|
|
213
288
|
.action(async() => {
|
|
214
289
|
try {
|
|
215
290
|
const result = await validator.checkEnvironment();
|
|
216
291
|
logger.log('\n🔍 AI Fabrix Environment Check\n');
|
|
217
|
-
logger.log(`Docker: ${result.docker === 'ok' ? '
|
|
218
|
-
logger.log(`Ports: ${result.ports === 'ok' ? '
|
|
219
|
-
logger.log(`Secrets: ${result.secrets === 'ok' ? '
|
|
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'}`);
|
|
220
295
|
if (result.recommendations.length > 0) {
|
|
221
296
|
logger.log('\n📋 Recommendations:');
|
|
222
297
|
result.recommendations.forEach(rec => logger.log(` • ${rec}`));
|
|
@@ -231,7 +306,7 @@ function setupDoctorCommand(program) {
|
|
|
231
306
|
});
|
|
232
307
|
logger.log('\n🏥 Infrastructure Health:');
|
|
233
308
|
Object.entries(health).forEach(([service, status]) => {
|
|
234
|
-
const icon = status === 'healthy' ? '
|
|
309
|
+
const icon = status === 'healthy' ? '✔' : status === 'unknown' ? '❓' : '✖';
|
|
235
310
|
logger.log(` ${icon} ${service}: ${status}`);
|
|
236
311
|
});
|
|
237
312
|
} catch (error) {
|
|
@@ -248,17 +323,21 @@ function setupDoctorCommand(program) {
|
|
|
248
323
|
|
|
249
324
|
function setupStatusCommand(program) {
|
|
250
325
|
program.command('status')
|
|
251
|
-
.description('Show
|
|
326
|
+
.description('Show infra services and running apps (ports, URLs)')
|
|
252
327
|
.action(async() => {
|
|
253
328
|
try {
|
|
329
|
+
const summary = await loadInfraStatusSummary();
|
|
254
330
|
const status = await infra.getInfraStatus();
|
|
255
|
-
logger.log('
|
|
331
|
+
logger.log('');
|
|
332
|
+
logger.log(formatInfraStatusTitleLine(summary.devIdStr, summary.remoteServer));
|
|
333
|
+
logger.log('');
|
|
334
|
+
logInfraStatusConfigurationSummary(summary);
|
|
256
335
|
Object.entries(status).forEach(([service, info]) => {
|
|
257
|
-
const icon = String(info.status).trim().toLowerCase() === 'running' ? '
|
|
258
|
-
logger.log(`${icon} ${service}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
336
|
+
const icon = String(info.status).trim().toLowerCase() === 'running' ? '✔' : '✖';
|
|
337
|
+
logger.log(`${icon} ${service}`);
|
|
338
|
+
logPaddedFieldRow('Status', info.status);
|
|
339
|
+
logPaddedFieldRow('Port', info.port);
|
|
340
|
+
logPaddedFieldRow('URL', info.url);
|
|
262
341
|
logger.log('');
|
|
263
342
|
});
|
|
264
343
|
const apps = await infra.getAppStatus();
|
|
@@ -266,12 +345,12 @@ function setupStatusCommand(program) {
|
|
|
266
345
|
logger.log('📱 Running Applications\n');
|
|
267
346
|
apps.forEach((appInfo) => {
|
|
268
347
|
const s = String(appInfo.status).trim().toLowerCase();
|
|
269
|
-
const icon = s.includes('running') || s.includes('up') ? '
|
|
270
|
-
logger.log(`${icon} ${appInfo.name}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
348
|
+
const icon = s.includes('running') || s.includes('up') ? '✔' : '✖';
|
|
349
|
+
logger.log(`${icon} ${appInfo.name}`);
|
|
350
|
+
logPaddedFieldRow('Container', appInfo.container);
|
|
351
|
+
logPaddedFieldRow('Port', appInfo.port);
|
|
352
|
+
logPaddedFieldRow('Status', appInfo.status);
|
|
353
|
+
logPaddedFieldRow('URL', appInfo.url);
|
|
275
354
|
logger.log('');
|
|
276
355
|
});
|
|
277
356
|
}
|
|
@@ -285,16 +364,16 @@ function setupStatusCommand(program) {
|
|
|
285
364
|
const INFRA_SERVICES = ['postgres', 'redis', 'pgadmin', 'redis-commander', 'traefik'];
|
|
286
365
|
|
|
287
366
|
function setupRestartCommand(program) {
|
|
288
|
-
program.command('restart <service>')
|
|
289
|
-
.description('Restart
|
|
367
|
+
program.command('restart <service|app>')
|
|
368
|
+
.description('Restart infra service (postgres, redis, …) or a builder/<app> container')
|
|
290
369
|
.action(async(service) => {
|
|
291
370
|
try {
|
|
292
371
|
if (INFRA_SERVICES.includes(service)) {
|
|
293
372
|
await infra.restartService(service);
|
|
294
|
-
logger.log(
|
|
373
|
+
logger.log(`✔ ${service} service restarted successfully`);
|
|
295
374
|
} else {
|
|
296
375
|
await appLib.restartApp(service);
|
|
297
|
-
logger.log(
|
|
376
|
+
logger.log(`✔ ${service} restarted successfully`);
|
|
298
377
|
}
|
|
299
378
|
} catch (error) {
|
|
300
379
|
handleCommandError(error, 'restart');
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview parameters subcommand (validate kv:// catalog coverage)
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 2.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { handleCommandError } = require('../utils/cli-utils');
|
|
8
|
+
const { handleParametersValidate } = require('../commands/parameters-validate');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {import('commander').Command} program - Commander program
|
|
12
|
+
*/
|
|
13
|
+
function setupParametersCommands(program) {
|
|
14
|
+
const parameters = program
|
|
15
|
+
.command('parameters')
|
|
16
|
+
.description('Infra parameter catalog (kv:// keys, generators, Azure naming hints)');
|
|
17
|
+
|
|
18
|
+
parameters
|
|
19
|
+
.command('validate')
|
|
20
|
+
.description('Check env.template kv:// references against lib/schema/infra.parameter.yaml')
|
|
21
|
+
.option('--catalog <path>', 'Override path to infra.parameter.yaml')
|
|
22
|
+
.action(async(opts) => {
|
|
23
|
+
try {
|
|
24
|
+
const result = await handleParametersValidate({ catalogPath: opts.catalog });
|
|
25
|
+
if (!result.valid) process.exit(1);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
handleCommandError(error, 'parameters validate');
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = { setupParametersCommands };
|
package/lib/cli/setup-secrets.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @version 2.0.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
10
10
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
11
11
|
const { handleSecretsSet } = require('../commands/secrets-set');
|
|
12
12
|
const { handleSecretsList } = require('../commands/secrets-list');
|
|
@@ -16,10 +16,101 @@ const { handleSecure } = require('../commands/secure');
|
|
|
16
16
|
const config = require('../core/config');
|
|
17
17
|
const logger = require('../utils/logger');
|
|
18
18
|
|
|
19
|
+
const SECRET_GROUP_HELP_AFTER = `
|
|
20
|
+
Subcommands:
|
|
21
|
+
list, set, remove, remove-all User secrets.local.yaml (add --shared for shared/remote)
|
|
22
|
+
set-secrets-file Point config at a shared secrets file or https URL
|
|
23
|
+
validate YAML structure (+ optional --naming)
|
|
24
|
+
|
|
25
|
+
Also: aifabrix secure Encrypt secrets.local.yaml (ISO 27001)
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
$ aifabrix secret list
|
|
29
|
+
$ aifabrix secret set myapp/clientSecret "your-value"
|
|
30
|
+
$ aifabrix secret remove old-key
|
|
31
|
+
$ aifabrix secret remove-all
|
|
32
|
+
$ aifabrix secret validate
|
|
33
|
+
|
|
34
|
+
Shared over https: key BASH_NPM_TOKEN --shared → NPM_TOKEN available in terminal (exported).
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
const SECRET_LIST_HELP_AFTER = `
|
|
38
|
+
Examples:
|
|
39
|
+
$ aifabrix secret list
|
|
40
|
+
$ aifabrix secret list --shared
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
const SECRET_SET_HELP_AFTER = `
|
|
44
|
+
Examples:
|
|
45
|
+
$ aifabrix secret set myapp/clientSecret "your-secret"
|
|
46
|
+
$ aifabrix secret set hubspot/apiKey "$HUBSPOT_KEY"
|
|
47
|
+
$ aifabrix secret set team/shared-token "value" --shared
|
|
48
|
+
$ aifabrix secret set BASH_NPM_TOKEN "$NPM_TOKEN" --shared
|
|
49
|
+
|
|
50
|
+
With https aifabrix-secrets: keys named BASH_<NAME> --shared expose <NAME> in your
|
|
51
|
+
terminal as an exported env var (e.g. BASH_NPM_TOKEN → NPM_TOKEN).
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
const SECRET_REMOVE_HELP_AFTER = `
|
|
55
|
+
Examples:
|
|
56
|
+
$ aifabrix secret remove deprecated-key
|
|
57
|
+
$ aifabrix secret remove shared-key --shared
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
const SECRET_REMOVE_ALL_HELP_AFTER = `
|
|
61
|
+
You will be asked to type "yes" to confirm unless you pass --yes.
|
|
62
|
+
|
|
63
|
+
Examples:
|
|
64
|
+
$ aifabrix secret remove-all
|
|
65
|
+
$ aifabrix secret remove-all --yes
|
|
66
|
+
$ aifabrix secret remove-all --shared
|
|
67
|
+
$ aifabrix secret remove-all --shared --yes
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
const SECRET_SET_SECRETS_FILE_HELP_AFTER = `
|
|
71
|
+
Examples:
|
|
72
|
+
$ aifabrix secret set-secrets-file ./shared-secrets.yaml
|
|
73
|
+
$ aifabrix secret set-secrets-file https://dev.example.com/api/secrets
|
|
74
|
+
$ aifabrix secret set-secrets-file ""
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
const SECRET_VALIDATE_HELP_AFTER = `
|
|
78
|
+
Examples:
|
|
79
|
+
$ aifabrix secret validate
|
|
80
|
+
$ aifabrix secret validate ./secrets.local.yaml
|
|
81
|
+
$ aifabrix secret validate --naming
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
const SECURE_HELP_AFTER = `
|
|
85
|
+
Examples:
|
|
86
|
+
$ aifabrix secure
|
|
87
|
+
$ aifabrix secure --secrets-encryption <32-byte-hex-or-base64>
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
function setupSecretRemoveAllCommand(secretCmd) {
|
|
91
|
+
const { handleSecretsRemoveAll } = require('../commands/secrets-remove-all');
|
|
92
|
+
secretCmd
|
|
93
|
+
.command('remove-all')
|
|
94
|
+
.description('Remove all secret keys (requires typing "yes" unless --yes)')
|
|
95
|
+
.addHelpText('after', SECRET_REMOVE_ALL_HELP_AFTER)
|
|
96
|
+
.option('--shared', 'Remove all from shared secrets (file or remote API)')
|
|
97
|
+
.option('-y, --yes', 'Skip confirmation prompt (non-interactive / scripts)')
|
|
98
|
+
.action(async options => {
|
|
99
|
+
try {
|
|
100
|
+
await config.ensureSecretsEncryptionKey();
|
|
101
|
+
await handleSecretsRemoveAll(options);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
handleCommandError(error, 'secret remove-all');
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
19
109
|
function setupSecretValidateCommand(secretCmd) {
|
|
20
110
|
secretCmd
|
|
21
111
|
.command('validate [path]')
|
|
22
112
|
.description('Validate secrets file (YAML structure and optional naming convention)')
|
|
113
|
+
.addHelpText('after', SECRET_VALIDATE_HELP_AFTER)
|
|
23
114
|
.option('--naming', 'Check key names against *KeyVault convention')
|
|
24
115
|
.action(async(pathArg, options) => {
|
|
25
116
|
try {
|
|
@@ -39,7 +130,8 @@ function setupSecretValidateCommand(secretCmd) {
|
|
|
39
130
|
*/
|
|
40
131
|
function setupSecureCommand(program) {
|
|
41
132
|
program.command('secure')
|
|
42
|
-
.description('Encrypt secrets
|
|
133
|
+
.description('Encrypt secrets.local.yaml at rest (ISO 27001)')
|
|
134
|
+
.addHelpText('after', SECURE_HELP_AFTER)
|
|
43
135
|
.option('--secrets-encryption <key>', 'Encryption key (32 bytes, hex or base64)')
|
|
44
136
|
.action(async(options) => {
|
|
45
137
|
try {
|
|
@@ -59,11 +151,13 @@ function setupSecureCommand(program) {
|
|
|
59
151
|
function setupSecretsCommands(program) {
|
|
60
152
|
const secretCmd = program
|
|
61
153
|
.command('secret')
|
|
62
|
-
.description('
|
|
154
|
+
.description('User and shared secrets (list, set, remove, remove-all, validate)')
|
|
155
|
+
.addHelpText('after', SECRET_GROUP_HELP_AFTER);
|
|
63
156
|
|
|
64
157
|
secretCmd
|
|
65
158
|
.command('list')
|
|
66
|
-
.description('List secret keys (
|
|
159
|
+
.description('List secret keys (--shared for shared/remote)')
|
|
160
|
+
.addHelpText('after', SECRET_LIST_HELP_AFTER)
|
|
67
161
|
.option('--shared', 'List shared secrets (from config aifabrix-secrets or remote API)')
|
|
68
162
|
.action(async(options) => {
|
|
69
163
|
try {
|
|
@@ -77,7 +171,8 @@ function setupSecretsCommands(program) {
|
|
|
77
171
|
|
|
78
172
|
secretCmd
|
|
79
173
|
.command('set <key> <value>')
|
|
80
|
-
.description('Set a secret value
|
|
174
|
+
.description('Set a secret value')
|
|
175
|
+
.addHelpText('after', SECRET_SET_HELP_AFTER)
|
|
81
176
|
.option('--shared', 'Save to general secrets file (from config.yaml aifabrix-secrets) instead of user secrets')
|
|
82
177
|
.action(async(key, value, options) => {
|
|
83
178
|
try {
|
|
@@ -91,7 +186,8 @@ function setupSecretsCommands(program) {
|
|
|
91
186
|
|
|
92
187
|
secretCmd
|
|
93
188
|
.command('remove <key>')
|
|
94
|
-
.description('Remove a secret
|
|
189
|
+
.description('Remove a secret key')
|
|
190
|
+
.addHelpText('after', SECRET_REMOVE_HELP_AFTER)
|
|
95
191
|
.option('--shared', 'Remove from shared secrets (file or remote API)')
|
|
96
192
|
.action(async(key, options) => {
|
|
97
193
|
try {
|
|
@@ -103,6 +199,7 @@ function setupSecretsCommands(program) {
|
|
|
103
199
|
}
|
|
104
200
|
});
|
|
105
201
|
|
|
202
|
+
setupSecretRemoveAllCommand(secretCmd);
|
|
106
203
|
setupSecretSetSecretsFileCommand(secretCmd);
|
|
107
204
|
setupSecretValidateCommand(secretCmd);
|
|
108
205
|
setupSecureCommand(program);
|
|
@@ -115,7 +212,8 @@ function setupSecretsCommands(program) {
|
|
|
115
212
|
function setupSecretSetSecretsFileCommand(secretCmd) {
|
|
116
213
|
secretCmd
|
|
117
214
|
.command('set-secrets-file <path>')
|
|
118
|
-
.description('Set
|
|
215
|
+
.description('Set shared secrets path in config (file or https; empty clears; not validated)')
|
|
216
|
+
.addHelpText('after', SECRET_SET_SECRETS_FILE_HELP_AFTER)
|
|
119
217
|
.action(async(secretsPath) => {
|
|
120
218
|
try {
|
|
121
219
|
const trimmed = (secretsPath || '').trim();
|
|
@@ -123,7 +221,7 @@ function setupSecretSetSecretsFileCommand(secretCmd) {
|
|
|
123
221
|
throw new Error('Only https URLs are allowed for remote secrets');
|
|
124
222
|
}
|
|
125
223
|
await config.setSecretsPath(trimmed);
|
|
126
|
-
logger.log(trimmed === '' ?
|
|
224
|
+
logger.log(trimmed === '' ? formatSuccessLine('Secrets file path cleared') : formatSuccessLine(`Secrets file path set to ${trimmed}`));
|
|
127
225
|
} catch (error) {
|
|
128
226
|
handleCommandError(error, 'secret set-secrets-file');
|
|
129
227
|
process.exit(1);
|