kustodian 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +346 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +67 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/command.d.ts +57 -0
- package/dist/cli/command.d.ts.map +1 -0
- package/dist/cli/command.js +26 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/commands/apply.d.ts +8 -0
- package/dist/cli/commands/apply.d.ts.map +1 -0
- package/dist/cli/commands/apply.js +802 -0
- package/dist/cli/commands/apply.js.map +1 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +403 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/sources.d.ts +5 -0
- package/dist/cli/commands/sources.d.ts.map +1 -0
- package/dist/cli/commands/sources.js +377 -0
- package/dist/cli/commands/sources.js.map +1 -0
- package/dist/cli/commands/update.d.ts +5 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +314 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +5 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +126 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/container.d.ts +48 -0
- package/dist/cli/container.d.ts.map +1 -0
- package/dist/cli/container.js +49 -0
- package/dist/cli/container.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +9 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/middleware.d.ts +118 -0
- package/dist/cli/middleware.d.ts.map +1 -0
- package/dist/cli/middleware.js +280 -0
- package/dist/cli/middleware.js.map +1 -0
- package/dist/cli/runner.d.ts +34 -0
- package/dist/cli/runner.d.ts.map +1 -0
- package/dist/cli/runner.js +156 -0
- package/dist/cli/runner.js.map +1 -0
- package/dist/cli/utils/defaults.d.ts +23 -0
- package/dist/cli/utils/defaults.d.ts.map +1 -0
- package/dist/cli/utils/defaults.js +43 -0
- package/dist/cli/utils/defaults.js.map +1 -0
- package/dist/core/error.d.ts +117 -0
- package/dist/core/error.d.ts.map +1 -0
- package/dist/core/error.js +210 -0
- package/dist/core/error.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +31 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +78 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/path.d.ts +57 -0
- package/dist/core/path.d.ts.map +1 -0
- package/dist/core/path.js +154 -0
- package/dist/core/path.js.map +1 -0
- package/dist/core/result.d.ts +80 -0
- package/dist/core/result.d.ts.map +1 -0
- package/dist/core/result.js +150 -0
- package/dist/core/result.js.map +1 -0
- package/dist/core/types.d.ts +80 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/generator/external-substitutions.d.ts +21 -0
- package/dist/generator/external-substitutions.d.ts.map +1 -0
- package/dist/generator/external-substitutions.js +49 -0
- package/dist/generator/external-substitutions.js.map +1 -0
- package/dist/generator/flux.d.ts +61 -0
- package/dist/generator/flux.d.ts.map +1 -0
- package/dist/generator/flux.js +294 -0
- package/dist/generator/flux.js.map +1 -0
- package/dist/generator/generator.d.ts +77 -0
- package/dist/generator/generator.d.ts.map +1 -0
- package/dist/generator/generator.js +183 -0
- package/dist/generator/generator.js.map +1 -0
- package/dist/generator/index.d.ts +9 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +9 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/kustomization-resolution.d.ts +40 -0
- package/dist/generator/kustomization-resolution.d.ts.map +1 -0
- package/dist/generator/kustomization-resolution.js +59 -0
- package/dist/generator/kustomization-resolution.js.map +1 -0
- package/dist/generator/namespace.d.ts +74 -0
- package/dist/generator/namespace.d.ts.map +1 -0
- package/dist/generator/namespace.js +109 -0
- package/dist/generator/namespace.js.map +1 -0
- package/dist/generator/output.d.ts +56 -0
- package/dist/generator/output.d.ts.map +1 -0
- package/dist/generator/output.js +171 -0
- package/dist/generator/output.js.map +1 -0
- package/dist/generator/preservation.d.ts +45 -0
- package/dist/generator/preservation.d.ts.map +1 -0
- package/dist/generator/preservation.js +71 -0
- package/dist/generator/preservation.js.map +1 -0
- package/dist/generator/substitution.d.ts +79 -0
- package/dist/generator/substitution.d.ts.map +1 -0
- package/dist/generator/substitution.js +210 -0
- package/dist/generator/substitution.js.map +1 -0
- package/dist/generator/types.d.ts +162 -0
- package/dist/generator/types.d.ts.map +1 -0
- package/dist/generator/types.js +2 -0
- package/dist/generator/types.js.map +1 -0
- package/dist/generator/validation/cycle-detection.d.ts +25 -0
- package/dist/generator/validation/cycle-detection.d.ts.map +1 -0
- package/dist/generator/validation/cycle-detection.js +101 -0
- package/dist/generator/validation/cycle-detection.js.map +1 -0
- package/dist/generator/validation/enablement.d.ts +24 -0
- package/dist/generator/validation/enablement.d.ts.map +1 -0
- package/dist/generator/validation/enablement.js +69 -0
- package/dist/generator/validation/enablement.js.map +1 -0
- package/dist/generator/validation/graph.d.ts +29 -0
- package/dist/generator/validation/graph.d.ts.map +1 -0
- package/dist/generator/validation/graph.js +106 -0
- package/dist/generator/validation/graph.js.map +1 -0
- package/dist/generator/validation/index.d.ts +38 -0
- package/dist/generator/validation/index.d.ts.map +1 -0
- package/dist/generator/validation/index.js +64 -0
- package/dist/generator/validation/index.js.map +1 -0
- package/dist/generator/validation/reference.d.ts +45 -0
- package/dist/generator/validation/reference.d.ts.map +1 -0
- package/dist/generator/validation/reference.js +143 -0
- package/dist/generator/validation/reference.js.map +1 -0
- package/dist/generator/validation/requirements.d.ts +25 -0
- package/dist/generator/validation/requirements.d.ts.map +1 -0
- package/dist/generator/validation/requirements.js +64 -0
- package/dist/generator/validation/requirements.js.map +1 -0
- package/dist/generator/validation/types.d.ts +116 -0
- package/dist/generator/validation/types.d.ts.map +1 -0
- package/dist/generator/validation/types.js +13 -0
- package/dist/generator/validation/types.js.map +1 -0
- package/dist/k8s/exec.d.ts +20 -0
- package/dist/k8s/exec.d.ts.map +1 -0
- package/dist/k8s/exec.js +47 -0
- package/dist/k8s/exec.js.map +1 -0
- package/dist/k8s/flux.d.ts +57 -0
- package/dist/k8s/flux.d.ts.map +1 -0
- package/dist/k8s/flux.js +202 -0
- package/dist/k8s/flux.js.map +1 -0
- package/dist/k8s/index.d.ts +6 -0
- package/dist/k8s/index.d.ts.map +1 -0
- package/dist/k8s/index.js +6 -0
- package/dist/k8s/index.js.map +1 -0
- package/dist/k8s/kubeconfig.d.ts +45 -0
- package/dist/k8s/kubeconfig.d.ts.map +1 -0
- package/dist/k8s/kubeconfig.js +152 -0
- package/dist/k8s/kubeconfig.js.map +1 -0
- package/dist/k8s/kubectl.d.ts +68 -0
- package/dist/k8s/kubectl.d.ts.map +1 -0
- package/dist/k8s/kubectl.js +187 -0
- package/dist/k8s/kubectl.js.map +1 -0
- package/dist/k8s/types.d.ts +65 -0
- package/dist/k8s/types.d.ts.map +1 -0
- package/dist/k8s/types.js +2 -0
- package/dist/k8s/types.js.map +1 -0
- package/dist/loader/file.d.ts +39 -0
- package/dist/loader/file.d.ts.map +1 -0
- package/dist/loader/file.js +121 -0
- package/dist/loader/file.js.map +1 -0
- package/dist/loader/index.d.ts +5 -0
- package/dist/loader/index.d.ts.map +1 -0
- package/dist/loader/index.js +5 -0
- package/dist/loader/index.js.map +1 -0
- package/dist/loader/profile.d.ts +23 -0
- package/dist/loader/profile.d.ts.map +1 -0
- package/dist/loader/profile.js +84 -0
- package/dist/loader/profile.js.map +1 -0
- package/dist/loader/project.d.ts +76 -0
- package/dist/loader/project.d.ts.map +1 -0
- package/dist/loader/project.js +279 -0
- package/dist/loader/project.js.map +1 -0
- package/dist/loader/yaml.d.ts +15 -0
- package/dist/loader/yaml.d.ts.map +1 -0
- package/dist/loader/yaml.js +44 -0
- package/dist/loader/yaml.js.map +1 -0
- package/dist/nodes/index.d.ts +5 -0
- package/dist/nodes/index.d.ts.map +1 -0
- package/dist/nodes/index.js +5 -0
- package/dist/nodes/index.js.map +1 -0
- package/dist/nodes/kubectl-labeler.d.ts +7 -0
- package/dist/nodes/kubectl-labeler.d.ts.map +1 -0
- package/dist/nodes/kubectl-labeler.js +89 -0
- package/dist/nodes/kubectl-labeler.js.map +1 -0
- package/dist/nodes/labeler.d.ts +74 -0
- package/dist/nodes/labeler.d.ts.map +1 -0
- package/dist/nodes/labeler.js +118 -0
- package/dist/nodes/labeler.js.map +1 -0
- package/dist/nodes/profile.d.ts +58 -0
- package/dist/nodes/profile.d.ts.map +1 -0
- package/dist/nodes/profile.js +128 -0
- package/dist/nodes/profile.js.map +1 -0
- package/dist/nodes/types.d.ts +84 -0
- package/dist/nodes/types.d.ts.map +1 -0
- package/dist/nodes/types.js +77 -0
- package/dist/nodes/types.js.map +1 -0
- package/dist/plugins/generators.d.ts +49 -0
- package/dist/plugins/generators.d.ts.map +1 -0
- package/dist/plugins/generators.js +7 -0
- package/dist/plugins/generators.js.map +1 -0
- package/dist/plugins/hooks.d.ts +120 -0
- package/dist/plugins/hooks.d.ts.map +1 -0
- package/dist/plugins/hooks.js +41 -0
- package/dist/plugins/hooks.js.map +1 -0
- package/dist/plugins/index.d.ts +8 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +15 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/loader.d.ts +40 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +236 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/object-types.d.ts +71 -0
- package/dist/plugins/object-types.d.ts.map +1 -0
- package/dist/plugins/object-types.js +65 -0
- package/dist/plugins/object-types.js.map +1 -0
- package/dist/plugins/registry.d.ts +87 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +158 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/substitution-providers.d.ts +48 -0
- package/dist/plugins/substitution-providers.d.ts.map +1 -0
- package/dist/plugins/substitution-providers.js +2 -0
- package/dist/plugins/substitution-providers.js.map +1 -0
- package/dist/plugins/types.d.ts +288 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +25 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/registry/auth.d.ts +14 -0
- package/dist/registry/auth.d.ts.map +1 -0
- package/dist/registry/auth.js +40 -0
- package/dist/registry/auth.js.map +1 -0
- package/dist/registry/client.d.ts +24 -0
- package/dist/registry/client.d.ts.map +1 -0
- package/dist/registry/client.js +85 -0
- package/dist/registry/client.js.map +1 -0
- package/dist/registry/dockerhub.d.ts +6 -0
- package/dist/registry/dockerhub.d.ts.map +1 -0
- package/dist/registry/dockerhub.js +91 -0
- package/dist/registry/dockerhub.js.map +1 -0
- package/dist/registry/ghcr.d.ts +6 -0
- package/dist/registry/ghcr.d.ts.map +1 -0
- package/dist/registry/ghcr.js +95 -0
- package/dist/registry/ghcr.js.map +1 -0
- package/dist/registry/helm.d.ts +11 -0
- package/dist/registry/helm.d.ts.map +1 -0
- package/dist/registry/helm.js +124 -0
- package/dist/registry/helm.js.map +1 -0
- package/dist/registry/index.d.ts +8 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +12 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/types.d.ts +55 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +2 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/registry/version.d.ts +22 -0
- package/dist/registry/version.d.ts.map +1 -0
- package/dist/registry/version.js +62 -0
- package/dist/registry/version.js.map +1 -0
- package/dist/schema/cluster.d.ts +2890 -0
- package/dist/schema/cluster.d.ts.map +1 -0
- package/dist/schema/cluster.js +231 -0
- package/dist/schema/cluster.js.map +1 -0
- package/dist/schema/common.d.ts +1059 -0
- package/dist/schema/common.d.ts.map +1 -0
- package/dist/schema/common.js +340 -0
- package/dist/schema/common.js.map +1 -0
- package/dist/schema/index.d.ts +8 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +8 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/node-list.d.ts +361 -0
- package/dist/schema/node-list.d.ts.map +1 -0
- package/dist/schema/node-list.js +104 -0
- package/dist/schema/node-list.js.map +1 -0
- package/dist/schema/profile.d.ts +166 -0
- package/dist/schema/profile.d.ts.map +1 -0
- package/dist/schema/profile.js +61 -0
- package/dist/schema/profile.js.map +1 -0
- package/dist/schema/project.d.ts +168 -0
- package/dist/schema/project.d.ts.map +1 -0
- package/dist/schema/project.js +40 -0
- package/dist/schema/project.js.map +1 -0
- package/dist/schema/sources.d.ts +338 -0
- package/dist/schema/sources.d.ts.map +1 -0
- package/dist/schema/sources.js +111 -0
- package/dist/schema/sources.js.map +1 -0
- package/dist/schema/template.d.ts +2711 -0
- package/dist/schema/template.d.ts.map +1 -0
- package/dist/schema/template.js +97 -0
- package/dist/schema/template.js.map +1 -0
- package/dist/sources/cache/index.d.ts +9 -0
- package/dist/sources/cache/index.d.ts.map +1 -0
- package/dist/sources/cache/index.js +278 -0
- package/dist/sources/cache/index.js.map +1 -0
- package/dist/sources/cache/metadata.d.ts +36 -0
- package/dist/sources/cache/metadata.d.ts.map +1 -0
- package/dist/sources/cache/metadata.js +21 -0
- package/dist/sources/cache/metadata.js.map +1 -0
- package/dist/sources/cache/ttl.d.ts +20 -0
- package/dist/sources/cache/ttl.d.ts.map +1 -0
- package/dist/sources/cache/ttl.js +53 -0
- package/dist/sources/cache/ttl.js.map +1 -0
- package/dist/sources/fetchers/git.d.ts +6 -0
- package/dist/sources/fetchers/git.d.ts.map +1 -0
- package/dist/sources/fetchers/git.js +165 -0
- package/dist/sources/fetchers/git.js.map +1 -0
- package/dist/sources/fetchers/http.d.ts +6 -0
- package/dist/sources/fetchers/http.d.ts.map +1 -0
- package/dist/sources/fetchers/http.js +159 -0
- package/dist/sources/fetchers/http.js.map +1 -0
- package/dist/sources/fetchers/index.d.ts +11 -0
- package/dist/sources/fetchers/index.d.ts.map +1 -0
- package/dist/sources/fetchers/index.js +24 -0
- package/dist/sources/fetchers/index.js.map +1 -0
- package/dist/sources/fetchers/oci.d.ts +6 -0
- package/dist/sources/fetchers/oci.d.ts.map +1 -0
- package/dist/sources/fetchers/oci.js +156 -0
- package/dist/sources/fetchers/oci.js.map +1 -0
- package/dist/sources/fetchers/types.d.ts +25 -0
- package/dist/sources/fetchers/types.d.ts.map +1 -0
- package/dist/sources/fetchers/types.js +2 -0
- package/dist/sources/fetchers/types.js.map +1 -0
- package/dist/sources/index.d.ts +6 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +10 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/loader.d.ts +34 -0
- package/dist/sources/loader.d.ts.map +1 -0
- package/dist/sources/loader.js +89 -0
- package/dist/sources/loader.js.map +1 -0
- package/dist/sources/resolver.d.ts +17 -0
- package/dist/sources/resolver.d.ts.map +1 -0
- package/dist/sources/resolver.js +125 -0
- package/dist/sources/resolver.js.map +1 -0
- package/dist/sources/types.d.ts +151 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +2 -0
- package/dist/sources/types.js.map +1 -0
- package/package.json +101 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { KustodianErrorType, ResultType } from '../core/index.js';
|
|
2
|
+
import type { PluginRegistryType } from '../plugins/index.js';
|
|
3
|
+
import type { ClusterType, KustomizationType, SubstitutionType, TemplateType } from '../schema/index.js';
|
|
4
|
+
import type { ResolvedTemplateType } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Pattern for matching substitution variables: ${variable_name}
|
|
7
|
+
*/
|
|
8
|
+
export declare const SUBSTITUTION_PATTERN: RegExp;
|
|
9
|
+
/**
|
|
10
|
+
* Result of validating substitution values.
|
|
11
|
+
*/
|
|
12
|
+
export interface SubstitutionValidationResultType {
|
|
13
|
+
valid: boolean;
|
|
14
|
+
missing: string[];
|
|
15
|
+
unused: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Extracts variable names from a string containing ${var} patterns.
|
|
19
|
+
*/
|
|
20
|
+
export declare function extract_variables(text: string): string[];
|
|
21
|
+
/**
|
|
22
|
+
* Applies substitution values to a string containing ${var} patterns.
|
|
23
|
+
*/
|
|
24
|
+
export declare function substitute_string(text: string, values: Record<string, string>): string;
|
|
25
|
+
/**
|
|
26
|
+
* Applies substitution values to an object recursively.
|
|
27
|
+
* Only processes string values within the object.
|
|
28
|
+
*/
|
|
29
|
+
export declare function substitute_object<T>(obj: T, values: Record<string, string>): T;
|
|
30
|
+
/**
|
|
31
|
+
* Collects substitution values from a kustomization definition and cluster values.
|
|
32
|
+
* Returns a record of variable name to value.
|
|
33
|
+
*/
|
|
34
|
+
export declare function collect_substitution_values(kustomization: KustomizationType, cluster_values?: Record<string, string>): Record<string, string>;
|
|
35
|
+
/**
|
|
36
|
+
* Collects template-level version entries as substitution values.
|
|
37
|
+
* These are shared across all kustomizations in the template.
|
|
38
|
+
*/
|
|
39
|
+
export declare function collect_template_versions(template: TemplateType, cluster_values?: Record<string, string>): Record<string, string>;
|
|
40
|
+
/**
|
|
41
|
+
* Collects all substitution values from template versions and kustomization substitutions.
|
|
42
|
+
* Precedence: template versions < kustomization substitutions < cluster values
|
|
43
|
+
*/
|
|
44
|
+
export declare function collect_all_substitution_values(template: TemplateType, kustomization: KustomizationType, cluster_values?: Record<string, string>): Record<string, string>;
|
|
45
|
+
/**
|
|
46
|
+
* Gets all defined substitution names from a kustomization.
|
|
47
|
+
*/
|
|
48
|
+
export declare function get_defined_substitutions(kustomization: KustomizationType): string[];
|
|
49
|
+
/**
|
|
50
|
+
* Gets all required substitution names (those without defaults) from a kustomization.
|
|
51
|
+
*/
|
|
52
|
+
export declare function get_required_substitutions(kustomization: KustomizationType): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Validates that all required substitutions have values.
|
|
55
|
+
*/
|
|
56
|
+
export declare function validate_substitutions(kustomization: KustomizationType, cluster_values?: Record<string, string>): SubstitutionValidationResultType;
|
|
57
|
+
/**
|
|
58
|
+
* Generates the postBuild.substitute object for a Flux Kustomization.
|
|
59
|
+
* Only includes values that have actual values (not undefined).
|
|
60
|
+
*/
|
|
61
|
+
export declare function generate_flux_substitutions(values: Record<string, string>): Record<string, string> | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Extracts all substitutions from resolved templates.
|
|
64
|
+
* Returns a flat list of all substitution objects from all kustomizations.
|
|
65
|
+
*/
|
|
66
|
+
export declare function extract_all_substitutions(templates: ResolvedTemplateType[]): SubstitutionType[];
|
|
67
|
+
/**
|
|
68
|
+
* Resolves external substitutions using registered providers.
|
|
69
|
+
* Only resolves plugin-provided substitution types (e.g., 'sops', 'vault').
|
|
70
|
+
* Core types (version, helm, namespace, generic) are handled elsewhere.
|
|
71
|
+
* Legacy types (doppler, 1password) are handled by their respective plugins.
|
|
72
|
+
*
|
|
73
|
+
* @param templates - All resolved templates
|
|
74
|
+
* @param cluster - Cluster configuration
|
|
75
|
+
* @param registry - Plugin registry with registered substitution providers
|
|
76
|
+
* @returns Result containing a map of substitution names to their resolved values
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolve_external_substitutions(templates: ResolvedTemplateType[], cluster: ClusterType, registry: PluginRegistryType): Promise<ResultType<Record<string, string>, KustodianErrorType>>;
|
|
79
|
+
//# sourceMappingURL=substitution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"substitution.d.ts","sourceRoot":"","sources":["../../src/generator/substitution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACb,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAoC,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAUxD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAItF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAkB9E;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,iBAAiB,EAChC,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYxB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,YAAY,EACtB,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYxB;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,YAAY,EACtB,aAAa,EAAE,iBAAiB,EAChC,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYxB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,aAAa,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAEpF;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAIrF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,iBAAiB,EAChC,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC1C,gCAAgC,CAgBlC;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAQpC;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,oBAAoB,EAAE,GAAG,gBAAgB,EAAE,CAgB/F;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,oBAAoB,EAAE,EACjC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,CA0DjE"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { Errors, failure, is_success, success } from '../core/index.js';
|
|
2
|
+
import { is_plugin_substitution } from '../schema/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Pattern for matching substitution variables: ${variable_name}
|
|
5
|
+
*/
|
|
6
|
+
export const SUBSTITUTION_PATTERN = /\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g;
|
|
7
|
+
/**
|
|
8
|
+
* Extracts variable names from a string containing ${var} patterns.
|
|
9
|
+
*/
|
|
10
|
+
export function extract_variables(text) {
|
|
11
|
+
const matches = text.matchAll(SUBSTITUTION_PATTERN);
|
|
12
|
+
const variables = new Set();
|
|
13
|
+
for (const match of matches) {
|
|
14
|
+
const variable_name = match[1];
|
|
15
|
+
if (variable_name !== undefined) {
|
|
16
|
+
variables.add(variable_name);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return Array.from(variables);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Applies substitution values to a string containing ${var} patterns.
|
|
23
|
+
*/
|
|
24
|
+
export function substitute_string(text, values) {
|
|
25
|
+
return text.replace(SUBSTITUTION_PATTERN, (match, variable_name) => {
|
|
26
|
+
return values[variable_name] ?? match;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Applies substitution values to an object recursively.
|
|
31
|
+
* Only processes string values within the object.
|
|
32
|
+
*/
|
|
33
|
+
export function substitute_object(obj, values) {
|
|
34
|
+
if (typeof obj === 'string') {
|
|
35
|
+
return substitute_string(obj, values);
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(obj)) {
|
|
38
|
+
return obj.map((item) => substitute_object(item, values));
|
|
39
|
+
}
|
|
40
|
+
if (obj !== null && typeof obj === 'object') {
|
|
41
|
+
const result = {};
|
|
42
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
43
|
+
result[key] = substitute_object(value, values);
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
return obj;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Collects substitution values from a kustomization definition and cluster values.
|
|
51
|
+
* Returns a record of variable name to value.
|
|
52
|
+
*/
|
|
53
|
+
export function collect_substitution_values(kustomization, cluster_values = {}) {
|
|
54
|
+
const values = {};
|
|
55
|
+
for (const sub of kustomization.substitutions ?? []) {
|
|
56
|
+
// Cluster value takes precedence over default
|
|
57
|
+
const value = cluster_values[sub.name] ?? sub.default;
|
|
58
|
+
if (value !== undefined && typeof value === 'string') {
|
|
59
|
+
values[sub.name] = value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return values;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Collects template-level version entries as substitution values.
|
|
66
|
+
* These are shared across all kustomizations in the template.
|
|
67
|
+
*/
|
|
68
|
+
export function collect_template_versions(template, cluster_values = {}) {
|
|
69
|
+
const values = {};
|
|
70
|
+
for (const version of template.spec.versions ?? []) {
|
|
71
|
+
// Cluster value takes precedence over default
|
|
72
|
+
const value = cluster_values[version.name] ?? version.default;
|
|
73
|
+
if (value !== undefined && typeof value === 'string') {
|
|
74
|
+
values[version.name] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return values;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Collects all substitution values from template versions and kustomization substitutions.
|
|
81
|
+
* Precedence: template versions < kustomization substitutions < cluster values
|
|
82
|
+
*/
|
|
83
|
+
export function collect_all_substitution_values(template, kustomization, cluster_values = {}) {
|
|
84
|
+
// Start with template-level versions (lowest precedence)
|
|
85
|
+
const template_versions = collect_template_versions(template, cluster_values);
|
|
86
|
+
// Add kustomization-level substitutions (higher precedence)
|
|
87
|
+
const kustomization_values = collect_substitution_values(kustomization, cluster_values);
|
|
88
|
+
// Merge with kustomization values taking precedence over template versions
|
|
89
|
+
return {
|
|
90
|
+
...template_versions,
|
|
91
|
+
...kustomization_values,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Gets all defined substitution names from a kustomization.
|
|
96
|
+
*/
|
|
97
|
+
export function get_defined_substitutions(kustomization) {
|
|
98
|
+
return (kustomization.substitutions ?? []).map((sub) => sub.name);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Gets all required substitution names (those without defaults) from a kustomization.
|
|
102
|
+
*/
|
|
103
|
+
export function get_required_substitutions(kustomization) {
|
|
104
|
+
return (kustomization.substitutions ?? [])
|
|
105
|
+
.filter((sub) => sub.default === undefined)
|
|
106
|
+
.map((sub) => sub.name);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Validates that all required substitutions have values.
|
|
110
|
+
*/
|
|
111
|
+
export function validate_substitutions(kustomization, cluster_values = {}) {
|
|
112
|
+
const required = get_required_substitutions(kustomization);
|
|
113
|
+
const defined = get_defined_substitutions(kustomization);
|
|
114
|
+
const provided = Object.keys(cluster_values);
|
|
115
|
+
// Find missing required values
|
|
116
|
+
const missing = required.filter((name) => cluster_values[name] === undefined);
|
|
117
|
+
// Find unused provided values
|
|
118
|
+
const unused = provided.filter((name) => !defined.includes(name));
|
|
119
|
+
return {
|
|
120
|
+
valid: missing.length === 0,
|
|
121
|
+
missing,
|
|
122
|
+
unused,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Generates the postBuild.substitute object for a Flux Kustomization.
|
|
127
|
+
* Only includes values that have actual values (not undefined).
|
|
128
|
+
*/
|
|
129
|
+
export function generate_flux_substitutions(values) {
|
|
130
|
+
const entries = Object.entries(values).filter(([, value]) => value !== undefined);
|
|
131
|
+
if (entries.length === 0) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
return Object.fromEntries(entries);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Extracts all substitutions from resolved templates.
|
|
138
|
+
* Returns a flat list of all substitution objects from all kustomizations.
|
|
139
|
+
*/
|
|
140
|
+
export function extract_all_substitutions(templates) {
|
|
141
|
+
const substitutions = [];
|
|
142
|
+
for (const resolved of templates) {
|
|
143
|
+
if (!resolved.enabled) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
for (const kustomization of resolved.template.spec.kustomizations) {
|
|
147
|
+
if (kustomization.substitutions) {
|
|
148
|
+
substitutions.push(...kustomization.substitutions);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return substitutions;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Resolves external substitutions using registered providers.
|
|
156
|
+
* Only resolves plugin-provided substitution types (e.g., 'sops', 'vault').
|
|
157
|
+
* Core types (version, helm, namespace, generic) are handled elsewhere.
|
|
158
|
+
* Legacy types (doppler, 1password) are handled by their respective plugins.
|
|
159
|
+
*
|
|
160
|
+
* @param templates - All resolved templates
|
|
161
|
+
* @param cluster - Cluster configuration
|
|
162
|
+
* @param registry - Plugin registry with registered substitution providers
|
|
163
|
+
* @returns Result containing a map of substitution names to their resolved values
|
|
164
|
+
*/
|
|
165
|
+
export async function resolve_external_substitutions(templates, cluster, registry) {
|
|
166
|
+
const values = {};
|
|
167
|
+
// Extract all substitutions
|
|
168
|
+
const all_substitutions = extract_all_substitutions(templates);
|
|
169
|
+
// Filter to only external (plugin-provided) substitutions
|
|
170
|
+
const external_substitutions = all_substitutions.filter((sub) => is_plugin_substitution(sub));
|
|
171
|
+
if (external_substitutions.length === 0) {
|
|
172
|
+
return success(values);
|
|
173
|
+
}
|
|
174
|
+
// Group substitutions by type
|
|
175
|
+
const by_type = new Map();
|
|
176
|
+
for (const sub of external_substitutions) {
|
|
177
|
+
if (!('type' in sub) || !sub.type) {
|
|
178
|
+
continue; // Should not happen after filtering, but be safe
|
|
179
|
+
}
|
|
180
|
+
const type = sub.type;
|
|
181
|
+
if (!by_type.has(type)) {
|
|
182
|
+
by_type.set(type, []);
|
|
183
|
+
}
|
|
184
|
+
by_type.get(type)?.push(sub);
|
|
185
|
+
}
|
|
186
|
+
// Resolve each type using its provider
|
|
187
|
+
for (const [type, subs] of by_type) {
|
|
188
|
+
const provider = registry.get_substitution_provider(type);
|
|
189
|
+
if (!provider) {
|
|
190
|
+
// No provider registered for this type - skip with warning
|
|
191
|
+
// In the future, we could make this an error or collect warnings
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
// Resolve this batch of substitutions
|
|
195
|
+
// Find plugin config for this provider
|
|
196
|
+
const plugin_config = cluster.spec.plugins?.find((p) => p.name === provider.type)?.config;
|
|
197
|
+
const result = await provider.resolve(subs, {
|
|
198
|
+
cluster,
|
|
199
|
+
templates: templates.map((t) => t.template),
|
|
200
|
+
config: plugin_config ?? undefined,
|
|
201
|
+
});
|
|
202
|
+
if (!is_success(result)) {
|
|
203
|
+
return failure(Errors.validation_error(`Failed to resolve ${type} substitutions: ${result.error.message}`));
|
|
204
|
+
}
|
|
205
|
+
// Merge resolved values
|
|
206
|
+
Object.assign(values, result.value);
|
|
207
|
+
}
|
|
208
|
+
return success(values);
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=substitution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"substitution.js","sourceRoot":"","sources":["../../src/generator/substitution.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAQxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAI5D;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,iCAAiC,CAAC;AAWtE;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,MAA8B;IAC5E,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE;QACjE,OAAO,MAAM,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAI,GAAM,EAAE,MAA8B;IACzE,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAM,CAAC;IAC7C,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAM,CAAC;IACjE,CAAC;IAED,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,MAAW,CAAC;IACrB,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CACzC,aAAgC,EAChC,iBAAyC,EAAE;IAE3C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;QACpD,8CAA8C;QAC9C,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC;QACtD,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAsB,EACtB,iBAAyC,EAAE;IAE3C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACnD,8CAA8C;QAC9C,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC;QAC9D,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,+BAA+B,CAC7C,QAAsB,EACtB,aAAgC,EAChC,iBAAyC,EAAE;IAE3C,yDAAyD;IACzD,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAE9E,4DAA4D;IAC5D,MAAM,oBAAoB,GAAG,2BAA2B,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IAExF,2EAA2E;IAC3E,OAAO;QACL,GAAG,iBAAiB;QACpB,GAAG,oBAAoB;KACxB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,aAAgC;IACxE,OAAO,CAAC,aAAa,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,aAAgC;IACzE,OAAO,CAAC,aAAa,CAAC,aAAa,IAAI,EAAE,CAAC;SACvC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC;SAC1C,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,aAAgC,EAChC,iBAAyC,EAAE;IAE3C,MAAM,QAAQ,GAAG,0BAA0B,CAAC,aAAa,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAE7C,+BAA+B;IAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC;IAE9E,8BAA8B;IAC9B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAElE,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC;QAC3B,OAAO;QACP,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAA8B;IAE9B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAElF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,SAAiC;IACzE,MAAM,aAAa,GAAuB,EAAE,CAAC;IAE7C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtB,SAAS;QACX,CAAC;QAED,KAAK,MAAM,aAAa,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAClE,IAAI,aAAa,CAAC,aAAa,EAAE,CAAC;gBAChC,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,SAAiC,EACjC,OAAoB,EACpB,QAA4B;IAE5B,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,4BAA4B;IAC5B,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAE/D,0DAA0D;IAC1D,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC;IAE9F,IAAI,sBAAsB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IAED,8BAA8B;IAC9B,MAAM,OAAO,GAAG,IAAI,GAAG,EAA8B,CAAC;IACtD,KAAK,MAAM,GAAG,IAAI,sBAAsB,EAAE,CAAC;QACzC,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAClC,SAAS,CAAC,iDAAiD;QAC7D,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,uCAAuC;IACvC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,QAAQ,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAE1D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,2DAA2D;YAC3D,iEAAiE;YACjE,SAAS;QACX,CAAC;QAED,sCAAsC;QACtC,uCAAuC;QACvC,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAE1F,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE;YAC1C,OAAO;YACP,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC3C,MAAM,EAAE,aAAa,IAAI,SAAS;SACnC,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,OAAO,OAAO,CACZ,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,IAAI,mBAAmB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAC5F,CAAC;QACJ,CAAC;QAED,wBAAwB;QACxB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { ClusterType, KustomizationType, TemplateType } from '../schema/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Options for the generation process.
|
|
4
|
+
*/
|
|
5
|
+
export interface GenerateOptionsType {
|
|
6
|
+
dry_run?: boolean;
|
|
7
|
+
output_dir?: string;
|
|
8
|
+
skip_validation?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A resolved template with its values.
|
|
12
|
+
*/
|
|
13
|
+
export interface ResolvedTemplateType {
|
|
14
|
+
template: TemplateType;
|
|
15
|
+
values: Record<string, string>;
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A resolved kustomization with substitution values applied.
|
|
20
|
+
*/
|
|
21
|
+
export interface ResolvedKustomizationType {
|
|
22
|
+
template: TemplateType;
|
|
23
|
+
kustomization: KustomizationType;
|
|
24
|
+
values: Record<string, string>;
|
|
25
|
+
namespace: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generation context for a cluster.
|
|
29
|
+
*/
|
|
30
|
+
export interface GenerationContextType {
|
|
31
|
+
cluster: ClusterType;
|
|
32
|
+
templates: ResolvedTemplateType[];
|
|
33
|
+
output_dir: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Result of a single kustomization generation.
|
|
37
|
+
*/
|
|
38
|
+
export interface GeneratedKustomizationType {
|
|
39
|
+
name: string;
|
|
40
|
+
template: string;
|
|
41
|
+
path: string;
|
|
42
|
+
flux_kustomization: FluxKustomizationType;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Kustomize JSON patch operation.
|
|
46
|
+
*/
|
|
47
|
+
export interface KustomizePatchOpType {
|
|
48
|
+
op: 'add' | 'remove' | 'replace';
|
|
49
|
+
path: string;
|
|
50
|
+
value?: unknown;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Kustomize patch with target selector.
|
|
54
|
+
*/
|
|
55
|
+
export interface KustomizePatchType {
|
|
56
|
+
patch: string;
|
|
57
|
+
target: {
|
|
58
|
+
kind: string;
|
|
59
|
+
name?: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Result of the full generation process.
|
|
64
|
+
*/
|
|
65
|
+
export interface GenerationResultType {
|
|
66
|
+
cluster: string;
|
|
67
|
+
output_dir: string;
|
|
68
|
+
kustomizations: GeneratedKustomizationType[];
|
|
69
|
+
oci_repository?: FluxOCIRepositoryType;
|
|
70
|
+
controller_patches?: KustomizePatchType[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Flux OCIRepository resource type.
|
|
74
|
+
*/
|
|
75
|
+
export interface FluxOCIRepositoryType {
|
|
76
|
+
apiVersion: 'source.toolkit.fluxcd.io/v1';
|
|
77
|
+
kind: 'OCIRepository';
|
|
78
|
+
metadata: {
|
|
79
|
+
name: string;
|
|
80
|
+
namespace: string;
|
|
81
|
+
};
|
|
82
|
+
spec: {
|
|
83
|
+
interval: string;
|
|
84
|
+
url: string;
|
|
85
|
+
ref: {
|
|
86
|
+
tag?: string;
|
|
87
|
+
digest?: string;
|
|
88
|
+
semver?: string;
|
|
89
|
+
};
|
|
90
|
+
provider?: 'aws' | 'azure' | 'gcp' | 'generic';
|
|
91
|
+
secretRef?: {
|
|
92
|
+
name: string;
|
|
93
|
+
};
|
|
94
|
+
insecure?: boolean;
|
|
95
|
+
timeout?: string;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Flux Kustomization patch target selector.
|
|
100
|
+
*/
|
|
101
|
+
export interface FluxPatchTargetType {
|
|
102
|
+
kind: string;
|
|
103
|
+
name?: string;
|
|
104
|
+
namespace?: string;
|
|
105
|
+
labelSelector?: string;
|
|
106
|
+
annotationSelector?: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Flux Kustomization patch.
|
|
110
|
+
*/
|
|
111
|
+
export interface FluxPatchType {
|
|
112
|
+
patch: string;
|
|
113
|
+
target: FluxPatchTargetType;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Flux Kustomization resource type.
|
|
117
|
+
*/
|
|
118
|
+
export interface FluxKustomizationType {
|
|
119
|
+
apiVersion: 'kustomize.toolkit.fluxcd.io/v1';
|
|
120
|
+
kind: 'Kustomization';
|
|
121
|
+
metadata: {
|
|
122
|
+
name: string;
|
|
123
|
+
namespace: string;
|
|
124
|
+
};
|
|
125
|
+
spec: {
|
|
126
|
+
interval: string;
|
|
127
|
+
targetNamespace?: string;
|
|
128
|
+
path: string;
|
|
129
|
+
prune: boolean;
|
|
130
|
+
wait: boolean;
|
|
131
|
+
timeout?: string;
|
|
132
|
+
retryInterval?: string;
|
|
133
|
+
sourceRef: {
|
|
134
|
+
kind: 'GitRepository' | 'OCIRepository';
|
|
135
|
+
name: string;
|
|
136
|
+
};
|
|
137
|
+
dependsOn?: Array<{
|
|
138
|
+
name: string;
|
|
139
|
+
namespace?: string;
|
|
140
|
+
}>;
|
|
141
|
+
postBuild?: {
|
|
142
|
+
substitute?: Record<string, string>;
|
|
143
|
+
};
|
|
144
|
+
healthChecks?: Array<{
|
|
145
|
+
apiVersion: string;
|
|
146
|
+
kind: string;
|
|
147
|
+
name: string;
|
|
148
|
+
namespace: string;
|
|
149
|
+
}>;
|
|
150
|
+
customHealthChecks?: Array<{
|
|
151
|
+
apiVersion: string;
|
|
152
|
+
kind: string;
|
|
153
|
+
namespace?: string;
|
|
154
|
+
/** CEL expression for when resource is healthy/current */
|
|
155
|
+
current?: string;
|
|
156
|
+
/** CEL expression for when resource has failed */
|
|
157
|
+
failed?: string;
|
|
158
|
+
}>;
|
|
159
|
+
patches?: FluxPatchType[];
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/generator/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/generator/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CycleDetectionResultType, GraphNodeType } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Detects cycles in the dependency graph using depth-first search (DFS).
|
|
4
|
+
*
|
|
5
|
+
* Uses a three-color algorithm:
|
|
6
|
+
* - Unvisited (white): Node hasn't been processed
|
|
7
|
+
* - Visiting (gray): Node is currently in the DFS stack
|
|
8
|
+
* - Visited (black): Node and all its descendants have been processed
|
|
9
|
+
*
|
|
10
|
+
* If we encounter a Visiting node during DFS, we've found a cycle.
|
|
11
|
+
*
|
|
12
|
+
* Also performs topological sorting if no cycles are found.
|
|
13
|
+
*
|
|
14
|
+
* @param nodes - Map of graph nodes
|
|
15
|
+
* @returns Cycles found and topological order (if no cycles)
|
|
16
|
+
*/
|
|
17
|
+
export declare function detect_cycles(nodes: Map<string, GraphNodeType>): CycleDetectionResultType;
|
|
18
|
+
/**
|
|
19
|
+
* Checks if a graph has cycles.
|
|
20
|
+
*
|
|
21
|
+
* @param nodes - Map of graph nodes
|
|
22
|
+
* @returns True if the graph has at least one cycle
|
|
23
|
+
*/
|
|
24
|
+
export declare function has_cycles(nodes: Map<string, GraphNodeType>): boolean;
|
|
25
|
+
//# sourceMappingURL=cycle-detection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cycle-detection.d.ts","sourceRoot":"","sources":["../../../src/generator/validation/cycle-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAyB1F;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,wBAAwB,CA2DzF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,OAAO,CAGrE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visit state for DFS traversal.
|
|
3
|
+
*/
|
|
4
|
+
var VisitState;
|
|
5
|
+
(function (VisitState) {
|
|
6
|
+
/** Node has not been visited yet */
|
|
7
|
+
VisitState[VisitState["Unvisited"] = 0] = "Unvisited";
|
|
8
|
+
/** Node is currently being visited (in the DFS stack) */
|
|
9
|
+
VisitState[VisitState["Visiting"] = 1] = "Visiting";
|
|
10
|
+
/** Node has been fully processed */
|
|
11
|
+
VisitState[VisitState["Visited"] = 2] = "Visited";
|
|
12
|
+
})(VisitState || (VisitState = {}));
|
|
13
|
+
/**
|
|
14
|
+
* Formats a cycle into a human-readable message.
|
|
15
|
+
*
|
|
16
|
+
* @param cycle - Array of node IDs forming the cycle
|
|
17
|
+
* @returns Formatted cycle message
|
|
18
|
+
*/
|
|
19
|
+
function format_cycle_message(cycle) {
|
|
20
|
+
const cycle_str = cycle.join(' → ');
|
|
21
|
+
return `Dependency cycle detected: ${cycle_str}`;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Detects cycles in the dependency graph using depth-first search (DFS).
|
|
25
|
+
*
|
|
26
|
+
* Uses a three-color algorithm:
|
|
27
|
+
* - Unvisited (white): Node hasn't been processed
|
|
28
|
+
* - Visiting (gray): Node is currently in the DFS stack
|
|
29
|
+
* - Visited (black): Node and all its descendants have been processed
|
|
30
|
+
*
|
|
31
|
+
* If we encounter a Visiting node during DFS, we've found a cycle.
|
|
32
|
+
*
|
|
33
|
+
* Also performs topological sorting if no cycles are found.
|
|
34
|
+
*
|
|
35
|
+
* @param nodes - Map of graph nodes
|
|
36
|
+
* @returns Cycles found and topological order (if no cycles)
|
|
37
|
+
*/
|
|
38
|
+
export function detect_cycles(nodes) {
|
|
39
|
+
const state = new Map();
|
|
40
|
+
const cycles = [];
|
|
41
|
+
const topological_order = [];
|
|
42
|
+
// Initialize all nodes as unvisited
|
|
43
|
+
for (const id of nodes.keys()) {
|
|
44
|
+
state.set(id, VisitState.Unvisited);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* DFS traversal function.
|
|
48
|
+
*
|
|
49
|
+
* @param node_id - Current node being visited
|
|
50
|
+
* @param path - Current path from DFS root to this node
|
|
51
|
+
*/
|
|
52
|
+
function dfs(node_id, path) {
|
|
53
|
+
state.set(node_id, VisitState.Visiting);
|
|
54
|
+
path.push(node_id);
|
|
55
|
+
const node = nodes.get(node_id);
|
|
56
|
+
if (node) {
|
|
57
|
+
for (const dep_id of node.dependencies) {
|
|
58
|
+
const dep_state = state.get(dep_id);
|
|
59
|
+
if (dep_state === VisitState.Visiting) {
|
|
60
|
+
// Found a cycle - extract it from the path
|
|
61
|
+
const cycle_start_index = path.indexOf(dep_id);
|
|
62
|
+
const cycle = [...path.slice(cycle_start_index), dep_id];
|
|
63
|
+
cycles.push({
|
|
64
|
+
type: 'cycle',
|
|
65
|
+
cycle,
|
|
66
|
+
message: format_cycle_message(cycle),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else if (dep_state === VisitState.Unvisited) {
|
|
70
|
+
dfs(dep_id, path);
|
|
71
|
+
}
|
|
72
|
+
// If Visited, skip - already fully processed
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
state.set(node_id, VisitState.Visited);
|
|
76
|
+
path.pop();
|
|
77
|
+
// Add to end for post-order (dependencies come before dependents)
|
|
78
|
+
topological_order.push(node_id);
|
|
79
|
+
}
|
|
80
|
+
// Visit all nodes (handles disconnected components)
|
|
81
|
+
for (const node_id of nodes.keys()) {
|
|
82
|
+
if (state.get(node_id) === VisitState.Unvisited) {
|
|
83
|
+
dfs(node_id, []);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
cycles,
|
|
88
|
+
topological_order: cycles.length === 0 ? topological_order : null,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Checks if a graph has cycles.
|
|
93
|
+
*
|
|
94
|
+
* @param nodes - Map of graph nodes
|
|
95
|
+
* @returns True if the graph has at least one cycle
|
|
96
|
+
*/
|
|
97
|
+
export function has_cycles(nodes) {
|
|
98
|
+
const result = detect_cycles(nodes);
|
|
99
|
+
return result.cycles.length > 0;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=cycle-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cycle-detection.js","sourceRoot":"","sources":["../../../src/generator/validation/cycle-detection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ClusterType, TemplateType } from '../../schema/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Missing dependency error - a deployed kustomization depends on one from a template not listed in cluster.yaml.
|
|
4
|
+
*/
|
|
5
|
+
export interface MissingDependencyErrorType {
|
|
6
|
+
readonly type: 'missing_dependency';
|
|
7
|
+
/** Node ID of the deployed kustomization */
|
|
8
|
+
readonly source: string;
|
|
9
|
+
/** Node ID of the missing dependency */
|
|
10
|
+
readonly target: string;
|
|
11
|
+
readonly message: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Validates that all kustomization dependencies are satisfied by templates listed in cluster.yaml.
|
|
15
|
+
*
|
|
16
|
+
* Templates are only deployed if they are explicitly listed in cluster.yaml.
|
|
17
|
+
* This validates that all dependency references point to kustomizations from listed templates.
|
|
18
|
+
*
|
|
19
|
+
* @param cluster - Cluster configuration
|
|
20
|
+
* @param templates - Array of templates
|
|
21
|
+
* @returns Array of validation errors (empty if valid)
|
|
22
|
+
*/
|
|
23
|
+
export declare function validate_enablement_dependencies(cluster: ClusterType, templates: TemplateType[]): MissingDependencyErrorType[];
|
|
24
|
+
//# sourceMappingURL=enablement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enablement.d.ts","sourceRoot":"","sources":["../../../src/generator/validation/enablement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAKvE;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,YAAY,EAAE,GACxB,0BAA0B,EAAE,CAkE9B"}
|