@aifabrix/builder 2.44.4 → 2.44.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/cli-layout.mdc +1 -1
- package/.cursor/rules/project-rules.mdc +1 -1
- package/.npmrc.token +1 -1
- package/README.md +15 -23
- package/integration/hubspot-test/README.md +2 -0
- package/integration/hubspot-test/test.js +5 -3
- package/jest.projects.js +68 -17
- package/lib/api/controller-health.api.js +49 -0
- package/lib/api/dimension-values.api.js +82 -0
- package/lib/api/dimensions.api.js +114 -0
- package/lib/api/external-systems.api.js +1 -0
- package/lib/api/integration-clients.api.js +168 -0
- package/lib/api/types/dimension-values.types.js +28 -0
- package/lib/api/types/dimensions.types.js +31 -0
- package/lib/api/types/integration-clients.types.js +45 -0
- package/lib/api/types/wizard.types.js +2 -1
- package/lib/api/validation-runner.js +46 -25
- package/lib/app/deploy-config.js +11 -1
- package/lib/app/deploy-status-display.js +3 -3
- package/lib/app/deploy.js +36 -14
- package/lib/app/display.js +15 -11
- package/lib/app/push.js +46 -23
- package/lib/app/register.js +1 -1
- package/lib/app/restart-display.js +95 -0
- package/lib/app/rotate-secret.js +1 -1
- package/lib/app/run-container-start.js +12 -6
- package/lib/app/run-env-compose.js +30 -1
- package/lib/app/run-helpers.js +44 -12
- package/lib/app/run-reload-sync.js +148 -0
- package/lib/app/run-resolve-image.js +51 -1
- package/lib/app/run.js +99 -73
- package/lib/build/index.js +75 -45
- package/lib/cli/doctor-check.js +117 -0
- package/lib/cli/index.js +8 -2
- package/lib/cli/infra-guided.js +445 -0
- package/lib/cli/setup-app.help.js +1 -1
- package/lib/cli/setup-app.js +20 -2
- package/lib/cli/setup-app.test-commands.js +9 -5
- package/lib/cli/setup-auth.js +26 -0
- package/lib/cli/setup-dev-path-commands.js +50 -3
- package/lib/cli/setup-infra.js +138 -61
- package/lib/cli/setup-integration-client.js +182 -0
- package/lib/cli/setup-parameters.js +21 -2
- package/lib/cli/setup-platform.js +102 -0
- package/lib/cli/setup-secrets.js +18 -6
- package/lib/cli/setup-utility.js +97 -33
- package/lib/commands/datasource-capability-dimension-cli.js +128 -0
- package/lib/commands/datasource-capability-output.js +29 -0
- package/lib/commands/datasource-capability-relate-cli.js +140 -0
- package/lib/commands/datasource-capability.js +411 -0
- package/lib/commands/datasource-unified-test-cli.options.js +1 -1
- package/lib/commands/datasource.js +53 -13
- package/lib/commands/dev-down.js +3 -3
- package/lib/commands/dev-infra-gate.js +32 -0
- package/lib/commands/dev-init.js +13 -7
- package/lib/commands/dimension-value.js +179 -0
- package/lib/commands/dimension.js +330 -0
- package/lib/commands/integration-client.js +430 -0
- package/lib/commands/login-device.js +65 -30
- package/lib/commands/login.js +21 -10
- package/lib/commands/parameters-validate.js +78 -13
- package/lib/commands/repair-datasource-auto-rbac.js +166 -0
- package/lib/commands/repair-datasource-keys.js +10 -5
- package/lib/commands/repair-datasource.js +19 -7
- package/lib/commands/repair-env-template.js +4 -1
- package/lib/commands/repair-openapi-sync.js +172 -0
- package/lib/commands/repair-persist.js +102 -0
- package/lib/commands/repair-rbac-extract.js +27 -0
- package/lib/commands/repair-rbac-migrate.js +186 -0
- package/lib/commands/repair-rbac.js +225 -19
- package/lib/commands/repair-system-alignment.js +246 -0
- package/lib/commands/repair-system-permissions.js +168 -0
- package/lib/commands/repair.js +120 -354
- package/lib/commands/secure.js +1 -1
- package/lib/commands/setup-modes.js +455 -0
- package/lib/commands/setup-prompts.js +388 -0
- package/lib/commands/setup.js +149 -0
- package/lib/commands/teardown.js +228 -0
- package/lib/commands/test-e2e-external.js +4 -3
- package/lib/commands/up-common.js +97 -12
- package/lib/commands/up-dataplane.js +33 -11
- package/lib/commands/up-miso.js +7 -11
- package/lib/commands/upload.js +109 -23
- package/lib/commands/wizard-core-helpers.js +14 -11
- package/lib/commands/wizard-core.js +58 -15
- package/lib/commands/wizard-dataplane.js +2 -2
- package/lib/commands/wizard-entity-selection.js +72 -14
- package/lib/commands/wizard-headless.js +7 -3
- package/lib/commands/wizard-helpers.js +13 -1
- package/lib/commands/wizard.js +210 -61
- package/lib/constants/infra-compose-service-names.js +40 -0
- package/lib/core/env-reader.js +16 -3
- package/lib/core/secrets-admin-env.js +101 -0
- package/lib/core/secrets-ensure-infra.js +34 -1
- package/lib/core/secrets-ensure.js +88 -66
- package/lib/core/secrets-env-content.js +432 -0
- package/lib/core/secrets-env-write.js +27 -1
- package/lib/core/secrets-load.js +248 -0
- package/lib/core/secrets-names.js +32 -0
- package/lib/core/secrets.js +17 -757
- package/lib/datasource/capability/basic-exposure.js +76 -0
- package/lib/datasource/capability/capability-diff-slice.js +41 -0
- package/lib/datasource/capability/capability-key.js +34 -0
- package/lib/datasource/capability/capability-resolve.js +172 -0
- package/lib/datasource/capability/capability-storage-keys.js +22 -0
- package/lib/datasource/capability/copy-operations.js +348 -0
- package/lib/datasource/capability/copy-test-payload.js +139 -0
- package/lib/datasource/capability/create-operations.js +235 -0
- package/lib/datasource/capability/dimension-operations.js +151 -0
- package/lib/datasource/capability/dimension-validate.js +219 -0
- package/lib/datasource/capability/json-pointer.js +31 -0
- package/lib/datasource/capability/reference-rewrite.js +51 -0
- package/lib/datasource/capability/relate-operations.js +325 -0
- package/lib/datasource/capability/relate-validate.js +219 -0
- package/lib/datasource/capability/remove-operations.js +275 -0
- package/lib/datasource/capability/run-capability-copy.js +152 -0
- package/lib/datasource/capability/run-capability-diff.js +135 -0
- package/lib/datasource/capability/run-capability-dimension.js +291 -0
- package/lib/datasource/capability/run-capability-edit.js +377 -0
- package/lib/datasource/capability/run-capability-relate.js +193 -0
- package/lib/datasource/capability/run-capability-remove.js +105 -0
- package/lib/datasource/capability/templates/minimal-fetch.json +18 -0
- package/lib/datasource/capability/validate-capability-slice.js +35 -0
- package/lib/datasource/list.js +136 -23
- package/lib/datasource/log-viewer.js +2 -4
- package/lib/datasource/unified-validation-run.js +51 -16
- package/lib/datasource/validate.js +53 -1
- package/lib/deployment/deploy-poll-ui.js +60 -0
- package/lib/deployment/deployer-status.js +29 -3
- package/lib/deployment/deployer.js +48 -30
- package/lib/deployment/environment.js +7 -2
- package/lib/deployment/poll-interval.js +72 -0
- package/lib/deployment/push.js +11 -9
- package/lib/external-system/deploy.js +4 -1
- package/lib/external-system/download.js +61 -32
- package/lib/external-system/sync-deploy-manifest.js +33 -0
- package/lib/generator/wizard-prompts.js +7 -1
- package/lib/generator/wizard.js +34 -0
- package/lib/infrastructure/index.js +49 -19
- package/lib/infrastructure/orphan-infra-docker-teardown.js +177 -0
- package/lib/parameters/infra-kv-discovery.js +29 -4
- package/lib/parameters/infra-parameter-catalog.js +6 -3
- package/lib/parameters/infra-parameter-validate.js +67 -19
- package/lib/resolvers/datasource-resolver.js +53 -0
- package/lib/resolvers/dimension-file.js +52 -0
- package/lib/resolvers/manifest-resolver.js +133 -0
- package/lib/schema/external-datasource.schema.json +183 -53
- package/lib/schema/external-system.schema.json +23 -10
- package/lib/schema/infra.parameter.yaml +26 -11
- package/lib/schema/wizard-config.schema.json +2 -2
- package/lib/utils/aifabrix-config-dir-walk.js +40 -0
- package/lib/utils/aifabrix-runtime-config-dir.js +26 -3
- package/lib/utils/app-run-containers.js +2 -2
- package/lib/utils/bash-secret-env.js +59 -0
- package/lib/utils/cli-secrets-error-format.js +78 -0
- package/lib/utils/cli-test-layout-chalk.js +31 -9
- package/lib/utils/cli-utils.js +4 -36
- package/lib/utils/datasource-test-run-display.js +8 -0
- package/lib/utils/dev-hosts-helper.js +3 -2
- package/lib/utils/dev-init-ssh-merge.js +2 -1
- package/lib/utils/docker-build.js +17 -9
- package/lib/utils/docker-reload-mount.js +127 -0
- package/lib/utils/external-readme.js +117 -4
- package/lib/utils/external-system-local-test-tty.js +3 -2
- package/lib/utils/external-system-readiness-core.js +45 -12
- package/lib/utils/external-system-readiness-deploy-display.js +3 -3
- package/lib/utils/external-system-readiness-display-internals.js +33 -3
- package/lib/utils/external-system-readiness-display.js +10 -1
- package/lib/utils/file-upload.js +40 -3
- package/lib/utils/health-check-db-init.js +107 -0
- package/lib/utils/health-check-public-warn.js +69 -0
- package/lib/utils/health-check-url.js +19 -4
- package/lib/utils/health-check.js +135 -105
- package/lib/utils/help-builder.js +5 -1
- package/lib/utils/image-name.js +34 -7
- package/lib/utils/integration-file-backup.js +74 -0
- package/lib/utils/mutagen-install.js +30 -3
- package/lib/utils/paths.js +108 -25
- package/lib/utils/postgres-wipe.js +212 -0
- package/lib/utils/register-aifabrix-shell-env.js +15 -0
- package/lib/utils/remote-dev-auth.js +21 -5
- package/lib/utils/remote-docker-env.js +9 -1
- package/lib/utils/remote-secrets-loader.js +42 -3
- package/lib/utils/resolve-docker-image-ref.js +9 -3
- package/lib/utils/secrets-ancestor-paths.js +47 -0
- package/lib/utils/secrets-helpers.js +17 -10
- package/lib/utils/secrets-kv-refs.js +42 -0
- package/lib/utils/secrets-kv-scope.js +19 -2
- package/lib/utils/secrets-materialize-local.js +134 -0
- package/lib/utils/secrets-path.js +24 -10
- package/lib/utils/secrets-utils.js +2 -2
- package/lib/utils/system-builder-root.js +34 -0
- package/lib/utils/url-declarative-resolve-build.js +6 -1
- package/lib/utils/url-declarative-runtime-base-path.js +32 -0
- package/lib/utils/url-declarative-vdir-inactive-env.js +2 -1
- package/lib/utils/urls-local-registry.js +73 -20
- package/lib/utils/validation-poll-ui.js +81 -0
- package/lib/utils/validation-run-poll.js +29 -5
- package/lib/utils/with-muted-logger.js +53 -0
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +1 -1
- package/templates/applications/dataplane/rbac.yaml +10 -10
- package/templates/applications/keycloak/env.template +8 -6
- package/templates/applications/miso-controller/application.yaml +7 -0
- package/templates/applications/miso-controller/env.template +7 -7
- package/templates/applications/miso-controller/rbac.yaml +9 -9
- package/templates/external-system/README.md.hbs +89 -102
- package/.nyc_output/55e9d034-ddab-4579-a706-e02a91d75c91.json +0 -1
- package/.nyc_output/processinfo/55e9d034-ddab-4579-a706-e02a91d75c91.json +0 -1
- package/.nyc_output/processinfo/index.json +0 -1
- package/lib/api/service-users.api.js +0 -150
- package/lib/api/types/service-users.types.js +0 -65
- package/lib/cli/setup-service-user.js +0 -187
- package/lib/commands/service-user.js +0 -429
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TTY ora spinner + throttled non-TTY lines for unified validation run polling (aligned with deploy-poll-ui).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Validation run poll presentation helpers
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
const logger = require('./logger');
|
|
13
|
+
|
|
14
|
+
function shouldUseValidationPollSpinner() {
|
|
15
|
+
return Boolean(process && process.stdout && process.stdout.isTTY);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Single-line ora text / log line for validation polling.
|
|
20
|
+
*
|
|
21
|
+
* @param {Object|null|undefined} envelope - Latest GET envelope (optional before first poll tick)
|
|
22
|
+
* @param {number} attemptIndex - Zero-based poll index after initial POST
|
|
23
|
+
* @param {number} deadlineMs - Wall-clock deadline (Date.now() + remaining budget)
|
|
24
|
+
* @returns {string}
|
|
25
|
+
*/
|
|
26
|
+
function buildValidationPollSpinnerText(envelope, attemptIndex, deadlineMs) {
|
|
27
|
+
const remainingSec = Math.max(0, Math.ceil((deadlineMs - Date.now()) / 1000));
|
|
28
|
+
if (!envelope || typeof envelope !== 'object') {
|
|
29
|
+
return `Waiting for validation run… starting (budget ~${remainingSec}s)`;
|
|
30
|
+
}
|
|
31
|
+
const c =
|
|
32
|
+
envelope.reportCompleteness !== undefined && envelope.reportCompleteness !== null
|
|
33
|
+
? String(envelope.reportCompleteness)
|
|
34
|
+
: '?';
|
|
35
|
+
const st =
|
|
36
|
+
envelope.status !== undefined && envelope.status !== null ? String(envelope.status) : '?';
|
|
37
|
+
return `Waiting for validation run… completeness=${c} status=${st} (poll ${attemptIndex + 1} · ~${remainingSec}s left)`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const NON_TTY_THROTTLE_MS = 5000;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {number} deadlineMs - Absolute deadline for poll budget display
|
|
44
|
+
* @returns {{ usesSpinner: boolean, onPollProgress: Function, finish: () => void }}
|
|
45
|
+
*/
|
|
46
|
+
function createValidationPollHandlers(deadlineMs) {
|
|
47
|
+
if (shouldUseValidationPollSpinner()) {
|
|
48
|
+
const ora = require('ora');
|
|
49
|
+
const spinner = ora({
|
|
50
|
+
text: buildValidationPollSpinnerText(null, 0, deadlineMs),
|
|
51
|
+
spinner: 'dots'
|
|
52
|
+
}).start();
|
|
53
|
+
return {
|
|
54
|
+
usesSpinner: true,
|
|
55
|
+
onPollProgress: (envelope, attemptIndex, _meta) => {
|
|
56
|
+
spinner.text = buildValidationPollSpinnerText(envelope, attemptIndex, deadlineMs);
|
|
57
|
+
},
|
|
58
|
+
finish: () => {
|
|
59
|
+
spinner.stop();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let lastNonTtyLogAt = 0;
|
|
65
|
+
return {
|
|
66
|
+
usesSpinner: false,
|
|
67
|
+
onPollProgress: (envelope, attemptIndex, _meta) => {
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
if (now - lastNonTtyLogAt < NON_TTY_THROTTLE_MS) return;
|
|
70
|
+
lastNonTtyLogAt = now;
|
|
71
|
+
logger.log(chalk.gray(buildValidationPollSpinnerText(envelope, attemptIndex, deadlineMs)));
|
|
72
|
+
},
|
|
73
|
+
finish: () => {}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
createValidationPollHandlers,
|
|
79
|
+
shouldUseValidationPollSpinner,
|
|
80
|
+
buildValidationPollSpinnerText
|
|
81
|
+
};
|
|
@@ -34,8 +34,8 @@ function sleep(ms) {
|
|
|
34
34
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function maybeLogPollProgress(envelope, verbosePoll, lastProgressLogAtRef) {
|
|
38
|
-
if (!verbosePoll || !envelope || typeof envelope !== 'object') return;
|
|
37
|
+
function maybeLogPollProgress(envelope, verbosePoll, lastProgressLogAtRef, skipBecauseUi) {
|
|
38
|
+
if (skipBecauseUi || !verbosePoll || !envelope || typeof envelope !== 'object') return;
|
|
39
39
|
const now = Date.now();
|
|
40
40
|
if (now - lastProgressLogAtRef[0] < 5000) return;
|
|
41
41
|
lastProgressLogAtRef[0] = now;
|
|
@@ -57,6 +57,21 @@ function isTerminalReportCompleteness(envelope) {
|
|
|
57
57
|
return envelope.reportCompleteness === 'full';
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
function emitPollProgressLine(
|
|
61
|
+
envelope,
|
|
62
|
+
verbosePoll,
|
|
63
|
+
lastProgressLogAtRef,
|
|
64
|
+
onPollProgress,
|
|
65
|
+
attempt,
|
|
66
|
+
deadline
|
|
67
|
+
) {
|
|
68
|
+
const hasPollUi = typeof onPollProgress === 'function';
|
|
69
|
+
maybeLogPollProgress(envelope, verbosePoll, lastProgressLogAtRef, hasPollUi);
|
|
70
|
+
if (hasPollUi) {
|
|
71
|
+
onPollProgress(envelope, attempt, { deadlineMs: deadline });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
60
75
|
/**
|
|
61
76
|
* Poll until reportCompleteness === 'full' or budget exhausted.
|
|
62
77
|
* @async
|
|
@@ -66,7 +81,8 @@ function isTerminalReportCompleteness(envelope) {
|
|
|
66
81
|
* @param {string} opts.testRunId
|
|
67
82
|
* @param {number} opts.budgetMs - Remaining wall-clock budget for polls only (POST excluded)
|
|
68
83
|
* @param {typeof getValidationRunWithTransportRetry} [opts.fetchRun] - Inject for tests (default: GET with transport retry)
|
|
69
|
-
* @param {boolean} [opts.verbosePoll] - Log throttled progress (plan §3.13)
|
|
84
|
+
* @param {boolean} [opts.verbosePoll] - Log throttled progress (plan §3.13); skipped when `onPollProgress` is set
|
|
85
|
+
* @param {Function|null} [opts.onPollProgress] - `(envelope, attemptIndex, { deadlineMs })` each non-terminal poll
|
|
70
86
|
* @param {number} [opts.pollRequestTimeoutMs] - Per-GET HTTP timeout (match validation aggregate budget)
|
|
71
87
|
* @returns {Promise<{ envelope: Object|null, timedOut: boolean, lastApiResult: Object|null }>}
|
|
72
88
|
*/
|
|
@@ -78,7 +94,8 @@ async function pollValidationRunUntilComplete(opts) {
|
|
|
78
94
|
budgetMs,
|
|
79
95
|
fetchRun = getValidationRunWithTransportRetry,
|
|
80
96
|
verbosePoll = false,
|
|
81
|
-
pollRequestTimeoutMs
|
|
97
|
+
pollRequestTimeoutMs,
|
|
98
|
+
onPollProgress = null
|
|
82
99
|
} = opts;
|
|
83
100
|
const pollTransportOpts =
|
|
84
101
|
Number.isFinite(pollRequestTimeoutMs) && pollRequestTimeoutMs > 0
|
|
@@ -100,7 +117,14 @@ async function pollValidationRunUntilComplete(opts) {
|
|
|
100
117
|
return { envelope, timedOut: false, lastApiResult };
|
|
101
118
|
}
|
|
102
119
|
|
|
103
|
-
|
|
120
|
+
emitPollProgressLine(
|
|
121
|
+
envelope,
|
|
122
|
+
verbosePoll,
|
|
123
|
+
lastProgressLogAtRef,
|
|
124
|
+
onPollProgress,
|
|
125
|
+
attempt,
|
|
126
|
+
deadline
|
|
127
|
+
);
|
|
104
128
|
|
|
105
129
|
const delay = Math.min(nextPollDelayMs(attempt), Math.max(0, deadline - Date.now()));
|
|
106
130
|
attempt += 1;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Temporarily mute logger.log output for guided UX flows.
|
|
3
|
+
*
|
|
4
|
+
* Used by guided installer-style commands (e.g. up-platform default mode) to avoid
|
|
5
|
+
* streaming orchestration mechanics while preserving errors and warnings.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const logger = require('./logger');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Run a function while muting logger.log/info.
|
|
14
|
+
*
|
|
15
|
+
* - logger.error and logger.warn are preserved.
|
|
16
|
+
* - An optional allowlist can let specific messages through (rare).
|
|
17
|
+
*
|
|
18
|
+
* @template T
|
|
19
|
+
* @param {() => Promise<T>} fn
|
|
20
|
+
* @param {{ allow?: ((...args: any[]) => boolean) }} [opts]
|
|
21
|
+
* @returns {Promise<T>}
|
|
22
|
+
*/
|
|
23
|
+
async function withMutedLogger(fn, opts = {}) {
|
|
24
|
+
const original = {
|
|
25
|
+
log: logger.log,
|
|
26
|
+
info: logger.info
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const allow = typeof opts.allow === 'function' ? opts.allow : null;
|
|
30
|
+
|
|
31
|
+
const muted = (...args) => {
|
|
32
|
+
try {
|
|
33
|
+
if (allow && allow(...args)) {
|
|
34
|
+
return original.log(...args);
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
// ignore allow errors; treat as muted
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
logger.log = muted;
|
|
43
|
+
logger.info = muted;
|
|
44
|
+
try {
|
|
45
|
+
return await fn();
|
|
46
|
+
} finally {
|
|
47
|
+
logger.log = original.log;
|
|
48
|
+
logger.info = original.info;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = { withMutedLogger };
|
|
53
|
+
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ app:
|
|
|
8
8
|
version: 1.9.5
|
|
9
9
|
|
|
10
10
|
# Image Configuration
|
|
11
|
-
# Set tag to match your build (e.g. aifabrix build dataplane -t
|
|
11
|
+
# Set tag to match your build (e.g. aifabrix build dataplane -t 1.0.0 then tag: 1.0.0)
|
|
12
12
|
# Registry is required so the controller can pull the image (avoids "docker: not found" on the controller host).
|
|
13
13
|
image:
|
|
14
14
|
name: aifabrix/dataplane
|
|
@@ -232,19 +232,19 @@ permissions:
|
|
|
232
232
|
roles: ["aifabrix-platform-admin", "aifabrix-security-admin", "aifabrix-compliance-admin", "aifabrix-observer"]
|
|
233
233
|
description: "Read group information"
|
|
234
234
|
|
|
235
|
-
# OpenAPI
|
|
236
|
-
- name: "
|
|
235
|
+
# OpenAPI / MCP spec bundle (mounted specs under /api/v1/specs)
|
|
236
|
+
- name: "spec:read"
|
|
237
237
|
roles: ["aifabrix-platform-admin", "aifabrix-security-admin", "aifabrix-deployment-admin", "aifabrix-compliance-admin", "aifabrix-developer", "aifabrix-observer"]
|
|
238
|
-
description: "Read OpenAPI
|
|
239
|
-
|
|
240
|
-
- name: "
|
|
238
|
+
description: "Read OpenAPI/MCP spec bundles"
|
|
239
|
+
|
|
240
|
+
- name: "spec:update"
|
|
241
241
|
roles: ["aifabrix-platform-admin", "aifabrix-developer"]
|
|
242
|
-
description: "Update OpenAPI
|
|
243
|
-
|
|
244
|
-
- name: "
|
|
242
|
+
description: "Update OpenAPI/MCP spec bundles (uploaded or user-owned)"
|
|
243
|
+
|
|
244
|
+
- name: "spec:delete"
|
|
245
245
|
roles: ["aifabrix-platform-admin", "aifabrix-developer"]
|
|
246
|
-
description: "Delete OpenAPI
|
|
247
|
-
|
|
246
|
+
description: "Delete OpenAPI/MCP spec bundles (user-owned only; internal specs are not deletable via API)"
|
|
247
|
+
|
|
248
248
|
# External data source write operations
|
|
249
249
|
- name: "external-data-source:write"
|
|
250
250
|
roles: ["aifabrix-platform-admin", "aifabrix-developer"]
|
|
@@ -23,15 +23,17 @@ KC_HTTP_RELATIVE_PATH=url://vdir-public
|
|
|
23
23
|
# must use the PUBLIC URL as issuer in all tokens so they match what the
|
|
24
24
|
# controller expects (KEYCLOAK_SERVER_URL).
|
|
25
25
|
# - Users log in via http://localhost:${KEYCLOAK_PUBLIC_PORT} (browser/CLI)
|
|
26
|
-
# - Server calls Keycloak at
|
|
26
|
+
# - Server calls Keycloak at url://keycloak-internal for token exchange and refresh
|
|
27
27
|
# - Controller sends Host: localhost:${KEYCLOAK_PUBLIC_PORT} so Keycloak validates issuer
|
|
28
28
|
# against public URL (requires KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true)
|
|
29
29
|
# When KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true, hostname must be a full URL.
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
KC_HOSTNAME
|
|
30
|
+
# KC_HTTP_RELATIVE_PATH carries the runtime base path (url://vdir-public), and application.yaml
|
|
31
|
+
# frontDoorRouting exposes the same path for internal server-to-server URLs when enabled.
|
|
32
|
+
# Hostname v2: use a full public URL so Keycloak generates redirects that preserve the /auth base path.
|
|
33
|
+
# `url://public` expands to the full front-door URL (including /auth when Traefik + frontDoorRouting.enabled are on).
|
|
34
|
+
# NOTE: Prefer KC_HOSTNAME (not KC_HOSTNAME_URL). hostname-url triggers legacy hostname v1 warnings and, depending on
|
|
35
|
+
# runtime, may not be treated as an active hostname for hostname-backchannel-dynamic.
|
|
36
|
+
KC_HOSTNAME=url://public
|
|
35
37
|
# nginx / Traefik send X-Forwarded-*; required when using an edge proxy (Keycloak 26+).
|
|
36
38
|
KC_PROXY_HEADERS=xforwarded
|
|
37
39
|
# Required for Host header to work: Keycloak resolves backchannel URL from request headers
|
|
@@ -7,6 +7,8 @@ app:
|
|
|
7
7
|
version: '1.9.5'
|
|
8
8
|
|
|
9
9
|
# Image Configuration
|
|
10
|
+
# Set tag to match your build (e.g. aifabrix build miso-controller -t 1.0.0 then tag: 1.0.0)
|
|
11
|
+
# Registry is required so the controller can pull the image (avoids "docker: not found" on the controller host).
|
|
10
12
|
image:
|
|
11
13
|
name: aifabrix/miso-controller
|
|
12
14
|
tag: latest
|
|
@@ -57,6 +59,11 @@ build:
|
|
|
57
59
|
language: typescript # Runtime language for template selection (typescript or python)
|
|
58
60
|
reloadStart: pnpm run start:reload # When running with --reload
|
|
59
61
|
|
|
62
|
+
# Repository Configuration (pipeline validate: REPOSITORY_URL_MISMATCH)
|
|
63
|
+
repository:
|
|
64
|
+
enabled: true
|
|
65
|
+
repositoryUrl: https://github.com/aifabrix/aifabrix-miso
|
|
66
|
+
|
|
60
67
|
# =============================================================================
|
|
61
68
|
# Portal Input Configuration (Deployment Wizard)
|
|
62
69
|
# =============================================================================
|
|
@@ -28,8 +28,12 @@ SKIP_FIRST_TIME_SETUP=false
|
|
|
28
28
|
# Optional custom controller key for onboarding (default: miso-controller)
|
|
29
29
|
ONBOARDING_CONTROLLER_KEY=miso-controller
|
|
30
30
|
|
|
31
|
-
#
|
|
32
|
-
|
|
31
|
+
# Infrastructure/service name used by controller/onboarding flows
|
|
32
|
+
INFRASTRUCTURE_NAME=aifabrix
|
|
33
|
+
|
|
34
|
+
# Azure region (required for first-time onboarding: controller record / provisioning metadata).
|
|
35
|
+
# Use the region you deploy to (e.g. westeurope, eastus, northeurope). Single env name: LOCATION.
|
|
36
|
+
LOCATION=westeurope
|
|
33
37
|
|
|
34
38
|
# Required for admin user creation during onboarding
|
|
35
39
|
# Password for the initial administrator user (username: admin)
|
|
@@ -311,7 +315,7 @@ NPM_TOKEN=kv://BASH_NPM_TOKEN
|
|
|
311
315
|
# url://public includes front-door path from application.yaml (e.g. /controller).
|
|
312
316
|
MISO_WEB_SERVER_URL=url://public
|
|
313
317
|
MISO_CONTROLLER_URL=url://internal
|
|
314
|
-
|
|
318
|
+
MISO_RELATIVE_PATH=url://vdir-public
|
|
315
319
|
# MISO Environment Configuration (miso, dev, tst, pro)
|
|
316
320
|
MISO_ENVIRONMENT=miso
|
|
317
321
|
|
|
@@ -319,10 +323,6 @@ MISO_ENVIRONMENT=miso
|
|
|
319
323
|
MISO_CLIENTID=kv://miso-controller-client-idKeyVault
|
|
320
324
|
MISO_CLIENTSECRET=kv://miso-controller-client-secretKeyVault
|
|
321
325
|
|
|
322
|
-
# Allowed origins for CORS validation (comma-separated)
|
|
323
|
-
# Use wildcards for ports: http://localhost:*
|
|
324
|
-
MISO_ALLOWED_ORIGINS=http://localhost:*,url://host-public,url://host-private,url://dataplane-host-public,url://dataplane-host-private
|
|
325
|
-
|
|
326
326
|
# Evaluation mode (optional .env override of DB controller.configuration.evaluation):
|
|
327
327
|
# When true (default if DB omits flag), infra deploy may coerce :envKey to `miso` — e2e poll on `dev` can 404.
|
|
328
328
|
# Set false locally to force path envKey to match deploy + GET .../deployments/:id.
|
|
@@ -35,22 +35,22 @@ roles:
|
|
|
35
35
|
groups: ['AI-Fabrix-Observers']
|
|
36
36
|
|
|
37
37
|
permissions:
|
|
38
|
-
#
|
|
39
|
-
- name: '
|
|
38
|
+
# Integration clients (Keycloak OIDC clients + control-plane metadata)
|
|
39
|
+
- name: 'integration-client:create'
|
|
40
40
|
roles: ['aifabrix-platform-admin', 'aifabrix-security-admin']
|
|
41
|
-
description: 'Create
|
|
41
|
+
description: 'Create integration clients and Keycloak OIDC clients'
|
|
42
42
|
|
|
43
|
-
- name: '
|
|
43
|
+
- name: 'integration-client:read'
|
|
44
44
|
roles: ['aifabrix-platform-admin', 'aifabrix-security-admin', 'aifabrix-observer']
|
|
45
|
-
description: 'View
|
|
45
|
+
description: 'View integration clients and their configurations'
|
|
46
46
|
|
|
47
|
-
- name: '
|
|
47
|
+
- name: 'integration-client:update'
|
|
48
48
|
roles: ['aifabrix-platform-admin', 'aifabrix-security-admin']
|
|
49
|
-
description: 'Update
|
|
49
|
+
description: 'Update integration client configuration and regenerate secrets'
|
|
50
50
|
|
|
51
|
-
- name: '
|
|
51
|
+
- name: 'integration-client:delete'
|
|
52
52
|
roles: ['aifabrix-platform-admin', 'aifabrix-security-admin']
|
|
53
|
-
description: 'Deactivate
|
|
53
|
+
description: 'Deactivate integration clients'
|
|
54
54
|
|
|
55
55
|
# User Management
|
|
56
56
|
- name: 'users:create'
|
|
@@ -2,132 +2,119 @@
|
|
|
2
2
|
|
|
3
3
|
{{description}}
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## At a glance
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
| | |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| **System key** | `{{systemKey}}` |
|
|
10
|
+
| **Type** | `{{systemType}}` |
|
|
11
|
+
| **Datasources** | {{datasourceCount}} |
|
|
10
12
|
|
|
11
13
|
## Files
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
| File | Purpose |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `application{{fileExt}}` | App manifest and `externalIntegration` |
|
|
18
|
+
| `{{systemKey}}-system{{fileExt}}` | Auth, API definition, roles |
|
|
15
19
|
{{#each datasources}}
|
|
16
|
-
|
|
20
|
+
| `{{fileName}}` | Datasource: {{displayName}} (**capabilities** here) |
|
|
17
21
|
{{/each}}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
| `env.template` | Secrets and env placeholders |
|
|
23
|
+
| `{{systemKey}}-deploy.json` | Deploy manifest (`aifabrix json {{appName}}`) |
|
|
24
|
+
| `deploy.js` | Deploy helper |
|
|
25
|
+
| `wizard.yaml` | Wizard input |
|
|
26
|
+
| `{{rbacOptionalFile}}` | Roles and permissions |
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
## Typical workflow
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
1. **Login** — `aifabrix login` (controller URL set via `aifabrix auth config` if needed).
|
|
31
|
+
2. **Change config** — edit JSON/YAML under `integration/{{appName}}/`, or extend with `aifabrix wizard --app {{appName}}`.
|
|
32
|
+
3. **Adjust operations** — use `aifabrix datasource capability …` to copy, add, or remove **capabilities** (see below).
|
|
33
|
+
4. **Check locally** — `aifabrix validate {{appName}}` and `aifabrix datasource validate` on files you touched.
|
|
34
|
+
5. **Align manifest** — `aifabrix repair {{appName}}` after bigger edits.
|
|
35
|
+
6. **Publish** — `aifabrix upload {{appName}}` or `aifabrix deploy {{appName}}`.
|
|
26
36
|
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
aifabrix auth config --set-controller <url> --set-environment dev
|
|
30
|
-
aifabrix login
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### 1. Extend External System
|
|
37
|
+
Rollback an experiment: `datasource capability remove …` → validate → upload/deploy again.
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
aifabrix wizard --app {{appName}}
|
|
39
|
-
```
|
|
39
|
+
## Capabilities (per datasource)
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Each `*-datasource-*` file lists **capabilities**: named slices that tie together HTTP/API definitions and execution steps. Use the CLI to clone or drop them safely instead of editing huge JSON by hand.
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
**After any change:** run `aifabrix datasource validate <file-or-key>` (or `aifabrix validate {{appName}}` for the whole app).
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
45
|
+
| Command | What it does |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `datasource capability copy` | Clone one capability to a new name (`--from` / `--as`). Supports `--dry-run`, `--overwrite`, backups. If `exposed.profiles.<from>` exists, it’s copied to `exposed.profiles.<as>`. |
|
|
48
|
+
| `datasource capability create` (or `add`) | New capability from `--from`, `--template`, or `--openapi-operation`. |
|
|
49
|
+
| `datasource capability remove` | Remove one capability (`--capability`; optional `--profile`). Use `--dry-run` first. |
|
|
50
|
+
| `datasource capability validate` | Schema check for the file or one `--capability`. |
|
|
51
|
+
| `datasource capability diff` | Compare two files for one capability. |
|
|
52
|
+
| `datasource capability edit` | Edit one capability’s API definition, runtime steps, or exposure profile in your editor (TTY). |
|
|
53
|
+
| `datasource capability relate` | Link this datasource to another (foreign-key style metadata). See `--help` for flags. |
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
Short alias (recommended): `af ds cap <command> …`
|
|
56
|
+
Full command: `aifabrix datasource capability <command> …`
|
|
51
57
|
|
|
52
|
-
|
|
58
|
+
Examples (use the first datasource from the Files table):
|
|
53
59
|
|
|
54
60
|
```bash
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
{{/each}}
|
|
58
|
-
```
|
|
59
|
-
{{/if}}{{/if}}
|
|
60
|
-
|
|
61
|
-
### 3. Validate configuration (local only)
|
|
61
|
+
# Preview cloning "create" to "createBasic" (no write)
|
|
62
|
+
af ds cap copy {{#if hasDatasources}}{{datasources.[0].datasourceKey}}{{else}}<datasource-key>{{/if}} --from create --as createBasic --dry-run
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
# Apply the copy, then validate
|
|
65
|
+
af ds cap copy {{#if hasDatasources}}{{datasources.[0].datasourceKey}}{{else}}<datasource-key>{{/if}} --from create --as createBasic
|
|
66
|
+
af ds validate {{#if hasDatasources}}{{datasources.[0].datasourceKey}}{{else}}<datasource-key>{{/if}}
|
|
64
67
|
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
# Remove a capability you no longer need
|
|
69
|
+
af ds cap remove {{#if hasDatasources}}{{datasources.[0].datasourceKey}}{{else}}<datasource-key>{{/if}} --capability createBasic --dry-run
|
|
67
70
|
```
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
### 4. Repair Deployment Manifest
|
|
72
|
-
|
|
73
|
-
**Run repair regularly.** It keeps naming conventions, filenames, and the deployment manifest aligned with AI Fabrix platform best practices. Use it after editing datasources, env.template, or system config—and run it often to catch drift early.
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
aifabrix repair {{appName}}
|
|
77
|
-
```
|
|
72
|
+
For flags, run `af ds cap <command> --help`.
|
|
78
73
|
|
|
79
|
-
|
|
80
|
-
--auth <method> Set authentication method (oauth2, aad, apikey, basic, queryParam, oidc, hmac, none); updates system file and env.template
|
|
81
|
-
--dry-run Report changes only; do not write
|
|
82
|
-
--rbac Ensure RBAC permissions per datasource and add default Admin/Reader roles if none exist
|
|
83
|
-
--expose Set exposed.attributes on each datasource to all fieldMappings.attributes keys
|
|
84
|
-
--sync Add default sync section to datasources that lack it
|
|
85
|
-
--test Generate testPayload.payloadTemplate and testPayload.expectedResult from attributes
|
|
74
|
+
## Single datasource lifecycle (production-ready)
|
|
86
75
|
|
|
87
|
-
|
|
76
|
+
Start with one datasource and iterate until it’s stable.
|
|
88
77
|
|
|
89
78
|
```bash
|
|
90
|
-
|
|
79
|
+
af ds validate {{#if hasDatasources}}{{datasources.[0].datasourceKey}}{{else}}<datasource-key>{{/if}}
|
|
80
|
+
af ds test {{#if hasDatasources}}{{datasources.[0].datasourceKey}}{{else}}<datasource-key>{{/if}} --debug --sync
|
|
81
|
+
af ds test-integration {{#if hasDatasources}}{{datasources.[0].datasourceKey}}{{else}}<datasource-key>{{/if}} --sync
|
|
82
|
+
af ds test-e2e {{#if hasDatasources}}{{datasources.[0].datasourceKey}}{{else}}<datasource-key>{{/if}} --debug --sync
|
|
91
83
|
```
|
|
92
84
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
| Command | Where it runs | Calls dataplane? |
|
|
96
|
-
|--------|----------------|------------------|
|
|
97
|
-
| `aifabrix validate {{appName}}` | Local (schemas / files) | No |
|
|
98
|
-
| `aifabrix test {{appName}}` | Local (manifest / payload checks) | No |
|
|
99
|
-
| `aifabrix test-integration {{appName}}`, `aifabrix test-e2e {{appName}}`, `aifabrix datasource test …`, `aifabrix datasource test-integration …`, `aifabrix datasource test-e2e …` | Through configured auth | Yes — unified validation / pipeline API |
|
|
85
|
+
{{#if secretPaths}}{{#if secretPaths.length}}
|
|
100
86
|
|
|
101
|
-
|
|
87
|
+
## Secrets
|
|
102
88
|
|
|
103
|
-
|
|
89
|
+
Store values the CLI expects (no secrets in Git):
|
|
104
90
|
|
|
105
91
|
```bash
|
|
106
|
-
|
|
107
|
-
aifabrix
|
|
92
|
+
{{#each secretPaths}}
|
|
93
|
+
aifabrix secret set {{path}} <your value> # {{description}}
|
|
94
|
+
{{/each}}
|
|
108
95
|
```
|
|
96
|
+
{{/if}}{{/if}}
|
|
109
97
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
aifabrix test-integration {{appName}}
|
|
114
|
-
```
|
|
98
|
+
## Repair
|
|
115
99
|
|
|
116
|
-
|
|
100
|
+
Keeps filenames, lists, and deploy manifest in sync after manual edits.
|
|
117
101
|
|
|
118
102
|
```bash
|
|
119
|
-
aifabrix
|
|
103
|
+
aifabrix repair {{appName}}
|
|
120
104
|
```
|
|
121
105
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
--debug Include debug output and write log to integration/{{appName}}/logs/
|
|
126
|
-
--no-async Use sync mode (no polling); single POST per datasource
|
|
106
|
+
Useful flags: `--dry-run`, `--auth <method>`, `--rbac`, `--expose`, `--sync`, `--test`.
|
|
107
|
+
|
|
108
|
+
## Validate and test
|
|
127
109
|
|
|
128
|
-
|
|
110
|
+
| Command | Network |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| `aifabrix validate {{appName}}` | Off — schemas and files only |
|
|
113
|
+
| `aifabrix test {{appName}}` | Off — local checks |
|
|
114
|
+
| `aifabrix test-integration {{appName}}` | On — needs login + dataplane |
|
|
115
|
+
| `aifabrix test-e2e {{appName}}` | On — full pipeline per datasource |
|
|
129
116
|
|
|
130
|
-
|
|
117
|
+
Single datasource E2E:
|
|
131
118
|
|
|
132
119
|
{{#if hasDatasources}}
|
|
133
120
|
```bash
|
|
@@ -137,28 +124,28 @@ aifabrix datasource test-e2e {{datasourceKey}} --app {{../appName}}
|
|
|
137
124
|
|
|
138
125
|
{{/each}}
|
|
139
126
|
```
|
|
127
|
+
{{else}}
|
|
128
|
+
```bash
|
|
129
|
+
aifabrix datasource test-e2e <datasource-key> --app {{appName}}
|
|
130
|
+
```
|
|
140
131
|
{{/if}}
|
|
141
132
|
|
|
142
|
-
|
|
143
|
-
-a, --app {{appName}} App key (default: resolve from cwd if inside integration/{{appName}}/)
|
|
144
|
-
-e, --env <env> Environment: dev, tst, or pro
|
|
145
|
-
-v, --verbose Show detailed step output and poll progress
|
|
146
|
-
--debug Include debug output and write log to integration/{{appName}}/logs/
|
|
147
|
-
--no-run-scenarios Skip expanding testPayload.scenarios in capacity step
|
|
148
|
-
--no-cleanup Disable cleanup after test (body cleanup: false)
|
|
149
|
-
--primary-key-value <value|@path> Primary key value or path to JSON file (e.g. @pk.json) for body primaryKeyValue
|
|
150
|
-
--no-async Use sync mode (no polling); single POST, no asyncRun
|
|
151
|
-
|
|
152
|
-
## Deployment
|
|
133
|
+
Common E2E flags: `-v` / `--verbose`, `-d` / `--debug`, `--no-async`.
|
|
153
134
|
|
|
154
|
-
Deploy
|
|
135
|
+
## Deploy
|
|
155
136
|
|
|
156
137
|
```bash
|
|
157
138
|
aifabrix deploy {{appName}}
|
|
158
139
|
```
|
|
159
140
|
|
|
160
|
-
##
|
|
141
|
+
## Remove app
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
aifabrix delete {{appName}}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## When something fails
|
|
161
148
|
|
|
162
|
-
- **
|
|
163
|
-
- **
|
|
164
|
-
- **
|
|
149
|
+
- **Validation errors** — Fix JSON/schema issues; run `aifabrix validate {{appName}}` and `aifabrix datasource validate` on the file you changed.
|
|
150
|
+
- **Auth** — `aifabrix auth config` + `aifabrix login` before upload, deploy, or remote tests.
|
|
151
|
+
- **Wrong folder** — Run CLI from the project root (where `integration/{{appName}}/` lives).
|