@aifabrix/builder 2.44.6 → 2.45.5
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 +7 -3
- package/.cursor/rules/docs-rules.mdc +3 -1
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
- package/jest.projects.js +100 -1
- package/lib/api/agent-metadata-validation.api.js +93 -0
- package/lib/api/audit-api-helpers.js +68 -0
- package/lib/api/audit.api.js +119 -0
- package/lib/api/auth-cache.api.js +44 -0
- package/lib/api/certificates.api.js +4 -4
- package/lib/api/credential.api.js +2 -2
- package/lib/api/dataplane-health.api.js +137 -0
- package/lib/api/dataplane-sync.api.js +27 -0
- package/lib/api/datasources-core.api.js +21 -18
- package/lib/api/datasources-extended.api.js +22 -22
- package/lib/api/dimensions.api.js +3 -0
- package/lib/api/external-systems.api.js +13 -13
- package/lib/api/governance-scenarios.api.js +39 -0
- package/lib/api/groups.api.js +79 -0
- package/lib/api/index.js +45 -2
- package/lib/api/pipeline.api.js +4 -4
- package/lib/api/protection.api.js +157 -0
- package/lib/api/records-bulk.api.js +30 -0
- package/lib/api/records-search-parse.js +49 -0
- package/lib/api/records-search.api.js +29 -0
- package/lib/api/types/agent-metadata-validation.types.js +67 -0
- package/lib/api/types/audit.types.js +72 -0
- package/lib/api/types/dataplane-health.types.js +27 -0
- package/lib/api/types/dimensions.types.js +2 -0
- package/lib/api/types/governance-scenarios.types.js +39 -0
- package/lib/api/types/protection.types.js +69 -0
- package/lib/api/types/records-bulk.types.js +35 -0
- package/lib/api/types/records-search.types.js +28 -0
- package/lib/api/user-groups.api.js +50 -0
- package/lib/api/users.api.js +95 -0
- package/lib/api/validation-run.api.js +3 -3
- package/lib/api/validation-runner.js +3 -3
- package/lib/api/wizard-platform.api.js +3 -3
- package/lib/api/wizard.api.js +21 -21
- package/lib/app/deploy.js +34 -19
- package/lib/app/helpers.js +3 -3
- package/lib/app/index.js +3 -3
- package/lib/app/register.js +7 -6
- package/lib/app/restart-display.js +52 -21
- package/lib/app/rotate-secret.js +7 -6
- package/lib/app/run-helpers.js +15 -8
- package/lib/app/run.js +57 -9
- package/lib/app/show-display.js +7 -0
- package/lib/app/show.js +87 -5
- package/lib/build/index.js +9 -5
- package/lib/cli/index.js +4 -2
- package/lib/cli/infra-guided.js +62 -28
- package/lib/cli/installation-log-command.js +73 -0
- package/lib/cli/setup-app.help.js +50 -2
- package/lib/cli/setup-app.js +44 -25
- package/lib/cli/setup-app.test-commands.js +80 -21
- package/lib/cli/setup-auth.js +124 -52
- package/lib/cli/setup-external-system.js +37 -3
- package/lib/cli/setup-infra-up-dataplane-action.js +111 -0
- package/lib/cli/setup-infra-up-platform-action.js +131 -0
- package/lib/cli/setup-infra.js +60 -119
- package/lib/cli/setup-platform.js +1 -1
- package/lib/cli/setup-utility-help-after.js +45 -0
- package/lib/cli/setup-utility-resolve.js +132 -0
- package/lib/cli/setup-utility.js +148 -116
- package/lib/commands/app-logs.js +81 -33
- package/lib/commands/auth-config.js +116 -18
- package/lib/commands/auth-status-dataplane-version.js +231 -0
- package/lib/commands/auth-status-display.js +94 -0
- package/lib/commands/auth-status.js +70 -6
- package/lib/commands/credential-push.js +10 -5
- package/lib/commands/datasource-load-export-cli.js +178 -0
- package/lib/commands/datasource-test-trust-cli.js +114 -0
- package/lib/commands/datasource-unified-test-cli.js +25 -17
- package/lib/commands/datasource-unified-test-cli.options.js +18 -3
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
- package/lib/commands/datasource-verify-audit-cli.js +96 -0
- package/lib/commands/datasource.js +68 -1
- package/lib/commands/dimension-value.js +43 -13
- package/lib/commands/dimension.js +38 -7
- package/lib/commands/identity-apply-sync.js +131 -0
- package/lib/commands/identity-group-cli.js +146 -0
- package/lib/commands/identity-membership-role-cache.js +175 -0
- package/lib/commands/identity-shared.js +94 -0
- package/lib/commands/identity-user-cli.js +158 -0
- package/lib/commands/identity.js +43 -0
- package/lib/commands/login.js +46 -16
- package/lib/commands/protection-cli-leaves.js +286 -0
- package/lib/commands/protection.js +50 -0
- package/lib/commands/repair.js +13 -3
- package/lib/commands/setup-modes.js +19 -6
- package/lib/commands/setup-prompts.js +41 -8
- package/lib/commands/setup.js +114 -9
- package/lib/commands/teardown.js +54 -5
- package/lib/commands/test-e2e-external.js +40 -9
- package/lib/commands/test-governance-cli-options.js +47 -0
- package/lib/commands/test-governance-command-action.js +55 -0
- package/lib/commands/test-governance-external.js +88 -0
- package/lib/commands/test-trust-cli-options.js +32 -0
- package/lib/commands/test-trust-command-action.js +118 -0
- package/lib/commands/test-trust-external.js +127 -0
- package/lib/commands/up-common.js +48 -14
- package/lib/commands/up-dataplane.js +21 -18
- package/lib/commands/up-miso.js +12 -8
- package/lib/commands/upload.js +38 -15
- package/lib/commands/wizard-core.js +3 -0
- package/lib/core/audit-logger.js +1 -34
- package/lib/core/config-admin-email.js +56 -0
- package/lib/core/config-device-dataplane.js +185 -0
- package/lib/core/config-normalize.js +60 -0
- package/lib/core/config-registered-controller-urls.js +54 -0
- package/lib/core/config.js +33 -50
- package/lib/core/secrets-ensure-infra.js +1 -1
- package/lib/core/secrets-env-content.js +86 -90
- package/lib/core/secrets-env-declarative-expand.js +170 -0
- package/lib/core/secrets-env-write.js +2 -0
- package/lib/core/secrets-load.js +106 -102
- package/lib/datasource/agent-trust-debug-log.js +45 -0
- package/lib/datasource/agent-trust-fetch.js +115 -0
- package/lib/datasource/agent-trust-map.js +101 -0
- package/lib/datasource/agent-trust-mock.js +44 -0
- package/lib/datasource/agent-trust-run.js +93 -0
- package/lib/datasource/agent-trust-timeout.js +25 -0
- package/lib/datasource/audit-evidence-display.js +80 -0
- package/lib/datasource/audit-evidence-extract-debug.js +103 -0
- package/lib/datasource/audit-evidence-extract.js +177 -0
- package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
- package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
- package/lib/datasource/audit-evidence-poll.js +109 -0
- package/lib/datasource/audit-evidence-run.js +177 -0
- package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
- package/lib/datasource/audit-evidence-verify-matrix.js +177 -0
- package/lib/datasource/audit-evidence-verify.js +108 -0
- package/lib/datasource/bulk-loader-run-batches.js +88 -0
- package/lib/datasource/bulk-loader-service-retry.js +52 -0
- package/lib/datasource/bulk-loader-service.js +127 -0
- package/lib/datasource/capability/run-capability-dimension.js +2 -1
- package/lib/datasource/datasource-exporter-resolve.js +82 -0
- package/lib/datasource/datasource-exporter-service.js +144 -0
- package/lib/datasource/datasource-identifier.js +148 -0
- package/lib/datasource/datasource-load-export-context.js +92 -0
- package/lib/datasource/integration-context.js +6 -4
- package/lib/datasource/local-data-paths.js +145 -0
- package/lib/datasource/log-cleaner.js +241 -0
- package/lib/datasource/log-viewer.js +111 -6
- package/lib/datasource/record-file-parser.js +85 -0
- package/lib/datasource/record-mapper.js +129 -0
- package/lib/datasource/resolve-app.js +74 -55
- package/lib/datasource/test-e2e.js +26 -2
- package/lib/datasource/unified-validation-run-resolve.js +45 -12
- package/lib/datasource/unified-validation-run.js +43 -17
- package/lib/datasource/validate.js +37 -20
- package/lib/external-system/deploy.js +5 -1
- package/lib/external-system/test-system-level.js +25 -4
- package/lib/external-system/test.js +3 -1
- package/lib/governance/governance-pack-loader.js +70 -0
- package/lib/governance/governance-run-display.js +119 -0
- package/lib/identity/identity-apply-core.js +108 -0
- package/lib/identity/identity-apply-phases.js +244 -0
- package/lib/identity/identity-apply-service.js +77 -0
- package/lib/identity/identity-csv-parser.js +114 -0
- package/lib/internal/fs-real-sync.js +29 -1
- package/lib/internal/node-fs.js +2 -0
- package/lib/protection/auth-context.js +45 -0
- package/lib/protection/convert-batch.js +90 -0
- package/lib/protection/load.js +41 -0
- package/lib/protection/paths.js +158 -0
- package/lib/protection/preflight-datasource-ready.js +46 -0
- package/lib/protection/protection-create-probe-lines.js +142 -0
- package/lib/protection/protection-create-probes.js +95 -0
- package/lib/protection/protection-create-scaffold.js +281 -0
- package/lib/protection/protection-display-helpers.js +445 -0
- package/lib/protection/protection-display.js +215 -0
- package/lib/protection/protection-preset-registry.js +97 -0
- package/lib/protection/report-exit.js +62 -0
- package/lib/protection/resolve.js +202 -0
- package/lib/protection/run-commands-validate.js +130 -0
- package/lib/protection/run-commands.js +216 -0
- package/lib/protection/run-protection-create-helpers.js +134 -0
- package/lib/protection/run-protection-create-probes-flow.js +43 -0
- package/lib/protection/run-protection-create.js +191 -0
- package/lib/protection/scope.js +22 -0
- package/lib/protection/sync-after-upload.js +64 -0
- package/lib/protection/upload-batch.js +127 -0
- package/lib/protection/validate-batch.js +113 -0
- package/lib/protection/validate-local.js +65 -0
- package/lib/resolvers/dimension-file.js +29 -4
- package/lib/schema/application-schema.json +4 -0
- package/lib/schema/external-datasource.schema.json +47 -13
- package/lib/schema/flag-map-validation-run.json +2 -2
- package/lib/schema/infra.parameter.yaml +10 -0
- package/lib/schema/protection.schema.json +374 -0
- package/lib/schema/type/credential-field-registry.json +636 -0
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/agent-trust-run-display.js +231 -0
- package/lib/utils/agent-trust-run-exit.js +59 -0
- package/lib/utils/agent-trust-wait-ui.js +94 -0
- package/lib/utils/app-config-resolver.js +24 -1
- package/lib/utils/applications-config-defaults.js +206 -0
- package/lib/utils/auth-config-validator.js +2 -12
- package/lib/utils/bash-secret-env.js +1 -1
- package/lib/utils/cli-exit-codes.js +30 -0
- package/lib/utils/cli-sync-options.js +33 -0
- package/lib/utils/compose-generate-docker-compose.js +111 -6
- package/lib/utils/compose-generator.js +17 -8
- package/lib/utils/controller-url.js +50 -7
- package/lib/utils/credential-push-ui.js +90 -0
- package/lib/utils/dataplane-cli-version-gate.js +202 -0
- package/lib/utils/dataplane-cli-version-help.js +74 -0
- package/lib/utils/datasource-export-display.js +137 -0
- package/lib/utils/datasource-load-display.js +174 -0
- package/lib/utils/datasource-load-export-ui.js +120 -0
- package/lib/utils/datasource-test-run-capability-scope.js +3 -3
- package/lib/utils/datasource-test-run-display.js +3 -3
- package/lib/utils/datasource-test-run-tty-log.js +5 -1
- package/lib/utils/env-copy.js +99 -14
- package/lib/utils/env-template.js +5 -1
- package/lib/utils/health-check-url.js +18 -15
- package/lib/utils/health-check.js +7 -5
- package/lib/utils/help-builder.js +30 -24
- package/lib/utils/infra-optional-service-flags.js +69 -0
- package/lib/utils/installation-log-core.js +282 -0
- package/lib/utils/installation-log-record.js +237 -0
- package/lib/utils/installation-log.js +123 -0
- package/lib/utils/log-redaction.js +105 -0
- package/lib/utils/manifest-location.js +164 -0
- package/lib/utils/manifest-source-emit.js +184 -0
- package/lib/utils/paths.js +238 -89
- package/lib/utils/remote-secrets-loader.js +7 -1
- package/lib/utils/run-cli-flags.js +29 -0
- package/lib/utils/secrets-canonical.js +10 -3
- package/lib/utils/secrets-path.js +3 -4
- package/lib/utils/secrets-utils.js +20 -10
- package/lib/utils/semver-compare.js +127 -0
- package/lib/utils/system-builder-root.js +10 -2
- package/lib/utils/upload-pipeline-ui.js +91 -0
- package/lib/utils/url-declarative-public-base.js +80 -12
- package/lib/utils/url-declarative-resolve-build-urls.js +238 -0
- package/lib/utils/url-declarative-resolve-build.js +24 -393
- package/lib/utils/url-declarative-resolve-expand-token.js +189 -0
- package/lib/utils/url-declarative-resolve-load-doc.js +12 -3
- package/lib/utils/url-declarative-resolve-surface-state.js +102 -0
- package/lib/utils/url-declarative-resolve.js +47 -7
- package/lib/utils/url-declarative-runtime-base-path.js +21 -1
- package/lib/utils/urls-local-registry-scan.js +103 -0
- package/lib/utils/urls-local-registry.js +161 -90
- package/lib/utils/validation-poll-ui.js +14 -7
- package/lib/validation/wizard-config-validator.js +58 -19
- package/package.json +3 -1
- package/templates/applications/dataplane/application.yaml +4 -0
- package/templates/applications/dataplane/env.template +13 -1
- package/templates/applications/dataplane/rbac.yaml +4 -0
- package/templates/applications/miso-controller/application.yaml +2 -0
- package/templates/applications/miso-controller/env.template +27 -29
- package/templates/external-system/README.md.hbs +56 -8
- package/.npmrc.token +0 -1
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Primary `urls.local.yaml`
|
|
3
|
-
* `secrets.local.yaml
|
|
2
|
+
* Primary `urls.local.yaml` beside `config.yaml` (same directory as {@link module:lib/utils/paths.getConfigDirForPaths}),
|
|
3
|
+
* aligned with `secrets.local.yaml`. When missing, {@link readUrlsLocalRegistrySync} may read a legacy
|
|
4
|
+
* file under {@link module:lib/utils/paths.getAifabrixHome} (older releases when `aifabrix-home` was `$HOME`).
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
+
* Per-app keys (see {@link mergeDocIntoRegistry}): `appKey-port`, `appKey-pattern`, `appKey-containerPort`,
|
|
7
|
+
* optional `appKey-internalDockerUseOriginOnly` (boolean) — overrides `frontDoorRouting.internalDockerUseOriginOnly`
|
|
8
|
+
* for declarative `url://` resolution when set (e.g. Keycloak internal URL without `/auth` when true).
|
|
9
|
+
*
|
|
10
|
+
* @fileoverview Read/write registry; scan builder/package dirs in canonical order (plan 141 P3).
|
|
11
|
+
* Duplicate `app.key`: last scan directory wins — no cross-root mtime merge or `AIFABRIX_BUILDER_DIR` ordering.
|
|
6
12
|
* @author AI Fabrix Team
|
|
7
13
|
* @version 1.0.0
|
|
8
14
|
*/
|
|
@@ -14,17 +20,18 @@ const path = require('path');
|
|
|
14
20
|
const yaml = require('js-yaml');
|
|
15
21
|
const { DECLARATIVE_URL_INFRA_DEFAULTS } = require('./infra-env-defaults');
|
|
16
22
|
const pathsUtil = require('./paths');
|
|
23
|
+
const { collectLatestApplicationYamlEntriesPerApp } = require('./urls-local-registry-scan');
|
|
17
24
|
|
|
18
25
|
/**
|
|
19
|
-
* @returns {string} Absolute path to urls.local.yaml (
|
|
26
|
+
* @returns {string} Absolute path to urls.local.yaml (beside config.yaml)
|
|
20
27
|
*/
|
|
21
28
|
function getUrlsLocalYamlPath() {
|
|
22
|
-
return path.join(pathsUtil.
|
|
29
|
+
return path.join(pathsUtil.getConfigDirForPaths(), 'urls.local.yaml');
|
|
23
30
|
}
|
|
24
31
|
|
|
25
|
-
/** @returns {string}
|
|
26
|
-
function
|
|
27
|
-
return path.join(pathsUtil.
|
|
32
|
+
/** @returns {string} Legacy primary path from older CLI (under resolved AI Fabrix home) */
|
|
33
|
+
function getLegacyUrlsLocalYamlPathAtAifabrixHome() {
|
|
34
|
+
return path.join(pathsUtil.getAifabrixHome(), 'urls.local.yaml');
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
function loadRegistryYamlFile(filePath) {
|
|
@@ -44,9 +51,9 @@ function readUrlsLocalRegistrySync() {
|
|
|
44
51
|
if (fsRealSync.existsSync(primary)) {
|
|
45
52
|
return loadRegistryYamlFile(primary);
|
|
46
53
|
}
|
|
47
|
-
const
|
|
48
|
-
if (path.resolve(
|
|
49
|
-
return loadRegistryYamlFile(
|
|
54
|
+
const legacy = getLegacyUrlsLocalYamlPathAtAifabrixHome();
|
|
55
|
+
if (path.resolve(legacy) !== path.resolve(primary) && fsRealSync.existsSync(legacy)) {
|
|
56
|
+
return loadRegistryYamlFile(legacy);
|
|
50
57
|
}
|
|
51
58
|
return {};
|
|
52
59
|
}
|
|
@@ -90,22 +97,6 @@ function writeMergedRegistry(merged) {
|
|
|
90
97
|
return merged;
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
/**
|
|
94
|
-
* @param {string} cfgPath
|
|
95
|
-
* @returns {object|null}
|
|
96
|
-
*/
|
|
97
|
-
function tryLoadApplicationYaml(cfgPath) {
|
|
98
|
-
if (!fsRealSync.existsSync(cfgPath)) {
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
try {
|
|
102
|
-
const doc = yaml.load(fsRealSync.readFileSync(cfgPath, 'utf8'));
|
|
103
|
-
return doc && typeof doc === 'object' ? doc : null;
|
|
104
|
-
} catch {
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
100
|
/**
|
|
110
101
|
* @param {object} doc
|
|
111
102
|
* @returns {number|null}
|
|
@@ -152,114 +143,193 @@ function mergeDocIntoRegistry(merged, doc, folderName) {
|
|
|
152
143
|
} else {
|
|
153
144
|
delete merged[ckey];
|
|
154
145
|
}
|
|
146
|
+
|
|
147
|
+
mergeInternalDockerOriginOnlyRegistryKeyFromDoc(merged, appKey, doc);
|
|
155
148
|
}
|
|
156
149
|
|
|
157
150
|
/**
|
|
151
|
+
* When `application.yaml` explicitly sets `frontDoorRouting.internalDockerUseOriginOnly`, mirror it into
|
|
152
|
+
* `urls.local.yaml` on refresh. If the property is absent, leave any existing registry value unchanged
|
|
153
|
+
* (supports hand-edited `appKey-internalDockerUseOriginOnly` without a YAML field).
|
|
154
|
+
*
|
|
158
155
|
* @param {Object} merged
|
|
159
|
-
* @param {string}
|
|
156
|
+
* @param {string} appKey
|
|
157
|
+
* @param {object} doc
|
|
160
158
|
*/
|
|
161
|
-
function
|
|
162
|
-
|
|
159
|
+
function mergeInternalDockerOriginOnlyRegistryKeyFromDoc(merged, appKey, doc) {
|
|
160
|
+
const key = `${appKey}-internalDockerUseOriginOnly`;
|
|
161
|
+
const fd = doc && doc.frontDoorRouting;
|
|
162
|
+
if (!fd || typeof fd !== 'object') {
|
|
163
163
|
return;
|
|
164
164
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
165
|
+
if (!Object.prototype.hasOwnProperty.call(fd, 'internalDockerUseOriginOnly')) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const v = fd.internalDockerUseOriginOnly;
|
|
169
|
+
if (v === true) {
|
|
170
|
+
merged[key] = true;
|
|
171
|
+
} else if (v === false) {
|
|
172
|
+
merged[key] = false;
|
|
173
|
+
} else {
|
|
174
|
+
delete merged[key];
|
|
174
175
|
}
|
|
175
176
|
}
|
|
176
177
|
|
|
177
178
|
/**
|
|
178
|
-
*
|
|
179
|
-
* @
|
|
180
|
-
*
|
|
181
|
-
* @
|
|
179
|
+
* Append a directory to the scan list when it exists, is a directory, and is not already included (resolved).
|
|
180
|
+
* Later entries win duplicate `app.key` merges (see {@link collectLatestApplicationYamlEntriesPerApp}).
|
|
181
|
+
*
|
|
182
|
+
* @param {string[]} scanDirs
|
|
183
|
+
* @param {string|null|undefined} dirPath
|
|
184
|
+
* @returns {void}
|
|
182
185
|
*/
|
|
183
|
-
function
|
|
184
|
-
|
|
186
|
+
function pushUniqueScanDir(scanDirs, dirPath) {
|
|
187
|
+
if (!dirPath || typeof dirPath !== 'string') {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
let resolved;
|
|
191
|
+
try {
|
|
192
|
+
resolved = path.resolve(dirPath);
|
|
193
|
+
} catch {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
if (!fsRealSync.existsSync(resolved) || !fsRealSync.statSync(resolved).isDirectory()) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
} catch {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
for (const existing of scanDirs) {
|
|
204
|
+
try {
|
|
205
|
+
if (path.resolve(existing) === resolved) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
} catch {
|
|
209
|
+
// ignore
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
scanDirs.push(resolved);
|
|
185
213
|
}
|
|
186
214
|
|
|
187
215
|
/**
|
|
188
|
-
* Builder dirs to scan in order; later merges overwrite registry keys from earlier dirs.
|
|
189
|
-
* When `AIFABRIX_BUILDER_DIR` is set and differs from projectRoot/builder, env builder root is merged last.
|
|
190
|
-
* Otherwise projectRoot/builder is merged last so explicit refresh roots override getBuilderRoot().
|
|
191
|
-
*
|
|
192
|
-
* @param {string} root - Resolved project root passed to refresh
|
|
193
|
-
* @param {string|null} effectiveBuilderDir - pathsUtil.getBuilderRoot()
|
|
194
216
|
* @returns {string[]}
|
|
195
217
|
*/
|
|
196
|
-
function
|
|
197
|
-
const
|
|
198
|
-
let resolvedLegacy;
|
|
199
|
-
let resolvedEffective;
|
|
218
|
+
function getPackageBuilderLikeDirsForRegistryScan() {
|
|
219
|
+
const out = [];
|
|
200
220
|
try {
|
|
201
|
-
|
|
202
|
-
resolvedEffective = effectiveBuilderDir ? path.resolve(effectiveBuilderDir) : null;
|
|
221
|
+
out.push(path.join(pathsUtil.getIntegrationBuilderBaseDir(), 'packages'));
|
|
203
222
|
} catch {
|
|
204
|
-
|
|
223
|
+
// ignore
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
const pr = pathsUtil.getProjectRoot();
|
|
227
|
+
if (pr) {
|
|
228
|
+
out.push(path.join(pr, 'packages'));
|
|
229
|
+
}
|
|
230
|
+
} catch {
|
|
231
|
+
// ignore
|
|
205
232
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
// Only treat env as authoritative when getBuilderRoot() is actually that path. Otherwise a stray
|
|
209
|
-
// AIFABRIX_BUILDER_DIR on CI (or Jest mocking getBuilderRoot to a temp dir) must not force
|
|
210
|
-
// [legacy, effective] — that order lets the real checkout builder overwrite the mocked root last.
|
|
211
|
-
const effectiveMatchesEnvVar = effectiveBuilderMatchesEnvVar(resolvedEffective, envResolved);
|
|
233
|
+
return out;
|
|
234
|
+
}
|
|
212
235
|
|
|
213
|
-
|
|
214
|
-
|
|
236
|
+
/**
|
|
237
|
+
* Canonical builder/package scan roots (low → high priority). Plan 141 P3: fixed order replaces
|
|
238
|
+
* mtime merge and `AIFABRIX_BUILDER_DIR` scan ordering; `findProjectRootFromCwd` builder is last when enabled.
|
|
239
|
+
*
|
|
240
|
+
* @param {string|null} root
|
|
241
|
+
* @param {string|null} effectiveBuilderDir
|
|
242
|
+
* @param {{ excludeCwdBuilderScan?: boolean }} opts
|
|
243
|
+
* @returns {string[]}
|
|
244
|
+
*/
|
|
245
|
+
function buildCanonicalRegistryScanDirs(root, effectiveBuilderDir, opts = {}) {
|
|
246
|
+
const scanDirs = [];
|
|
247
|
+
pushUniqueScanDir(scanDirs, pathsUtil.getSystemBuilderRoot());
|
|
248
|
+
pushUniqueScanDir(scanDirs, effectiveBuilderDir);
|
|
249
|
+
if (root) {
|
|
250
|
+
pushUniqueScanDir(scanDirs, path.join(root, 'builder'));
|
|
215
251
|
}
|
|
216
|
-
|
|
217
|
-
|
|
252
|
+
for (const pkg of getPackageBuilderLikeDirsForRegistryScan()) {
|
|
253
|
+
pushUniqueScanDir(scanDirs, pkg);
|
|
218
254
|
}
|
|
219
|
-
if (
|
|
220
|
-
|
|
255
|
+
if (!opts.excludeCwdBuilderScan) {
|
|
256
|
+
let cwdRoot = null;
|
|
257
|
+
try {
|
|
258
|
+
cwdRoot = pathsUtil.findProjectRootFromCwd();
|
|
259
|
+
} catch {
|
|
260
|
+
cwdRoot = null;
|
|
261
|
+
}
|
|
262
|
+
if (cwdRoot && typeof cwdRoot === 'string') {
|
|
263
|
+
pushUniqueScanDir(scanDirs, path.join(cwdRoot, 'builder'));
|
|
264
|
+
}
|
|
221
265
|
}
|
|
222
|
-
return
|
|
266
|
+
return scanDirs;
|
|
223
267
|
}
|
|
224
268
|
|
|
225
269
|
/**
|
|
226
270
|
* Merge scan results into registry (does not remove stale keys).
|
|
227
271
|
* @param {string|null} projectRoot - getProjectRoot() or null (same semantics as projectRoot || getProjectRoot())
|
|
272
|
+
* @param {{ excludeCwdBuilderScan?: boolean }} [opts] - When `excludeCwdBuilderScan` is true, omit cwd
|
|
273
|
+
* checkout `builder/` (tests / `ctx.projectRoot` isolation — avoids merging ambient repo `builder/`).
|
|
228
274
|
* @returns {Object} Updated registry
|
|
229
275
|
*/
|
|
230
|
-
function refreshUrlsLocalRegistryFromBuilder(projectRoot) {
|
|
276
|
+
function refreshUrlsLocalRegistryFromBuilder(projectRoot, opts) {
|
|
277
|
+
const o = opts && typeof opts === 'object' ? opts : {};
|
|
231
278
|
const root = projectRoot || pathsUtil.getProjectRoot();
|
|
232
279
|
const merged = { ...readUrlsLocalRegistrySync() };
|
|
233
280
|
if (!root) {
|
|
234
281
|
return writeMergedRegistry(merged);
|
|
235
282
|
}
|
|
236
|
-
// Published npm tarball omits builder/ under the package root (.npmignore). Global installs
|
|
237
|
-
//
|
|
283
|
+
// Published npm tarball omits builder/ under the package root (.npmignore). Global installs still
|
|
284
|
+
// resolve materialized apps via getBuilderRoot() (same parent as getSystemBuilderRoot when aligned).
|
|
238
285
|
let effectiveBuilderDir = null;
|
|
239
286
|
try {
|
|
240
287
|
effectiveBuilderDir = pathsUtil.getBuilderRoot();
|
|
241
288
|
} catch {
|
|
242
289
|
effectiveBuilderDir = null;
|
|
243
290
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (fsRealSync.existsSync(sysRoot)) {
|
|
249
|
-
const resolvedList = builderDirs.map((d) => path.resolve(d));
|
|
250
|
-
if (!resolvedList.includes(resolvedSys)) {
|
|
251
|
-
builderDirs = [sysRoot, ...builderDirs];
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
} catch {
|
|
255
|
-
// ignore
|
|
256
|
-
}
|
|
257
|
-
for (const builderDir of builderDirs) {
|
|
258
|
-
mergeBuilderDirIntoRegistry(merged, builderDir);
|
|
291
|
+
const scanDirs = buildCanonicalRegistryScanDirs(root, effectiveBuilderDir, o);
|
|
292
|
+
const entries = collectLatestApplicationYamlEntriesPerApp(scanDirs);
|
|
293
|
+
for (const { folderName, doc } of entries) {
|
|
294
|
+
mergeDocIntoRegistry(merged, doc, folderName);
|
|
259
295
|
}
|
|
260
296
|
return writeMergedRegistry(merged);
|
|
261
297
|
}
|
|
262
298
|
|
|
299
|
+
const REGISTRY_BOOL_TRUE = new Set([true, 'true', 'yes', 'on', 1, '1']);
|
|
300
|
+
const REGISTRY_BOOL_FALSE = new Set([false, 'false', 'no', 'off', 0, '0']);
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* @param {unknown} raw
|
|
304
|
+
* @returns {boolean|undefined}
|
|
305
|
+
*/
|
|
306
|
+
function coerceRegistryBool(raw) {
|
|
307
|
+
if (REGISTRY_BOOL_TRUE.has(raw)) {
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
if (REGISTRY_BOOL_FALSE.has(raw)) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
return undefined;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Optional `appKey-internalDockerUseOriginOnly` in `urls.local.yaml` (boolean or common string coercions).
|
|
318
|
+
* When set, declarative URL resolution uses this value instead of (or in addition to) `application.yaml`.
|
|
319
|
+
*
|
|
320
|
+
* @param {string} appKey
|
|
321
|
+
* @param {Object|null|undefined} registry
|
|
322
|
+
* @returns {boolean|undefined} undefined when the key is absent or not coercible to boolean
|
|
323
|
+
*/
|
|
324
|
+
function readRegistryInternalDockerUseOriginOnly(appKey, registry) {
|
|
325
|
+
const r = registry && typeof registry === 'object' ? registry : {};
|
|
326
|
+
const key = `${appKey}-internalDockerUseOriginOnly`;
|
|
327
|
+
if (!Object.prototype.hasOwnProperty.call(r, key)) {
|
|
328
|
+
return undefined;
|
|
329
|
+
}
|
|
330
|
+
return coerceRegistryBool(r[key]);
|
|
331
|
+
}
|
|
332
|
+
|
|
263
333
|
/**
|
|
264
334
|
* @param {string} appKey
|
|
265
335
|
* @param {Object} registry
|
|
@@ -293,5 +363,6 @@ module.exports = {
|
|
|
293
363
|
writeUrlsLocalRegistrySync,
|
|
294
364
|
refreshUrlsLocalRegistryFromBuilder,
|
|
295
365
|
normalizePatternForUrl,
|
|
296
|
-
getRegistryEntryForApp
|
|
366
|
+
getRegistryEntryForApp,
|
|
367
|
+
readRegistryInternalDockerUseOriginOnly
|
|
297
368
|
};
|
|
@@ -23,10 +23,12 @@ function shouldUseValidationPollSpinner() {
|
|
|
23
23
|
* @param {number} deadlineMs - Wall-clock deadline (Date.now() + remaining budget)
|
|
24
24
|
* @returns {string}
|
|
25
25
|
*/
|
|
26
|
-
function buildValidationPollSpinnerText(envelope, attemptIndex, deadlineMs) {
|
|
26
|
+
function buildValidationPollSpinnerText(envelope, attemptIndex, deadlineMs, subject) {
|
|
27
27
|
const remainingSec = Math.max(0, Math.ceil((deadlineMs - Date.now()) / 1000));
|
|
28
|
+
const label =
|
|
29
|
+
subject && String(subject).trim() ? String(subject).trim() : 'validation run';
|
|
28
30
|
if (!envelope || typeof envelope !== 'object') {
|
|
29
|
-
return `Waiting for
|
|
31
|
+
return `Waiting for ${label}… starting (budget ~${remainingSec}s)`;
|
|
30
32
|
}
|
|
31
33
|
const c =
|
|
32
34
|
envelope.reportCompleteness !== undefined && envelope.reportCompleteness !== null
|
|
@@ -34,26 +36,29 @@ function buildValidationPollSpinnerText(envelope, attemptIndex, deadlineMs) {
|
|
|
34
36
|
: '?';
|
|
35
37
|
const st =
|
|
36
38
|
envelope.status !== undefined && envelope.status !== null ? String(envelope.status) : '?';
|
|
37
|
-
return `Waiting for
|
|
39
|
+
return `Waiting for ${label}… completeness=${c} status=${st} (poll ${attemptIndex + 1} · ~${remainingSec}s left)`;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
const NON_TTY_THROTTLE_MS = 5000;
|
|
41
43
|
|
|
42
44
|
/**
|
|
43
45
|
* @param {number} deadlineMs - Absolute deadline for poll budget display
|
|
46
|
+
* @param {Object} [opts]
|
|
47
|
+
* @param {string} [opts.subject] - Datasource key or label shown in poll text
|
|
44
48
|
* @returns {{ usesSpinner: boolean, onPollProgress: Function, finish: () => void }}
|
|
45
49
|
*/
|
|
46
|
-
function createValidationPollHandlers(deadlineMs) {
|
|
50
|
+
function createValidationPollHandlers(deadlineMs, opts = {}) {
|
|
51
|
+
const subject = opts.subject;
|
|
47
52
|
if (shouldUseValidationPollSpinner()) {
|
|
48
53
|
const ora = require('ora');
|
|
49
54
|
const spinner = ora({
|
|
50
|
-
text: buildValidationPollSpinnerText(null, 0, deadlineMs),
|
|
55
|
+
text: buildValidationPollSpinnerText(null, 0, deadlineMs, subject),
|
|
51
56
|
spinner: 'dots'
|
|
52
57
|
}).start();
|
|
53
58
|
return {
|
|
54
59
|
usesSpinner: true,
|
|
55
60
|
onPollProgress: (envelope, attemptIndex, _meta) => {
|
|
56
|
-
spinner.text = buildValidationPollSpinnerText(envelope, attemptIndex, deadlineMs);
|
|
61
|
+
spinner.text = buildValidationPollSpinnerText(envelope, attemptIndex, deadlineMs, subject);
|
|
57
62
|
},
|
|
58
63
|
finish: () => {
|
|
59
64
|
spinner.stop();
|
|
@@ -68,7 +73,9 @@ function createValidationPollHandlers(deadlineMs) {
|
|
|
68
73
|
const now = Date.now();
|
|
69
74
|
if (now - lastNonTtyLogAt < NON_TTY_THROTTLE_MS) return;
|
|
70
75
|
lastNonTtyLogAt = now;
|
|
71
|
-
logger.log(
|
|
76
|
+
logger.log(
|
|
77
|
+
chalk.gray(buildValidationPollSpinnerText(envelope, attemptIndex, deadlineMs, subject))
|
|
78
|
+
);
|
|
72
79
|
},
|
|
73
80
|
finish: () => {}
|
|
74
81
|
};
|
|
@@ -164,36 +164,73 @@ function validateWizardConfigSchema(config) {
|
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Candidate bases for relative openapi-file paths (first existing wins).
|
|
169
|
+
* @param {string} configPath - Path to wizard.yaml
|
|
170
|
+
* @returns {string[]}
|
|
171
|
+
*/
|
|
172
|
+
function wizardOpenApiFilePathCandidates(filePath, configPath) {
|
|
173
|
+
const raw = String(filePath || '').trim();
|
|
174
|
+
if (!raw) {
|
|
175
|
+
return [];
|
|
176
|
+
}
|
|
177
|
+
if (path.isAbsolute(raw)) {
|
|
178
|
+
return [path.resolve(raw)];
|
|
179
|
+
}
|
|
180
|
+
const configDir = path.dirname(path.resolve(configPath));
|
|
181
|
+
return [...new Set([
|
|
182
|
+
path.resolve(process.cwd(), raw),
|
|
183
|
+
path.resolve(configDir, raw)
|
|
184
|
+
])];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Resolve openapi-file path for wizard config (absolute path).
|
|
189
|
+
* Relative paths: process.cwd() first, then wizard.yaml directory.
|
|
190
|
+
* @param {string} filePath
|
|
191
|
+
* @param {string} configPath
|
|
192
|
+
* @returns {Promise<string>}
|
|
193
|
+
*/
|
|
194
|
+
async function resolveWizardOpenApiFilePath(filePath, configPath) {
|
|
195
|
+
const candidates = wizardOpenApiFilePathCandidates(filePath, configPath);
|
|
196
|
+
if (candidates.length === 0) {
|
|
197
|
+
return '';
|
|
198
|
+
}
|
|
199
|
+
for (const candidate of candidates) {
|
|
200
|
+
try {
|
|
201
|
+
await fs.access(candidate);
|
|
202
|
+
return candidate;
|
|
203
|
+
} catch (error) {
|
|
204
|
+
if (error.code !== 'ENOENT') {
|
|
205
|
+
throw error;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return candidates[0];
|
|
210
|
+
}
|
|
211
|
+
|
|
167
212
|
/**
|
|
168
213
|
* Validate file path exists (for openapi-file source type)
|
|
169
214
|
* @function validateFilePath
|
|
170
215
|
* @param {string} filePath - Path to validate
|
|
171
|
-
* @param {string}
|
|
172
|
-
* @returns {Promise<Object>} Validation result with valid flag and
|
|
216
|
+
* @param {string} configPath - Path to wizard.yaml (relative paths resolve from cwd, then config dir)
|
|
217
|
+
* @returns {Promise<Object>} Validation result with valid flag, errors, and resolvedPath
|
|
173
218
|
*/
|
|
174
|
-
async function validateFilePath(filePath,
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
: path.resolve(baseDir, filePath);
|
|
179
|
-
if (!path.isAbsolute(filePath)) {
|
|
180
|
-
const baseWithSep = baseDir.endsWith(path.sep) ? baseDir : `${baseDir}${path.sep}`;
|
|
181
|
-
if (!resolvedPath.startsWith(baseWithSep)) {
|
|
182
|
-
return {
|
|
183
|
-
valid: false,
|
|
184
|
-
errors: [`OpenAPI file path must be within: ${baseDir}`]
|
|
185
|
-
};
|
|
186
|
-
}
|
|
219
|
+
async function validateFilePath(filePath, configPath) {
|
|
220
|
+
const resolvedPath = await resolveWizardOpenApiFilePath(filePath, configPath);
|
|
221
|
+
if (!resolvedPath) {
|
|
222
|
+
return { valid: false, errors: ['OpenAPI file path is required'], resolvedPath: '' };
|
|
187
223
|
}
|
|
188
224
|
try {
|
|
189
225
|
await fs.access(resolvedPath);
|
|
190
226
|
} catch (error) {
|
|
191
227
|
return {
|
|
192
228
|
valid: false,
|
|
193
|
-
errors: [`OpenAPI file not found: ${resolvedPath}`]
|
|
229
|
+
errors: [`OpenAPI file not found: ${resolvedPath}`],
|
|
230
|
+
resolvedPath
|
|
194
231
|
};
|
|
195
232
|
}
|
|
196
|
-
return { valid: true, errors: [] };
|
|
233
|
+
return { valid: true, errors: [], resolvedPath };
|
|
197
234
|
}
|
|
198
235
|
|
|
199
236
|
/**
|
|
@@ -229,10 +266,11 @@ function validateSchemaAndResolveEnvVars(config, shouldResolveEnvVars) {
|
|
|
229
266
|
async function performSemanticValidations(config, configPath, validateFilePaths) {
|
|
230
267
|
const errors = [];
|
|
231
268
|
if (validateFilePaths && config.source?.type === 'openapi-file' && config.source?.filePath) {
|
|
232
|
-
const
|
|
233
|
-
const fileResult = await validateFilePath(config.source.filePath, basePath);
|
|
269
|
+
const fileResult = await validateFilePath(config.source.filePath, configPath);
|
|
234
270
|
if (!fileResult.valid) {
|
|
235
271
|
errors.push(...fileResult.errors);
|
|
272
|
+
} else if (fileResult.resolvedPath) {
|
|
273
|
+
config.source.filePath = fileResult.resolvedPath;
|
|
236
274
|
}
|
|
237
275
|
}
|
|
238
276
|
if (config.mode === 'add-datasource' && !config.systemIdOrKey) {
|
|
@@ -296,6 +334,7 @@ module.exports = {
|
|
|
296
334
|
wizardConfigExists,
|
|
297
335
|
validateWizardConfig,
|
|
298
336
|
validateWizardConfigSchema,
|
|
337
|
+
resolveWizardOpenApiFilePath,
|
|
299
338
|
resolveEnvVar,
|
|
300
339
|
resolveEnvVarsInObject,
|
|
301
340
|
formatValidationErrors,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aifabrix/builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.45.5",
|
|
4
4
|
"description": "AI Fabrix Local Fabric & Deployment SDK",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
"precommit": "npm run lint:fix && npm run test",
|
|
37
37
|
"install:local": "node scripts/install-local.js && which aifabrix && which af",
|
|
38
38
|
"uninstall:local": "node scripts/install-local.js uninstall && which aifabrix && which af",
|
|
39
|
+
"install:global": "npm install -g . --force && which aifabrix && which af && aifabrix --version",
|
|
40
|
+
"uninstall:global": "npm uninstall -g @aifabrix/builder",
|
|
39
41
|
"diagnose:cli": "node scripts/diagnose-cli.js",
|
|
40
42
|
"check:schema-sync": "node scripts/check-datasource-test-run-schema-sync.js",
|
|
41
43
|
"check:flags": "jest tests/lib/schema/flag-map-validation-run.test.js --runInBand --config jest.config.default.js"
|
|
@@ -26,6 +26,8 @@ environmentScopedResources: true
|
|
|
26
26
|
frontDoorRouting:
|
|
27
27
|
pattern: /data/*
|
|
28
28
|
enabled: true
|
|
29
|
+
# Docker url://internal full URLs: http://dataplane:PORT only (ingress /data is not on in-container routes).
|
|
30
|
+
internalDockerUseOriginOnly: false
|
|
29
31
|
host: ${DEV_USERNAME}.${REMOTE_HOST}
|
|
30
32
|
tls: ${TLS_ENABLED}
|
|
31
33
|
|
|
@@ -63,6 +65,8 @@ build:
|
|
|
63
65
|
envOutputPath: ../../.env # Copy to repo root for local dev
|
|
64
66
|
language: python # Runtime language for template selection (typescript or python)
|
|
65
67
|
reloadStart: uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3001} --reload # PORT set from port above at run time; default 3001 must match port
|
|
68
|
+
# Pulled-image local compose (no bind-mount): drives `command` in generated docker-compose. Override for non-standard images (e.g. stub ACR tags).
|
|
69
|
+
imageRun: exec python -m uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3001}
|
|
66
70
|
|
|
67
71
|
# =============================================================================
|
|
68
72
|
# Portal Input Configuration (Deployment Wizard)
|
|
@@ -21,7 +21,7 @@ LOG_FORMAT=json
|
|
|
21
21
|
# Production with persistent logs: use /mnt/data/logs/app.log and mount a volume at /mnt/data.
|
|
22
22
|
LOG_FILE_PATH=/mnt/data/logs/app.log
|
|
23
23
|
# If true, run without Redis/Celery (single process)
|
|
24
|
-
LOCAL_MODE=
|
|
24
|
+
LOCAL_MODE=true
|
|
25
25
|
|
|
26
26
|
# When API_KEY is set, a matching Bearer token bypasses OAuth2 validation
|
|
27
27
|
# Same kv:// as miso-controller API_KEY so pipeline Bearer bypass uses one secrets.local entry
|
|
@@ -30,6 +30,9 @@ API_KEY=kv://miso-controller-secrets-apiKeyVault
|
|
|
30
30
|
# API Configuration
|
|
31
31
|
API_V1_STR=/api/v1
|
|
32
32
|
VERSION=1.9.5
|
|
33
|
+
# Minimum supported aifabrix-builder CLI semver (advertised on /health and /api/v1/health; empty = no gate)
|
|
34
|
+
# MIN_BUILDER_CLI_VERSION=2.45.0
|
|
35
|
+
MIN_BUILDER_CLI_VERSION=2.45.0
|
|
33
36
|
# Base URL for the dataplane web server (used for default OAuth2 callback URL when redirectUri is omitted)
|
|
34
37
|
# url:// resolves after kv://; includes front-door path from application.yaml (e.g. /data)
|
|
35
38
|
DATAPLANE_WEB_SERVER_URL=url://public
|
|
@@ -165,6 +168,15 @@ RBAC_EXPLAIN_MODE_ENABLED=false
|
|
|
165
168
|
# validates only (no second DB write). Default false.
|
|
166
169
|
AUDIT_ASYNC_SHADOW_ENQUEUE=false
|
|
167
170
|
|
|
171
|
+
# Policy Library management HTTP API gate. When false (default), management
|
|
172
|
+
# routes are not registered (404): /api/v1/policies/*, /api/v1/external/{key}/policies,
|
|
173
|
+
# /api/v1/users/{id}/policies, /api/v1/groups/{id}/policies, IDE /validate/policy and
|
|
174
|
+
# /simulate/policy-impact/{datasourceKey}. ABAC runtime evaluation is unaffected.
|
|
175
|
+
# Set to true for local dev when iterating on policy CRUD APIs.
|
|
176
|
+
# Policy Library management HTTP APIs (default false → routes not registered, 404).
|
|
177
|
+
# Set true for local dev policy CRUD; pair with VITE_POLICY_MANAGEMENT_ENABLED=true in app-ui.
|
|
178
|
+
POLICY_MANAGEMENT_API_ENABLED=false
|
|
179
|
+
|
|
168
180
|
# =============================================================================
|
|
169
181
|
# OBSERVABILITY CONFIGURATION
|
|
170
182
|
# =============================================================================
|
|
@@ -280,6 +280,10 @@ permissions:
|
|
|
280
280
|
- name: "record:search"
|
|
281
281
|
roles: ["aifabrix-platform-admin", "aifabrix-security-admin", "aifabrix-deployment-admin", "aifabrix-compliance-admin", "aifabrix-developer", "aifabrix-observer"]
|
|
282
282
|
description: "Search records"
|
|
283
|
+
|
|
284
|
+
- name: "governance:evaluate"
|
|
285
|
+
roles: ["aifabrix-platform-admin", "aifabrix-security-admin", "aifabrix-developer"]
|
|
286
|
+
description: "Run governance scenario acceptance (subject impersonation for ABAC proof)"
|
|
283
287
|
|
|
284
288
|
# IDE simulation operations
|
|
285
289
|
- name: "dataplane:abac-simulate"
|
|
@@ -23,6 +23,8 @@ port: 3000
|
|
|
23
23
|
frontDoorRouting:
|
|
24
24
|
pattern: /miso/*
|
|
25
25
|
enabled: true
|
|
26
|
+
# Docker url://internal full URLs: http://miso-controller:PORT only (ingress /miso is not on in-container routes).
|
|
27
|
+
internalDockerUseOriginOnly: false
|
|
26
28
|
host: ${DEV_USERNAME}.${REMOTE_HOST}
|
|
27
29
|
tls: ${TLS_ENABLED}
|
|
28
30
|
|