@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,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argo CD composites — turn Chant build targets into Argo `Application`s.
|
|
3
|
+
*
|
|
4
|
+
* The k8s lexicon stays runtime-agnostic: it only emits manifests. These
|
|
5
|
+
* composites are the opt-in bridge to Argo CD's reconciliation layer. Authoring
|
|
6
|
+
* an `Application` by hand is ~30 lines of nested YAML; `ArgoAppFor` collapses
|
|
7
|
+
* it to one call with production-friendly defaults.
|
|
8
|
+
*
|
|
9
|
+
* - ArgoAppFor(target, opts) → a single K8s::Argo::Application
|
|
10
|
+
* - ArgoAppSetForRegions(regions, …) → one ApplicationSet, fanned out per region
|
|
11
|
+
* - registerArgoCluster(opts) → the cluster-registration Secret
|
|
12
|
+
*/
|
|
13
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
14
|
+
import { Application as ApplicationResource, ApplicationSet as ApplicationSetResource, Secret as SecretResource, } from "../generated/index.js";
|
|
15
|
+
const IN_CLUSTER_SERVER = "https://kubernetes.default.svc";
|
|
16
|
+
/** The default, safe sync policy: automated, non-pruning, self-healing. */
|
|
17
|
+
function defaultSyncPolicy() {
|
|
18
|
+
return {
|
|
19
|
+
automated: { prune: false, selfHeal: true },
|
|
20
|
+
syncOptions: ["CreateNamespace=true"],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function renderSyncPolicy(policy) {
|
|
24
|
+
const out = {};
|
|
25
|
+
if (policy.automated) {
|
|
26
|
+
out.automated = {
|
|
27
|
+
...(policy.automated.prune !== undefined && { prune: policy.automated.prune }),
|
|
28
|
+
...(policy.automated.selfHeal !== undefined && { selfHeal: policy.automated.selfHeal }),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (policy.syncOptions && policy.syncOptions.length > 0) {
|
|
32
|
+
out.syncOptions = policy.syncOptions;
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
function renderDestination(dest) {
|
|
37
|
+
return {
|
|
38
|
+
...(dest.server !== undefined && { server: dest.server }),
|
|
39
|
+
...(dest.name !== undefined && { name: dest.name }),
|
|
40
|
+
namespace: dest.namespace,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const ArgoApplication = Composite((props) => {
|
|
44
|
+
const { target, repo, path, destination = { server: IN_CLUSTER_SERVER, namespace: target }, targetRevision = "HEAD", project = "default", argoNamespace = "argocd", syncPolicy, labels = {}, defaults, } = props;
|
|
45
|
+
const resolvedSyncPolicy = syncPolicy ?? defaultSyncPolicy();
|
|
46
|
+
const renderedSync = renderSyncPolicy(resolvedSyncPolicy);
|
|
47
|
+
const application = new ApplicationResource(mergeDefaults({
|
|
48
|
+
metadata: {
|
|
49
|
+
name: target,
|
|
50
|
+
namespace: argoNamespace,
|
|
51
|
+
labels: {
|
|
52
|
+
"app.kubernetes.io/name": target,
|
|
53
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
54
|
+
...labels,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
spec: {
|
|
58
|
+
project,
|
|
59
|
+
source: { repoURL: repo, path, targetRevision },
|
|
60
|
+
destination: renderDestination(destination),
|
|
61
|
+
...(Object.keys(renderedSync).length > 0 && { syncPolicy: renderedSync }),
|
|
62
|
+
},
|
|
63
|
+
}, defaults?.application));
|
|
64
|
+
return { application };
|
|
65
|
+
}, "ArgoApplication");
|
|
66
|
+
/**
|
|
67
|
+
* Turn a Chant build target into an Argo CD `Application` in one call.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* import { ArgoAppFor } from "@intentius/chant-lexicon-k8s";
|
|
72
|
+
*
|
|
73
|
+
* export const api = ArgoAppFor("api", {
|
|
74
|
+
* repo: "https://github.com/acme/infra",
|
|
75
|
+
* path: "dist/api",
|
|
76
|
+
* destination: { server: "https://kubernetes.default.svc", namespace: "api" },
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export function ArgoAppFor(target, options) {
|
|
81
|
+
return ArgoApplication({ target, ...options });
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Emit one `ApplicationSet` that fans out across regions via a list generator —
|
|
85
|
+
* one synced Application per region, all scoped to a single AppProject.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* import { ArgoAppSetForRegions } from "@intentius/chant-lexicon-k8s";
|
|
90
|
+
*
|
|
91
|
+
* export const crdb = ArgoAppSetForRegions(
|
|
92
|
+
* ["east", "central", "west"],
|
|
93
|
+
* (region) => ({
|
|
94
|
+
* server: clusterServers[region],
|
|
95
|
+
* namespace: `crdb-${region}`,
|
|
96
|
+
* path: `dist/${region}`,
|
|
97
|
+
* }),
|
|
98
|
+
* { name: "crdb", repo: "https://github.com/acme/infra", project: "crdb" },
|
|
99
|
+
* );
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export function ArgoAppSetForRegions(regions, fn, options) {
|
|
103
|
+
return ArgoApplicationSet({ regions, fn, options });
|
|
104
|
+
}
|
|
105
|
+
const ArgoApplicationSet = Composite((props) => {
|
|
106
|
+
const { regions, fn, options } = props;
|
|
107
|
+
const { name, repo, path: setPath, project = "default", argoNamespace = "argocd", targetRevision: setRevision = "HEAD", syncPolicy, labels = {}, defaults, } = options;
|
|
108
|
+
// One list-generator element per region, carrying the resolved per-region
|
|
109
|
+
// values the template interpolates.
|
|
110
|
+
const elements = regions.map((region) => {
|
|
111
|
+
const t = fn(region);
|
|
112
|
+
const path = t.path ?? setPath;
|
|
113
|
+
if (path === undefined) {
|
|
114
|
+
throw new Error(`ArgoAppSetForRegions("${name}"): region "${region}" has no path — set options.path or return a path from the mapper.`);
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
region,
|
|
118
|
+
...(t.server !== undefined && { server: t.server }),
|
|
119
|
+
...(t.name !== undefined && { clusterName: t.name }),
|
|
120
|
+
namespace: t.namespace,
|
|
121
|
+
path,
|
|
122
|
+
targetRevision: t.targetRevision ?? setRevision,
|
|
123
|
+
};
|
|
124
|
+
});
|
|
125
|
+
// Destination interpolates server or name depending on what the mapper gave.
|
|
126
|
+
const usesServer = elements.every((e) => "server" in e);
|
|
127
|
+
const destination = usesServer
|
|
128
|
+
? { server: "{{server}}", namespace: "{{namespace}}" }
|
|
129
|
+
: { name: "{{clusterName}}", namespace: "{{namespace}}" };
|
|
130
|
+
const resolvedSyncPolicy = syncPolicy ?? defaultSyncPolicy();
|
|
131
|
+
const renderedSync = renderSyncPolicy(resolvedSyncPolicy);
|
|
132
|
+
const applicationSet = new ApplicationSetResource(mergeDefaults({
|
|
133
|
+
metadata: {
|
|
134
|
+
name,
|
|
135
|
+
namespace: argoNamespace,
|
|
136
|
+
labels: {
|
|
137
|
+
"app.kubernetes.io/name": name,
|
|
138
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
139
|
+
...labels,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
spec: {
|
|
143
|
+
generators: [{ list: { elements } }],
|
|
144
|
+
template: {
|
|
145
|
+
metadata: { name: `{{region}}-${name}` },
|
|
146
|
+
spec: {
|
|
147
|
+
// Single static AppProject for the whole set (ARGO004).
|
|
148
|
+
project,
|
|
149
|
+
source: { repoURL: repo, path: "{{path}}", targetRevision: "{{targetRevision}}" },
|
|
150
|
+
destination,
|
|
151
|
+
...(Object.keys(renderedSync).length > 0 && { syncPolicy: renderedSync }),
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
}, defaults?.applicationSet));
|
|
156
|
+
return { applicationSet };
|
|
157
|
+
}, "ArgoApplicationSet");
|
|
158
|
+
/**
|
|
159
|
+
* Register an external cluster with Argo CD — emits the cluster Secret labelled
|
|
160
|
+
* `argocd.argoproj.io/secret-type: cluster` that ARGO003 looks for.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* import { registerArgoCluster } from "@intentius/chant-lexicon-k8s";
|
|
165
|
+
*
|
|
166
|
+
* export const east = registerArgoCluster({
|
|
167
|
+
* name: "east",
|
|
168
|
+
* server: "https://east.example.com",
|
|
169
|
+
* config: { tlsClientConfig: { insecure: false } },
|
|
170
|
+
* });
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export function registerArgoCluster(options) {
|
|
174
|
+
return ArgoClusterSecret(options);
|
|
175
|
+
}
|
|
176
|
+
const ArgoClusterSecret = Composite((options) => {
|
|
177
|
+
const { name, server, config, argoNamespace = "argocd", labels = {}, defaults } = options;
|
|
178
|
+
const configString = config === undefined ? undefined : typeof config === "string" ? config : JSON.stringify(config);
|
|
179
|
+
const secret = new SecretResource(mergeDefaults({
|
|
180
|
+
metadata: {
|
|
181
|
+
// Secret names can't contain characters from the server URL; use the
|
|
182
|
+
// cluster name as the object name.
|
|
183
|
+
name: `cluster-${name}`,
|
|
184
|
+
namespace: argoNamespace,
|
|
185
|
+
labels: {
|
|
186
|
+
"argocd.argoproj.io/secret-type": "cluster",
|
|
187
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
188
|
+
...labels,
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
type: "Opaque",
|
|
192
|
+
stringData: {
|
|
193
|
+
name,
|
|
194
|
+
server,
|
|
195
|
+
...(configString !== undefined && { config: configString }),
|
|
196
|
+
},
|
|
197
|
+
}, defaults?.secret));
|
|
198
|
+
return { secret };
|
|
199
|
+
}, "ArgoClusterSecret");
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AutoscaledService composite — Deployment + Service + HPA + PDB.
|
|
3
|
+
*
|
|
4
|
+
* A higher-level construct for production HTTP services with autoscaling
|
|
5
|
+
* and disruption budget. Enforces that HPA targets match the Deployment,
|
|
6
|
+
* PDB selectors match pod labels, and resource requests are set.
|
|
7
|
+
*/
|
|
8
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
9
|
+
import { Deployment, Service, HorizontalPodAutoscaler, PodDisruptionBudget } from "../generated/index.js";
|
|
10
|
+
/**
|
|
11
|
+
* Create an AutoscaledService composite — returns prop objects for
|
|
12
|
+
* a Deployment, Service, HorizontalPodAutoscaler, and PodDisruptionBudget.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { AutoscaledService } from "@intentius/chant-lexicon-k8s";
|
|
17
|
+
*
|
|
18
|
+
* const { deployment, service, hpa, pdb } = AutoscaledService({
|
|
19
|
+
* name: "api",
|
|
20
|
+
* image: "api:1.0",
|
|
21
|
+
* maxReplicas: 10,
|
|
22
|
+
* cpuRequest: "100m",
|
|
23
|
+
* memoryRequest: "128Mi",
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export const AutoscaledService = Composite((props) => {
|
|
28
|
+
const { name, image, port = 80, minReplicas = 2, maxReplicas, targetCPUPercent = 70, targetMemoryPercent, minAvailable = 1, cpuRequest, memoryRequest, cpuLimit, memoryLimit, topologySpread = false, livenessPath = "/healthz", readinessPath = "/readyz", initContainers, securityContext, terminationGracePeriodSeconds, priorityClassName, labels: extraLabels = {}, namespace, env, serviceAccountName, volumes: explicitVolumes = [], volumeMounts: explicitMounts = [], tmpDirs = [], defaults: defs, } = props;
|
|
29
|
+
const commonLabels = {
|
|
30
|
+
"app.kubernetes.io/name": name,
|
|
31
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
32
|
+
...extraLabels,
|
|
33
|
+
};
|
|
34
|
+
// Build topologySpreadConstraints if enabled
|
|
35
|
+
const topologyConstraints = (() => {
|
|
36
|
+
if (!topologySpread)
|
|
37
|
+
return undefined;
|
|
38
|
+
const maxSkew = typeof topologySpread === "object" ? (topologySpread.maxSkew ?? 1) : 1;
|
|
39
|
+
const topologyKey = typeof topologySpread === "object"
|
|
40
|
+
? (topologySpread.topologyKey ?? "topology.kubernetes.io/zone")
|
|
41
|
+
: "topology.kubernetes.io/zone";
|
|
42
|
+
return [{
|
|
43
|
+
maxSkew,
|
|
44
|
+
topologyKey,
|
|
45
|
+
whenUnsatisfiable: "DoNotSchedule",
|
|
46
|
+
labelSelector: { matchLabels: { "app.kubernetes.io/name": name } },
|
|
47
|
+
}];
|
|
48
|
+
})();
|
|
49
|
+
// Generate emptyDir volumes/mounts from tmpDirs, then merge with explicit
|
|
50
|
+
const tmpVolumes = tmpDirs.map((_, i) => ({ name: `tmp-${i}`, emptyDir: {} }));
|
|
51
|
+
const tmpMounts = tmpDirs.map((dir, i) => ({ name: `tmp-${i}`, mountPath: dir }));
|
|
52
|
+
const allVolumes = [...explicitVolumes, ...tmpVolumes];
|
|
53
|
+
const allMounts = [...explicitMounts, ...tmpMounts];
|
|
54
|
+
const resources = {
|
|
55
|
+
requests: { cpu: cpuRequest, memory: memoryRequest },
|
|
56
|
+
...(cpuLimit || memoryLimit
|
|
57
|
+
? {
|
|
58
|
+
limits: {
|
|
59
|
+
...(cpuLimit && { cpu: cpuLimit }),
|
|
60
|
+
...(memoryLimit && { memory: memoryLimit }),
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
: {}),
|
|
64
|
+
};
|
|
65
|
+
const deployment = new Deployment(mergeDefaults({
|
|
66
|
+
metadata: {
|
|
67
|
+
name,
|
|
68
|
+
...(namespace && { namespace }),
|
|
69
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "server" },
|
|
70
|
+
},
|
|
71
|
+
spec: {
|
|
72
|
+
replicas: minReplicas,
|
|
73
|
+
selector: { matchLabels: { "app.kubernetes.io/name": name } },
|
|
74
|
+
template: {
|
|
75
|
+
metadata: { labels: { "app.kubernetes.io/name": name, ...extraLabels } },
|
|
76
|
+
spec: {
|
|
77
|
+
containers: [
|
|
78
|
+
{
|
|
79
|
+
name,
|
|
80
|
+
image,
|
|
81
|
+
ports: [{ containerPort: port, name: "http" }],
|
|
82
|
+
resources,
|
|
83
|
+
livenessProbe: {
|
|
84
|
+
httpGet: { path: livenessPath, port },
|
|
85
|
+
initialDelaySeconds: 10,
|
|
86
|
+
periodSeconds: 10,
|
|
87
|
+
},
|
|
88
|
+
readinessProbe: {
|
|
89
|
+
httpGet: { path: readinessPath, port },
|
|
90
|
+
initialDelaySeconds: 5,
|
|
91
|
+
periodSeconds: 5,
|
|
92
|
+
},
|
|
93
|
+
...(env && { env }),
|
|
94
|
+
...(securityContext && { securityContext }),
|
|
95
|
+
...(allMounts.length > 0 && { volumeMounts: allMounts }),
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
...(initContainers && {
|
|
99
|
+
initContainers: initContainers.map((ic) => ({
|
|
100
|
+
name: ic.name,
|
|
101
|
+
image: ic.image,
|
|
102
|
+
...(ic.command && { command: ic.command }),
|
|
103
|
+
...(ic.args && { args: ic.args }),
|
|
104
|
+
})),
|
|
105
|
+
}),
|
|
106
|
+
...(topologyConstraints && { topologySpreadConstraints: topologyConstraints }),
|
|
107
|
+
...(terminationGracePeriodSeconds !== undefined && { terminationGracePeriodSeconds }),
|
|
108
|
+
...(priorityClassName && { priorityClassName }),
|
|
109
|
+
...(serviceAccountName && { serviceAccountName }),
|
|
110
|
+
...(allVolumes.length > 0 && { volumes: allVolumes }),
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
}, defs?.deployment));
|
|
115
|
+
const service = new Service(mergeDefaults({
|
|
116
|
+
metadata: {
|
|
117
|
+
name,
|
|
118
|
+
...(namespace && { namespace }),
|
|
119
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "server" },
|
|
120
|
+
},
|
|
121
|
+
spec: {
|
|
122
|
+
selector: { "app.kubernetes.io/name": name },
|
|
123
|
+
ports: [{ port: 80, targetPort: port, protocol: "TCP", name: "http" }],
|
|
124
|
+
type: "ClusterIP",
|
|
125
|
+
},
|
|
126
|
+
}, defs?.service));
|
|
127
|
+
const metrics = [
|
|
128
|
+
{
|
|
129
|
+
type: "Resource",
|
|
130
|
+
resource: {
|
|
131
|
+
name: "cpu",
|
|
132
|
+
target: { type: "Utilization", averageUtilization: targetCPUPercent },
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
if (targetMemoryPercent !== undefined) {
|
|
137
|
+
metrics.push({
|
|
138
|
+
type: "Resource",
|
|
139
|
+
resource: {
|
|
140
|
+
name: "memory",
|
|
141
|
+
target: { type: "Utilization", averageUtilization: targetMemoryPercent },
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
const hpa = new HorizontalPodAutoscaler(mergeDefaults({
|
|
146
|
+
metadata: {
|
|
147
|
+
name,
|
|
148
|
+
...(namespace && { namespace }),
|
|
149
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "autoscaler" },
|
|
150
|
+
},
|
|
151
|
+
spec: {
|
|
152
|
+
scaleTargetRef: {
|
|
153
|
+
apiVersion: "apps/v1",
|
|
154
|
+
kind: "Deployment",
|
|
155
|
+
name,
|
|
156
|
+
},
|
|
157
|
+
minReplicas,
|
|
158
|
+
maxReplicas,
|
|
159
|
+
metrics,
|
|
160
|
+
},
|
|
161
|
+
}, defs?.hpa));
|
|
162
|
+
const pdb = new PodDisruptionBudget(mergeDefaults({
|
|
163
|
+
metadata: {
|
|
164
|
+
name,
|
|
165
|
+
...(namespace && { namespace }),
|
|
166
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "disruption-budget" },
|
|
167
|
+
},
|
|
168
|
+
spec: {
|
|
169
|
+
minAvailable,
|
|
170
|
+
selector: { matchLabels: { "app.kubernetes.io/name": name } },
|
|
171
|
+
},
|
|
172
|
+
}, defs?.pdb));
|
|
173
|
+
return { deployment, service, hpa, pdb };
|
|
174
|
+
}, "AutoscaledService");
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AzureDiskStorageClass composite — StorageClass for Azure Disk CSI driver.
|
|
3
|
+
*
|
|
4
|
+
* @aks Creates a StorageClass with the `disk.csi.azure.com` provisioner.
|
|
5
|
+
*/
|
|
6
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
7
|
+
import { StorageClass } from "../generated/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Create an AzureDiskStorageClass composite — returns prop objects for
|
|
10
|
+
* a StorageClass with the Azure Disk CSI provisioner.
|
|
11
|
+
*
|
|
12
|
+
* @aks
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { AzureDiskStorageClass } from "@intentius/chant-lexicon-k8s";
|
|
16
|
+
*
|
|
17
|
+
* const { storageClass } = AzureDiskStorageClass({
|
|
18
|
+
* name: "premium-disk",
|
|
19
|
+
* skuName: "Premium_LRS",
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const AzureDiskStorageClass = Composite((props) => {
|
|
24
|
+
const { name, skuName = "Premium_LRS", cachingMode = "ReadOnly", networkAccessPolicy = "AllowAll", reclaimPolicy = "Delete", volumeBindingMode = "WaitForFirstConsumer", allowVolumeExpansion = true, labels: extraLabels = {}, defaults: defs, } = props;
|
|
25
|
+
const commonLabels = {
|
|
26
|
+
"app.kubernetes.io/name": name,
|
|
27
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
28
|
+
...extraLabels,
|
|
29
|
+
};
|
|
30
|
+
const parameters = {
|
|
31
|
+
skuName,
|
|
32
|
+
cachingMode,
|
|
33
|
+
networkAccessPolicy,
|
|
34
|
+
};
|
|
35
|
+
const storageClass = new StorageClass(mergeDefaults({
|
|
36
|
+
metadata: {
|
|
37
|
+
name,
|
|
38
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "storage" },
|
|
39
|
+
},
|
|
40
|
+
provisioner: "disk.csi.azure.com",
|
|
41
|
+
parameters,
|
|
42
|
+
reclaimPolicy,
|
|
43
|
+
volumeBindingMode,
|
|
44
|
+
allowVolumeExpansion,
|
|
45
|
+
}, defs?.storageClass));
|
|
46
|
+
return { storageClass };
|
|
47
|
+
}, "AzureDiskStorageClass");
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AzureFileStorageClass composite — StorageClass for Azure Files CSI driver.
|
|
3
|
+
*
|
|
4
|
+
* @aks Creates a StorageClass with the `file.csi.azure.com` provisioner.
|
|
5
|
+
* Azure Files provides ReadWriteMany access mode (shared across pods/nodes).
|
|
6
|
+
*/
|
|
7
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
8
|
+
import { StorageClass } from "../generated/index.js";
|
|
9
|
+
/**
|
|
10
|
+
* Create an AzureFileStorageClass composite — returns prop objects for
|
|
11
|
+
* a StorageClass with the Azure Files CSI provisioner.
|
|
12
|
+
*
|
|
13
|
+
* @aks
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { AzureFileStorageClass } from "@intentius/chant-lexicon-k8s";
|
|
17
|
+
*
|
|
18
|
+
* const { storageClass } = AzureFileStorageClass({
|
|
19
|
+
* name: "azure-files-shared",
|
|
20
|
+
* skuName: "Premium_LRS",
|
|
21
|
+
* protocol: "nfs",
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const AzureFileStorageClass = Composite((props) => {
|
|
26
|
+
const { name, skuName = "Premium_LRS", protocol = "smb", shareName, reclaimPolicy = "Delete", labels: extraLabels = {}, defaults: defs, } = props;
|
|
27
|
+
const commonLabels = {
|
|
28
|
+
"app.kubernetes.io/name": name,
|
|
29
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
30
|
+
...extraLabels,
|
|
31
|
+
};
|
|
32
|
+
const parameters = {
|
|
33
|
+
skuName,
|
|
34
|
+
protocol,
|
|
35
|
+
};
|
|
36
|
+
if (shareName)
|
|
37
|
+
parameters.shareName = shareName;
|
|
38
|
+
const storageClass = new StorageClass(mergeDefaults({
|
|
39
|
+
metadata: {
|
|
40
|
+
name,
|
|
41
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "storage" },
|
|
42
|
+
},
|
|
43
|
+
provisioner: "file.csi.azure.com",
|
|
44
|
+
parameters,
|
|
45
|
+
reclaimPolicy,
|
|
46
|
+
}, defs?.storageClass));
|
|
47
|
+
return { storageClass };
|
|
48
|
+
}, "AzureFileStorageClass");
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AzureMonitorCollector composite — DaemonSet + RBAC + ConfigMap for Azure Monitor / OTel collector.
|
|
3
|
+
*
|
|
4
|
+
* @aks Azure Monitor agent with OpenTelemetry collector config for
|
|
5
|
+
* Log Analytics workspace integration on AKS clusters.
|
|
6
|
+
*/
|
|
7
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
8
|
+
import { DaemonSet, ServiceAccount, ClusterRole, ClusterRoleBinding, ConfigMap } from "../generated/index.js";
|
|
9
|
+
/**
|
|
10
|
+
* Create an AzureMonitorCollector composite — returns prop objects for
|
|
11
|
+
* a DaemonSet, ServiceAccount, ClusterRole, ClusterRoleBinding, and ConfigMap.
|
|
12
|
+
*
|
|
13
|
+
* @aks
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { AzureMonitorCollector } from "@intentius/chant-lexicon-k8s";
|
|
17
|
+
*
|
|
18
|
+
* const { daemonSet, serviceAccount, clusterRole, clusterRoleBinding, configMap } = AzureMonitorCollector({
|
|
19
|
+
* workspaceId: "00000000-0000-0000-0000-000000000000",
|
|
20
|
+
* clusterName: "my-aks-cluster",
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export const AzureMonitorCollector = Composite((props) => {
|
|
25
|
+
const { workspaceId, clusterName, name = "azure-monitor-collector", image = "mcr.microsoft.com/azuremonitor/containerinsights/ciprod:3.1.35", namespace = "azure-monitor", labels: extraLabels = {}, cpuRequest = "100m", memoryRequest = "256Mi", cpuLimit = "500m", memoryLimit = "512Mi", clientId, defaults: defs, } = props;
|
|
26
|
+
const saName = `${name}-sa`;
|
|
27
|
+
const clusterRoleName = `${name}-role`;
|
|
28
|
+
const bindingName = `${name}-binding`;
|
|
29
|
+
const configMapName = `${name}-config`;
|
|
30
|
+
const commonLabels = {
|
|
31
|
+
"app.kubernetes.io/name": name,
|
|
32
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
33
|
+
...extraLabels,
|
|
34
|
+
};
|
|
35
|
+
// Build OTel collector config YAML for Azure Monitor
|
|
36
|
+
const collectorConfig = `receivers:
|
|
37
|
+
otlp:
|
|
38
|
+
protocols:
|
|
39
|
+
grpc:
|
|
40
|
+
endpoint: 0.0.0.0:4317
|
|
41
|
+
http:
|
|
42
|
+
endpoint: 0.0.0.0:4318
|
|
43
|
+
|
|
44
|
+
processors:
|
|
45
|
+
batch:
|
|
46
|
+
timeout: 30s
|
|
47
|
+
send_batch_size: 8192
|
|
48
|
+
|
|
49
|
+
exporters:
|
|
50
|
+
azuremonitor:
|
|
51
|
+
connection_string: InstrumentationKey=\${APPINSIGHTS_INSTRUMENTATIONKEY}
|
|
52
|
+
endpoint: https://dc.services.visualstudio.com/v2/track
|
|
53
|
+
azuremonitor/logs:
|
|
54
|
+
workspace_id: ${workspaceId}
|
|
55
|
+
cluster_name: ${clusterName}
|
|
56
|
+
|
|
57
|
+
service:
|
|
58
|
+
pipelines:
|
|
59
|
+
metrics:
|
|
60
|
+
receivers: [otlp]
|
|
61
|
+
processors: [batch]
|
|
62
|
+
exporters: [azuremonitor]
|
|
63
|
+
traces:
|
|
64
|
+
receivers: [otlp]
|
|
65
|
+
processors: [batch]
|
|
66
|
+
exporters: [azuremonitor]
|
|
67
|
+
logs:
|
|
68
|
+
receivers: [otlp]
|
|
69
|
+
processors: [batch]
|
|
70
|
+
exporters: [azuremonitor/logs]
|
|
71
|
+
`;
|
|
72
|
+
const container = {
|
|
73
|
+
name,
|
|
74
|
+
image,
|
|
75
|
+
ports: [
|
|
76
|
+
{ containerPort: 4317, name: "otlp-grpc" },
|
|
77
|
+
{ containerPort: 4318, name: "otlp-http" },
|
|
78
|
+
],
|
|
79
|
+
env: [
|
|
80
|
+
{ name: "AKS_CLUSTER_NAME", value: clusterName },
|
|
81
|
+
{ name: "WORKSPACE_ID", value: workspaceId },
|
|
82
|
+
],
|
|
83
|
+
resources: {
|
|
84
|
+
requests: { cpu: cpuRequest, memory: memoryRequest },
|
|
85
|
+
limits: { cpu: cpuLimit, memory: memoryLimit },
|
|
86
|
+
},
|
|
87
|
+
volumeMounts: [
|
|
88
|
+
{ name: "config", mountPath: "/etc/otel", readOnly: true },
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
const daemonSet = new DaemonSet(mergeDefaults({
|
|
92
|
+
metadata: {
|
|
93
|
+
name,
|
|
94
|
+
namespace,
|
|
95
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
|
|
96
|
+
},
|
|
97
|
+
spec: {
|
|
98
|
+
selector: { matchLabels: { "app.kubernetes.io/name": name } },
|
|
99
|
+
template: {
|
|
100
|
+
metadata: { labels: { "app.kubernetes.io/name": name, ...extraLabels } },
|
|
101
|
+
spec: {
|
|
102
|
+
serviceAccountName: saName,
|
|
103
|
+
containers: [container],
|
|
104
|
+
volumes: [
|
|
105
|
+
{ name: "config", configMap: { name: configMapName } },
|
|
106
|
+
],
|
|
107
|
+
tolerations: [{ operator: "Exists" }],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
}, defs?.daemonSet));
|
|
112
|
+
const saLabels = {
|
|
113
|
+
...commonLabels,
|
|
114
|
+
"app.kubernetes.io/component": "agent",
|
|
115
|
+
};
|
|
116
|
+
if (clientId) {
|
|
117
|
+
saLabels["azure.workload.identity/use"] = "true";
|
|
118
|
+
}
|
|
119
|
+
const serviceAccount = new ServiceAccount(mergeDefaults({
|
|
120
|
+
metadata: {
|
|
121
|
+
name: saName,
|
|
122
|
+
namespace,
|
|
123
|
+
labels: saLabels,
|
|
124
|
+
...(clientId ? { annotations: { "azure.workload.identity/client-id": clientId } } : {}),
|
|
125
|
+
},
|
|
126
|
+
}, defs?.serviceAccount));
|
|
127
|
+
const clusterRole = new ClusterRole(mergeDefaults({
|
|
128
|
+
metadata: {
|
|
129
|
+
name: clusterRoleName,
|
|
130
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
|
|
131
|
+
},
|
|
132
|
+
rules: [
|
|
133
|
+
{ apiGroups: [""], resources: ["pods", "nodes", "endpoints"], verbs: ["get", "list", "watch"] },
|
|
134
|
+
{ apiGroups: ["apps"], resources: ["replicasets"], verbs: ["get", "list", "watch"] },
|
|
135
|
+
{ apiGroups: ["batch"], resources: ["jobs"], verbs: ["get", "list", "watch"] },
|
|
136
|
+
{ apiGroups: [""], resources: ["nodes/proxy"], verbs: ["get"] },
|
|
137
|
+
{ apiGroups: [""], resources: ["nodes/stats", "configmaps", "events"], verbs: ["create", "get"] },
|
|
138
|
+
{ apiGroups: [""], resources: ["configmaps"], verbs: ["get", "update", "create"], resourceNames: ["otel-container-insight-clusterleader"] },
|
|
139
|
+
],
|
|
140
|
+
}, defs?.clusterRole));
|
|
141
|
+
const clusterRoleBinding = new ClusterRoleBinding(mergeDefaults({
|
|
142
|
+
metadata: {
|
|
143
|
+
name: bindingName,
|
|
144
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
|
|
145
|
+
},
|
|
146
|
+
roleRef: {
|
|
147
|
+
apiGroup: "rbac.authorization.k8s.io",
|
|
148
|
+
kind: "ClusterRole",
|
|
149
|
+
name: clusterRoleName,
|
|
150
|
+
},
|
|
151
|
+
subjects: [
|
|
152
|
+
{
|
|
153
|
+
kind: "ServiceAccount",
|
|
154
|
+
name: saName,
|
|
155
|
+
namespace,
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
}, defs?.clusterRoleBinding));
|
|
159
|
+
const configMap = new ConfigMap(mergeDefaults({
|
|
160
|
+
metadata: {
|
|
161
|
+
name: configMapName,
|
|
162
|
+
namespace,
|
|
163
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "config" },
|
|
164
|
+
},
|
|
165
|
+
data: {
|
|
166
|
+
"config.yaml": collectorConfig,
|
|
167
|
+
},
|
|
168
|
+
}, defs?.configMap));
|
|
169
|
+
return {
|
|
170
|
+
daemonSet,
|
|
171
|
+
serviceAccount,
|
|
172
|
+
clusterRole,
|
|
173
|
+
clusterRoleBinding,
|
|
174
|
+
configMap,
|
|
175
|
+
};
|
|
176
|
+
}, "AzureMonitorCollector");
|