@aifabrix/builder 2.43.0 → 2.44.1
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/.cursor/rules/cli-layout.mdc +75 -0
- package/.cursor/rules/project-rules.mdc +8 -0
- package/.npmrc.token +1 -0
- package/.nyc_output/55e9d034-ddab-4579-a706-e02a91d75c91.json +1 -0
- package/.nyc_output/processinfo/55e9d034-ddab-4579-a706-e02a91d75c91.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -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 +301 -0
- package/lib/api/certificates.api.js +62 -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 +11 -3
- package/lib/api/pipeline.api.js +67 -20
- package/lib/api/types/certificates.types.js +48 -0
- 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 +111 -0
- package/lib/api/validation-runner.js +109 -0
- package/lib/app/certification-show-enrich.js +129 -0
- package/lib/app/certification-verify-rows.js +60 -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 +44 -1
- package/lib/app/show.js +93 -9
- package/lib/build/index.js +13 -10
- package/lib/certification/cli-cert-sync-skip.js +21 -0
- package/lib/certification/merge-certification-from-artifact.js +185 -0
- package/lib/certification/post-unified-cert-sync.js +33 -0
- package/lib/certification/sync-after-external-command.js +52 -0
- package/lib/certification/sync-system-certification.js +197 -0
- package/lib/cli/index.js +2 -0
- package/lib/cli/setup-app.help.js +67 -0
- package/lib/cli/setup-app.js +61 -121
- package/lib/cli/setup-app.test-commands.js +195 -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 +84 -23
- package/lib/cli/setup-infra.js +126 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +137 -18
- package/lib/cli/setup-service-user.js +1 -1
- package/lib/cli/setup-utility.js +54 -22
- 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 +32 -11
- 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 +428 -0
- package/lib/commands/datasource-unified-test-cli.options.js +191 -0
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +106 -0
- package/lib/commands/datasource-validation-cli.js +143 -0
- package/lib/commands/datasource.js +125 -95
- 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 +149 -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 +189 -67
- package/lib/datasource/resolve-app.js +4 -4
- package/lib/datasource/test-e2e.js +113 -146
- package/lib/datasource/test-integration.js +114 -122
- package/lib/datasource/unified-validation-run-body.js +68 -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 +93 -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 +166 -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 +70 -7
- package/lib/infrastructure/helpers-docker-check.js +67 -0
- package/lib/infrastructure/helpers.js +203 -42
- package/lib/infrastructure/index.js +31 -18
- package/lib/infrastructure/services.js +21 -67
- 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 +203 -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 +226 -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 +77 -17
- 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/configuration-env-resolver.js +11 -8
- package/lib/utils/controller-deployment-outcome.js +68 -0
- package/lib/utils/credential-display.js +2 -2
- package/lib/utils/credential-secrets-env.js +5 -5
- 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-certificate-tty.js +82 -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 +459 -0
- package/lib/utils/datasource-test-run-exit.js +83 -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 +242 -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-system-test-tty-overview.js +120 -0
- package/lib/utils/external-system-system-test-tty.js +417 -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 +148 -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 +112 -0
- package/lib/utils/validation-run-post-retry.js +85 -0
- package/lib/utils/validation-run-request.js +116 -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-external-cert-sync.js +23 -0
- package/lib/validation/validate.js +8 -14
- 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 +9 -4
- package/scripts/check-datasource-test-run-schema-sync.js +34 -0
- package/scripts/diagnose-cli.js +150 -0
- package/scripts/install-local.js +307 -55
- package/scripts/pnpm-global-remove.js +48 -0
- package/templates/README.md +15 -2
- package/templates/applications/dataplane/application.yaml +52 -2
- package/templates/applications/dataplane/env.template +79 -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 +33 -16
- package/templates/infra/servers.json.hbs +3 -1
- 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
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
10
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
10
11
|
|
|
11
12
|
const path = require('path');
|
|
12
13
|
const fs = require('fs');
|
|
@@ -84,6 +85,23 @@ function getDatasourceKeys(appPath, configPath, variables, systemKey, systemPars
|
|
|
84
85
|
return keys;
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Full upload to dataplane when --sync (same path as `aifabrix upload <systemKey>`).
|
|
90
|
+
* @param {string} systemKey
|
|
91
|
+
* @param {Object} options
|
|
92
|
+
* @returns {Promise<void>}
|
|
93
|
+
*/
|
|
94
|
+
async function syncLocalIfRequested(systemKey, options) {
|
|
95
|
+
if (options.sync !== true) return;
|
|
96
|
+
logger.log(chalk.cyan('Syncing local config to dataplane…'));
|
|
97
|
+
const { uploadExternalSystem } = require('./upload');
|
|
98
|
+
await uploadExternalSystem(systemKey, {
|
|
99
|
+
verbose: !!options.verbose,
|
|
100
|
+
minimal: true
|
|
101
|
+
});
|
|
102
|
+
logger.log(formatSuccessLine('Sync complete'));
|
|
103
|
+
}
|
|
104
|
+
|
|
87
105
|
/* eslint-disable max-lines-per-function, max-statements -- Load context, then loop over keys */
|
|
88
106
|
/**
|
|
89
107
|
* Runs E2E for all datasources of an external system. Uses each datasource's payloadTemplate (no extra params required).
|
|
@@ -95,6 +113,7 @@ function getDatasourceKeys(appPath, configPath, variables, systemKey, systemPars
|
|
|
95
113
|
* @param {boolean} [options.debug] - Include debug, write log
|
|
96
114
|
* @param {boolean} [options.verbose] - Verbose output
|
|
97
115
|
* @param {boolean} [options.async] - If false, sync mode (default true)
|
|
116
|
+
* @param {boolean} [options.sync] - When true, run full upload (`uploadExternalSystem`) before per-datasource E2E
|
|
98
117
|
* @returns {Promise<{ success: boolean, results: Array<{ key: string, success: boolean, error?: string }> }>}
|
|
99
118
|
*/
|
|
100
119
|
async function runTestE2EForExternalSystem(externalSystem, options = {}) {
|
|
@@ -137,6 +156,8 @@ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
|
|
|
137
156
|
return { success: true, results: [] };
|
|
138
157
|
}
|
|
139
158
|
|
|
159
|
+
await syncLocalIfRequested(systemKey, options);
|
|
160
|
+
|
|
140
161
|
const results = [];
|
|
141
162
|
const opts = {
|
|
142
163
|
app: externalSystem,
|
|
@@ -150,7 +171,12 @@ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
|
|
|
150
171
|
const data = await runDatasourceTestE2E(key, opts);
|
|
151
172
|
const steps = data.steps || data.completedActions || [];
|
|
152
173
|
const failed = data.success === false || steps.some(s => s.success === false || s.error);
|
|
153
|
-
results.push({
|
|
174
|
+
results.push({
|
|
175
|
+
key,
|
|
176
|
+
success: !failed,
|
|
177
|
+
error: failed ? (data.error || 'E2E step failed') : undefined,
|
|
178
|
+
datasourceTestRun: data.datasourceTestRun
|
|
179
|
+
});
|
|
154
180
|
} catch (err) {
|
|
155
181
|
results.push({ key, success: false, error: err.message });
|
|
156
182
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* AI Fabrix Builder - Up Commands Shared Helpers
|
|
3
4
|
*
|
|
@@ -213,7 +214,7 @@ async function ensureAppFromTemplate(appName) {
|
|
|
213
214
|
const primaryCopied = await ensureTemplateAtPath(appName, appPath);
|
|
214
215
|
if (primaryCopied) {
|
|
215
216
|
logger.log(chalk.blue(`Creating builder/${appName} from template...`));
|
|
216
|
-
logger.log(
|
|
217
|
+
logger.log(formatSuccessLine(`Copied template for ${appName}`));
|
|
217
218
|
}
|
|
218
219
|
|
|
219
220
|
const cwdBuilderPath = path.join(process.cwd(), 'builder', appName);
|
|
@@ -221,7 +222,7 @@ async function ensureAppFromTemplate(appName) {
|
|
|
221
222
|
const cwdCopied = await ensureTemplateAtPath(appName, cwdBuilderPath);
|
|
222
223
|
if (cwdCopied) {
|
|
223
224
|
logger.log(chalk.blue(`Creating builder/${appName} in project (from template)...`));
|
|
224
|
-
logger.log(
|
|
225
|
+
logger.log(formatSuccessLine(`Copied template for ${appName} into builder/`));
|
|
225
226
|
}
|
|
226
227
|
}
|
|
227
228
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine, formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* AI Fabrix Builder - Up Dataplane Command
|
|
3
4
|
*
|
|
@@ -11,10 +12,12 @@
|
|
|
11
12
|
* @version 2.0.0
|
|
12
13
|
*/
|
|
13
14
|
|
|
15
|
+
const path = require('path');
|
|
14
16
|
const readline = require('readline');
|
|
15
17
|
const chalk = require('chalk');
|
|
16
18
|
const pathsUtil = require('../utils/paths');
|
|
17
19
|
const { loadConfigFile } = require('../utils/config-format');
|
|
20
|
+
const { resolveDockerImageRef, normalizeDockerRegistryPrefix } = require('../utils/resolve-docker-image-ref');
|
|
18
21
|
const logger = require('../utils/logger');
|
|
19
22
|
const config = require('../core/config');
|
|
20
23
|
const { checkAuthentication } = require('../utils/app-register-auth');
|
|
@@ -96,7 +99,7 @@ async function resolveControllerUrlWithHealthCheck() {
|
|
|
96
99
|
throw new Error(`Controller at ${normalizedNew} is not responding. Ensure the controller is running and reachable, then run "aifabrix up-dataplane" again.`);
|
|
97
100
|
}
|
|
98
101
|
|
|
99
|
-
logger.log(
|
|
102
|
+
logger.log(formatSuccessLine(`Using controller: ${normalizedNew}`));
|
|
100
103
|
return normalizedNew;
|
|
101
104
|
}
|
|
102
105
|
|
|
@@ -114,7 +117,7 @@ async function registerOrRotateDataplane(options, controllerUrl, environmentKey,
|
|
|
114
117
|
logger.log(chalk.blue('Dataplane already registered; rotating secret...'));
|
|
115
118
|
await rotateSecret('dataplane', options);
|
|
116
119
|
} else {
|
|
117
|
-
const imageOverride = options.image ||
|
|
120
|
+
const imageOverride = options.image || buildDataplaneImageRef(options);
|
|
118
121
|
const registerOpts = { imageOverride, image: imageOverride, registryMode: options.registryMode };
|
|
119
122
|
await registerApplication('dataplane', registerOpts);
|
|
120
123
|
}
|
|
@@ -126,25 +129,32 @@ async function registerOrRotateDataplane(options, controllerUrl, environmentKey,
|
|
|
126
129
|
* @returns {Promise<void>}
|
|
127
130
|
*/
|
|
128
131
|
async function deployDataplaneToController(options) {
|
|
129
|
-
const imageOverride = options.image ||
|
|
132
|
+
const imageOverride = options.image || buildDataplaneImageRef(options);
|
|
130
133
|
const deployOpts = { imageOverride, image: imageOverride, registryMode: options.registryMode };
|
|
131
134
|
await app.deployApp('dataplane', deployOpts);
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
/**
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* @
|
|
138
|
+
* Full pullable image ref when CLI `--registry` and/or manifest `image.registry` is set.
|
|
139
|
+
* Returns undefined when neither is set (register/deploy use application config as before).
|
|
140
|
+
* @param {Object} [options] - Commander options
|
|
141
|
+
* @param {string} [options.registry] - CLI registry override (wins over manifest)
|
|
142
|
+
* @returns {string|undefined} Full reference or undefined
|
|
138
143
|
*/
|
|
139
|
-
function buildDataplaneImageRef(
|
|
144
|
+
function buildDataplaneImageRef(options = {}) {
|
|
140
145
|
try {
|
|
141
146
|
const builderPath = pathsUtil.getBuilderPath('dataplane');
|
|
142
147
|
const configPath = pathsUtil.resolveApplicationConfigPath(builderPath);
|
|
143
|
-
const variables = loadConfigFile(configPath);
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
const variables = loadConfigFile(configPath) || {};
|
|
149
|
+
const cli = normalizeDockerRegistryPrefix(options.registry);
|
|
150
|
+
const manifestReg = normalizeDockerRegistryPrefix(variables.image?.registry);
|
|
151
|
+
if (!cli && !manifestReg) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
const { imageName, imageTag } = resolveDockerImageRef('dataplane', variables, {
|
|
155
|
+
registry: options.registry || undefined
|
|
156
|
+
});
|
|
157
|
+
return `${imageName}:${imageTag}`;
|
|
148
158
|
} catch {
|
|
149
159
|
return undefined;
|
|
150
160
|
}
|
|
@@ -167,7 +177,7 @@ function buildDataplaneImageRef(registry) {
|
|
|
167
177
|
async function handleUpDataplane(options = {}) {
|
|
168
178
|
const builderDir = await config.getAifabrixBuilderDir();
|
|
169
179
|
if (builderDir) {
|
|
170
|
-
process.env.AIFABRIX_BUILDER_DIR = builderDir;
|
|
180
|
+
process.env.AIFABRIX_BUILDER_DIR = path.resolve(builderDir);
|
|
171
181
|
}
|
|
172
182
|
logger.log(chalk.blue('Starting up-dataplane (register/rotate, deploy, then run dataplane locally)...\n'));
|
|
173
183
|
|
|
@@ -182,7 +192,7 @@ async function handleUpDataplane(options = {}) {
|
|
|
182
192
|
'Dataplane is only supported in dev environment. Set with: aifabrix auth --set-environment dev.'
|
|
183
193
|
);
|
|
184
194
|
}
|
|
185
|
-
logger.log(
|
|
195
|
+
logger.log(formatSuccessLine('Logged in and environment is dev'));
|
|
186
196
|
|
|
187
197
|
await ensureAppFromTemplate('dataplane');
|
|
188
198
|
// If envOutputPath target folder does not exist, set envOutputPath to null
|
|
@@ -192,9 +202,12 @@ async function handleUpDataplane(options = {}) {
|
|
|
192
202
|
|
|
193
203
|
await deployDataplaneToController(options);
|
|
194
204
|
logger.log('');
|
|
195
|
-
await app.runApp('dataplane', {
|
|
205
|
+
await app.runApp('dataplane', {
|
|
206
|
+
skipEnvOutputPath: true,
|
|
207
|
+
registry: options.registry || undefined
|
|
208
|
+
});
|
|
196
209
|
|
|
197
|
-
logger.log(
|
|
210
|
+
logger.log(formatSuccessParagraph('up-dataplane complete. Dataplane is registered, deployed in dev, and running locally.'));
|
|
198
211
|
}
|
|
199
212
|
|
|
200
213
|
module.exports = { handleUpDataplane, buildDataplaneImageRef };
|
package/lib/commands/up-miso.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine, formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* AI Fabrix Builder - Up Miso Command
|
|
3
4
|
*
|
|
@@ -9,9 +10,8 @@
|
|
|
9
10
|
* @version 2.0.0
|
|
10
11
|
*/
|
|
11
12
|
|
|
13
|
+
const path = require('path');
|
|
12
14
|
const chalk = require('chalk');
|
|
13
|
-
const pathsUtil = require('../utils/paths');
|
|
14
|
-
const { loadConfigFile } = require('../utils/config-format');
|
|
15
15
|
const logger = require('../utils/logger');
|
|
16
16
|
const config = require('../core/config');
|
|
17
17
|
const infra = require('../infrastructure');
|
|
@@ -38,26 +38,6 @@ function parseImageOptions(imageOpts) {
|
|
|
38
38
|
return map;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
/**
|
|
42
|
-
* Build full image ref from registry and app config (registry/name:tag)
|
|
43
|
-
* @param {string} appName - keycloak or miso-controller
|
|
44
|
-
* @param {string} registry - Registry URL
|
|
45
|
-
* @returns {string} Full image reference
|
|
46
|
-
*/
|
|
47
|
-
function buildImageRefFromRegistry(appName, registry) {
|
|
48
|
-
try {
|
|
49
|
-
const builderPath = pathsUtil.getBuilderPath(appName);
|
|
50
|
-
const configPath = pathsUtil.resolveApplicationConfigPath(builderPath);
|
|
51
|
-
const variables = loadConfigFile(configPath);
|
|
52
|
-
const name = variables?.image?.name || variables?.app?.key || appName;
|
|
53
|
-
const tag = variables?.image?.tag || 'latest';
|
|
54
|
-
const base = (registry || '').replace(/\/+$/, '');
|
|
55
|
-
return base ? `${base}/${name}:${tag}` : undefined;
|
|
56
|
-
} catch {
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
41
|
/**
|
|
62
42
|
* Build run options and run keycloak, then miso-controller
|
|
63
43
|
* @async
|
|
@@ -65,10 +45,20 @@ function buildImageRefFromRegistry(appName, registry) {
|
|
|
65
45
|
*/
|
|
66
46
|
async function runMisoApps(options) {
|
|
67
47
|
const imageMap = parseImageOptions(options.image);
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
48
|
+
const common = {
|
|
49
|
+
registry: options.registry,
|
|
50
|
+
registryMode: options.registryMode,
|
|
51
|
+
skipEnvOutputPath: true,
|
|
52
|
+
skipInfraCheck: true
|
|
53
|
+
};
|
|
54
|
+
const keycloakRunOpts = { ...common };
|
|
55
|
+
if (imageMap.keycloak) {
|
|
56
|
+
keycloakRunOpts.image = imageMap.keycloak;
|
|
57
|
+
}
|
|
58
|
+
const misoRunOpts = { ...common };
|
|
59
|
+
if (imageMap['miso-controller']) {
|
|
60
|
+
misoRunOpts.image = imageMap['miso-controller'];
|
|
61
|
+
}
|
|
72
62
|
logger.log(chalk.blue('Starting keycloak...'));
|
|
73
63
|
await app.runApp('keycloak', keycloakRunOpts);
|
|
74
64
|
logger.log(chalk.blue('Starting miso-controller...'));
|
|
@@ -90,7 +80,7 @@ async function runMisoApps(options) {
|
|
|
90
80
|
async function handleUpMiso(options = {}) {
|
|
91
81
|
const builderDir = await config.getAifabrixBuilderDir();
|
|
92
82
|
if (builderDir) {
|
|
93
|
-
process.env.AIFABRIX_BUILDER_DIR = builderDir;
|
|
83
|
+
process.env.AIFABRIX_BUILDER_DIR = path.resolve(builderDir);
|
|
94
84
|
}
|
|
95
85
|
logger.log(chalk.blue('Starting up-miso (keycloak + miso-controller from images)...\n'));
|
|
96
86
|
// Strict: only this developer's infra (same as status), so up-miso and status agree
|
|
@@ -99,7 +89,7 @@ async function handleUpMiso(options = {}) {
|
|
|
99
89
|
if (!allHealthy) {
|
|
100
90
|
throw new Error('Infrastructure is not up. Run \'aifabrix up-infra\' first.');
|
|
101
91
|
}
|
|
102
|
-
logger.log(
|
|
92
|
+
logger.log(formatSuccessLine('Infrastructure is up'));
|
|
103
93
|
await ensureAppFromTemplate('keycloak');
|
|
104
94
|
await ensureAppFromTemplate('miso-controller');
|
|
105
95
|
// If envOutputPath target folder does not exist, set envOutputPath to null
|
|
@@ -109,7 +99,7 @@ async function handleUpMiso(options = {}) {
|
|
|
109
99
|
patchEnvOutputPathForDeployOnly('keycloak');
|
|
110
100
|
patchEnvOutputPathForDeployOnly('miso-controller');
|
|
111
101
|
await runMisoApps(options);
|
|
112
|
-
logger.log(
|
|
102
|
+
logger.log(formatSuccessParagraph('up-miso complete. Keycloak and miso-controller are running.') +
|
|
113
103
|
chalk.gray('\n Run onboarding and register Keycloak from the miso-controller repo if needed. Use \'aifabrix up-dataplane\' for dataplane.'));
|
|
114
104
|
}
|
|
115
105
|
|
package/lib/commands/upload.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
|
-
* Upload external system to dataplane (single pipeline upload:
|
|
3
|
+
* Upload external system to dataplane (single pipeline upload: validate → publish → controller register).
|
|
3
4
|
*
|
|
4
|
-
* @fileoverview Upload command handler for aifabrix upload <
|
|
5
|
+
* @fileoverview Upload command handler for aifabrix upload <systemKey>
|
|
5
6
|
* @author AI Fabrix Team
|
|
6
7
|
* @version 2.0.0
|
|
7
8
|
*/
|
|
@@ -21,9 +22,21 @@ const {
|
|
|
21
22
|
const { validateExternalSystemComplete } = require('../validation/validate');
|
|
22
23
|
const { displayValidationResults } = require('../validation/validate-display');
|
|
23
24
|
const { generateControllerManifest } = require('../generator/external-controller-manifest');
|
|
24
|
-
const {
|
|
25
|
+
const {
|
|
26
|
+
uploadApplicationViaPipeline,
|
|
27
|
+
validatePipelineConfig,
|
|
28
|
+
testSystemViaPipeline
|
|
29
|
+
} = require('../api/pipeline.api');
|
|
25
30
|
const { formatApiError } = require('../utils/api-error-handler');
|
|
26
31
|
const { logDataplanePipelineWarning } = require('../utils/dataplane-pipeline-warning');
|
|
32
|
+
const { unwrapPublicationResult, unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
33
|
+
const {
|
|
34
|
+
logUploadReadinessSummary,
|
|
35
|
+
logServerValidationWarnings,
|
|
36
|
+
logProbeRuntimeBlock
|
|
37
|
+
} = require('../utils/external-system-readiness-display');
|
|
38
|
+
const { maybeSyncSystemCertificationFromDataplane } = require('../certification/sync-system-certification');
|
|
39
|
+
const { cliOptsSkipCertSync } = require('../certification/cli-cert-sync-skip');
|
|
27
40
|
|
|
28
41
|
/**
|
|
29
42
|
* Validates system-key format (same as download).
|
|
@@ -66,10 +79,10 @@ async function resolveDataplaneAndAuth(systemKey) {
|
|
|
66
79
|
const authConfig = await getDeploymentAuth(controllerUrl, environment, systemKey);
|
|
67
80
|
|
|
68
81
|
if (!authConfig.token && !authConfig.clientId) {
|
|
69
|
-
throw new Error('Authentication required. Run "aifabrix login" or "aifabrix app register <
|
|
82
|
+
throw new Error('Authentication required. Run "aifabrix login" or "aifabrix app register <systemKey>" first.');
|
|
70
83
|
}
|
|
71
84
|
|
|
72
|
-
logger.log(chalk.
|
|
85
|
+
logger.log(chalk.gray('Resolving dataplane URL...'));
|
|
73
86
|
const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig);
|
|
74
87
|
return { dataplaneUrl, authConfig, environment };
|
|
75
88
|
}
|
|
@@ -79,7 +92,7 @@ async function resolveDataplaneAndAuth(systemKey) {
|
|
|
79
92
|
* @param {string} dataplaneUrl - Dataplane base URL
|
|
80
93
|
* @param {Object} authConfig - Auth config
|
|
81
94
|
* @param {Object} payload - { version, application, dataSources, status: "draft" }
|
|
82
|
-
* @returns {Promise<Object>}
|
|
95
|
+
* @returns {Promise<Object>} Raw API response envelope
|
|
83
96
|
*/
|
|
84
97
|
async function runUploadValidatePublish(dataplaneUrl, authConfig, payload) {
|
|
85
98
|
const res = await uploadApplicationViaPipeline(dataplaneUrl, authConfig, payload);
|
|
@@ -91,9 +104,8 @@ async function runUploadValidatePublish(dataplaneUrl, authConfig, payload) {
|
|
|
91
104
|
}
|
|
92
105
|
|
|
93
106
|
/**
|
|
94
|
-
* Builds a short summary of validation errors for the thrown message.
|
|
95
107
|
* @param {Object} validationResult - Result from validateExternalSystemComplete
|
|
96
|
-
* @returns {string}
|
|
108
|
+
* @returns {string}
|
|
97
109
|
*/
|
|
98
110
|
function formatValidationErrorSummary(validationResult) {
|
|
99
111
|
const errors = validationResult.errors || [];
|
|
@@ -108,7 +120,6 @@ function formatValidationErrorSummary(validationResult) {
|
|
|
108
120
|
}
|
|
109
121
|
|
|
110
122
|
/**
|
|
111
|
-
* Throws if validation result is invalid (displays results first).
|
|
112
123
|
* @param {Object} validationResult - Result from validateExternalSystemComplete
|
|
113
124
|
* @throws {Error} If validationResult.valid is false
|
|
114
125
|
*/
|
|
@@ -162,52 +173,151 @@ async function pushAndLogCredentialSecrets(dataplaneUrl, authConfig, systemKey,
|
|
|
162
173
|
}
|
|
163
174
|
|
|
164
175
|
/**
|
|
165
|
-
*
|
|
166
|
-
* @param {string}
|
|
167
|
-
* @param {Object}
|
|
168
|
-
* @param {
|
|
169
|
-
* @returns {Promise<void>}
|
|
170
|
-
* @throws {Error} If validation or API calls fail
|
|
176
|
+
* Optional server-side pipeline validate when --verbose.
|
|
177
|
+
* @param {string} dataplaneUrl
|
|
178
|
+
* @param {Object} authConfig
|
|
179
|
+
* @param {Object} payload
|
|
171
180
|
*/
|
|
172
|
-
async function
|
|
173
|
-
|
|
174
|
-
|
|
181
|
+
async function maybeRunVerboseServerValidation(dataplaneUrl, authConfig, payload) {
|
|
182
|
+
const vr = await validatePipelineConfig(dataplaneUrl, authConfig, {
|
|
183
|
+
config: {
|
|
184
|
+
version: payload.version,
|
|
185
|
+
application: payload.application,
|
|
186
|
+
dataSources: payload.dataSources
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
if (vr?.success === false) {
|
|
190
|
+
throw new Error(formatApiError(vr, dataplaneUrl));
|
|
191
|
+
}
|
|
192
|
+
const body = unwrapApiData(vr);
|
|
193
|
+
logServerValidationWarnings(body);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Omit payloadTemplate so POST /validation/run uses the **validation-engine** path
|
|
198
|
+
* (same as deploy --probe). Needed for certification and dataplane auto-issue of integration
|
|
199
|
+
* certificates after a successful run. If RBAC/live checks fail right after upload until the
|
|
200
|
+
* controller syncs permissions, skip --probe or retry once permissions are visible.
|
|
201
|
+
*/
|
|
202
|
+
const UPLOAD_PROBE_TEST_DATA = {};
|
|
175
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Optional POST validation/run after successful upload.
|
|
206
|
+
* @param {string} dataplaneUrl
|
|
207
|
+
* @param {string} systemKey
|
|
208
|
+
* @param {Object} authConfig
|
|
209
|
+
* @param {number|undefined} probeTimeoutMs
|
|
210
|
+
*/
|
|
211
|
+
async function maybeRunUploadProbe(dataplaneUrl, systemKey, authConfig, probeTimeoutMs) {
|
|
212
|
+
logger.log(chalk.blue('\nRunning runtime checks (--probe)...'));
|
|
213
|
+
const timeoutMs = probeTimeoutMs === undefined || probeTimeoutMs === null ? 120000 : probeTimeoutMs;
|
|
214
|
+
try {
|
|
215
|
+
const pr = await testSystemViaPipeline(
|
|
216
|
+
dataplaneUrl,
|
|
217
|
+
systemKey,
|
|
218
|
+
authConfig,
|
|
219
|
+
UPLOAD_PROBE_TEST_DATA,
|
|
220
|
+
{ timeout: timeoutMs }
|
|
221
|
+
);
|
|
222
|
+
if (pr.success === false) {
|
|
223
|
+
logger.log(chalk.yellow(`⚠ Probe request failed: ${pr.formattedError || pr.error || 'unknown error'}`));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const probeData = unwrapApiData(pr);
|
|
227
|
+
logProbeRuntimeBlock(probeData, systemKey);
|
|
228
|
+
} catch (e) {
|
|
229
|
+
logger.log(chalk.yellow(`⚠ Probe failed: ${e.message}`));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Local validation, manifest, payload, and configuration resolution.
|
|
235
|
+
* @param {string} systemKey
|
|
236
|
+
* @returns {Promise<{ manifest: Object, payload: Object }>}
|
|
237
|
+
*/
|
|
238
|
+
async function buildValidatedUploadManifestPayload(systemKey) {
|
|
176
239
|
const validationResult = await validateExternalSystemComplete(systemKey, { type: 'external' });
|
|
177
240
|
throwIfValidationFailed(validationResult);
|
|
178
|
-
logger.log(
|
|
179
|
-
|
|
241
|
+
logger.log(formatSuccessLine('Local validation passed'));
|
|
180
242
|
const manifest = await generateControllerManifest(systemKey, { type: 'external' });
|
|
181
243
|
const payload = buildUploadPayload(manifest);
|
|
182
244
|
await resolvePayloadConfiguration(systemKey, payload);
|
|
245
|
+
return { manifest, payload };
|
|
246
|
+
}
|
|
183
247
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
248
|
+
/**
|
|
249
|
+
* Upload path after dry-run check.
|
|
250
|
+
* @param {string} systemKey
|
|
251
|
+
* @param {Object} options
|
|
252
|
+
* @param {Object} manifest
|
|
253
|
+
* @param {Object} payload
|
|
254
|
+
*/
|
|
255
|
+
async function runUploadPublishAndSummary(systemKey, options, manifest, payload) {
|
|
190
256
|
const { dataplaneUrl, authConfig, environment } = await resolveDataplaneAndAuth(systemKey);
|
|
191
257
|
requireBearerForDataplanePipeline(authConfig);
|
|
192
|
-
logger.log(chalk.
|
|
258
|
+
logger.log(chalk.gray('Target:'));
|
|
259
|
+
logger.log(chalk.gray(`Environment: ${environment}`));
|
|
260
|
+
logger.log(chalk.gray(`Dataplane: ${dataplaneUrl}`));
|
|
193
261
|
logDataplanePipelineWarning();
|
|
194
|
-
|
|
262
|
+
if (options.verbose) {
|
|
263
|
+
await maybeRunVerboseServerValidation(dataplaneUrl, authConfig, payload);
|
|
264
|
+
}
|
|
195
265
|
await pushAndLogCredentialSecrets(dataplaneUrl, authConfig, systemKey, payload);
|
|
196
|
-
await runUploadValidatePublish(dataplaneUrl, authConfig, payload);
|
|
197
|
-
|
|
266
|
+
const rawRes = await runUploadValidatePublish(dataplaneUrl, authConfig, payload);
|
|
267
|
+
const publication = unwrapPublicationResult(rawRes);
|
|
268
|
+
if (!publication) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
'Unexpected response from dataplane upload: missing publication result (uploadId/system/datasources).'
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
logUploadReadinessSummary({
|
|
274
|
+
environment,
|
|
275
|
+
dataplaneUrl,
|
|
276
|
+
systemKey,
|
|
277
|
+
publication,
|
|
278
|
+
manifest,
|
|
279
|
+
minimal: !!options.minimal,
|
|
280
|
+
willProbe: !!options.probe
|
|
281
|
+
});
|
|
282
|
+
if (options.probe) {
|
|
283
|
+
await maybeRunUploadProbe(dataplaneUrl, systemKey, authConfig, options.probeTimeout);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const dsKeys = (payload.dataSources || []).map((ds) => ds && ds.key).filter(Boolean);
|
|
287
|
+
await maybeSyncSystemCertificationFromDataplane({
|
|
288
|
+
label: 'upload',
|
|
289
|
+
noCertSync: cliOptsSkipCertSync(options),
|
|
290
|
+
systemKey,
|
|
291
|
+
dataplaneUrl,
|
|
292
|
+
authConfig,
|
|
293
|
+
datasourceKeys: dsKeys
|
|
294
|
+
});
|
|
198
295
|
}
|
|
199
296
|
|
|
200
297
|
/**
|
|
201
|
-
*
|
|
202
|
-
* @param {string}
|
|
203
|
-
* @param {
|
|
204
|
-
* @param {
|
|
298
|
+
* Uploads external system: publishes to dataplane and registers with controller (draft).
|
|
299
|
+
* @param {string} systemKey - External system key (integration/<systemKey>/)
|
|
300
|
+
* @param {Object} [options] - Options
|
|
301
|
+
* @param {boolean} [options.dryRun] - Validate and build payload only; no API calls
|
|
302
|
+
* @param {boolean} [options.verbose] - POST pipeline/validate for server warnings
|
|
303
|
+
* @param {boolean} [options.probe] - POST validation/run after publish
|
|
304
|
+
* @param {number} [options.probeTimeout] - Probe timeout ms (default 120000)
|
|
305
|
+
* @param {boolean} [options.minimal] - Short summary only
|
|
306
|
+
* @returns {Promise<void>}
|
|
307
|
+
* @throws {Error} If validation or API calls fail
|
|
205
308
|
*/
|
|
206
|
-
function
|
|
207
|
-
|
|
208
|
-
logger.log(chalk.blue(
|
|
209
|
-
|
|
210
|
-
|
|
309
|
+
async function uploadExternalSystem(systemKey, options = {}) {
|
|
310
|
+
validateSystemKeyFormat(systemKey);
|
|
311
|
+
logger.log(chalk.blue(`\nUploading external system: ${chalk.bold(systemKey)}`));
|
|
312
|
+
const { manifest, payload } = await buildValidatedUploadManifestPayload(systemKey);
|
|
313
|
+
if (options.dryRun) {
|
|
314
|
+
logger.log(chalk.yellow('Dry run: would upload payload (no API calls).'));
|
|
315
|
+
logger.log(
|
|
316
|
+
chalk.gray(` System: ${manifest.key}, version: ${payload.version}, datasources: ${payload.dataSources.length}`)
|
|
317
|
+
);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
await runUploadPublishAndSummary(systemKey, options, manifest, payload);
|
|
211
321
|
}
|
|
212
322
|
|
|
213
323
|
module.exports = {
|
|
@@ -308,7 +308,7 @@ function throwConfigGenerationError(generateResponse, options = {}) {
|
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
/**
|
|
311
|
-
* Write debug log to integration/<
|
|
311
|
+
* Write debug log to integration/<systemKey>/debug.log
|
|
312
312
|
* @async
|
|
313
313
|
* @param {string} appName - Application name
|
|
314
314
|
* @param {string} content - Debug log content
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const chalk = require('chalk');
|
|
8
8
|
const logger = require('../utils/logger');
|
|
9
|
+
const { infoLine, formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
9
10
|
const { getDataplaneUrl } = require('../datasource/deploy');
|
|
10
11
|
const { listEnvironmentApplications } = require('../api/environments.api');
|
|
11
12
|
|
|
@@ -75,7 +76,7 @@ function createDataplaneNotFoundError() {
|
|
|
75
76
|
async function tryFallbackDataplaneUrl(controllerUrl, environment, authConfig) {
|
|
76
77
|
try {
|
|
77
78
|
const fallbackUrl = await getDataplaneUrl(controllerUrl, 'dataplane', environment, authConfig);
|
|
78
|
-
logger.log(
|
|
79
|
+
logger.log(formatSuccessLine(`Dataplane URL: ${fallbackUrl}`));
|
|
79
80
|
return fallbackUrl;
|
|
80
81
|
} catch (fallbackError) {
|
|
81
82
|
if (isNotFoundError(fallbackError)) {
|
|
@@ -96,12 +97,12 @@ async function tryFallbackDataplaneUrl(controllerUrl, environment, authConfig) {
|
|
|
96
97
|
* @throws {Error} If dataplane URL cannot be discovered
|
|
97
98
|
*/
|
|
98
99
|
async function discoverDataplaneUrl(controllerUrl, environment, authConfig) {
|
|
99
|
-
logger.log(
|
|
100
|
+
logger.log(infoLine('🌐 Getting dataplane URL from controller...'));
|
|
100
101
|
try {
|
|
101
102
|
const dataplaneAppKey = await findDataplaneServiceAppKey(controllerUrl, environment, authConfig);
|
|
102
103
|
if (dataplaneAppKey) {
|
|
103
104
|
const dataplaneUrl = await getDataplaneUrl(controllerUrl, dataplaneAppKey, environment, authConfig);
|
|
104
|
-
logger.log(
|
|
105
|
+
logger.log(formatSuccessLine(`Dataplane URL: ${dataplaneUrl}`));
|
|
105
106
|
return dataplaneUrl;
|
|
106
107
|
}
|
|
107
108
|
return await tryFallbackDataplaneUrl(controllerUrl, environment, authConfig);
|
|
@@ -117,9 +117,9 @@ function showWizardConfigSummary(config, displayPath) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
|
-
* Ensure integration/<
|
|
121
|
-
* @param {string} appKey -
|
|
122
|
-
* @returns {Promise<string>} Resolved config path (integration/<
|
|
120
|
+
* Ensure integration/<systemKey> directory exists
|
|
121
|
+
* @param {string} appKey - Integration folder name (system key)
|
|
122
|
+
* @returns {Promise<string>} Resolved config path (integration/<systemKey>/wizard.yaml)
|
|
123
123
|
*/
|
|
124
124
|
async function ensureIntegrationDir(appKey) {
|
|
125
125
|
const dir = path.join(process.cwd(), 'integration', appKey);
|
package/lib/commands/wizard.js
CHANGED
|
@@ -344,7 +344,7 @@ async function executeWizardFlow(appKey, dataplaneUrl, authConfig, flowOpts = {}
|
|
|
344
344
|
|
|
345
345
|
/**
|
|
346
346
|
* Load wizard config from configPath if it exists (for prefill)
|
|
347
|
-
* @param {string} [configPath] - Path to wizard.yaml (e.g. integration/<
|
|
347
|
+
* @param {string} [configPath] - Path to wizard.yaml (e.g. integration/<systemKey>/wizard.yaml)
|
|
348
348
|
* @param {string} [appName] - App name (for log message)
|
|
349
349
|
* @returns {Promise<Object|null>} Loaded config or null
|
|
350
350
|
*/
|
|
@@ -441,7 +441,7 @@ async function handleWizardError(appKey, configPath, mode, systemIdOrKey, error)
|
|
|
441
441
|
* @param {Object} options - Command options
|
|
442
442
|
* @param {string} [options.app] - Application name (from positional or -a)
|
|
443
443
|
* @param {string} [options.config] - Path to wizard.yaml (headless mode)
|
|
444
|
-
* @param {string} [options.configPath] - Resolved path integration/<
|
|
444
|
+
* @param {string} [options.configPath] - Resolved path integration/<systemKey>/wizard.yaml for load/save
|
|
445
445
|
* @returns {Promise<void>} Resolves when wizard completes
|
|
446
446
|
* @throws {Error} If wizard fails (wizardResumeMessage set when appKey known)
|
|
447
447
|
*/
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
const path = require('path');
|
|
14
|
-
const
|
|
14
|
+
const fsRealSync = require('../internal/fs-real-sync');
|
|
15
15
|
const config = require('./config');
|
|
16
16
|
const { decryptSecret, isEncrypted } = require('../utils/secrets-encryption');
|
|
17
17
|
const { ensureSecureFilePermissions } = require('../utils/secure-file-permissions');
|
|
@@ -48,18 +48,27 @@ function parseAdminEnvContent(content) {
|
|
|
48
48
|
* Use the returned object only in memory (e.g. to build a temporary .env for docker compose).
|
|
49
49
|
*
|
|
50
50
|
* @async
|
|
51
|
-
* @param {string} [adminSecretsPath] - Path to admin-secrets.env; default: ~/.aifabrix
|
|
51
|
+
* @param {string} [adminSecretsPath] - Path to admin-secrets.env; default: beside config.yaml (typically ~/.aifabrix), with legacy fallback under aifabrix-home when only that file exists
|
|
52
52
|
* @returns {Promise<Object.<string, string>>} Plain object e.g. { POSTGRES_PASSWORD, PGADMIN_DEFAULT_EMAIL, ... }
|
|
53
53
|
* @throws {Error} If file missing, or encrypted value and decryption fails / no key configured
|
|
54
54
|
*/
|
|
55
55
|
async function readAndDecryptAdminSecrets(adminSecretsPath) {
|
|
56
56
|
const pathsUtil = require('../utils/paths');
|
|
57
|
-
|
|
58
|
-
if (!
|
|
57
|
+
let resolvedPath = adminSecretsPath;
|
|
58
|
+
if (!resolvedPath) {
|
|
59
|
+
const systemPath = path.join(pathsUtil.getAifabrixSystemDir(), 'admin-secrets.env');
|
|
60
|
+
const legacyPath = path.join(pathsUtil.getAifabrixHome(), 'admin-secrets.env');
|
|
61
|
+
resolvedPath = fsRealSync.existsSync(systemPath)
|
|
62
|
+
? systemPath
|
|
63
|
+
: fsRealSync.existsSync(legacyPath)
|
|
64
|
+
? legacyPath
|
|
65
|
+
: systemPath;
|
|
66
|
+
}
|
|
67
|
+
if (!fsRealSync.existsSync(resolvedPath)) {
|
|
59
68
|
throw new Error(`Admin secrets file not found: ${resolvedPath}. Run 'aifabrix up-infra' or ensure admin-secrets.env exists.`);
|
|
60
69
|
}
|
|
61
70
|
ensureSecureFilePermissions(resolvedPath);
|
|
62
|
-
const content =
|
|
71
|
+
const content = fsRealSync.readFileSync(resolvedPath, 'utf8');
|
|
63
72
|
const raw = parseAdminEnvContent(content);
|
|
64
73
|
const encryptionKey = await config.getSecretsEncryptionKey();
|
|
65
74
|
const out = {};
|