@aifabrix/builder 2.42.1 → 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 +2 -2
- 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 +157 -0
- package/integration/{hubspot → hubspot-test}/application.json +6 -6
- package/integration/{hubspot → hubspot-test}/create-hubspot.js +10 -10
- package/integration/hubspot-test/env.template +4 -0
- package/integration/hubspot-test/hubspot-test-datasource-company.json +138 -0
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +146 -0
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +146 -0
- package/integration/hubspot-test/hubspot-test-datasource-users.json +76 -0
- package/integration/{hubspot/hubspot-deploy.json → hubspot-test/hubspot-test-deploy.json} +201 -24
- package/integration/{hubspot/hubspot-system.json → hubspot-test/hubspot-test-system.json} +8 -7
- package/integration/hubspot-test/rbac.json +166 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-credential-real.yaml +3 -3
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-env-vars.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-add-datasource.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-create.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-select.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-known-platform.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +2 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-mode.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-file.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-url.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-source.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-array-test.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +5 -0
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +5 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-dataplane-down-tests.js +1 -7
- package/integration/{hubspot → hubspot-test}/test-dataplane-down.js +3 -3
- package/integration/{hubspot → hubspot-test}/test.js +137 -102
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-e2e.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-platform.yaml +1 -1
- 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/service-users.api.js +111 -2
- package/lib/api/types/dev.types.js +4 -3
- package/lib/api/types/pipeline.types.js +8 -5
- package/lib/api/types/service-users.types.js +41 -0
- 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 +19 -8
- package/lib/app/rotate-secret.js +17 -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 +59 -123
- package/lib/cli/setup-app.test-commands.js +179 -0
- package/lib/cli/setup-auth.js +36 -14
- 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 +190 -103
- package/lib/cli/setup-environment.js +11 -20
- package/lib/cli/setup-external-system.js +62 -22
- package/lib/cli/setup-infra.js +139 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +147 -10
- package/lib/cli/setup-service-user.js +146 -20
- package/lib/cli/setup-utility.js +47 -19
- 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 +10 -14
- 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 +123 -71
- 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 +16 -10
- package/lib/commands/repair-rbac.js +25 -19
- package/lib/commands/repair.js +116 -32
- package/lib/commands/secrets-list.js +23 -12
- package/lib/commands/secrets-remove-all.js +220 -0
- package/lib/commands/secrets-remove.js +22 -13
- package/lib/commands/secrets-set.js +21 -12
- package/lib/commands/secrets-validate.js +20 -7
- package/lib/commands/secure.js +10 -9
- package/lib/commands/service-user.js +243 -13
- package/lib/commands/test-e2e-external.js +27 -1
- package/lib/commands/up-common.js +28 -2
- package/lib/commands/up-dataplane.js +31 -18
- 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 +16 -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 +59 -58
- package/lib/core/diff.js +3 -2
- package/lib/core/ensure-encryption-key.js +2 -4
- 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 +228 -42
- package/lib/core/templates-env.js +4 -3
- package/lib/core/templates.js +1 -1
- package/lib/datasource/abac-validator.js +148 -0
- package/lib/datasource/deploy.js +75 -53
- package/lib/datasource/field-reference-validator.js +77 -36
- package/lib/datasource/integration-context.js +63 -0
- package/lib/datasource/list.js +8 -7
- package/lib/datasource/log-viewer.js +252 -0
- package/lib/datasource/resolve-app.js +109 -0
- package/lib/datasource/test-e2e.js +95 -155
- package/lib/datasource/test-integration.js +121 -109
- 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 +162 -15
- 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 +104 -14
- 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-controller-manifest.js +3 -3
- package/lib/generator/external.js +23 -11
- package/lib/generator/helpers.js +71 -12
- package/lib/generator/index.js +8 -4
- package/lib/generator/split-readme.js +12 -7
- package/lib/generator/split-variables.js +2 -1
- package/lib/generator/split.js +46 -11
- package/lib/generator/wizard-readme.js +3 -3
- package/lib/generator/wizard.js +16 -13
- package/lib/infrastructure/compose.js +60 -6
- package/lib/infrastructure/helpers.js +238 -51
- package/lib/infrastructure/index.js +64 -37
- 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 +1201 -433
- 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-config-resolver.js +23 -1
- 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 +209 -6
- 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/credential-secrets-env.js +16 -1
- 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 +42 -11
- package/lib/utils/env-template.js +2 -2
- package/lib/utils/environment-scoped-resources.js +144 -0
- package/lib/utils/error-formatter.js +125 -9
- 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-env-template.js +180 -0
- package/lib/utils/external-readme.js +8 -1
- package/lib/utils/external-system-display.js +277 -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 +32 -14
- package/lib/utils/health-check-url.js +119 -0
- package/lib/utils/health-check.js +59 -25
- package/lib/utils/help-builder.js +14 -13
- 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 +29 -7
- package/lib/utils/paths.js +136 -48
- 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 +171 -51
- package/lib/utils/secrets-helpers.js +70 -59
- package/lib/utils/secrets-kv-scope.js +60 -0
- package/lib/utils/secrets-utils.js +35 -37
- package/lib/utils/secrets-validation.js +3 -1
- package/lib/utils/secrets-yaml-preserve.js +109 -0
- package/lib/utils/secure-file-permissions.js +91 -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 +37 -5
- 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 +78 -1
- package/lib/validation/datasource-warnings.js +56 -0
- package/lib/validation/env-template-auth.js +50 -2
- package/lib/validation/external-manifest-validator.js +35 -7
- package/lib/validation/validate-display.js +37 -31
- package/lib/validation/validate.js +9 -10
- package/lib/validation/validator-unresolved-placeholders.js +98 -0
- package/lib/validation/validator.js +32 -78
- package/lib/validation/wizard-config-validator.js +2 -1
- package/package.json +11 -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 +80 -18
- 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 +55 -14
- 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/env.template.hbs +22 -0
- 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/integration/hubspot/README.md +0 -102
- package/integration/hubspot/env.template +0 -4
- package/integration/hubspot/hubspot-datasource-company.json +0 -541
- package/integration/hubspot/hubspot-datasource-contact.json +0 -639
- package/integration/hubspot/hubspot-datasource-deal.json +0 -588
- package/integration/hubspot/hubspot-datasource-users.json +0 -116
- package/integration/hubspot/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
- package/lib/api/external-test.api.js +0 -111
- package/lib/schema/env-config.yaml +0 -43
- /package/integration/{hubspot → hubspot-test}/companies.json +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-app-name.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-missing-app.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-dataplane-down-helpers.js +0 -0
|
@@ -10,28 +10,37 @@
|
|
|
10
10
|
const chalk = require('chalk');
|
|
11
11
|
const logger = require('../utils/logger');
|
|
12
12
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
13
|
-
const {
|
|
13
|
+
const {
|
|
14
|
+
runServiceUserCreate,
|
|
15
|
+
runServiceUserList,
|
|
16
|
+
runServiceUserRotateSecret,
|
|
17
|
+
runServiceUserDelete,
|
|
18
|
+
runServiceUserUpdateGroups,
|
|
19
|
+
runServiceUserUpdateRedirectUris
|
|
20
|
+
} = require('../commands/service-user');
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
* Sets up service-user commands
|
|
17
|
-
* @param {Command} program - Commander program instance
|
|
18
|
-
*/
|
|
19
|
-
function setupServiceUserCommands(program) {
|
|
20
|
-
const serviceUser = program
|
|
21
|
-
.command('service-user')
|
|
22
|
-
.description('Create and manage service users (API clients) for integrations and CI')
|
|
23
|
-
.addHelpText('after', `
|
|
22
|
+
const HELP_AFTER = `
|
|
24
23
|
Service users are dedicated accounts for integrations, CI pipelines, or API clients.
|
|
25
|
-
|
|
24
|
+
Use: list (service-user:read), create (service-user:create), rotate-secret, update-groups, update-redirect-uris (service-user:update), delete (service-user:delete).
|
|
25
|
+
The controller returns a one-time clientSecret on create and rotate-secret—save it immediately; it cannot be retrieved again.
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
$ aifabrix service-user create -u
|
|
29
|
-
--redirect-uris
|
|
27
|
+
Examples:
|
|
28
|
+
$ aifabrix service-user create -u postman -e postman@aifabrix.dev \\
|
|
29
|
+
--redirect-uris https://oauth.pstmn.io/v1/callback --group-names AI-Fabrix-Platform-Admins
|
|
30
|
+
$ aifabrix service-user list
|
|
31
|
+
$ aifabrix service-user rotate-secret --id <uuid>
|
|
32
|
+
$ aifabrix service-user delete --id <uuid>
|
|
33
|
+
$ aifabrix service-user update-groups --id <uuid> --group-names Group1,Group2
|
|
34
|
+
$ aifabrix service-user update-redirect-uris --id <uuid> --redirect-uris https://app.example.com/callback
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
Run "aifabrix login" first.`;
|
|
37
|
+
|
|
38
|
+
function parseOptionalInt(val) {
|
|
39
|
+
return (val !== undefined && val !== null) ? parseInt(val, 10) : undefined;
|
|
40
|
+
}
|
|
32
41
|
|
|
33
|
-
|
|
34
|
-
|
|
42
|
+
function addCreateCommand(serviceUser) {
|
|
43
|
+
serviceUser.command('create')
|
|
35
44
|
.description('Create a service user and receive a one-time clientSecret (save it now; it will not be shown again)')
|
|
36
45
|
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
37
46
|
.option('-u, --username <username>', 'Service user username (required)')
|
|
@@ -41,15 +50,14 @@ Required: permission service-user:create on the controller. Run "aifabrix login"
|
|
|
41
50
|
.option('-d, --description <description>', 'Description for the service user')
|
|
42
51
|
.action(async(options) => {
|
|
43
52
|
try {
|
|
44
|
-
|
|
53
|
+
await runServiceUserCreate({
|
|
45
54
|
controller: options.controller,
|
|
46
55
|
username: options.username,
|
|
47
56
|
email: options.email,
|
|
48
57
|
redirectUris: options.redirectUris,
|
|
49
58
|
groupNames: options.groupNames,
|
|
50
59
|
description: options.description
|
|
51
|
-
};
|
|
52
|
-
await runServiceUserCreate(opts);
|
|
60
|
+
});
|
|
53
61
|
} catch (error) {
|
|
54
62
|
logger.error(chalk.red(`Error: ${error.message}`));
|
|
55
63
|
handleCommandError(error, 'service-user create');
|
|
@@ -58,4 +66,122 @@ Required: permission service-user:create on the controller. Run "aifabrix login"
|
|
|
58
66
|
});
|
|
59
67
|
}
|
|
60
68
|
|
|
69
|
+
function addListCommand(serviceUser) {
|
|
70
|
+
serviceUser.command('list')
|
|
71
|
+
.description('List service users (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 runServiceUserList({
|
|
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
|
+
logger.error(chalk.red(`Error: ${error.message}`));
|
|
90
|
+
handleCommandError(error, 'service-user list');
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function addRotateSecretCommand(serviceUser) {
|
|
97
|
+
serviceUser.command('rotate-secret')
|
|
98
|
+
.description('Rotate (regenerate) secret for a service user; new secret shown once only')
|
|
99
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
100
|
+
.option('--id <uuid>', 'Service user ID (required)')
|
|
101
|
+
.action(async(options) => {
|
|
102
|
+
try {
|
|
103
|
+
await runServiceUserRotateSecret({ controller: options.controller, id: options.id });
|
|
104
|
+
} catch (error) {
|
|
105
|
+
logger.error(chalk.red(`Error: ${error.message}`));
|
|
106
|
+
handleCommandError(error, 'service-user rotate-secret');
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function addDeleteCommand(serviceUser) {
|
|
113
|
+
serviceUser.command('delete')
|
|
114
|
+
.description('Delete (deactivate) a service user')
|
|
115
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
116
|
+
.option('--id <uuid>', 'Service user ID (required)')
|
|
117
|
+
.action(async(options) => {
|
|
118
|
+
try {
|
|
119
|
+
await runServiceUserDelete({ controller: options.controller, id: options.id });
|
|
120
|
+
} catch (error) {
|
|
121
|
+
logger.error(chalk.red(`Error: ${error.message}`));
|
|
122
|
+
handleCommandError(error, 'service-user delete');
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function addUpdateGroupsCommand(serviceUser) {
|
|
129
|
+
serviceUser.command('update-groups')
|
|
130
|
+
.description('Update group assignments for a service user')
|
|
131
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
132
|
+
.option('--id <uuid>', 'Service user ID (required)')
|
|
133
|
+
.option('--group-names <names>', 'Comma-separated group names (required)')
|
|
134
|
+
.action(async(options) => {
|
|
135
|
+
try {
|
|
136
|
+
await runServiceUserUpdateGroups({
|
|
137
|
+
controller: options.controller,
|
|
138
|
+
id: options.id,
|
|
139
|
+
groupNames: options.groupNames
|
|
140
|
+
});
|
|
141
|
+
} catch (error) {
|
|
142
|
+
logger.error(chalk.red(`Error: ${error.message}`));
|
|
143
|
+
handleCommandError(error, 'service-user update-groups');
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function addUpdateRedirectUrisCommand(serviceUser) {
|
|
150
|
+
serviceUser.command('update-redirect-uris')
|
|
151
|
+
.description('Update redirect URIs for a service user (min 1)')
|
|
152
|
+
.option('--controller <url>', 'Controller base URL (default: from config)')
|
|
153
|
+
.option('--id <uuid>', 'Service user ID (required)')
|
|
154
|
+
.option('--redirect-uris <uris>', 'Comma-separated redirect URIs (required, min 1)')
|
|
155
|
+
.action(async(options) => {
|
|
156
|
+
try {
|
|
157
|
+
await runServiceUserUpdateRedirectUris({
|
|
158
|
+
controller: options.controller,
|
|
159
|
+
id: options.id,
|
|
160
|
+
redirectUris: options.redirectUris
|
|
161
|
+
});
|
|
162
|
+
} catch (error) {
|
|
163
|
+
logger.error(chalk.red(`Error: ${error.message}`));
|
|
164
|
+
handleCommandError(error, 'service-user update-redirect-uris');
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Sets up service-user commands
|
|
172
|
+
* @param {Command} program - Commander program instance
|
|
173
|
+
*/
|
|
174
|
+
function setupServiceUserCommands(program) {
|
|
175
|
+
const serviceUser = program
|
|
176
|
+
.command('service-user')
|
|
177
|
+
.description('OAuth service users on Controller (integrations, CI)')
|
|
178
|
+
.addHelpText('after', HELP_AFTER);
|
|
179
|
+
addCreateCommand(serviceUser);
|
|
180
|
+
addListCommand(serviceUser);
|
|
181
|
+
addRotateSecretCommand(serviceUser);
|
|
182
|
+
addDeleteCommand(serviceUser);
|
|
183
|
+
addUpdateGroupsCommand(serviceUser);
|
|
184
|
+
addUpdateRedirectUrisCommand(serviceUser);
|
|
185
|
+
}
|
|
186
|
+
|
|
61
187
|
module.exports = { setupServiceUserCommands };
|
package/lib/cli/setup-utility.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* CLI utility command setup (resolve, json, split-json, show, validate, diff).
|
|
3
4
|
*
|
|
@@ -15,6 +16,19 @@ const logger = require('../utils/logger');
|
|
|
15
16
|
const { handleCommandError, logOfflinePathWhenType } = require('../utils/cli-utils');
|
|
16
17
|
const { detectAppType, getDeployJsonPath, getResolveAppPath } = require('../utils/paths');
|
|
17
18
|
|
|
19
|
+
const JSON_HELP_AFTER = `
|
|
20
|
+
Example:
|
|
21
|
+
$ aifabrix json myapp
|
|
22
|
+
Generates *-deploy.json (or application-schema.json) for commit before deploy.
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const VALIDATE_HELP_AFTER = `
|
|
26
|
+
Examples:
|
|
27
|
+
$ aifabrix validate myapp
|
|
28
|
+
$ aifabrix validate --integration
|
|
29
|
+
$ aifabrix validate --builder
|
|
30
|
+
`;
|
|
31
|
+
|
|
18
32
|
/**
|
|
19
33
|
* Resolve app path and type for split-json (integration first, then builder).
|
|
20
34
|
*
|
|
@@ -67,7 +81,7 @@ async function handleSplitJsonCommand(appName, options) {
|
|
|
67
81
|
* @returns {void}
|
|
68
82
|
*/
|
|
69
83
|
function logSplitJsonResult(result) {
|
|
70
|
-
logger.log(
|
|
84
|
+
logger.log(formatSuccessParagraph('Successfully split deployment JSON into component files:'));
|
|
71
85
|
logger.log(` • env.template: ${result.envTemplate}`);
|
|
72
86
|
logger.log(` • application.yaml: ${result.variables}`);
|
|
73
87
|
if (result.systemFile) {
|
|
@@ -88,7 +102,7 @@ function logSplitJsonResult(result) {
|
|
|
88
102
|
|
|
89
103
|
function setupResolveCommand(program) {
|
|
90
104
|
program.command('resolve <app>')
|
|
91
|
-
.description('Generate .env
|
|
105
|
+
.description('Generate .env from template; optional validate after')
|
|
92
106
|
.option('-f, --force', 'Generate missing secret keys in secrets file')
|
|
93
107
|
.option('--skip-validation', 'Skip file validation after generating .env')
|
|
94
108
|
.action(async(appName, options) => {
|
|
@@ -101,7 +115,7 @@ function setupResolveCommand(program) {
|
|
|
101
115
|
options.force,
|
|
102
116
|
{ appPath, envOnly, skipOutputPath: false, preserveFromPath: null }
|
|
103
117
|
);
|
|
104
|
-
logger.log(
|
|
118
|
+
logger.log(`✔ Generated .env file: ${envPath}`);
|
|
105
119
|
if (envOnly) {
|
|
106
120
|
logger.log(chalk.gray(' (env-only mode: validation skipped; no application.yaml)'));
|
|
107
121
|
} else if (!options.skipValidation) {
|
|
@@ -109,7 +123,7 @@ function setupResolveCommand(program) {
|
|
|
109
123
|
const result = await validate.validateAppOrFile(appName);
|
|
110
124
|
validate.displayValidationResults(result);
|
|
111
125
|
if (!result.valid) {
|
|
112
|
-
logger.log(chalk.yellow('\n
|
|
126
|
+
logger.log(chalk.yellow('\n⚠ Validation found errors. Fix them before deploying.'));
|
|
113
127
|
process.exit(1);
|
|
114
128
|
}
|
|
115
129
|
}
|
|
@@ -122,19 +136,20 @@ function setupResolveCommand(program) {
|
|
|
122
136
|
|
|
123
137
|
function setupJsonCommand(program) {
|
|
124
138
|
program.command('json <app>')
|
|
125
|
-
.description('
|
|
139
|
+
.description('Write deployment JSON to disk for version control')
|
|
140
|
+
.addHelpText('after', JSON_HELP_AFTER)
|
|
126
141
|
.action(async(appName, options) => {
|
|
127
142
|
try {
|
|
128
143
|
const result = await generator.generateDeployJsonWithValidation(appName, options);
|
|
129
144
|
if (result.success) {
|
|
130
145
|
const fileName = result.path.includes('application-schema.json') ? 'application-schema.json' : 'deployment JSON';
|
|
131
|
-
logger.log(
|
|
146
|
+
logger.log(`✔ Generated ${fileName}: ${result.path}`);
|
|
132
147
|
if (result.validation.warnings && result.validation.warnings.length > 0) {
|
|
133
|
-
logger.log('\n
|
|
148
|
+
logger.log('\n⚠ Warnings:');
|
|
134
149
|
result.validation.warnings.forEach(w => logger.log(` • ${w}`));
|
|
135
150
|
}
|
|
136
151
|
} else {
|
|
137
|
-
logger.log('
|
|
152
|
+
logger.log('✖ Validation failed:');
|
|
138
153
|
(result.validation.errors || []).forEach(e => logger.log(` • ${e}`));
|
|
139
154
|
process.exit(1);
|
|
140
155
|
}
|
|
@@ -147,7 +162,7 @@ function setupJsonCommand(program) {
|
|
|
147
162
|
|
|
148
163
|
function setupSplitJsonCommand(program) {
|
|
149
164
|
program.command('split-json <app>')
|
|
150
|
-
.description('Split
|
|
165
|
+
.description('Split deploy JSON into env.template, application.yaml, rbac, README, …')
|
|
151
166
|
.option('-o, --output <dir>', 'Output directory for component files (defaults to same directory as JSON)')
|
|
152
167
|
.action(async(appName, options) => {
|
|
153
168
|
try {
|
|
@@ -160,12 +175,13 @@ function setupSplitJsonCommand(program) {
|
|
|
160
175
|
}
|
|
161
176
|
|
|
162
177
|
function setupRepairCommand(program) {
|
|
163
|
-
program.command('repair <
|
|
164
|
-
.description('
|
|
178
|
+
program.command('repair <systemKey>')
|
|
179
|
+
.description('Fix external integration drift (files, RBAC, manifest, …)')
|
|
165
180
|
.option('--auth <method>', 'Set authentication method (oauth2, aad, apikey, basic, queryParam, oidc, hmac, none); updates system file and env.template')
|
|
181
|
+
.option('--doc', 'Regenerate README.md from deployment manifest')
|
|
166
182
|
.option('--dry-run', 'Report changes only; do not write')
|
|
167
183
|
.option('--rbac', 'Ensure RBAC permissions per datasource and add default Admin/Reader roles if none exist')
|
|
168
|
-
.option('--expose', 'Set exposed.
|
|
184
|
+
.option('--expose', 'Set exposed.schema on each datasource from all fieldMappings.attributes keys (metadata.<key>); removes deprecated exposed.attributes if present')
|
|
169
185
|
.option('--sync', 'Add default sync section to datasources that lack it')
|
|
170
186
|
.option('--test', 'Generate testPayload.payloadTemplate and testPayload.expectedResult from attributes')
|
|
171
187
|
.action(async(appName, options) => {
|
|
@@ -174,9 +190,18 @@ function setupRepairCommand(program) {
|
|
|
174
190
|
const { detectAppType } = require('../utils/paths');
|
|
175
191
|
const { appPath } = await detectAppType(appName);
|
|
176
192
|
logOfflinePathWhenType(appPath);
|
|
193
|
+
let format = 'yaml';
|
|
194
|
+
try {
|
|
195
|
+
const config = require('../core/config');
|
|
196
|
+
format = (await config.getFormat()) || format;
|
|
197
|
+
} catch (_) {
|
|
198
|
+
// use default yaml when config unavailable
|
|
199
|
+
}
|
|
177
200
|
const result = await repairExternalIntegration(appName, {
|
|
178
201
|
auth: options.auth,
|
|
202
|
+
doc: options.doc,
|
|
179
203
|
dryRun: options.dryRun,
|
|
204
|
+
format,
|
|
180
205
|
rbac: options.rbac,
|
|
181
206
|
expose: options.expose,
|
|
182
207
|
sync: options.sync,
|
|
@@ -186,7 +211,9 @@ function setupRepairCommand(program) {
|
|
|
186
211
|
logger.log(chalk.yellow('\nWould apply:'));
|
|
187
212
|
result.changes.forEach(c => logger.log(chalk.gray(` ${c}`)));
|
|
188
213
|
} else if (result.updated) {
|
|
189
|
-
logger.log(
|
|
214
|
+
logger.log(formatSuccessParagraph('Repaired external integration config.'));
|
|
215
|
+
} else if (result.readmeRegenerated) {
|
|
216
|
+
logger.log(formatSuccessParagraph('Regenerated README.md from deployment manifest.'));
|
|
190
217
|
} else {
|
|
191
218
|
logger.log(chalk.gray('No changes needed; config already matches files on disk.'));
|
|
192
219
|
}
|
|
@@ -199,7 +226,7 @@ function setupRepairCommand(program) {
|
|
|
199
226
|
|
|
200
227
|
function setupConvertCommand(program) {
|
|
201
228
|
program.command('convert <app>')
|
|
202
|
-
.description('Convert integration
|
|
229
|
+
.description('Convert integration config files between JSON and YAML')
|
|
203
230
|
.option('--format <format>', 'Target format: json | yaml (required unless config format is set)')
|
|
204
231
|
.option('-f, --force', 'Skip confirmation prompt')
|
|
205
232
|
.action(async(appName, options) => {
|
|
@@ -217,7 +244,7 @@ function setupConvertCommand(program) {
|
|
|
217
244
|
}
|
|
218
245
|
const { runConvert } = require('../commands/convert');
|
|
219
246
|
const { converted, deleted } = await runConvert(appName, { format: normalized, force: options.force });
|
|
220
|
-
logger.log(
|
|
247
|
+
logger.log(formatSuccessParagraph('Convert complete.'));
|
|
221
248
|
converted.forEach(p => logger.log(` • ${p}`));
|
|
222
249
|
if (deleted.length > 0) {
|
|
223
250
|
logger.log(chalk.gray(' Removed old files:'));
|
|
@@ -231,8 +258,8 @@ function setupConvertCommand(program) {
|
|
|
231
258
|
}
|
|
232
259
|
|
|
233
260
|
function setupShowCommand(program) {
|
|
234
|
-
program.command('show <
|
|
235
|
-
.description('Show
|
|
261
|
+
program.command('show <app>')
|
|
262
|
+
.description('Show app from local tree (default) or controller (--online)')
|
|
236
263
|
.option('--online', 'Fetch application data from the controller')
|
|
237
264
|
.option('--json', 'Output as JSON')
|
|
238
265
|
.action(async(appKey, options) => {
|
|
@@ -291,7 +318,8 @@ async function runValidateCommand(appOrFile, options) {
|
|
|
291
318
|
|
|
292
319
|
function setupValidateDiffCommands(program) {
|
|
293
320
|
program.command('validate [appOrFile]')
|
|
294
|
-
.description('Validate
|
|
321
|
+
.description('Validate one app/file or all under integration/ or builder/')
|
|
322
|
+
.addHelpText('after', VALIDATE_HELP_AFTER)
|
|
295
323
|
.option('--format <format>', 'Output format: json | default (human-readable)')
|
|
296
324
|
.option('--integration', 'Validate all applications under integration/')
|
|
297
325
|
.option('--builder', 'Validate all applications under builder/')
|
|
@@ -303,7 +331,7 @@ function setupValidateDiffCommands(program) {
|
|
|
303
331
|
});
|
|
304
332
|
|
|
305
333
|
program.command('diff <file1> <file2>')
|
|
306
|
-
.description('
|
|
334
|
+
.description('Diff two config files (optional schema validate)')
|
|
307
335
|
.option('--no-validate', 'Skip schema validation (type check still applied)')
|
|
308
336
|
.action(async(file1, file2, cmd) => {
|
|
309
337
|
try {
|
package/lib/commands/app-down.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* Down-app command – stop container, optionally volumes, then remove image if unused
|
|
3
4
|
*
|
|
@@ -7,14 +8,11 @@
|
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
const chalk = require('chalk');
|
|
10
|
-
const { exec } = require('child_process');
|
|
11
|
-
const { promisify } = require('util');
|
|
12
11
|
const logger = require('../utils/logger');
|
|
13
12
|
const config = require('../core/config');
|
|
14
13
|
const containerHelpers = require('../utils/app-run-containers');
|
|
15
14
|
const { downApp } = require('../app/down');
|
|
16
|
-
|
|
17
|
-
const execAsync = promisify(exec);
|
|
15
|
+
const { execWithDockerEnv } = require('../utils/docker-exec');
|
|
18
16
|
|
|
19
17
|
/**
|
|
20
18
|
* Get image ID of a running container (sha or name:tag)
|
|
@@ -24,7 +22,7 @@ const execAsync = promisify(exec);
|
|
|
24
22
|
*/
|
|
25
23
|
async function getContainerImageId(containerName) {
|
|
26
24
|
try {
|
|
27
|
-
const { stdout } = await
|
|
25
|
+
const { stdout } = await execWithDockerEnv(
|
|
28
26
|
`docker inspect --format='{{.Image}}' ${containerName}`,
|
|
29
27
|
{ encoding: 'utf8' }
|
|
30
28
|
);
|
|
@@ -43,8 +41,8 @@ async function getContainerImageId(containerName) {
|
|
|
43
41
|
async function removeImageIfUnused(imageId) {
|
|
44
42
|
if (!imageId) return;
|
|
45
43
|
try {
|
|
46
|
-
await
|
|
47
|
-
logger.log(
|
|
44
|
+
await execWithDockerEnv(`docker rmi ${imageId}`);
|
|
45
|
+
logger.log(formatSuccessLine(`Image ${imageId} removed`));
|
|
48
46
|
} catch (err) {
|
|
49
47
|
const msg = (err && err.message) || '';
|
|
50
48
|
if (msg.includes('in use') || msg.includes('is being used')) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* Install command – run install (dependencies) inside app container (dev: running; tst: ephemeral with .env).
|
|
3
4
|
*
|
|
@@ -81,7 +82,7 @@ async function runInstallInDev(appName, developerId, installCmd) {
|
|
|
81
82
|
logger.log(chalk.blue(`Running install in container ${containerName}: ${installCmd}\n`));
|
|
82
83
|
const cmd = installCommandForReadOnlyApp(installCmd);
|
|
83
84
|
const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
|
|
84
|
-
return runDockerExec(containerName, cmd, envFilePath);
|
|
85
|
+
return await runDockerExec(containerName, cmd, envFilePath);
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
/**
|
|
@@ -92,7 +93,9 @@ async function runInstallInDev(appName, developerId, installCmd) {
|
|
|
92
93
|
* @param {string|null} [envFilePath] - Path to resolved .env for --env-file (optional; when set, install has registry tokens)
|
|
93
94
|
* @returns {Promise<number>} Exit code
|
|
94
95
|
*/
|
|
95
|
-
function runDockerExec(containerName, cmd, envFilePath = null) {
|
|
96
|
+
async function runDockerExec(containerName, cmd, envFilePath = null) {
|
|
97
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
98
|
+
const dockerEnv = await getDockerExecEnv();
|
|
96
99
|
return new Promise((resolve) => {
|
|
97
100
|
const args = [
|
|
98
101
|
'exec',
|
|
@@ -106,7 +109,8 @@ function runDockerExec(containerName, cmd, envFilePath = null) {
|
|
|
106
109
|
args.push(containerName, 'sh', '-c', cmd);
|
|
107
110
|
const proc = spawn('docker', args, {
|
|
108
111
|
stdio: 'inherit',
|
|
109
|
-
shell: false
|
|
112
|
+
shell: false,
|
|
113
|
+
env: dockerEnv
|
|
110
114
|
});
|
|
111
115
|
proc.on('close', code => resolve(code !== null ? code : 1));
|
|
112
116
|
proc.on('error', () => resolve(1));
|
|
@@ -120,7 +124,9 @@ function runDockerExec(containerName, cmd, envFilePath = null) {
|
|
|
120
124
|
* @param {string|null} [envFilePath] - Path to .env file for --env-file (optional)
|
|
121
125
|
* @returns {Promise<number>} Exit code
|
|
122
126
|
*/
|
|
123
|
-
function runDockerRunEphemeral(fullImage, cmd, envFilePath = null) {
|
|
127
|
+
async function runDockerRunEphemeral(fullImage, cmd, envFilePath = null) {
|
|
128
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
129
|
+
const dockerEnv = await getDockerExecEnv();
|
|
124
130
|
return new Promise((resolve) => {
|
|
125
131
|
const args = ['run', '--rm', '-e', `TMPDIR=${TMPDIR_VALUE}`, '-e', `npm_config_store_dir=${PNPM_STORE_DIR}`, '-e', 'CI=true'];
|
|
126
132
|
if (envFilePath) {
|
|
@@ -129,7 +135,8 @@ function runDockerRunEphemeral(fullImage, cmd, envFilePath = null) {
|
|
|
129
135
|
args.push(fullImage, 'sh', '-c', cmd);
|
|
130
136
|
const proc = spawn('docker', args, {
|
|
131
137
|
stdio: 'inherit',
|
|
132
|
-
shell: false
|
|
138
|
+
shell: false,
|
|
139
|
+
env: dockerEnv
|
|
133
140
|
});
|
|
134
141
|
proc.on('close', code => resolve(code !== null ? code : 1));
|
|
135
142
|
proc.on('error', () => resolve(1));
|
|
@@ -157,7 +164,7 @@ async function runAppInstall(appName, options = {}) {
|
|
|
157
164
|
if (env === 'dev') {
|
|
158
165
|
const code = await runInstallInDev(appName, developerId, installCmd);
|
|
159
166
|
if (code !== 0) process.exit(code);
|
|
160
|
-
logger.log(
|
|
167
|
+
logger.log(formatSuccessLine('Install completed'));
|
|
161
168
|
return;
|
|
162
169
|
}
|
|
163
170
|
|
|
@@ -166,7 +173,7 @@ async function runAppInstall(appName, options = {}) {
|
|
|
166
173
|
const cmd = installCommandForReadOnlyApp(installCmd);
|
|
167
174
|
const code = await runDockerRunEphemeral(fullImage, cmd, envFilePath);
|
|
168
175
|
if (code !== 0) process.exit(code);
|
|
169
|
-
logger.log(
|
|
176
|
+
logger.log(formatSuccessLine('Install completed'));
|
|
170
177
|
}
|
|
171
178
|
|
|
172
179
|
module.exports = { runAppInstall, getInstallCommand };
|
package/lib/commands/app-logs.js
CHANGED
|
@@ -7,15 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const chalk = require('chalk');
|
|
10
|
-
const {
|
|
10
|
+
const { spawn } = require('child_process');
|
|
11
11
|
const readline = require('readline');
|
|
12
|
-
const { promisify } = require('util');
|
|
13
12
|
const logger = require('../utils/logger');
|
|
14
13
|
const config = require('../core/config');
|
|
15
14
|
const containerHelpers = require('../utils/app-run-containers');
|
|
16
15
|
const { validateAppName } = require('../app/push');
|
|
17
16
|
|
|
18
|
-
const
|
|
17
|
+
const { execWithDockerEnv } = require('../utils/docker-exec');
|
|
19
18
|
|
|
20
19
|
/** Default number of log lines */
|
|
21
20
|
const DEFAULT_TAIL_LINES = 100;
|
|
@@ -132,7 +131,7 @@ function passesLevelFilter(lineLevel, minLevel) {
|
|
|
132
131
|
*/
|
|
133
132
|
async function dumpMaskedEnv(containerName) {
|
|
134
133
|
try {
|
|
135
|
-
const { stdout } = await
|
|
134
|
+
const { stdout } = await execWithDockerEnv(`docker exec ${containerName} env`, { encoding: 'utf8', timeout: 5000 });
|
|
136
135
|
const lines = stdout.split('\n').filter((l) => l.trim());
|
|
137
136
|
if (lines.length === 0) return;
|
|
138
137
|
logger.log(chalk.bold('\n--- Environment (sensitive values masked) ---\n'));
|
|
@@ -156,6 +155,8 @@ async function dumpMaskedEnv(containerName) {
|
|
|
156
155
|
* @returns {Promise<void>}
|
|
157
156
|
*/
|
|
158
157
|
async function runDockerLogs(containerName, options) {
|
|
158
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
159
|
+
const dockerEnv = await getDockerExecEnv();
|
|
159
160
|
const args = options.tail === 0 ? ['logs', containerName] : ['logs', '--tail', String(options.tail), containerName];
|
|
160
161
|
const minLevel =
|
|
161
162
|
options.level !== undefined && options.level !== null && options.level !== ''
|
|
@@ -164,14 +165,14 @@ async function runDockerLogs(containerName, options) {
|
|
|
164
165
|
|
|
165
166
|
if (minLevel === null || minLevel === undefined || !LOG_LEVELS.includes(minLevel)) {
|
|
166
167
|
return new Promise((resolve, reject) => {
|
|
167
|
-
const proc = spawn('docker', args, { stdio: 'inherit' });
|
|
168
|
+
const proc = spawn('docker', args, { stdio: 'inherit', env: dockerEnv });
|
|
168
169
|
proc.on('error', reject);
|
|
169
170
|
proc.on('close', (code) => (code === 0 ? resolve() : reject(new Error(`docker logs exited with ${code}`))));
|
|
170
171
|
});
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
return new Promise((resolve, reject) => {
|
|
174
|
-
const proc = spawn('docker', args, { stdio: ['inherit', 'pipe', 'pipe'] });
|
|
175
|
+
const proc = spawn('docker', args, { stdio: ['inherit', 'pipe', 'pipe'], env: dockerEnv });
|
|
175
176
|
proc.on('error', reject);
|
|
176
177
|
|
|
177
178
|
function onLine(line) {
|
|
@@ -213,7 +214,9 @@ async function runDockerLogs(containerName, options) {
|
|
|
213
214
|
* @param {number} [tail] - Lines to show (0 = full, omit --tail)
|
|
214
215
|
* @param {string|null} [minLevel] - Minimum log level to show (debug|info|warn|error)
|
|
215
216
|
*/
|
|
216
|
-
function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
217
|
+
async function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
218
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
219
|
+
const dockerEnv = await getDockerExecEnv();
|
|
217
220
|
const args = tail === 0 ? ['logs', '-f', containerName] : ['logs', '-f', '--tail', String(tail), containerName];
|
|
218
221
|
const level =
|
|
219
222
|
minLevel !== undefined && minLevel !== null && minLevel !== ''
|
|
@@ -222,7 +225,7 @@ function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
|
222
225
|
const useFilter = level !== null && level !== undefined && LOG_LEVELS.includes(level);
|
|
223
226
|
|
|
224
227
|
if (!useFilter) {
|
|
225
|
-
const proc = spawn('docker', args, { stdio: 'inherit' });
|
|
228
|
+
const proc = spawn('docker', args, { stdio: 'inherit', env: dockerEnv });
|
|
226
229
|
proc.on('error', (err) => {
|
|
227
230
|
logger.log(chalk.red(`Error: ${err.message}`));
|
|
228
231
|
process.exit(1);
|
|
@@ -233,7 +236,7 @@ function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
|
233
236
|
return;
|
|
234
237
|
}
|
|
235
238
|
|
|
236
|
-
const proc = spawn('docker', args, { stdio: ['inherit', 'pipe', 'pipe'] });
|
|
239
|
+
const proc = spawn('docker', args, { stdio: ['inherit', 'pipe', 'pipe'], env: dockerEnv });
|
|
237
240
|
proc.on('error', (err) => {
|
|
238
241
|
logger.log(chalk.red(`Error: ${err.message}`));
|
|
239
242
|
process.exit(1);
|
|
@@ -286,7 +289,7 @@ async function runAppLogs(appKey, options = {}) {
|
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
if (follow) {
|
|
289
|
-
runDockerLogsFollow(containerName, tail, level);
|
|
292
|
+
await runDockerLogsFollow(containerName, tail, level);
|
|
290
293
|
return;
|
|
291
294
|
}
|
|
292
295
|
|
|
@@ -48,6 +48,8 @@ async function runAppShell(appName, _options = {}) {
|
|
|
48
48
|
|
|
49
49
|
logger.log(chalk.blue(`Opening shell in ${containerName} (exit with 'exit' or Ctrl+D)...\n`));
|
|
50
50
|
|
|
51
|
+
const { getDockerExecEnv } = require('../utils/remote-docker-env');
|
|
52
|
+
const dockerEnv = await getDockerExecEnv();
|
|
51
53
|
const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
|
|
52
54
|
const proc = spawn('docker', [
|
|
53
55
|
'exec', '-it',
|
|
@@ -57,7 +59,8 @@ async function runAppShell(appName, _options = {}) {
|
|
|
57
59
|
'sh'
|
|
58
60
|
], {
|
|
59
61
|
stdio: 'inherit',
|
|
60
|
-
shell: false
|
|
62
|
+
shell: false,
|
|
63
|
+
env: dockerEnv
|
|
61
64
|
});
|
|
62
65
|
|
|
63
66
|
return new Promise((resolve, reject) => {
|