Repository navigation
Expand file tree
/
Copy pathTaskfile.yaml
More file actions
300 lines (258 loc) · 10.9 KB
/
Copy pathTaskfile.yaml
File metadata and controls
300 lines (258 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
version: "3"
vars:
ENVIRONMENT: '{{.ENVIRONMENT | default "development"}}'
tasks:
default:
desc: Show available tasks
cmds:
- task --list
help:
desc: Show usage
cmds:
- |
echo ""
echo "Usage:"
echo " task <target> [ENVIRONMENT=development|staging|production|hub]"
echo ""
task --list
# === Validation ===
lint:yaml:
desc: Run yamllint on all YAML files
cmds:
- yamllint -c .yamllint.yaml .
kustomize:build:
desc: Build all Kustomize overlays (all environments) + env-agnostic roots
cmds:
- |
echo "Building all Kustomize overlays..."
find . -path '*/overlays/*/kustomization.yaml' -exec dirname {} \; | while read dir; do
echo "Building $dir ..."
kustomize build --enable-helm "$dir" > /dev/null || exit 1
done
# Env-agnostic kustomize roots — identical on every cluster (their
# per-environment values resolve through External Secrets and the
# cluster generator), so they carry no per-env overlays.
for dir in dashboards/base addons/bootstrap/secret-stores; do
echo "Building $dir ..."
kustomize build --enable-helm "$dir" > /dev/null || exit 1
done
echo "All manifests built successfully."
kustomize:build:env:
desc: "Build overlays for ENVIRONMENT (default: development)"
cmds:
- |
echo "Building {{.ENVIRONMENT}} overlays..."
find . -path "*/overlays/{{.ENVIRONMENT}}/kustomization.yaml" -exec dirname {} \; | while read dir; do
echo "Building $dir ..."
kustomize build --enable-helm "$dir" > /dev/null || exit 1
done
echo "All {{.ENVIRONMENT}} overlays built successfully."
validate:dashboards:
desc: "Dashboard gate — grafana.com ids must exist and be AMG-saveable"
cmds:
- ./scripts/validate-dashboards.py
validate:fork-safety:
desc: "Fork-safety gate — no hardcoded catalog repoURL in applied ApplicationSets (local report-only; CI runs it --blocking)"
cmds:
- ./scripts/check-hardcoded-org.py
validate:helm-render:
desc: "Helm-render gate — template every addon against its appset-pinned chart + per-env values"
cmds:
- ./scripts/render-addons.py
validate:appset-schema:
desc: "ApplicationSet schema gate — kubeconform over applicationsets/"
cmds:
- KUBECONFORM_SKIP="" ./scripts/kubeconform-scan.sh applicationsets/
validate:gate-tests:
desc: "Gate-script unit tests + the coverage ratchet"
cmds:
# Through coverage so the ratchet in run.py applies. Bare `./run.py` still
# works and skips the ratchet — a developer running the suite should not
# be told the measurement failed, but CI and this target always measure.
- COVERAGE_REQUIRED=1 coverage run --rcfile=.coveragerc scripts/tests/run.py
validate:env-coverage:
desc: "Env-coverage gate — every addon carries a values file for each environment its appset reaches"
cmds:
- ./scripts/check-env-coverage.py
validate:image-pins:
desc: "Image-pin gate — every image the fleet renders carries an immutable reference"
cmds:
- ./scripts/check-image-pins.py
validate:image-vulnerabilities:
desc: "Image-CVE gate — every fixed CRITICAL in a rendered image is acknowledged in image-advisories.yaml"
cmds:
# Pulls and scans every image the pinned charts render, so it is slower
# than the structural gates and is NOT in `task validate`. CI runs it as
# its own blocking job; run it here before moving a chart pin.
- ./scripts/check-image-vulnerabilities.py
validate:workflows:
desc: "Workflow supply-chain gate — zizmor over .github/workflows, offline, MEDIUM+ blocks"
cmds:
- ./scripts/check-workflows.sh
validate:ai-config:
desc: "AI control-plane gate — model ids are us. inference profiles, routes are allowlisted, budgets enforce"
cmds:
- ./scripts/check-ai-config.py
validate:named-things:
desc: "Prose gate — every repo path, task target and file:line citation in markdown resolves"
cmds:
- ./scripts/check-named-things.py
validate:gate-controls:
desc: "Positive controls — every gate rejects the violation it exists to catch"
cmds:
- ./scripts/tests/controls.py
validate:alert-severity-routes:
desc: "Alert routing gate — every severity a rule claims resolves to a declared contact point"
cmds:
- ./scripts/check-alert-severity-routes.py
validate:empty-corpus:
desc: "Vacuity gate — no gate reports success over a corpus that is not there"
cmds:
- ./scripts/tests/empty-corpus.py
validate:reverify-tests:
desc: "Mutation harness — revert a gate behaviour and require the suite to name it"
cmds:
- ./scripts/tests/reverify-tests.sh
reverify:gates:
desc: "Tier-1 re-verification — plant a defect per gate and read each tool's own exit status (slow; runs `task validate` twice)"
cmds:
- ./scripts/tests/reverify-gates.sh
validate:policy-validity:
desc: "Policy-validity gate — every rendered policy overlay is one Kyverno will accept"
cmds:
- ./scripts/check-policy-validity.py
lint:python:
desc: "Python lint + typecheck — ruff and mypy over scripts/ INCLUDING scripts/tests"
cmds:
- ruff check .
# Tests are in scope on purpose: a fixture that drifts from the gate it
# exercises is exactly the drift a type checker sees and a test run does not.
- mypy
validate:falco-rule-floor:
desc: "Falco rule gate — every installed rule set is read, and the priority floor loads it"
cmds:
- ./scripts/check-falco-rule-floor.py
validate:log-volume-budget:
desc: "Log-volume gate — the Loki ingestion cutoff is declared and the fill alert leads it"
cmds:
- ./scripts/check-log-volume-budget.py
validate:renovate-coverage:
desc: "Renovate coverage gate — every chart pin, and every toolchain version a CI job runs on, is watched by a manager that resolves"
cmds:
- ./scripts/check-renovate-coverage.py
validate:sync-waves:
desc: "Sync-wave gate — documented category ordering holds across the appsets"
cmds:
- ./scripts/check-sync-waves.py
validate:label-values:
desc: "Label-value gate — every k8s label value satisfies the API server's grammar"
cmds:
- ./scripts/check-label-values.py
validate:appset-render:
desc: "Appset render gate — render the Karpenter EC2NodeClass patch template against fixture cluster Secrets"
dir: applicationsets/rendertest
cmds:
- go test ./...
validate:policy-admission:
desc: "Policy-admission gate — render the fleet and prove no addon is denied by the Enforce-tier Kyverno policies (+ exclusion-list parity)"
cmds:
- ./scripts/check-policy-admission.py
validate:externalsecret-keys:
desc: "ExternalSecret key gate — each names its remote secret once, and the delivering appset patches it"
cmds:
- ./scripts/check-externalsecret-keys.py
validate:secret-store-refs:
desc: "Secret-store gate — every reference names the one store this catalog declares, and the published contract states it"
cmds:
- ./scripts/check-secret-store-refs.py
validate:directory-manifest-size:
desc: "Directory-source gate — every directory source fits the combined-manifest ceiling the repo-server is configured for"
cmds:
- ./scripts/check-directory-manifest-size.py
- ./scripts/check-directory-manifest-size.py --self-test
validate:lb-scheme-inputs:
desc: "Load-balancer scheme gate — every input the controller decides a scheme on is one the injection policy reads"
cmds:
- ./scripts/check-lb-scheme-inputs.py
- ./scripts/check-lb-scheme-inputs.py --self-test
validate:athena-panel-columns:
desc: "Athena panel gate — every column a CUR panel names is one the export delivers"
cmds:
- ./scripts/check-athena-panel-columns.py
validate:
desc: Run every gate this repo can run offline — lint, build, helm-render, schema, sync waves, label values, appset render, policy admission, and the reference/derivation gates
deps:
- lint:yaml
- lint:python
- kustomize:build
- validate:helm-render
- validate:appset-schema
- validate:sync-waves
- validate:label-values
- validate:appset-render
- validate:policy-admission
- validate:externalsecret-keys
- validate:secret-store-refs
- validate:directory-manifest-size
- validate:lb-scheme-inputs
- validate:athena-panel-columns
- validate:dashboards
- validate:fork-safety
- validate:renovate-coverage
- validate:log-volume-budget
- validate:falco-rule-floor
- validate:policy-validity
- validate:gate-tests
- validate:gate-controls
- validate:alert-severity-routes
- validate:empty-corpus
- validate:reverify-tests
- validate:named-things
- validate:ai-config
- validate:workflows
- validate:image-pins
- validate:env-coverage
cmds:
- echo "All validations passed."
scan:
desc: "Schema + misconfiguration gates on rendered/ (run task render first)"
cmds:
# Shared kubeconform invocation — same skip list as CI (scripts/kubeconform-scan.sh).
- ./scripts/kubeconform-scan.sh rendered
- |
trivy config --exit-code 1 \
--severity MEDIUM,HIGH,CRITICAL \
--ignorefile .trivyignore.yaml \
rendered
# === Rendering ===
render:
desc: "Render overlays to rendered/ directory for ENVIRONMENT (default: development)"
cmds:
- |
mkdir -p rendered
echo "Rendering {{.ENVIRONMENT}} overlays..."
find . -path "*/overlays/{{.ENVIRONMENT}}/kustomization.yaml" -exec dirname {} \; | while read dir; do
name=$(echo "$dir" | sed 's|^\./||' | tr '/' '-')
echo "Rendering $dir ..."
kustomize build --enable-helm "$dir" > "rendered/${name}.yaml" || exit 1
done
# Druid catalog chart with synthetic tenant values — same render CI
# gates (see .github/workflows/ci.yml).
echo "Rendering catalog/druid/chart ..."
helm template ci catalog/druid/chart -n druid-ci \
-f catalog/druid/values.yaml \
--set hostedId=ci \
--set environment={{.ENVIRONMENT}} \
--set secrets.metadata=ci/druid/metadata \
--set secrets.admin=ci/druid/admin \
--set secrets.system=ci/druid/system \
--set secrets.keystore=ci/druid/keystore \
--set s3.indexLogsBucket=ci-druid-indexlogs \
--set s3.deepStorageBucket=ci-druid-deepstorage \
--set s3.msqBucket=ci-druid-msq \
> rendered/catalog-druid-chart.yaml
echo "All {{.ENVIRONMENT}} overlays rendered to rendered/"
clean:
desc: Remove rendered output
cmds:
- rm -rf rendered/