@aifabrix/builder 2.46.0 → 2.47.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/.npmrc.token +1 -0
- package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
- package/.temp/validation/summary.txt +5 -0
- package/jest.isolated-projects.js +18 -2
- package/jest.projects.js +24 -0
- package/lib/api/dataplane-health.api.js +19 -7
- package/lib/api/lifecycle.api.js +22 -1
- package/lib/api/resource-types.api.js +107 -0
- package/lib/api/runtime-configuration.api.js +72 -0
- package/lib/api/types/resource-types.types.js +45 -0
- package/lib/api/user-groups.api.js +9 -9
- package/lib/api/users.api.js +8 -8
- package/lib/api/wizard.api.js +10 -2
- package/lib/app/down.js +58 -26
- package/lib/app/index.js +2 -2
- package/lib/app/run-resolve-image.js +2 -1
- package/lib/app/run-stop-containers.js +113 -0
- package/lib/app/run.js +1 -31
- package/lib/app/show-display.js +35 -0
- package/lib/app/show.js +32 -1
- package/lib/build/index.js +17 -5
- package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
- package/lib/channels/add-channel.js +348 -0
- package/lib/channels/channel-artifact-generator.js +141 -0
- package/lib/channels/channel-audit.js +101 -0
- package/lib/channels/channel-auth-context.js +37 -0
- package/lib/channels/channel-credential.js +200 -0
- package/lib/channels/channel-display-name.js +64 -0
- package/lib/channels/channel-external-system.js +106 -0
- package/lib/channels/channel-integration-generator.js +274 -0
- package/lib/channels/channel-probe.js +89 -0
- package/lib/channels/channel-runtime-resolver.js +152 -0
- package/lib/channels/channel-status-display.js +141 -0
- package/lib/channels/channel-targets.js +115 -0
- package/lib/cli/index.js +18 -4
- package/lib/cli/infra-guided-auth.js +36 -12
- package/lib/cli/setup-app.js +54 -3
- package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
- package/lib/cli/setup-infra-up-platform-action.js +2 -1
- package/lib/cli/setup-npm.js +59 -0
- package/lib/cli/setup-platform.js +1 -1
- package/lib/cli/setup-secrets.js +1 -1
- package/lib/cli/setup-utility-help-after.js +4 -1
- package/lib/cli/setup-utility-resolve.js +8 -5
- package/lib/commands/app-logs.js +54 -26
- package/lib/commands/app.js +41 -0
- package/lib/commands/auth-status-dataplane-version.js +97 -61
- package/lib/commands/auth-status.js +2 -7
- package/lib/commands/channel.js +58 -0
- package/lib/commands/datasource.js +1 -1
- package/lib/commands/identity-apply-sync.js +49 -8
- package/lib/commands/identity-group-cli.js +66 -26
- package/lib/commands/identity-membership-role-cache.js +58 -37
- package/lib/commands/identity-shared.js +22 -1
- package/lib/commands/identity-user-cli.js +80 -34
- package/lib/commands/login-device.js +11 -3
- package/lib/commands/login.js +8 -3
- package/lib/commands/npm-config.js +103 -0
- package/lib/commands/repair-auth-apply.js +30 -4
- package/lib/commands/repair-auth-config.js +8 -13
- package/lib/commands/repair-datasource-com-v2.js +15 -0
- package/lib/commands/repair-datasource-service-contract.js +206 -0
- package/lib/commands/repair-datasource.js +53 -18
- package/lib/commands/repair-env-template.js +12 -12
- package/lib/commands/repair-openapi-sync.js +26 -4
- package/lib/commands/repair-steps.js +28 -13
- package/lib/commands/repair-system-alignment.js +7 -4
- package/lib/commands/resource-type.js +371 -0
- package/lib/commands/setup-modes.js +1 -1
- package/lib/commands/setup-prompts-platform-mode.js +24 -21
- package/lib/commands/test-trust-external.js +39 -90
- package/lib/commands/up-common.js +33 -1
- package/lib/commands/up-dataplane.js +8 -4
- package/lib/commands/upload.js +24 -3
- package/lib/commands/verify-trust-command-action.js +4 -1
- package/lib/commands/verify-trust-external.js +12 -20
- package/lib/core/config-setup-platform-mode.js +3 -3
- package/lib/core/setup-platform-mode.js +41 -6
- package/lib/datasource/capability/capability-diff-slice.js +2 -2
- package/lib/datasource/capability/capability-manifest.js +254 -0
- package/lib/datasource/capability/capability-resolve.js +3 -4
- package/lib/datasource/capability/copy-operations.js +5 -3
- package/lib/datasource/capability/remove-operations.js +2 -1
- package/lib/datasource/capability/run-capability-copy.js +32 -4
- package/lib/datasource/capability/run-capability-diff.js +3 -3
- package/lib/datasource/capability/run-capability-dimension.js +2 -4
- package/lib/datasource/capability/run-capability-edit.js +4 -7
- package/lib/datasource/capability/run-capability-relate.js +2 -4
- package/lib/datasource/capability/run-capability-remove.js +2 -4
- package/lib/datasource/capability/validate-capability-slice.js +2 -1
- package/lib/datasource/datasource-identifier.js +2 -1
- package/lib/datasource/datasource-validate-display.js +1 -1
- package/lib/datasource/field-reference-validator.js +24 -3
- package/lib/datasource/orphan-profiles-validator.js +98 -0
- package/lib/datasource/validate.js +41 -23
- package/lib/external-system/download-helpers.js +87 -0
- package/lib/external-system/download.js +61 -122
- package/lib/external-system/generator.js +1 -59
- package/lib/external-system/test.js +10 -15
- package/lib/generator/builders.js +11 -1
- package/lib/generator/external-controller-manifest.js +5 -2
- package/lib/generator/split.js +3 -1
- package/lib/generator/wizard.js +1 -28
- package/lib/identity/fk-reference.js +65 -0
- package/lib/identity/identity-apply-core.js +13 -58
- package/lib/identity/identity-apply-phases.js +5 -1
- package/lib/identity/identity-display.js +243 -0
- package/lib/identity/identity-response-helpers.js +52 -0
- package/lib/identity/identity-sync-errors.js +62 -0
- package/lib/identity/resolve-user-id.js +129 -0
- package/lib/identity/username-default.js +31 -0
- package/lib/lifecycle/certification-progress.js +2 -2
- package/lib/lifecycle/report-display-trust.js +70 -0
- package/lib/lifecycle/report-display.js +14 -13
- package/lib/resolvers/datasource-resolver.js +2 -3
- package/lib/resolvers/resource-type-file.js +159 -0
- package/lib/schema/application-schema.json +16 -0
- package/lib/schema/deployment-rules.yaml +2 -1
- package/lib/schema/external-datasource.schema.json +372 -58
- package/lib/schema/external-system.schema.json +331 -2
- package/lib/schema/type/document-storage.json +9 -5
- package/lib/utils/api.js +2 -1
- package/lib/utils/app-run-containers.js +25 -2
- package/lib/utils/authentication-shape.js +224 -0
- package/lib/utils/build-copy.js +36 -5
- package/lib/utils/build-resolve-image.js +66 -12
- package/lib/utils/celery-companion-apps.js +53 -0
- package/lib/utils/cli-utils.js +4 -0
- package/lib/utils/compose-celery-worker.js +23 -0
- package/lib/utils/compose-generate-docker-compose.js +9 -1
- package/lib/utils/configuration-env-resolver.js +36 -0
- package/lib/utils/controller-url.js +4 -1
- package/lib/utils/credential-secrets-env-kv.js +216 -0
- package/lib/utils/credential-secrets-env.js +52 -262
- package/lib/utils/dataplane-resolver.js +4 -115
- package/lib/utils/declarative-url-ports.js +24 -1
- package/lib/utils/dev-platform-tls.js +148 -0
- package/lib/utils/docker-build.js +1 -4
- package/lib/utils/external-env-template.js +10 -3
- package/lib/utils/external-system-validators.js +8 -2
- package/lib/utils/health-check-request.js +114 -0
- package/lib/utils/health-check-url.js +3 -1
- package/lib/utils/health-check.js +1 -113
- package/lib/utils/help-builder.js +3 -0
- package/lib/utils/keycloak-realm-ready.js +5 -1
- package/lib/utils/localhost-public-host.js +31 -0
- package/lib/utils/npm-user-config.js +145 -0
- package/lib/utils/paths.js +25 -0
- package/lib/utils/platform-controller-url.js +58 -4
- package/lib/utils/platform-kv-ref.js +57 -0
- package/lib/utils/runtime-configuration-download.js +189 -0
- package/lib/utils/runtime-configuration-values.js +119 -0
- package/lib/utils/schema-loader.js +19 -4
- package/lib/utils/url-declarative-public-base.js +33 -25
- package/lib/utils/worker-sidecars.js +142 -0
- package/lib/validation/external-manifest-validator.js +2 -0
- package/lib/validation/runtime-configuration-rules.js +98 -0
- package/lib/validation/validate-display-dimensions.js +154 -0
- package/lib/validation/validate-display-sections.js +276 -0
- package/lib/validation/validate-display-steps.js +67 -0
- package/lib/validation/validate-display.js +24 -402
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +5 -0
- package/templates/applications/dataplane/env.template +26 -13
- package/templates/applications/dataplane/rbac.yaml +108 -1
- package/templates/applications/miso-controller/application.yaml +2 -2
- package/templates/applications/miso-controller/env.template +37 -122
- package/templates/applications/miso-controller/rbac.yaml +28 -13
- package/templates/channels/chatgpt/install.template.md.hbs +49 -0
- package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
- package/templates/channels/slack/install.template.md.hbs +49 -0
- package/templates/channels/slack/manifest.template.json.hbs +66 -0
- package/templates/channels/teams-bot/install.template.md.hbs +49 -0
- package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
- package/templates/channels/web-embed/install.template.md.hbs +49 -0
- package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
- package/templates/python/docker-compose.hbs +56 -0
- package/templates/typescript/docker-compose.hbs +52 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Step-by-step validation display for external-system validate flow.
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const logger = require('../utils/logger');
|
|
11
|
+
const {
|
|
12
|
+
metadata,
|
|
13
|
+
formatBlockingError,
|
|
14
|
+
formatSuccessParagraph
|
|
15
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
16
|
+
const {
|
|
17
|
+
displayApplicationStep,
|
|
18
|
+
displayComponentsStep,
|
|
19
|
+
displayManifestStep,
|
|
20
|
+
displayRbacValidation,
|
|
21
|
+
displayAggregatedWarnings,
|
|
22
|
+
displayOverallStatus
|
|
23
|
+
} = require('./validate-display-sections');
|
|
24
|
+
const { displayDimensionsStep } = require('./validate-display-dimensions');
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Displays step-by-step validation results for external systems
|
|
28
|
+
* @function displayStepByStepValidation
|
|
29
|
+
* @param {Object} result - Validation result with steps
|
|
30
|
+
*/
|
|
31
|
+
function displayStepByStepValidation(result) {
|
|
32
|
+
if (result.valid) {
|
|
33
|
+
logger.log(formatSuccessParagraph('Validation passed!'));
|
|
34
|
+
} else {
|
|
35
|
+
logger.log(`\n${formatBlockingError('Validation failed!')}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
displayApplicationStep(result.steps.application);
|
|
39
|
+
|
|
40
|
+
if (!result.steps.components.valid || (result.steps.components.files && result.steps.components.files.length > 0)) {
|
|
41
|
+
displayComponentsStep(result.steps.components);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const datasourceFiles = result.steps.components.files?.filter(f =>
|
|
45
|
+
f.type === 'datasource' || f.type === 'external-datasource'
|
|
46
|
+
) || [];
|
|
47
|
+
displayDimensionsStep(datasourceFiles);
|
|
48
|
+
|
|
49
|
+
if (result.rbac) {
|
|
50
|
+
displayRbacValidation(result.rbac);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
displayManifestStep(result.steps.manifest, result.steps.components.files);
|
|
54
|
+
|
|
55
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
56
|
+
displayAggregatedWarnings(result.warnings);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
displayOverallStatus(result);
|
|
60
|
+
if (result.appPath) {
|
|
61
|
+
logger.log(`\n${metadata(path.resolve(result.appPath))}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = {
|
|
66
|
+
displayStepByStepValidation
|
|
67
|
+
};
|
|
@@ -1,389 +1,35 @@
|
|
|
1
|
-
const {
|
|
2
|
-
headerKeyValue,
|
|
3
|
-
metadata,
|
|
4
|
-
formatDatasourceListRow,
|
|
5
|
-
formatBlockingError,
|
|
6
|
-
formatSuccessLine,
|
|
7
|
-
formatSuccessParagraph,
|
|
8
|
-
successGlyph,
|
|
9
|
-
failureGlyph
|
|
10
|
-
} = require('../utils/cli-test-layout-chalk');
|
|
11
1
|
/**
|
|
12
2
|
* @fileoverview Validation display for `aifabrix validate` (tty-summary: cli-layout.mdc, layout.md).
|
|
13
3
|
* @author AI Fabrix Team
|
|
14
4
|
*/
|
|
15
5
|
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
16
8
|
const path = require('path');
|
|
17
9
|
const chalk = require('chalk');
|
|
18
10
|
const logger = require('../utils/logger');
|
|
19
|
-
const { loadConfigFile } = require('../utils/config-format');
|
|
20
|
-
const { flattenRootDimensionsForDisplay } = require('./dimension-display-helpers');
|
|
21
11
|
const {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
logger.log(` ${failureGlyph()} ${chalk.red('Application configuration has errors:')}`);
|
|
44
|
-
if (application.errors && application.errors.length > 0) {
|
|
45
|
-
application.errors.forEach(error => {
|
|
46
|
-
logErrorDetail(error);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (application.warnings && application.warnings.length > 0) {
|
|
51
|
-
application.warnings.forEach(warning => {
|
|
52
|
-
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Extracts dimensions from a datasource file for CLI display.
|
|
59
|
-
* Local bindings become `metadata.<field>`; FK bindings become `fk:<fk>→<dimension>...` plus optional `(actor: ...)`.
|
|
60
|
-
* @function extractDimensionsFromDatasource
|
|
61
|
-
* @param {string} filePath - Path to datasource file
|
|
62
|
-
* @returns {Object} Dimensions info { dimensions: Object, dimensionKeys: string[], hasDimensions: boolean }
|
|
63
|
-
*/
|
|
64
|
-
function extractDimensionsFromDatasource(filePath) {
|
|
65
|
-
try {
|
|
66
|
-
const parsed = loadConfigFile(filePath);
|
|
67
|
-
|
|
68
|
-
const rootFlat = flattenRootDimensionsForDisplay(parsed.dimensions);
|
|
69
|
-
const abacDimensions = parsed.abac?.dimensions || {};
|
|
70
|
-
const allDimensions = { ...rootFlat, ...abacDimensions };
|
|
71
|
-
const dimensionKeys = Object.keys(allDimensions);
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
dimensions: allDimensions,
|
|
75
|
-
dimensionKeys,
|
|
76
|
-
hasDimensions: dimensionKeys.length > 0
|
|
77
|
-
};
|
|
78
|
-
} catch {
|
|
79
|
-
return { dimensions: {}, dimensionKeys: [], hasDimensions: false };
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Displays external files validation results
|
|
85
|
-
* @function displayExternalFilesValidation
|
|
86
|
-
* @param {Array} externalFiles - External files validation results
|
|
87
|
-
*/
|
|
88
|
-
function displayExternalFilesValidation(externalFiles) {
|
|
89
|
-
if (!externalFiles || externalFiles.length === 0) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
logSectionTitle('External integration files');
|
|
94
|
-
externalFiles.forEach(file => {
|
|
95
|
-
if (file.valid) {
|
|
96
|
-
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
97
|
-
} else {
|
|
98
|
-
logger.log(formatDatasourceListRow('fail', file.file, file.type));
|
|
99
|
-
file.errors.forEach(error => {
|
|
100
|
-
logErrorDetail(error);
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
if (file.warnings && file.warnings.length > 0) {
|
|
104
|
-
file.warnings.forEach(warning => {
|
|
105
|
-
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Displays Dimensions (ABAC) validation results for datasources
|
|
113
|
-
* @function displayDimensionsValidation
|
|
114
|
-
* @param {Array} externalFiles - External files validation results
|
|
115
|
-
* @returns {Array} Warnings to add to aggregated warnings
|
|
116
|
-
*/
|
|
117
|
-
function displayDimensionsValidation(externalFiles) {
|
|
118
|
-
if (!externalFiles || externalFiles.length === 0) {
|
|
119
|
-
return [];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const datasourceFiles = externalFiles.filter(f =>
|
|
123
|
-
f.type === 'datasource' || f.type === 'external-datasource'
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
if (datasourceFiles.length === 0) {
|
|
127
|
-
return [];
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
logSectionTitle('Dimensions (ABAC)');
|
|
131
|
-
|
|
132
|
-
const warnings = [];
|
|
133
|
-
let anyDatasourceHasDimensions = false;
|
|
134
|
-
|
|
135
|
-
datasourceFiles.forEach(file => {
|
|
136
|
-
const dimensionsInfo = extractDimensionsFromDatasource(file.path);
|
|
137
|
-
|
|
138
|
-
if (dimensionsInfo.hasDimensions) {
|
|
139
|
-
anyDatasourceHasDimensions = true;
|
|
140
|
-
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
141
|
-
dimensionsInfo.dimensionKeys.forEach(key => {
|
|
142
|
-
const mapping = dimensionsInfo.dimensions[key];
|
|
143
|
-
logDimLine(`${key} → ${mapping}`);
|
|
144
|
-
});
|
|
145
|
-
} else {
|
|
146
|
-
logWarnRow(`${file.file} — no dimensions configured`);
|
|
147
|
-
warnings.push(`${file.file} - no dimensions configured, ABAC filtering disabled`);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
if (!anyDatasourceHasDimensions) {
|
|
152
|
-
logWarnRow('No dimensions configured — ABAC filtering disabled for all datasources');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return warnings;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Displays RBAC validation results
|
|
160
|
-
* @function displayRbacValidation
|
|
161
|
-
* @param {Object} rbac - RBAC validation result
|
|
162
|
-
*/
|
|
163
|
-
function displayRbacValidation(rbac) {
|
|
164
|
-
if (!rbac) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
logSectionTitle('RBAC configuration');
|
|
169
|
-
if (rbac.valid) {
|
|
170
|
-
logOkRowRest('RBAC configuration is valid');
|
|
171
|
-
} else {
|
|
172
|
-
logger.log(` ${failureGlyph()} ${chalk.red('RBAC configuration has errors:')}`);
|
|
173
|
-
rbac.errors.forEach(error => {
|
|
174
|
-
logErrorDetail(error);
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
if (rbac.warnings && rbac.warnings.length > 0) {
|
|
178
|
-
rbac.warnings.forEach(warning => {
|
|
179
|
-
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Displays file validation results (for direct file validation)
|
|
186
|
-
* @function displayFileValidation
|
|
187
|
-
* @param {Object} result - Validation result
|
|
188
|
-
*/
|
|
189
|
-
function displayFileValidation(result) {
|
|
190
|
-
if (!result.file) {
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
logSectionTitle('File');
|
|
195
|
-
logger.log(` ${headerKeyValue('Path:', result.file)}`);
|
|
196
|
-
logger.log(` ${headerKeyValue('Type:', String(result.type))}`);
|
|
197
|
-
if (result.valid) {
|
|
198
|
-
logOkRowRest('File is valid');
|
|
199
|
-
} else {
|
|
200
|
-
logger.log(` ${failureGlyph()} ${chalk.red('File has errors:')}`);
|
|
201
|
-
result.errors.forEach(error => {
|
|
202
|
-
logErrorDetail(error);
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
if (result.warnings && result.warnings.length > 0) {
|
|
206
|
-
result.warnings.forEach(warning => {
|
|
207
|
-
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Displays aggregated warnings
|
|
214
|
-
* @function displayAggregatedWarnings
|
|
215
|
-
* @param {Array} warnings - Array of warning messages
|
|
216
|
-
*/
|
|
217
|
-
function displayAggregatedWarnings(warnings) {
|
|
218
|
-
if (!warnings || warnings.length === 0) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
logSectionTitle('Warnings');
|
|
223
|
-
warnings.forEach(warning => {
|
|
224
|
-
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Displays application validation step
|
|
230
|
-
* @function displayApplicationStep
|
|
231
|
-
* @param {Object} application - Application validation result
|
|
232
|
-
* @returns {void}
|
|
233
|
-
*/
|
|
234
|
-
function displayApplicationStep(application) {
|
|
235
|
-
logSectionTitle('Application');
|
|
236
|
-
if (application.valid) {
|
|
237
|
-
logOkRowRest('Application configuration is valid');
|
|
238
|
-
} else {
|
|
239
|
-
logger.log(` ${failureGlyph()} ${chalk.red('Application configuration has errors:')}`);
|
|
240
|
-
application.errors.forEach(error => {
|
|
241
|
-
logErrorDetail(error);
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
if (application.warnings && application.warnings.length > 0) {
|
|
245
|
-
application.warnings.forEach(warning => {
|
|
246
|
-
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Displays external integration files step
|
|
253
|
-
* @function displayComponentsStep
|
|
254
|
-
* @param {Object} components - Components validation result
|
|
255
|
-
* @returns {void}
|
|
256
|
-
*/
|
|
257
|
-
function displayComponentsStep(components) {
|
|
258
|
-
const hasFiles = components.files && components.files.length > 0;
|
|
259
|
-
const hasErrors = components.errors && components.errors.length > 0;
|
|
260
|
-
if (!hasFiles && !hasErrors) {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
logSectionTitle('External integration files');
|
|
265
|
-
if (hasFiles) {
|
|
266
|
-
components.files.forEach(file => {
|
|
267
|
-
if (file.valid) {
|
|
268
|
-
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
269
|
-
} else {
|
|
270
|
-
logger.log(formatDatasourceListRow('fail', file.file, file.type));
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
if (hasErrors) {
|
|
275
|
-
components.errors.forEach(error => {
|
|
276
|
-
logger.log(formatBlockingError(error));
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Displays dimensions validation for datasources
|
|
283
|
-
* @function displayDimensionsStep
|
|
284
|
-
* @param {Array} datasourceFiles - Datasource files
|
|
285
|
-
* @returns {void}
|
|
286
|
-
*/
|
|
287
|
-
function displayDimensionsStep(datasourceFiles) {
|
|
288
|
-
if (datasourceFiles.length === 0) {
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
logSectionTitle('Dimensions (ABAC)');
|
|
293
|
-
datasourceFiles.forEach(file => {
|
|
294
|
-
try {
|
|
295
|
-
const dimensionsInfo = extractDimensionsFromDatasource(file.path || file.file);
|
|
296
|
-
if (dimensionsInfo.hasDimensions) {
|
|
297
|
-
logger.log(formatDatasourceListRow('ok', file.file, file.type));
|
|
298
|
-
dimensionsInfo.dimensionKeys.forEach(key => {
|
|
299
|
-
const mapping = dimensionsInfo.dimensions[key];
|
|
300
|
-
logDimLine(`${key} → ${mapping}`);
|
|
301
|
-
});
|
|
302
|
-
} else {
|
|
303
|
-
logWarnRow(`${file.file} — no dimensions configured`);
|
|
304
|
-
}
|
|
305
|
-
} catch {
|
|
306
|
-
// Skip if file path not available
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Displays deployment manifest step
|
|
313
|
-
* @function displayManifestStep
|
|
314
|
-
* @param {Object} manifest - Manifest validation result
|
|
315
|
-
* @param {Array} componentFiles - Component files
|
|
316
|
-
* @returns {void}
|
|
317
|
-
*/
|
|
318
|
-
function displayManifestStep(manifest, componentFiles) {
|
|
319
|
-
logSectionTitle('Deployment manifest');
|
|
320
|
-
if (manifest.skipped) {
|
|
321
|
-
logger.log(` ${chalk.gray('⏭')} ${chalk.white('Skipped (fix errors above first)')}`);
|
|
322
|
-
} else if (manifest.valid) {
|
|
323
|
-
logOkRowRest('Full deployment manifest is valid');
|
|
324
|
-
if (componentFiles) {
|
|
325
|
-
const datasourceFiles = componentFiles.filter(f => f.type === 'datasource' || f.type === 'external-datasource');
|
|
326
|
-
logger.log(` ${successGlyph()} ${chalk.white('System configuration valid')}`);
|
|
327
|
-
logger.log(` ${successGlyph()} ${chalk.white(`${datasourceFiles.length} datasource(s) valid`)}`);
|
|
328
|
-
logger.log(` ${successGlyph()} ${chalk.white('Schema validation passed')}`);
|
|
329
|
-
}
|
|
330
|
-
} else {
|
|
331
|
-
logger.log(` ${failureGlyph()} ${chalk.red('Full deployment manifest validation failed:')}`);
|
|
332
|
-
const errs = manifest.errors && manifest.errors.length > 0 ? manifest.errors : [];
|
|
333
|
-
if (errs.length > 0) {
|
|
334
|
-
errs.forEach(error => {
|
|
335
|
-
const msg = typeof error === 'string' ? error : String(error);
|
|
336
|
-
logErrorDetail(msg);
|
|
337
|
-
});
|
|
338
|
-
} else {
|
|
339
|
-
logErrorDetail('No error details available (check schema and manifest structure).');
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
if (manifest.warnings && manifest.warnings.length > 0) {
|
|
343
|
-
manifest.warnings.forEach(warning => {
|
|
344
|
-
logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Displays step-by-step validation results for external systems
|
|
351
|
-
* @function displayStepByStepValidation
|
|
352
|
-
* @param {Object} result - Validation result with steps
|
|
353
|
-
*/
|
|
354
|
-
function displayStepByStepValidation(result) {
|
|
355
|
-
if (result.valid) {
|
|
356
|
-
logger.log(formatSuccessParagraph('Validation passed!'));
|
|
357
|
-
} else {
|
|
358
|
-
logger.log(`\n${formatBlockingError('Validation failed!')}`);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
displayApplicationStep(result.steps.application);
|
|
362
|
-
|
|
363
|
-
if (!result.steps.components.valid || (result.steps.components.files && result.steps.components.files.length > 0)) {
|
|
364
|
-
displayComponentsStep(result.steps.components);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
const datasourceFiles = result.steps.components.files?.filter(f =>
|
|
368
|
-
f.type === 'datasource' || f.type === 'external-datasource'
|
|
369
|
-
) || [];
|
|
370
|
-
displayDimensionsStep(datasourceFiles);
|
|
371
|
-
|
|
372
|
-
if (result.rbac) {
|
|
373
|
-
displayRbacValidation(result.rbac);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
displayManifestStep(result.steps.manifest, result.steps.components.files);
|
|
377
|
-
|
|
378
|
-
if (result.warnings && result.warnings.length > 0) {
|
|
379
|
-
displayAggregatedWarnings(result.warnings);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
displayOverallStatus(result);
|
|
383
|
-
if (result.appPath) {
|
|
384
|
-
logger.log(`\n${metadata(path.resolve(result.appPath))}`);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
12
|
+
headerKeyValue,
|
|
13
|
+
metadata,
|
|
14
|
+
formatBlockingError,
|
|
15
|
+
formatSuccessLine,
|
|
16
|
+
formatSuccessParagraph,
|
|
17
|
+
failureGlyph
|
|
18
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
19
|
+
const { logSectionTitle } = require('./validate-display-log-helpers');
|
|
20
|
+
const {
|
|
21
|
+
displayApplicationValidation,
|
|
22
|
+
displayExternalFilesValidation,
|
|
23
|
+
displayRbacValidation,
|
|
24
|
+
displayFileValidation,
|
|
25
|
+
displayAggregatedWarnings,
|
|
26
|
+
displayOverallStatus
|
|
27
|
+
} = require('./validate-display-sections');
|
|
28
|
+
const {
|
|
29
|
+
displayDimensionsValidation,
|
|
30
|
+
extractDimensionsFromDatasource
|
|
31
|
+
} = require('./validate-display-dimensions');
|
|
32
|
+
const { displayStepByStepValidation } = require('./validate-display-steps');
|
|
387
33
|
|
|
388
34
|
/**
|
|
389
35
|
* Displays batch validation results (per-app blocks then summary).
|
|
@@ -418,31 +64,6 @@ function displayBatchValidationResults(batchResult) {
|
|
|
418
64
|
}
|
|
419
65
|
}
|
|
420
66
|
|
|
421
|
-
/**
|
|
422
|
-
* Displays overall validation status
|
|
423
|
-
* @param {Object} result - Validation result
|
|
424
|
-
*/
|
|
425
|
-
function displayOverallStatus(result) {
|
|
426
|
-
let hasErrors = result.errors && result.errors.length > 0;
|
|
427
|
-
if (!hasErrors && result.steps) {
|
|
428
|
-
const stepErrors = [result.steps.application, result.steps.components, result.steps.manifest]
|
|
429
|
-
.filter(Boolean)
|
|
430
|
-
.some(s => s.errors && s.errors.length > 0);
|
|
431
|
-
if (stepErrors) {
|
|
432
|
-
hasErrors = true;
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
const hasWarnings = result.warnings && result.warnings.length > 0;
|
|
436
|
-
logger.log('');
|
|
437
|
-
if (hasErrors) {
|
|
438
|
-
logger.log(headerKeyValue('Overall:', chalk.red('Failed')));
|
|
439
|
-
} else if (hasWarnings) {
|
|
440
|
-
logger.log(headerKeyValue('Overall:', chalk.yellow('Passed with warnings')));
|
|
441
|
-
} else {
|
|
442
|
-
logger.log(headerKeyValue('Overall:', chalk.green('Passed')));
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
67
|
/**
|
|
447
68
|
* Displays validation results in a user-friendly format
|
|
448
69
|
*
|
|
@@ -481,6 +102,7 @@ function displayValidationResults(result) {
|
|
|
481
102
|
logger.log(`\n${metadata(path.resolve(result.appPath))}`);
|
|
482
103
|
}
|
|
483
104
|
}
|
|
105
|
+
|
|
484
106
|
module.exports = {
|
|
485
107
|
displayValidationResults,
|
|
486
108
|
displayBatchValidationResults,
|
package/package.json
CHANGED
|
@@ -68,6 +68,11 @@ build:
|
|
|
68
68
|
reloadStart: WATCHFILES_FORCE_POLLING=1 uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3001} --reload --reload-dir /app/app
|
|
69
69
|
# Pulled-image local compose (no bind-mount): drives `command` in generated docker-compose. Override for non-standard images (e.g. stub ACR tags).
|
|
70
70
|
imageRun: exec python -m uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3001}
|
|
71
|
+
# Image policy (442.0): explicit Dockerfile COPY; worker/beat via python -m app.core.*
|
|
72
|
+
# integration/ in image: <systemKey>-deploy.json + application.json|yaml only (no test-*, wizard-configs).
|
|
73
|
+
worker: true
|
|
74
|
+
imageRunWorker: exec python -m app.core.celery_worker_main
|
|
75
|
+
imageRunBeat: exec python -m app.core.celery_beat_main
|
|
71
76
|
|
|
72
77
|
# =============================================================================
|
|
73
78
|
# Portal Input Configuration (Deployment Wizard)
|
|
@@ -20,12 +20,21 @@ LOG_FORMAT=json
|
|
|
20
20
|
# Docker default (no volume): use LOG_FILE_PATH=/app/logs/app.log (directory created in image).
|
|
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
|
-
# If true, run without Redis/Celery (single process)
|
|
23
|
+
# If true, run without Redis/Celery (single process). Set false on API/worker/beat in production.
|
|
24
24
|
LOCAL_MODE=true
|
|
25
25
|
|
|
26
|
+
# Celery worker process tuning (dataplane-worker container; optional overrides)
|
|
27
|
+
# CELERY_WORKER_QUEUES=external_data,document_sync,document_processing,audit
|
|
28
|
+
# CELERY_WORKER_CONCURRENCY=2
|
|
29
|
+
# CELERY_LOG_LEVEL=info
|
|
30
|
+
|
|
26
31
|
# When API_KEY is set, a matching Bearer token bypasses OAuth2 validation
|
|
27
32
|
# Same kv:// as miso-controller API_KEY so pipeline Bearer bypass uses one secrets.local entry
|
|
28
33
|
API_KEY=kv://miso-controller-secrets-apiKeyVault
|
|
34
|
+
# Comma-separated realm roles attached to API_KEY bypass (JWT realm_access.roles). Default: operator.
|
|
35
|
+
# Add integration RBAC role keys from published manifests when manual tests need selector/MCP access, e.g.:
|
|
36
|
+
# API_KEY_BYPASS_ROLES=operator,<role-from-manifest-rbac>
|
|
37
|
+
# API_KEY_BYPASS_ROLES=operator
|
|
29
38
|
|
|
30
39
|
# API Configuration
|
|
31
40
|
API_V1_STR=/api/v1
|
|
@@ -108,6 +117,7 @@ ABAC_POLICY_PARSE_CACHE_MAX_ENTRIES=2048
|
|
|
108
117
|
# =============================================================================
|
|
109
118
|
|
|
110
119
|
# MISO Application Client Credentials (per application)
|
|
120
|
+
# Backend-only: never expose MISO_CLIENTSECRET to the Vite frontend (use VITE_* in app-ui).
|
|
111
121
|
MISO_CLIENTID=kv://dataplane-client-idKeyVault
|
|
112
122
|
MISO_CLIENTSECRET=kv://dataplane-client-secretKeyVault
|
|
113
123
|
|
|
@@ -125,24 +135,17 @@ KEYCLOAK_REALM=aifabrix
|
|
|
125
135
|
MISO_WEB_SERVER_URL=url://miso-controller-public
|
|
126
136
|
# Internal: server-to-controller API calls (Docker: service:port; local: host:port — no front-door path).
|
|
127
137
|
MISO_CONTROLLER_URL=url://miso-controller-internal
|
|
138
|
+
# Browser logout page on miso-controller (path relative to MISO_WEB_SERVER_URL; not dataplane /login).
|
|
139
|
+
MISO_LOGOUT_URL=/logout
|
|
128
140
|
|
|
129
141
|
# Environment key sent to miso-controller (e.g. environmentKey on RBAC/register) when not supplied in the payload.
|
|
130
142
|
# Set MISO_PIPELINE_ENV_KEY=dev when the controller installation uses dev (e.g. MISO_CLIENTID=miso-controller-dev-dataplane).
|
|
131
143
|
# If unset, derived from MISO_CLIENTID (e.g. dev from miso-controller-dev-dataplane).
|
|
132
144
|
MISO_PIPELINE_ENV_KEY=
|
|
133
145
|
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
# OpenAI Configuration
|
|
139
|
-
OPENAI_API_KEY=kv://secrets-openaiApiKeyVault
|
|
140
|
-
|
|
141
|
-
# Azure OpenAI Configuration
|
|
142
|
-
AZURE_OPENAI_ENDPOINT=kv://azure-openaiapi-urlKeyVault
|
|
143
|
-
AZURE_OPENAI_API_KEY=kv://secrets-azureOpenaiApiKeyVault
|
|
144
|
-
AZURE_OPENAI_API_VERSION=2024-02-15-preview
|
|
145
|
-
AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o
|
|
146
|
+
# LLM: chat/embed route through governed enterprise-llm only. Provider credentials
|
|
147
|
+
# live on LLM provider external systems (integration/openai, azure-openai, ollama).
|
|
148
|
+
AI_VALIDATION_LLM_MODEL=gpt-4o-mini
|
|
146
149
|
|
|
147
150
|
# =============================================================================
|
|
148
151
|
# AUDIT CONFIGURATION
|
|
@@ -179,6 +182,11 @@ AUDIT_ASYNC_SHADOW_ENQUEUE=false
|
|
|
179
182
|
# Set true for local dev policy CRUD; pair with VITE_POLICY_MANAGEMENT_ENABLED=true in app-ui.
|
|
180
183
|
POLICY_MANAGEMENT_API_ENABLED=false
|
|
181
184
|
|
|
185
|
+
# Developer Access tab help links (optional; empty hides banner links in UI).
|
|
186
|
+
# VITE_DEVELOPER_GUIDE_URL=
|
|
187
|
+
# VITE_API_EXAMPLES_URL=
|
|
188
|
+
# VITE_MCP_INTEGRATION_GUIDE_URL=
|
|
189
|
+
|
|
182
190
|
# First-party HTTP internal SpecFile (398.2 / plan 397). When true, lifespan upserts
|
|
183
191
|
# internal:dataplane-first-party-http from the live COM-merged OpenAPI schema.
|
|
184
192
|
FIRST_PARTY_HTTP_INTERNAL_SPEC_SYNC_ON_STARTUP=false
|
|
@@ -199,6 +207,11 @@ OPENTELEMETRY_ENDPOINT=
|
|
|
199
207
|
# INTEGRATION CERTIFICATE SIGNING (RS256 PEM)
|
|
200
208
|
# =============================================================================
|
|
201
209
|
# Read by PemRsaCertificateSigner.from_environment in app/validation/certificates/signer.py.
|
|
210
|
+
# Workforce execute signing (437.4). Falls back to CERTIFICATE_* keys, then ephemeral dev RSA.
|
|
211
|
+
DATAPLANE_PRIVATE_KEY=
|
|
212
|
+
DATAPLANE_PUBLIC_KEY=
|
|
213
|
+
DATAPLANE_PUBLIC_KEY_ID=
|
|
214
|
+
|
|
202
215
|
# When CERTIFICATE_PRIVATE_KEY and CERTIFICATE_PUBLIC_KEY are both set (non-empty PEM), the
|
|
203
216
|
# engine uses RS256. When unset and LOCAL_MODE=true, a process-local ephemeral RSA keypair is used
|
|
204
217
|
# (still RS256, with publicKey + publicKeyFingerprint on issued certs). Non-local requires PEM keys.
|