@intentius/chant-lexicon-k8s 0.124.31 → 0.124.32
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/dist/actions/apps.js +18 -0
- package/dist/actions/batch.js +6 -0
- package/dist/actions/core.js +48 -0
- package/dist/actions/index.js +13 -0
- package/dist/actions/networking.js +11 -0
- package/dist/actions/rbac.js +8 -0
- package/dist/api/classify.js +123 -0
- package/dist/api/connect.js +62 -0
- package/dist/api/fake-cluster.js +175 -0
- package/dist/api/operation-surface.d.ts.map +1 -1
- package/dist/api/operation-surface.js +109 -0
- package/dist/api/owner-chain.js +100 -0
- package/dist/api/sweep-types.js +35 -0
- package/dist/behaviour-kinds.js +82 -0
- package/dist/codegen/docs-cli.js +2 -0
- package/dist/codegen/docs.js +146 -0
- package/dist/codegen/generate-cli.js +30 -0
- package/dist/codegen/generate-lexicon.js +74 -0
- package/dist/codegen/generate-list-map-keys.js +88 -0
- package/dist/codegen/generate-operations.js +53 -0
- package/dist/codegen/generate-typescript.js +124 -0
- package/dist/codegen/generate.js +173 -0
- package/dist/codegen/naming.js +174 -0
- package/dist/codegen/package.js +36 -0
- package/dist/codegen/patches.js +88 -0
- package/dist/codegen/typecheck.js +4 -0
- package/dist/codegen/versions.js +41 -0
- package/dist/components/argo-app.js +51 -0
- package/dist/components/builders.js +22 -0
- package/dist/components/capability-plugin.js +31 -0
- package/dist/components/flux-reconcile.js +61 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +18 -0
- package/dist/components/kubectl-apply.d.ts +83 -1
- package/dist/components/kubectl-apply.d.ts.map +1 -1
- package/dist/components/kubectl-apply.js +274 -0
- package/dist/components/kustomize-apply.js +25 -0
- package/dist/composites/adot-collector.js +184 -0
- package/dist/composites/agic-ingress.js +85 -0
- package/dist/composites/aks-external-dns-agent.js +146 -0
- package/dist/composites/alb-ingress.js +86 -0
- package/dist/composites/argo-app.js +199 -0
- package/dist/composites/autoscaled-service.js +174 -0
- package/dist/composites/azure-disk-storage-class.js +47 -0
- package/dist/composites/azure-file-storage-class.js +48 -0
- package/dist/composites/azure-monitor-collector.js +176 -0
- package/dist/composites/batch-job.js +139 -0
- package/dist/composites/catalog.js +4110 -0
- package/dist/composites/cockroachdb-cluster.js +371 -0
- package/dist/composites/cockroachdb-region-stack.js +369 -0
- package/dist/composites/config-connector-context.js +40 -0
- package/dist/composites/configured-app.js +135 -0
- package/dist/composites/cron-schedule.js +38 -0
- package/dist/composites/cron-workload.js +109 -0
- package/dist/composites/ebs-storage-class.js +54 -0
- package/dist/composites/efs-storage-class.js +46 -0
- package/dist/composites/external-dns-agent.js +122 -0
- package/dist/composites/filestore-storage-class.js +49 -0
- package/dist/composites/fluent-bit-agent.js +157 -0
- package/dist/composites/flux-app.js +156 -0
- package/dist/composites/gce-ingress.js +83 -0
- package/dist/composites/gce-pd-storage-class.js +49 -0
- package/dist/composites/gke-external-dns-agent.js +129 -0
- package/dist/composites/gke-fluent-bit-agent.js +165 -0
- package/dist/composites/gke-gateway.js +91 -0
- package/dist/composites/gke-otel-collector.js +94 -0
- package/dist/composites/index.js +51 -0
- package/dist/composites/inference-service.js +76 -0
- package/dist/composites/irsa-service-account.js +77 -0
- package/dist/composites/member-defaults.js +14 -0
- package/dist/composites/metrics-server.js +181 -0
- package/dist/composites/model.js +92 -0
- package/dist/composites/monitored-service.js +152 -0
- package/dist/composites/namespace-env.js +114 -0
- package/dist/composites/network-isolated-app.js +124 -0
- package/dist/composites/node-agent.js +149 -0
- package/dist/composites/operator-stack.js +268 -0
- package/dist/composites/otel-collector-agent.js +142 -0
- package/dist/composites/otel-collector-gateway.js +216 -0
- package/dist/composites/otel-collector-node.js +176 -0
- package/dist/composites/otel-collector-rbac.js +115 -0
- package/dist/composites/otel-collector-shape.js +128 -0
- package/dist/composites/otel-collector.js +115 -0
- package/dist/composites/otel-operator-collector.js +123 -0
- package/dist/composites/ray-cluster.js +378 -0
- package/dist/composites/ray-job.js +136 -0
- package/dist/composites/ray-service.js +178 -0
- package/dist/composites/secure-ingress.js +100 -0
- package/dist/composites/security-context.js +1 -0
- package/dist/composites/sidecar-app.js +105 -0
- package/dist/composites/stateful-app.js +111 -0
- package/dist/composites/vllm-serving-runtime.js +114 -0
- package/dist/composites/web-app.js +157 -0
- package/dist/composites/worker-pool.js +167 -0
- package/dist/composites/workload-identity-sa.js +81 -0
- package/dist/composites/workload-identity-service-account.js +77 -0
- package/dist/config-schema.js +72 -0
- package/dist/config.js +59 -0
- package/dist/coverage.js +27 -0
- package/dist/crd/crd-sources.js +615 -0
- package/dist/crd/loader.js +181 -0
- package/dist/crd/oci-chart.js +144 -0
- package/dist/crd/parser.js +382 -0
- package/dist/crd/project-codegen.js +273 -0
- package/dist/crd/types.js +7 -0
- package/dist/deep-observe-hooks.js +306 -0
- package/dist/deep-observe.js +234 -0
- package/dist/default-labels.js +87 -0
- package/dist/describe-resources.js +699 -0
- package/dist/describe-stack-status.js +99 -0
- package/dist/detect.js +11 -0
- package/dist/effect-receipt-row.js +205 -0
- package/dist/export-resources.js +39 -0
- package/dist/generated/index.js +1092 -0
- package/dist/generated/runtime.js +4 -0
- package/dist/group-namespace.js +96 -0
- package/dist/import/embedded.js +197 -0
- package/dist/import/generator.js +288 -0
- package/dist/import/live-export.js +85 -0
- package/dist/import/parser.js +204 -0
- package/dist/import/testdata/embedded/fixtures.js +60 -0
- package/dist/include/entity.js +78 -0
- package/dist/include/resolve.js +170 -0
- package/dist/index.js +59 -0
- package/dist/integrity.json +3 -3
- package/dist/kube/apply.js +90 -0
- package/dist/kube/connect.js +46 -0
- package/dist/kube/delete.js +138 -0
- package/dist/kube/describe.js +169 -0
- package/dist/kube/events.js +132 -0
- package/dist/kube/flags.js +91 -0
- package/dist/kube/get.js +159 -0
- package/dist/kube/group.js +123 -0
- package/dist/kube/logs.js +82 -0
- package/dist/kube/project.js +94 -0
- package/dist/kube/render.js +227 -0
- package/dist/kube/source.js +122 -0
- package/dist/kube/target.js +63 -0
- package/dist/kube/testing.js +28 -0
- package/dist/kube/top.js +99 -0
- package/dist/kube/verdict.js +72 -0
- package/dist/kube/wait.js +129 -0
- package/dist/kustomize/render.js +73 -0
- package/dist/kustomize/rendered-entity.js +67 -0
- package/dist/kustomize/root.js +68 -0
- package/dist/lint/audit-catalog.js +61 -0
- package/dist/lint/audit-lineage.js +118 -0
- package/dist/lint/post-synth/argo-helpers.js +36 -0
- package/dist/lint/post-synth/argo002.js +31 -0
- package/dist/lint/post-synth/argo003.js +53 -0
- package/dist/lint/post-synth/argo005.js +54 -0
- package/dist/lint/post-synth/crd-schema-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/crd-schema-helpers.js +214 -0
- package/dist/lint/post-synth/flux002.js +56 -0
- package/dist/lint/post-synth/flux003.js +50 -0
- package/dist/lint/post-synth/index.js +104 -0
- package/dist/lint/post-synth/k8s-helpers.js +186 -0
- package/dist/lint/post-synth/monitoring-selection-helpers.js +163 -0
- package/dist/lint/post-synth/otel-placement-helpers.js +293 -0
- package/dist/lint/post-synth/sops-helpers.js +43 -0
- package/dist/lint/post-synth/wk8005.js +44 -0
- package/dist/lint/post-synth/wk8006.js +56 -0
- package/dist/lint/post-synth/wk8041.js +60 -0
- package/dist/lint/post-synth/wk8042.js +36 -0
- package/dist/lint/post-synth/wk8101.js +52 -0
- package/dist/lint/post-synth/wk8102.js +30 -0
- package/dist/lint/post-synth/wk8103.js +33 -0
- package/dist/lint/post-synth/wk8104.js +58 -0
- package/dist/lint/post-synth/wk8105.js +33 -0
- package/dist/lint/post-synth/wk8201.js +44 -0
- package/dist/lint/post-synth/wk8202.js +34 -0
- package/dist/lint/post-synth/wk8203.js +34 -0
- package/dist/lint/post-synth/wk8204.js +71 -0
- package/dist/lint/post-synth/wk8205.js +38 -0
- package/dist/lint/post-synth/wk8207.js +33 -0
- package/dist/lint/post-synth/wk8208.js +33 -0
- package/dist/lint/post-synth/wk8209.js +33 -0
- package/dist/lint/post-synth/wk8301.js +49 -0
- package/dist/lint/post-synth/wk8302.js +34 -0
- package/dist/lint/post-synth/wk8303.js +68 -0
- package/dist/lint/post-synth/wk8304.js +58 -0
- package/dist/lint/post-synth/wk8305.js +96 -0
- package/dist/lint/post-synth/wk8306.js +38 -0
- package/dist/lint/post-synth/wk8401.js +86 -0
- package/dist/lint/post-synth/wk8402.js +31 -0
- package/dist/lint/post-synth/wk8403.js +49 -0
- package/dist/lint/post-synth/wk8404.js +36 -0
- package/dist/lint/post-synth/wk8405.js +65 -0
- package/dist/lint/post-synth/wk8406.js +50 -0
- package/dist/lint/post-synth/wk8407.js +58 -0
- package/dist/lint/post-synth/wk8501.js +36 -0
- package/dist/lint/post-synth/wk8502.js +35 -0
- package/dist/lint/post-synth/wk8503.js +164 -0
- package/dist/lint/post-synth/wk8504.js +20 -0
- package/dist/lint/post-synth/wk8505.js +31 -0
- package/dist/lint/post-synth/wk8601.js +40 -0
- package/dist/lint/post-synth/wk8602.js +120 -0
- package/dist/lint/post-synth/wk8603.js +63 -0
- package/dist/lint/post-synth/wk8604.js +31 -0
- package/dist/lint/post-synth/wk8605.js +124 -0
- package/dist/lint/post-synth/wk8606.js +22 -0
- package/dist/lint/post-synth/wk8701.js +31 -0
- package/dist/lint/post-synth/wk8702.js +37 -0
- package/dist/lint/post-synth/wk8703.js +31 -0
- package/dist/lint/post-synth/wk8704.js +135 -0
- package/dist/lint/post-synth/wk8705.js +38 -0
- package/dist/lint/rules/argo-appset-single-project.js +56 -0
- package/dist/lint/rules/argo-ast.js +94 -0
- package/dist/lint/rules/argo-automated-prune.js +59 -0
- package/dist/lint/rules/flux-source-ref-pin.js +44 -0
- package/dist/lint/rules/hardcoded-namespace.js +57 -0
- package/dist/lint/rules/latest-image-tag.js +103 -0
- package/dist/lint/rules/missing-resource-limits.js +85 -0
- package/dist/lsp/completions.d.ts.map +1 -1
- package/dist/lsp/completions.js +18 -0
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/lsp/hover.js +57 -0
- package/dist/manifest-entity.js +71 -0
- package/dist/manifest.json +1 -1
- package/dist/micro-time.js +49 -0
- package/dist/op/activities/apply-diff.d.ts +31 -0
- package/dist/op/activities/apply-diff.d.ts.map +1 -0
- package/dist/op/activities/apply-diff.js +79 -0
- package/dist/op/activities/argo.js +98 -0
- package/dist/op/activities/ensure-secret.js +38 -0
- package/dist/op/activities/index.js +51 -0
- package/dist/op/activities/kubectl.d.ts +64 -0
- package/dist/op/activities/kubectl.d.ts.map +1 -1
- package/dist/op/activities/kubectl.js +517 -0
- package/dist/op/activities/wait-for-ready.js +229 -0
- package/dist/op/builders.js +68 -0
- package/dist/package-cli.js +21 -0
- package/dist/patch/json-patch.js +187 -0
- package/dist/patch/rendered-patch.js +94 -0
- package/dist/plugin.js +741 -0
- package/dist/project-kinds.js +56 -0
- package/dist/receipt-store.js +216 -0
- package/dist/rules/crd-schema-helpers.ts +2 -1
- package/dist/secret-labels.js +33 -0
- package/dist/secret-store.js +116 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +578 -0
- package/dist/sops/encrypted-secret-file.js +194 -0
- package/dist/sops/entity.js +32 -0
- package/dist/spec/fetch.js +58 -0
- package/dist/spec/parse.js +622 -0
- package/dist/subscribe-changes.js +168 -0
- package/dist/teardown.js +197 -0
- package/dist/telemetry-release.js +86 -0
- package/dist/validate-cli.js +17 -0
- package/dist/validate.js +47 -0
- package/dist/variables.js +34 -0
- package/dist/whoami.js +109 -0
- package/package.json +12 -12
- package/src/api/operation-surface.ts +2 -1
- package/src/codegen/package.ts +2 -2
- package/src/components/index.ts +3 -0
- package/src/components/kubectl-apply-plan.k3d.e2e.test.ts +127 -0
- package/src/components/kubectl-apply.test.ts +262 -0
- package/src/components/kubectl-apply.ts +341 -12
- package/src/deep-observe-hooks.ts +2 -2
- package/src/import/roundtrip-build.test.ts +46 -0
- package/src/lint/post-synth/crd-schema-helpers.ts +2 -1
- package/src/lsp/completions.ts +2 -1
- package/src/lsp/hover.ts +2 -1
- package/src/op/activities/apply-diff.ts +87 -0
- package/src/op/activities/kubectl-plan.test.ts +224 -0
- package/src/op/activities/kubectl.ts +204 -16
- package/src/serializer.ts +2 -1
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kubernetes YAML parser for `chant import`.
|
|
3
|
+
*
|
|
4
|
+
* Parses Kubernetes manifests (single or multi-document YAML) into the core
|
|
5
|
+
* TemplateIR format, mapping K8s resources to the K8s::{Group}::{Kind} type
|
|
6
|
+
* convention.
|
|
7
|
+
*/
|
|
8
|
+
import { parseYAML, splitYAMLDocuments } from "@intentius/chant/yaml";
|
|
9
|
+
import { namespaceSegmentForGroup } from "../group-namespace.js";
|
|
10
|
+
import { delegateEmbedded } from "./embedded.js";
|
|
11
|
+
// ── GVK to type name mapping ───────────────────────────────────────
|
|
12
|
+
/**
|
|
13
|
+
* Well-known kind+apiVersion pairs mapped to K8s type names.
|
|
14
|
+
* Key format: "apiVersion/kind" (core group uses just "kind").
|
|
15
|
+
*/
|
|
16
|
+
const GVK_TYPE_MAP = {
|
|
17
|
+
// Core (v1)
|
|
18
|
+
"v1/Pod": "K8s::Core::Pod",
|
|
19
|
+
"v1/Service": "K8s::Core::Service",
|
|
20
|
+
"v1/ConfigMap": "K8s::Core::ConfigMap",
|
|
21
|
+
"v1/Secret": "K8s::Core::Secret",
|
|
22
|
+
"v1/Namespace": "K8s::Core::Namespace",
|
|
23
|
+
"v1/ServiceAccount": "K8s::Core::ServiceAccount",
|
|
24
|
+
"v1/PersistentVolume": "K8s::Core::PersistentVolume",
|
|
25
|
+
"v1/PersistentVolumeClaim": "K8s::Core::PersistentVolumeClaim",
|
|
26
|
+
"v1/Endpoints": "K8s::Core::Endpoints",
|
|
27
|
+
"v1/LimitRange": "K8s::Core::LimitRange",
|
|
28
|
+
"v1/ResourceQuota": "K8s::Core::ResourceQuota",
|
|
29
|
+
// Apps (apps/v1)
|
|
30
|
+
"apps/v1/Deployment": "K8s::Apps::Deployment",
|
|
31
|
+
"apps/v1/StatefulSet": "K8s::Apps::StatefulSet",
|
|
32
|
+
"apps/v1/DaemonSet": "K8s::Apps::DaemonSet",
|
|
33
|
+
"apps/v1/ReplicaSet": "K8s::Apps::ReplicaSet",
|
|
34
|
+
// Batch (batch/v1)
|
|
35
|
+
"batch/v1/Job": "K8s::Batch::Job",
|
|
36
|
+
"batch/v1/CronJob": "K8s::Batch::CronJob",
|
|
37
|
+
// Networking (networking.k8s.io/v1)
|
|
38
|
+
"networking.k8s.io/v1/Ingress": "K8s::Networking::Ingress",
|
|
39
|
+
"networking.k8s.io/v1/NetworkPolicy": "K8s::Networking::NetworkPolicy",
|
|
40
|
+
"networking.k8s.io/v1/IngressClass": "K8s::Networking::IngressClass",
|
|
41
|
+
// RBAC (rbac.authorization.k8s.io/v1)
|
|
42
|
+
"rbac.authorization.k8s.io/v1/Role": "K8s::Rbac::Role",
|
|
43
|
+
"rbac.authorization.k8s.io/v1/ClusterRole": "K8s::Rbac::ClusterRole",
|
|
44
|
+
"rbac.authorization.k8s.io/v1/RoleBinding": "K8s::Rbac::RoleBinding",
|
|
45
|
+
"rbac.authorization.k8s.io/v1/ClusterRoleBinding": "K8s::Rbac::ClusterRoleBinding",
|
|
46
|
+
// Autoscaling (autoscaling/v2)
|
|
47
|
+
"autoscaling/v2/HorizontalPodAutoscaler": "K8s::Autoscaling::HorizontalPodAutoscaler",
|
|
48
|
+
"autoscaling/v1/HorizontalPodAutoscaler": "K8s::Autoscaling::HorizontalPodAutoscaler",
|
|
49
|
+
// Policy (policy/v1)
|
|
50
|
+
"policy/v1/PodDisruptionBudget": "K8s::Policy::PodDisruptionBudget",
|
|
51
|
+
// Storage (storage.k8s.io/v1)
|
|
52
|
+
"storage.k8s.io/v1/StorageClass": "K8s::Storage::StorageClass",
|
|
53
|
+
// Certificates (certificates.k8s.io/v1)
|
|
54
|
+
"certificates.k8s.io/v1/CertificateSigningRequest": "K8s::Certificates::CertificateSigningRequest",
|
|
55
|
+
// Coordination (coordination.k8s.io/v1)
|
|
56
|
+
"coordination.k8s.io/v1/Lease": "K8s::Coordination::Lease",
|
|
57
|
+
// Discovery (discovery.k8s.io/v1)
|
|
58
|
+
"discovery.k8s.io/v1/EndpointSlice": "K8s::Discovery::EndpointSlice",
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Resolve apiVersion + kind to a K8s type name.
|
|
62
|
+
* Falls back to constructing from the apiVersion group.
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* `<apiVersion>/<kind>` keys that map to a type another key maps to first.
|
|
66
|
+
* The build writes the first key's apiVersion for that type, so a document
|
|
67
|
+
* written against a later key (`autoscaling/v1` HorizontalPodAutoscaler)
|
|
68
|
+
* keeps its own apiVersion as a property.
|
|
69
|
+
*/
|
|
70
|
+
const ALIASED_GVKS = (() => {
|
|
71
|
+
const firstForType = new Set();
|
|
72
|
+
const aliased = new Set();
|
|
73
|
+
for (const [key, type] of Object.entries(GVK_TYPE_MAP)) {
|
|
74
|
+
if (firstForType.has(type))
|
|
75
|
+
aliased.add(key);
|
|
76
|
+
else
|
|
77
|
+
firstForType.add(type);
|
|
78
|
+
}
|
|
79
|
+
return aliased;
|
|
80
|
+
})();
|
|
81
|
+
function resolveTypeName(apiVersion, kind) {
|
|
82
|
+
// Try exact match
|
|
83
|
+
const key = `${apiVersion}/${kind}`;
|
|
84
|
+
if (GVK_TYPE_MAP[key])
|
|
85
|
+
return GVK_TYPE_MAP[key];
|
|
86
|
+
// Core group uses just kind
|
|
87
|
+
if (apiVersion === "v1") {
|
|
88
|
+
const coreKey = `v1/${kind}`;
|
|
89
|
+
if (GVK_TYPE_MAP[coreKey])
|
|
90
|
+
return GVK_TYPE_MAP[coreKey];
|
|
91
|
+
}
|
|
92
|
+
// Construct from apiVersion group
|
|
93
|
+
const group = apiVersionToGroup(apiVersion);
|
|
94
|
+
return `K8s::${group}::${kind}`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Extract the namespace segment from an apiVersion string.
|
|
98
|
+
* "apps/v1" → "Apps"
|
|
99
|
+
* "v1" → "Core"
|
|
100
|
+
* "rbac.authorization.k8s.io/v1" → "Rbac"
|
|
101
|
+
* "argoproj.io/v1alpha1" → "Argo" (override)
|
|
102
|
+
*
|
|
103
|
+
* Splits the version off and hands the group to the shared rule, so an
|
|
104
|
+
* imported manifest is typed exactly as a declared one is.
|
|
105
|
+
*/
|
|
106
|
+
function apiVersionToGroup(apiVersion) {
|
|
107
|
+
const slashIdx = apiVersion.indexOf("/");
|
|
108
|
+
if (slashIdx === -1)
|
|
109
|
+
return "Core"; // core group (v1)
|
|
110
|
+
return namespaceSegmentForGroup(apiVersion.slice(0, slashIdx));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Convert a K8s object name to a camelCase logical identifier.
|
|
114
|
+
* Combines kind (lowercased first char) with the object name (PascalCased).
|
|
115
|
+
*
|
|
116
|
+
* E.g., kind="Deployment", name="my-app" → "deploymentMyApp"
|
|
117
|
+
*/
|
|
118
|
+
function toLogicalId(kind, name) {
|
|
119
|
+
const prefix = kind.charAt(0).toLowerCase() + kind.slice(1);
|
|
120
|
+
if (!name)
|
|
121
|
+
return prefix;
|
|
122
|
+
const pascalName = name
|
|
123
|
+
.split(/[-_.]/)
|
|
124
|
+
.map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1))
|
|
125
|
+
.join("");
|
|
126
|
+
return `${prefix}${pascalName}`;
|
|
127
|
+
}
|
|
128
|
+
// ── Parser ──────────────────────────────────────────────────────────
|
|
129
|
+
/**
|
|
130
|
+
* Kubernetes YAML parser implementation.
|
|
131
|
+
*
|
|
132
|
+
* Supports multi-document YAML (split on `---`, see `splitYAMLDocuments`). Each document is expected
|
|
133
|
+
* to be a standard Kubernetes object with apiVersion, kind, and metadata.
|
|
134
|
+
*/
|
|
135
|
+
export class K8sParser {
|
|
136
|
+
/**
|
|
137
|
+
* With `context.embedded` (`chant import`), content another lexicon owns
|
|
138
|
+
* is offered to it: every ConfigMap `data` value and a PrometheusRule's
|
|
139
|
+
* `spec.groups` (see ./embedded.ts). Without it, everything is kept as
|
|
140
|
+
* written.
|
|
141
|
+
*/
|
|
142
|
+
parse(content, context) {
|
|
143
|
+
const resources = [];
|
|
144
|
+
const namespaces = new Set();
|
|
145
|
+
// Split into documents on `---` / `...` markers (a trailing `# comment`
|
|
146
|
+
// allowed); empty and comment-only documents are dropped (#2965).
|
|
147
|
+
const documents = splitYAMLDocuments(content);
|
|
148
|
+
for (const docStr of documents) {
|
|
149
|
+
const doc = parseYAML(docStr);
|
|
150
|
+
if (!doc || typeof doc !== "object")
|
|
151
|
+
continue;
|
|
152
|
+
const resource = this.parseDocument(doc, context?.embedded);
|
|
153
|
+
if (resource) {
|
|
154
|
+
resources.push(resource);
|
|
155
|
+
// Track namespaces
|
|
156
|
+
const ns = doc.metadata;
|
|
157
|
+
if (ns?.namespace && typeof ns.namespace === "string") {
|
|
158
|
+
namespaces.add(ns.namespace);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const metadata = {};
|
|
163
|
+
if (namespaces.size > 0) {
|
|
164
|
+
metadata.namespaces = [...namespaces];
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
resources,
|
|
168
|
+
parameters: [],
|
|
169
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
parseDocument(doc, embedded) {
|
|
173
|
+
const apiVersion = doc.apiVersion;
|
|
174
|
+
const kind = doc.kind;
|
|
175
|
+
if (!apiVersion || !kind)
|
|
176
|
+
return null;
|
|
177
|
+
const metadata = (doc.metadata ?? {});
|
|
178
|
+
const name = metadata.name;
|
|
179
|
+
const type = resolveTypeName(apiVersion, kind);
|
|
180
|
+
const logicalId = toLogicalId(kind, name);
|
|
181
|
+
// Extract the user-configurable properties (skip apiVersion, kind)
|
|
182
|
+
const properties = {};
|
|
183
|
+
for (const [key, value] of Object.entries(doc)) {
|
|
184
|
+
if (key === "kind")
|
|
185
|
+
continue;
|
|
186
|
+
if (key === "apiVersion" && !ALIASED_GVKS.has(`${apiVersion}/${kind}`))
|
|
187
|
+
continue;
|
|
188
|
+
properties[key] = value;
|
|
189
|
+
}
|
|
190
|
+
if (embedded)
|
|
191
|
+
delegateEmbedded(type, kind, properties, embedded);
|
|
192
|
+
return {
|
|
193
|
+
logicalId,
|
|
194
|
+
type,
|
|
195
|
+
properties,
|
|
196
|
+
metadata: {
|
|
197
|
+
originalName: name,
|
|
198
|
+
apiVersion,
|
|
199
|
+
kind,
|
|
200
|
+
...(metadata.namespace ? { namespace: metadata.namespace } : {}),
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared by the embedded-content round trip (embedded-roundtrip.test.ts) and
|
|
3
|
+
* the type check of what it generates (embedded-types.e2e.test.ts): run
|
|
4
|
+
* `chant import` over a manifest file the way a user does, through
|
|
5
|
+
* `importCommand`, in a project inside this package so the lexicons resolve
|
|
6
|
+
* as they would for them.
|
|
7
|
+
*/
|
|
8
|
+
import { mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "fs";
|
|
9
|
+
import { join, relative, resolve } from "path";
|
|
10
|
+
import { importCommand } from "@intentius/chant/cli/commands/import";
|
|
11
|
+
import { parsePrometheusYaml } from "@intentius/chant-lexicon-prometheus/import/parser";
|
|
12
|
+
export const pkgDir = resolve(import.meta.dirname, "../../../..");
|
|
13
|
+
export const repoRoot = resolve(pkgDir, "../..");
|
|
14
|
+
export const read = (name) => readFileSync(join(import.meta.dirname, name), "utf-8");
|
|
15
|
+
function walk(dir, root, out) {
|
|
16
|
+
for (const entry of readdirSync(dir)) {
|
|
17
|
+
const path = join(dir, entry);
|
|
18
|
+
if (statSync(path).isDirectory())
|
|
19
|
+
walk(path, root, out);
|
|
20
|
+
else
|
|
21
|
+
out[relative(root, path)] = readFileSync(path, "utf-8");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* `chant import manifest.yaml --lexicon k8s` into a fresh project, or with
|
|
26
|
+
* `detect`, `chant import manifest.yaml` with the lexicon detected.
|
|
27
|
+
*/
|
|
28
|
+
export async function importManifest(yaml, options = {}) {
|
|
29
|
+
const dir = mkdtempSync(join(pkgDir, ".roundtrip-tmp-"));
|
|
30
|
+
writeFileSync(join(dir, "package.json"), '{ "name": "k8s-embedded-roundtrip", "private": true, "type": "module" }\n');
|
|
31
|
+
writeFileSync(join(dir, "chant.config.ts"), 'export default { lexicons: ["k8s"] };\n');
|
|
32
|
+
const srcDir = join(dir, "src");
|
|
33
|
+
mkdirSync(srcDir);
|
|
34
|
+
const templatePath = join(dir, "manifest.yaml");
|
|
35
|
+
writeFileSync(templatePath, yaml);
|
|
36
|
+
const result = await importCommand({ templatePath, output: srcDir, ...(options.detect ? {} : { lexicon: "k8s" }) });
|
|
37
|
+
const files = {};
|
|
38
|
+
walk(srcDir, srcDir, files);
|
|
39
|
+
return { result, dir, srcDir, files };
|
|
40
|
+
}
|
|
41
|
+
export function removeDir(dir) {
|
|
42
|
+
rmSync(dir, { recursive: true, force: true });
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* An alertmanager.yml as the prometheus importer reads it, receivers and
|
|
46
|
+
* time intervals sorted by name (the serializer sorts them): what an
|
|
47
|
+
* imported ConfigMap's `alertmanager.yml` must give back (#3031).
|
|
48
|
+
*/
|
|
49
|
+
export function alertmanagerConfig(text) {
|
|
50
|
+
const parsed = parsePrometheusYaml(text);
|
|
51
|
+
if (parsed.kind !== "alertmanager")
|
|
52
|
+
throw new Error("not an alertmanager.yml");
|
|
53
|
+
const byName = (a, b) => a.name.localeCompare(b.name);
|
|
54
|
+
const { receivers, time_intervals, ...rest } = parsed.config;
|
|
55
|
+
return {
|
|
56
|
+
...rest,
|
|
57
|
+
...(receivers ? { receivers: [...receivers].sort(byName) } : {}),
|
|
58
|
+
...(time_intervals ? { time_intervals: [...time_intervals].sort(byName) } : {}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `k8sInclude`: bring a plain multi-document YAML file or pinned URL into a
|
|
3
|
+
* build as it is (#3566 item 4).
|
|
4
|
+
*
|
|
5
|
+
* Before this, the way to ship a vendored manifest bundle (an operator's
|
|
6
|
+
* install.yaml, a CRD bundle) through chant was a kustomization directory
|
|
7
|
+
* listing it as its only resource. `k8sInclude` declares the file or URL
|
|
8
|
+
* directly. Its documents become the same verbatim manifest entities a
|
|
9
|
+
* kustomize build root produces (`../manifest-entity.ts`), so they get
|
|
10
|
+
* default labels and ownership stamping, post-synth checks, and
|
|
11
|
+
* `lifecycle diff --live` like any declared resource.
|
|
12
|
+
*
|
|
13
|
+
* This module is the declaration only, with no filesystem or network access,
|
|
14
|
+
* so the factory stays pure and folds under `--sandbox`. The bytes are read
|
|
15
|
+
* at `buildRoots()`, the build's one impure seam, in `./resolve.ts`, the same
|
|
16
|
+
* split `declareSecret({ provenance: "committed-encrypted" })` uses.
|
|
17
|
+
*
|
|
18
|
+
* The declaration itself never reaches the output: the serializer skips it,
|
|
19
|
+
* and it carries no `props`, so the live read paths never ask a cluster
|
|
20
|
+
* about it.
|
|
21
|
+
*/
|
|
22
|
+
import { DECLARABLE_MARKER } from "@intentius/chant/declarable";
|
|
23
|
+
/** Marks a `k8sInclude` declaration. */
|
|
24
|
+
export const K8S_INCLUDE_MARKER = Symbol.for("chant.k8s.include");
|
|
25
|
+
export const K8S_INCLUDE_ENTITY_TYPE = "chant:k8s:include";
|
|
26
|
+
/** Annotation stamped on every included document, valued with its source. */
|
|
27
|
+
export const INCLUDE_SOURCE_ANNOTATION = "chant.intentius.io/include-source";
|
|
28
|
+
const DIGEST_RE = /^sha256:[0-9a-f]{64}$/;
|
|
29
|
+
export function isK8sInclude(value) {
|
|
30
|
+
return (typeof value === "object" &&
|
|
31
|
+
value !== null &&
|
|
32
|
+
value[K8S_INCLUDE_MARKER] === true);
|
|
33
|
+
}
|
|
34
|
+
/** True for an `http://` or `https://` source. */
|
|
35
|
+
export function isRemoteSource(source) {
|
|
36
|
+
return /^https?:\/\//i.test(source);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Declare a local or pinned remote multi-document YAML to include in the
|
|
40
|
+
* build.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { k8sInclude } from "@intentius/chant-lexicon-k8s";
|
|
45
|
+
*
|
|
46
|
+
* export const certManager = k8sInclude({
|
|
47
|
+
* source: "https://github.com/cert-manager/cert-manager/releases/download/v1.16.2/cert-manager.yaml",
|
|
48
|
+
* digest: "sha256:...",
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* export const legacy = k8sInclude({ source: "manifests/legacy.yaml" });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export function k8sInclude(props) {
|
|
55
|
+
const source = props?.source;
|
|
56
|
+
if (typeof source !== "string" || source.length === 0) {
|
|
57
|
+
throw new Error("k8sInclude: `source` must be a non-empty path or URL");
|
|
58
|
+
}
|
|
59
|
+
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(source) && !isRemoteSource(source)) {
|
|
60
|
+
throw new Error(`k8sInclude("${source}"): only local paths and http(s) URLs are supported`);
|
|
61
|
+
}
|
|
62
|
+
if (props.digest !== undefined && !DIGEST_RE.test(props.digest)) {
|
|
63
|
+
throw new Error(`k8sInclude("${source}"): digest ${JSON.stringify(props.digest)} is not of the form "sha256:<64 lowercase hex>"`);
|
|
64
|
+
}
|
|
65
|
+
if (isRemoteSource(source) && props.digest === undefined) {
|
|
66
|
+
throw new Error(`k8sInclude("${source}"): a URL source must be pinned with \`digest: "sha256:<hex>"\`. ` +
|
|
67
|
+
`Compute it from a copy you have reviewed, e.g. \`curl -sL <url> | shasum -a 256\`.`);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
lexicon: "k8s",
|
|
71
|
+
entityType: K8S_INCLUDE_ENTITY_TYPE,
|
|
72
|
+
source,
|
|
73
|
+
...(props.digest !== undefined ? { digest: props.digest } : {}),
|
|
74
|
+
...(props.patches !== undefined ? { patches: JSON.parse(JSON.stringify(props.patches)) } : {}),
|
|
75
|
+
[DECLARABLE_MARKER]: true,
|
|
76
|
+
[K8S_INCLUDE_MARKER]: true,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolving `k8sInclude` declarations at `buildRoots()` (#3566 item 4).
|
|
3
|
+
*
|
|
4
|
+
* For each declaration in the discovered entity set: read the local file or
|
|
5
|
+
* fetch the URL, check the bytes against the pinned digest, parse the
|
|
6
|
+
* multi-document YAML, apply the declaration's patches, and wrap each
|
|
7
|
+
* document in a verbatim manifest entity stamped with the source.
|
|
8
|
+
*
|
|
9
|
+
* - Local paths resolve against the project root (the directory holding
|
|
10
|
+
* `chant.config.*`), as `declareSecret`'s committed ciphertext and
|
|
11
|
+
* `k8s.kustomize.roots` do.
|
|
12
|
+
* - A URL is fetched once. The bytes are cached under their digest in
|
|
13
|
+
* `~/.chant/includes/` (override with `CHANT_INCLUDE_CACHE_ROOT`, the
|
|
14
|
+
* counterpart of the helm lexicon's `CHANT_HELM_RENDER_ROOT`), and a build
|
|
15
|
+
* that finds a cached copy matching the digest never touches the network.
|
|
16
|
+
* Fetched bytes that do not match the digest fail the build and are not
|
|
17
|
+
* cached.
|
|
18
|
+
* - Entity names are `<declaration name>/<kindName>`, qualified by
|
|
19
|
+
* namespace and then numbered in document order on collision, the scheme
|
|
20
|
+
* kustomize roots use. Keying on the declaration's export name rather than
|
|
21
|
+
* the URL keeps the names stable when a pinned version is bumped, so the
|
|
22
|
+
* live diff lines up across the upgrade.
|
|
23
|
+
* - A missing file, a failed fetch, a file with no documents, and a
|
|
24
|
+
* document without a string `apiVersion` and `kind` each fail the build
|
|
25
|
+
* with the path or URL in the message. Empty documents (a stray `---`)
|
|
26
|
+
* are skipped.
|
|
27
|
+
*/
|
|
28
|
+
import { createHash } from "node:crypto";
|
|
29
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
30
|
+
import { homedir } from "node:os";
|
|
31
|
+
import { join, resolve } from "node:path";
|
|
32
|
+
import { loadAll } from "js-yaml";
|
|
33
|
+
import { applyRenderedPatches } from "../patch/rendered-patch.js";
|
|
34
|
+
import { addRenderedEntity, renderedManifestEntity } from "../kustomize/rendered-entity.js";
|
|
35
|
+
import { INCLUDE_SOURCE_ANNOTATION, isK8sInclude, isRemoteSource } from "./entity.js";
|
|
36
|
+
export const defaultIncludeFetcher = async (url) => {
|
|
37
|
+
const response = await fetch(url, { redirect: "follow" });
|
|
38
|
+
if (!response.ok)
|
|
39
|
+
throw new Error(`HTTP ${response.status} ${response.statusText}`.trim());
|
|
40
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
41
|
+
};
|
|
42
|
+
/** Where fetched include sources are cached, keyed by digest. */
|
|
43
|
+
export function includeCacheRoot() {
|
|
44
|
+
return process.env.CHANT_INCLUDE_CACHE_ROOT ?? join(homedir(), ".chant", "includes");
|
|
45
|
+
}
|
|
46
|
+
export function sha256Digest(bytes) {
|
|
47
|
+
return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
48
|
+
}
|
|
49
|
+
/** `sha256:<hex>` -> `sha256-<hex>.yaml`; colons are not filesystem-safe everywhere. */
|
|
50
|
+
function cachePath(root, digest) {
|
|
51
|
+
return join(root, `${digest.replace(":", "-")}.yaml`);
|
|
52
|
+
}
|
|
53
|
+
async function loadBytes(name, decl, opts) {
|
|
54
|
+
const read = opts.readFile ?? ((path) => readFileSync(path));
|
|
55
|
+
const label = `k8sInclude "${name}" (${decl.source})`;
|
|
56
|
+
if (!isRemoteSource(decl.source)) {
|
|
57
|
+
const absolute = resolve(opts.projectRoot, decl.source);
|
|
58
|
+
let bytes;
|
|
59
|
+
try {
|
|
60
|
+
bytes = read(absolute);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
throw new Error(`${label}: file not readable at ${absolute} — ${err instanceof Error ? err.message : String(err)}`);
|
|
64
|
+
}
|
|
65
|
+
if (decl.digest !== undefined) {
|
|
66
|
+
const actual = sha256Digest(bytes);
|
|
67
|
+
if (actual !== decl.digest) {
|
|
68
|
+
throw new Error(`${label}: ${absolute} does not match its pinned digest: expected ${decl.digest}, found ${actual}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return bytes;
|
|
72
|
+
}
|
|
73
|
+
// The factory refuses an unpinned URL; this guards a declaration revived
|
|
74
|
+
// from the entity wire format or built by hand.
|
|
75
|
+
if (decl.digest === undefined) {
|
|
76
|
+
throw new Error(`${label}: a URL source must be pinned with a sha256 digest`);
|
|
77
|
+
}
|
|
78
|
+
const root = opts.cacheRoot ?? includeCacheRoot();
|
|
79
|
+
const cached = cachePath(root, decl.digest);
|
|
80
|
+
if (existsSync(cached)) {
|
|
81
|
+
const bytes = readFileSync(cached);
|
|
82
|
+
// A corrupt or hand-edited cache entry is refetched, never trusted.
|
|
83
|
+
if (sha256Digest(bytes) === decl.digest)
|
|
84
|
+
return bytes;
|
|
85
|
+
}
|
|
86
|
+
const fetcher = opts.fetch ?? defaultIncludeFetcher;
|
|
87
|
+
let bytes;
|
|
88
|
+
try {
|
|
89
|
+
bytes = await fetcher(decl.source);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
throw new Error(`${label}: fetch failed — ${err instanceof Error ? err.message : String(err)}`);
|
|
93
|
+
}
|
|
94
|
+
const actual = sha256Digest(bytes);
|
|
95
|
+
if (actual !== decl.digest) {
|
|
96
|
+
throw new Error(`${label}: fetched bytes do not match the pinned digest: expected ${decl.digest}, fetched ${actual}. ` +
|
|
97
|
+
`The content at the URL changed, or the digest is wrong.`);
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
mkdirSync(root, { recursive: true });
|
|
101
|
+
const tmp = `${cached}.${process.pid}.tmp`;
|
|
102
|
+
writeFileSync(tmp, bytes);
|
|
103
|
+
renameSync(tmp, cached);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// A cache write failure is not fatal: the verified bytes are in memory,
|
|
107
|
+
// and the next build fetches again.
|
|
108
|
+
}
|
|
109
|
+
return bytes;
|
|
110
|
+
}
|
|
111
|
+
/** Parse, validate and patch one source's documents. */
|
|
112
|
+
function documentsOf(name, decl, text) {
|
|
113
|
+
const label = `k8sInclude "${name}" (${decl.source})`;
|
|
114
|
+
let parsed;
|
|
115
|
+
try {
|
|
116
|
+
parsed = loadAll(text);
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
throw new Error(`${label} is not valid YAML: ${err instanceof Error ? err.message : String(err)}`);
|
|
120
|
+
}
|
|
121
|
+
const docs = [];
|
|
122
|
+
parsed.forEach((doc, i) => {
|
|
123
|
+
if (doc === null || doc === undefined)
|
|
124
|
+
return;
|
|
125
|
+
if (typeof doc !== "object" || Array.isArray(doc)) {
|
|
126
|
+
throw new Error(`${label}: document ${i} is not a Kubernetes object`);
|
|
127
|
+
}
|
|
128
|
+
const record = doc;
|
|
129
|
+
if (typeof record.apiVersion !== "string" || !record.apiVersion || typeof record.kind !== "string" || !record.kind) {
|
|
130
|
+
throw new Error(`${label}: document ${i} has no string apiVersion and kind`);
|
|
131
|
+
}
|
|
132
|
+
docs.push(record);
|
|
133
|
+
});
|
|
134
|
+
if (docs.length === 0)
|
|
135
|
+
throw new Error(`${label} contains no YAML documents`);
|
|
136
|
+
return applyRenderedPatches(docs, decl.patches, label);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Resolve every declaration into entities. Throws on the first one that
|
|
140
|
+
* does not resolve: a build that would silently drop an included bundle
|
|
141
|
+
* must not proceed.
|
|
142
|
+
*/
|
|
143
|
+
export async function resolveIncludes(opts) {
|
|
144
|
+
const entities = new Map();
|
|
145
|
+
for (const [name, decl] of opts.declarations) {
|
|
146
|
+
const bytes = await loadBytes(name, decl, opts);
|
|
147
|
+
const text = Buffer.from(bytes).toString("utf-8");
|
|
148
|
+
for (const doc of documentsOf(name, decl, text)) {
|
|
149
|
+
// documentsOf checked apiVersion/kind, so the wrap cannot return null.
|
|
150
|
+
addRenderedEntity(entities, name, renderedManifestEntity(doc, decl.source, INCLUDE_SOURCE_ANNOTATION));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return entities;
|
|
154
|
+
}
|
|
155
|
+
/** Every `k8sInclude` declaration in an entity map, keyed by entity name. */
|
|
156
|
+
export function includeDeclarations(entities) {
|
|
157
|
+
const out = new Map();
|
|
158
|
+
for (const [name, entity] of entities) {
|
|
159
|
+
if (isK8sInclude(entity))
|
|
160
|
+
out.set(name, entity);
|
|
161
|
+
}
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
/** The `buildRoots` contribution: the documents of every `k8sInclude`. */
|
|
165
|
+
export async function includeBuildRoot(ctx, overrides) {
|
|
166
|
+
const declarations = includeDeclarations(ctx.entities ?? new Map());
|
|
167
|
+
if (declarations.size === 0)
|
|
168
|
+
return { entities: new Map() };
|
|
169
|
+
return { entities: await resolveIncludes({ projectRoot: ctx.projectRoot, declarations, ...overrides }) };
|
|
170
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Serializer
|
|
2
|
+
export { k8sSerializer } from "./serializer.js";
|
|
3
|
+
// Plugin
|
|
4
|
+
export { k8sPlugin } from "./plugin.js";
|
|
5
|
+
// Typed Op step-builder wrappers (chant #1288 Stage 2) — kubectlApply/
|
|
6
|
+
// waitForReady/ensureSecret — are deliberately NOT re-exported here: their
|
|
7
|
+
// types derive from the activities' own *Args interfaces, which name the API
|
|
8
|
+
// client and therefore sit behind the #1074 dynamic-import boundary this
|
|
9
|
+
// entry point must never reach, even type-only
|
|
10
|
+
// (examples/k8s-client-boundary.test.ts). Import them via the subpath
|
|
11
|
+
// `@intentius/chant-lexicon-k8s/op/builders`, the same way workers import
|
|
12
|
+
// `@intentius/chant-lexicon-k8s/op/activities`.
|
|
13
|
+
// The capability plugin core's loader discovers on this package (#1495 piece 2)
|
|
14
|
+
// — the kubectl-apply leaf a component composes, the way aws contributes
|
|
15
|
+
// cfn-deploy.
|
|
16
|
+
export { k8sCapabilityPlugin, K8S_VERB_FAMILIES } from "./components/capability-plugin.js";
|
|
17
|
+
export { kubectlApplyCapability, createKubectlApplyCapability } from "./components/kubectl-apply.js";
|
|
18
|
+
export { kustomizeApplyCapability, createKustomizeApplyCapability } from "./components/kustomize-apply.js";
|
|
19
|
+
// Default labels & annotations
|
|
20
|
+
export { defaultLabels, defaultAnnotations, isDefaultLabels, isDefaultAnnotations } from "./default-labels.js";
|
|
21
|
+
export { DEFAULT_LABELS_MARKER, DEFAULT_ANNOTATIONS_MARKER } from "./default-labels.js";
|
|
22
|
+
// Variables / label constants
|
|
23
|
+
export { K8sLabels, K8sAnnotations } from "./variables.js";
|
|
24
|
+
// Effect receipts (#2074, epic #1703): the k8s materialization row, meaning the
|
|
25
|
+
// factory a project declares (core's shape under the k8s lexicon, carrying
|
|
26
|
+
// the marker) and the name/label constants. The ConfigMap-backed store itself
|
|
27
|
+
// lives at the `/receipt-store` subpath, off the build path (#1074).
|
|
28
|
+
export { EffectReceipt, receiptConfigMapName, receiptConfigMapRef, receiptNamespaceFrom, isEffectReceiptObject, K8S_EFFECT_RECEIPT_ENTITY_TYPE, EFFECT_RECEIPTS_COMMENT_MARKER, RECEIPT_NAME_PREFIX, RECEIPT_DATA_KEY, RECEIPT_LABEL_KEY, RECEIPT_DEFAULT_NAMESPACE, RECEIPT_UNRESOLVED_VALUE_NOTE, parseReceiptComment, renderReceiptComment, } from "./effect-receipt-row.js";
|
|
29
|
+
// Generated-once secret marker (#1830) — constants only; the store adapter
|
|
30
|
+
// itself lives at the `/secret-store` subpath, off the build path (#1074).
|
|
31
|
+
export { GENERATED_ONCE_LABEL_KEY, GENERATED_ONCE_LABEL_VALUE, isGeneratedOnce } from "./secret-labels.js";
|
|
32
|
+
// MicroTime helpers — see micro-time.ts for why this exists.
|
|
33
|
+
export { microTime, isMicroTimeFormatted } from "./micro-time.js";
|
|
34
|
+
// Verbatim manifest escape hatch — a kind with no generated class, and what
|
|
35
|
+
// `chant carve emit` writes for a Terraform kubernetes_manifest (#999).
|
|
36
|
+
export { k8sManifest } from "./manifest-entity.js";
|
|
37
|
+
// Plain YAML included as it is, local or pinned URL (#3566). The factory is
|
|
38
|
+
// pure; the bytes are read at buildRoots() (./include/resolve.ts).
|
|
39
|
+
export { k8sInclude, isK8sInclude, INCLUDE_SOURCE_ANNOTATION } from "./include/entity.js";
|
|
40
|
+
// Patches on rendered documents: k8sInclude, kustomize roots, HelmRender (#3566).
|
|
41
|
+
export { renderedPatch, applyRenderedPatches, applyJsonPatch, applyMergePatch } from "./patch/rendered-patch.js";
|
|
42
|
+
// Generated entities — export everything from generated index
|
|
43
|
+
// After running `chant generate`, this re-exports all K8s resource classes
|
|
44
|
+
export * from "./generated/index.js";
|
|
45
|
+
// Composites
|
|
46
|
+
export { WebApp, StatefulApp, CronWorkload, AutoscaledService, WorkerPool, NamespaceEnv, NodeAgent, BatchJob, SecureIngress, ConfiguredApp, SidecarApp, MonitoredService, NetworkIsolatedApp, IrsaServiceAccount, AlbIngress, EbsStorageClass, EfsStorageClass, FluentBitAgent, ExternalDnsAgent, AdotCollector, OtelCollector, OtelCollectorGateway, gatewayExporter, OTEL_COLLECTOR_ANNOTATIONS, OtelOperatorCollector, MetricsServer, WorkloadIdentityServiceAccount, GcePdStorageClass, FilestoreStorageClass, GkeGateway, ConfigConnectorContext, GceIngress, CockroachDbCluster, CockroachDbRegionStack, RayCluster, RayJob, RayService, ArgoAppFor, ArgoAppSetForRegions, registerArgoCluster, FluxGitSource, FluxAppFor, AgicIngress, AzureDiskStorageClass, AzureFileStorageClass, AzureMonitorCollector, AksWorkloadIdentityServiceAccount, GkeFluentBitAgent, GkeOtelCollector, GkeExternalDnsAgent, AksExternalDnsAgent, Model, resolveModelStorageUri, OperatorStack, deriveHostVerbClass, DEFAULT_RESOURCE_RULES, } from "./composites/index.js";
|
|
47
|
+
// RBAC verb constants
|
|
48
|
+
export * from "./actions/index.js";
|
|
49
|
+
// Spec utilities (for tooling)
|
|
50
|
+
export { fetchK8sSchema, fetchSchemas, K8S_SCHEMA_VERSION } from "./spec/fetch.js";
|
|
51
|
+
export { parseK8sSwagger, k8sShortName, k8sServiceName, gvkToTypeName, gvkToApiVersion } from "./spec/parse.js";
|
|
52
|
+
// Code generation pipeline
|
|
53
|
+
export { generate, writeGeneratedFiles } from "./codegen/generate.js";
|
|
54
|
+
export { packageLexicon } from "./codegen/package.js";
|
|
55
|
+
export { parseCRD, parseCRDSpec } from "./crd/parser.js";
|
|
56
|
+
export { loadCRDs, loadMultipleCRDs } from "./crd/loader.js";
|
|
57
|
+
// Project-local CRD classes (`k8s.crds`, `chant generate`): the generated
|
|
58
|
+
// module registers its kinds through this.
|
|
59
|
+
export { registerProjectKinds } from "./project-kinds.js";
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "297c642f88996e02ecc1c6a83cd2421f6d9a9aa71ea68b89b0a78ec9efef65c8",
|
|
5
5
|
"meta.json": "c1831ac15083f5e0e45b29698d7b77f1c01646240fe6de5d6320753188594f69",
|
|
6
6
|
"types/index.d.ts": "5c5340046d090ae9db5553039d923cf92a8b2eb57aa4dc941273ed5bcfb5bc9d",
|
|
7
7
|
"rules/argo-appset-single-project.ts": "afa9f310753aa2d475f35012b13135b2dfaebed2a35d44edbe185ebc07673674",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"rules/argo002.ts": "d2f07daabfc7a4624d3d60ea151fd2380d43f1578dd6a17825f6f6e0ebc610ba",
|
|
16
16
|
"rules/argo003.ts": "a61024fbd3db772eface6b2e4fee618a5818f12a1050faea8e358e0fdc992396",
|
|
17
17
|
"rules/argo005.ts": "611ea489e005e3ead925013e636f0d7c6899fd0ce68c59a97541fc6fe4e8d25c",
|
|
18
|
-
"rules/crd-schema-helpers.ts": "
|
|
18
|
+
"rules/crd-schema-helpers.ts": "131783fd70ccb3e829084550f6e66e5af3d436d909803b2ab60b5c06f9f32039",
|
|
19
19
|
"rules/flux002.ts": "4269ce13121bc5b28c02aad06765dc85085a1c9ebcc936ae958663b85de07bc6",
|
|
20
20
|
"rules/flux003.ts": "a174af9941bd2491a9bbf72039ab2fc4d4f4de388b2884ddf7123f05594d9d4e",
|
|
21
21
|
"rules/k8s-helpers.ts": "868cac99b4505a8e060384a716047646da1583568ef6da471a186dc760961212",
|
|
@@ -78,5 +78,5 @@
|
|
|
78
78
|
"skills/chant-k8s-argo.md": "24c9a85b78a2fc5c6657424baac9cc6d6caff6f47605b8146b2c0082133181cf",
|
|
79
79
|
"skills/chant-k8s-flux.md": "9670efc2e9854bd14686b5adeb707396b9030a4dcaee6529b30abf56efe2c50c"
|
|
80
80
|
},
|
|
81
|
-
"composite": "
|
|
81
|
+
"composite": "067ab31520928c9a103272ab7cac3ae17752fe1bec0c6cee9bf54653005eb187"
|
|
82
82
|
}
|