Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
282 lines (243 loc) · 13.1 KB
/
Copy pathMakefile
File metadata and controls
282 lines (243 loc) · 13.1 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
# Generated by patternizer
# This Makefile includes the common pattern targets from Makefile-common
# You can add custom targets above or below the include line
include Makefile-common
##@ Key Management
.PHONY: gen-secrets
gen-secrets: ## Generate KBS keys, sealed-secrets signing key, and values-secret template
@scripts/gen-secrets.sh
.PHONY: cache-keys
cache-keys: ## Download Red Hat signing keys from official sources to ~/.coco-pattern/
@mkdir -p ~/.coco-pattern
@echo "Fetching Red Hat sigstore public key (release key 3)..."
@curl -fsSL https://www.redhat.com/security/data/63405576.txt -o ~/.coco-pattern/SIGSTORE-redhat-release3
@echo " Cached at ~/.coco-pattern/SIGSTORE-redhat-release3"
@echo "Fetching Red Hat GPG public key (release key 2)..."
@curl -fsSL https://access.redhat.com/security/data/fd431d51.txt -o ~/.coco-pattern/RPM-GPG-KEY-redhat-release
@echo " Cached at ~/.coco-pattern/RPM-GPG-KEY-redhat-release"
@echo "Done. Verify fingerprints at https://access.redhat.com/security/team/key/"
.PHONY: cache-registry-ca
cache-registry-ca: ## Copy mirror-registry CA cert to ~/.coco-pattern/ for use by load-secrets
@mkdir -p ~/.coco-pattern
@if [ -f ~/.coco-pattern/quay-ca-cert.pem ]; then \
mv ~/.coco-pattern/quay-ca-cert.pem ~/.coco-pattern/mirror-registry-ca-cert.pem; \
echo " Migrated quay-ca-cert.pem -> mirror-registry-ca-cert.pem"; \
fi
@if [ -f ~/mirror-registry-certs/ca.crt ]; then \
cp ~/mirror-registry-certs/ca.crt ~/.coco-pattern/mirror-registry-ca-cert.pem; \
echo " Cached mirror-registry CA at ~/.coco-pattern/mirror-registry-ca-cert.pem"; \
else \
echo "ERROR: ~/mirror-registry-certs/ca.crt not found."; \
echo " Ensure the mirror registry was initialised and its certs are at ~/mirror-registry-certs/"; \
exit 1; \
fi
.PHONY: load-bootstrap
load-bootstrap: ## Load ArgoCD bootstrap secrets (DEL-2) — run after cluster exists but before Vault is up
@echo "Loading ArgoCD OCI Helm registry bootstrap secret..."
@if ! ./pattern.sh ansible-playbook rhvp.cluster_utils.load_bootstrap_secrets --list-tasks >/dev/null 2>&1; then \
echo "ERROR: load_bootstrap_secrets playbook not found in utility container."; \
echo " Bump utility-container tag in imageset-config and re-mirror."; \
exit 1; \
fi
@echo "Pre-creating bootstrap secret target namespaces (avoids race with patterns-operator)..."
@python3 -c "\
import yaml, os, pathlib; \
pattern = yaml.safe_load(open('values-global.yaml'))['global']['pattern']; \
search = [pathlib.Path(p) for p in [ \
os.environ.get('VALUES_SECRET', ''), \
os.path.expanduser(f'~/values-secret-{pattern}.yaml'), \
os.path.expanduser('~/values-secret.yaml'), \
'values-secret.yaml', \
] if p]; \
f = next((p for p in search if p.is_file()), None); \
data = yaml.safe_load(f.read_text()) if f else {}; \
[print(ns) for s in data.get('bootstrap_secrets',[]) for ns in s.get('targetNamespaces',[])] \
" 2>/dev/null | \
sort -u | xargs -I{} sh -c 'oc create namespace {} --dry-run=client -o yaml | oc apply -f - 2>/dev/null; true'
./pattern.sh ansible-playbook rhvp.cluster_utils.load_bootstrap_secrets
.PHONY: gen-mirror-helm-secret
gen-mirror-helm-secret: ## Generate mirror-registry Helm OCI password file from mirror-registry init output
@mkdir -p ~/.coco-pattern
@echo "Enter the mirror-registry password (from ~/mirror-registry-init.txt or ~/mirror-registry-output/init.json):"
@read -r MRPASS; printf '%s' "$$MRPASS" > ~/.coco-pattern/mirror-registry-password; chmod 600 ~/.coco-pattern/mirror-registry-password
@echo " Saved to ~/.coco-pattern/mirror-registry-password"
.PHONY: enable-airgap-secrets
enable-airgap-secrets: ## Uncomment disconnected-mirror secrets (registryCaCert, bootstrap_secrets) in the generated values-secret file
@scripts/enable-airgap-secrets.sh
##@ Reference Value Collection
.PHONY: collect-firmware-refvals
collect-firmware-refvals: ## Collect bare-metal firmware values; set OCP_VERSION=x.y.z if oc is unavailable (e.g. airgap)
@scripts/collect_firmware_refvals.py --platform baremetal
.PHONY: collect-azure-refvals
collect-azure-refvals: ## Collect PCR reference values (Azure)
@scripts/collect_firmware_refvals.py --platform azure
.PHONY: collect-dcap-collateral
collect-dcap-collateral: dcap-tools ## Collect platform-independent TDX DCAP verification collateral (connected low side)
@scripts/collect-dcap-collateral.sh
##@ Intel TDX PCK Lifecycle
DCAP_PCSCLIENT_REPO ?= $(HOME)/.coco-pattern/intel-dcap
DCAP_PCSCLIENT_DIR ?= $(DCAP_PCSCLIENT_REPO)/tools/PcsClientTool
DCAP_PCSCLIENT_REF ?= 64b78f3766e7196d3d2c60e401540f0f853b2deb
DCAP_PCK_DIR ?= $(HOME)/.coco-pattern/dcap-pck
DCAP_REQUEST_BUNDLE ?= $(DCAP_PCK_DIR)/platform-request
DCAP_RESPONSE_BUNDLE ?= $(DCAP_PCK_DIR)/pck-response
DCAP_NAMESPACE ?= intel-dcap-operator-system
DCAP_QGS_DAEMONSET ?=
DCAP_PCK_EXPIRE_HOURS ?= 8760
DCAP_QGS_TIMEOUT ?= 10m
export DCAP_PCSCLIENT_REPO DCAP_PCSCLIENT_DIR DCAP_PCSCLIENT_REF DCAP_PCK_DIR DCAP_REQUEST_BUNDLE DCAP_RESPONSE_BUNDLE DCAP_NAMESPACE DCAP_QGS_DAEMONSET DCAP_PCK_EXPIRE_HOURS DCAP_QGS_TIMEOUT
.PHONY: dcap-tools
dcap-tools: ## Clone the pinned Intel PcsClientTool and install its Python dependencies (connected low side)
@python3 scripts/dcap-pck.py tools
.PHONY: dcap-platform-export
dcap-platform-export: ## Export QGS platform data as a transfer bundle (disconnected high side; requires oc)
@python3 scripts/dcap-pck.py export
.PHONY: dcap-pck-generate
dcap-pck-generate: dcap-tools ## Generate a PCK response bundle (connected low side; requires Intel PCS access)
@python3 scripts/dcap-pck.py generate
.PHONY: dcap-pck-import
dcap-pck-import: ## Import a PCK response bundle and restart QGS (disconnected high side; requires oc)
@python3 scripts/dcap-pck.py import
.PHONY: dcap-pck-provision
dcap-pck-provision: dcap-tools ## Resume export, generation, and import PCK cache (bastion connected to both Intel PCS and cluster)
@python3 scripts/dcap-pck.py provision
.PHONY: dcap-status
dcap-status: ## Check PCK and collateral expiry (requires oc)
@$(MAKE) check-pck-expiry
@$(MAKE) check-collateral-expiry
.PHONY: check-pck-expiry
check-pck-expiry: ## Check expiry of PCK cache secrets and platform data (requires oc login)
@scripts/check-pck-expiry.sh
.PHONY: check-collateral-expiry
check-collateral-expiry: ## Check expiry of TDX DCAP collateral in trustee-operator-system (requires oc login)
@scripts/check-collateral-expiry.sh
##@ AMD SEV-SNP VCEK Provisioning
.PHONY: snp-collect-vcek-urls
snp-collect-vcek-urls: ## Collect VCEK URLs from AMD SNP nodes (requires KUBECONFIG)
@scripts/collect-snp-vcek-urls.sh
.PHONY: snp-download-vcek
snp-download-vcek: ## Download VCEK certs from AMD KDS (requires internet)
@scripts/download-snp-vcek.sh
.PHONY: snp-gen-overrides
snp-gen-overrides: ## Generate SNP VCEK values override from cached certs (local only)
@scripts/gen-snp-vcek-overrides.sh
.PHONY: snp-offline-provision
snp-offline-provision: snp-collect-vcek-urls snp-download-vcek snp-gen-overrides ## Full SNP VCEK offline provisioning
##@ Disconnected Deployment
MIRROR_REGISTRY ?= quay.example.com:443/mirror
IMAGESET_CONFIG ?= airgap/imageset-config.yaml
OC_MIRROR_WORKSPACE ?= file://$(HOME)/oc-mirror-workspace
.PHONY: airgap-mirror
airgap-mirror: ## Mirror content to disconnected registry (requires MIRROR_REGISTRY)
oc-mirror -c $(IMAGESET_CONFIG) \
--workspace $(OC_MIRROR_WORKSPACE) \
--dest-tls-verify=false \
docker://$(MIRROR_REGISTRY) --v2
.PHONY: airgap-post-install
airgap-post-install: ## Post-install bootstrap (after airgap-mirror + labctl apply-mirror-resources)
@scripts/airgap-post-install.sh
.PHONY: airgap-deploy-pattern
airgap-deploy-pattern: ## Deploy Pattern CR directly (skip pattern.sh, use values-global.yaml config)
@scripts/airgap-post-install.sh --deploy-pattern
.PHONY: airgap-fix-manifests
airgap-fix-manifests: ## Fix oc-mirror manifest list failures with fallback mirroring
@scripts/airgap-post-install.sh --fix-manifest-lists
.PHONY: airgap-sync-repos
airgap-sync-repos: ## Push working copy changes to bare HTTP repos and restart git server
@scripts/airgap-post-install.sh --sync-repos-only
ARGOCD_CLI_DIR ?= $(HOME)/.local/bin
.PHONY: argocd-install
argocd-install: ## Download argocd CLI from the cluster's ArgoCD image into ~/.local/bin
@mkdir -p $(ARGOCD_CLI_DIR)
@ARGOCD_NS=$$(oc get argocd -A -o jsonpath='{.items[0].metadata.namespace}') || \
{ echo "ERROR: No ArgoCD instance found. Is KUBECONFIG set and the pattern deployed?"; exit 1; }; \
ARGOCD_IMG=$$(oc get deployment -n $$ARGOCD_NS -l app.kubernetes.io/component=server,app.kubernetes.io/part-of=argocd \
-o jsonpath='{.items[0].spec.template.spec.containers[0].image}') || \
{ echo "ERROR: Could not find ArgoCD server deployment in $$ARGOCD_NS"; exit 1; }; \
echo "Extracting argocd CLI from $$ARGOCD_IMG ..."; \
POD_NAME="argocd-cli-extract-$$$$"; \
oc run "$$POD_NAME" -n $$ARGOCD_NS --image="$$ARGOCD_IMG" \
--restart=Never --command -- sleep 300; \
echo "Waiting for extract pod..."; \
oc wait --for=condition=Ready pod/"$$POD_NAME" -n $$ARGOCD_NS --timeout=120s; \
oc cp "$$ARGOCD_NS/$$POD_NAME:/usr/local/bin/argocd" "$(ARGOCD_CLI_DIR)/argocd"; \
chmod +x "$(ARGOCD_CLI_DIR)/argocd"; \
oc delete pod "$$POD_NAME" -n $$ARGOCD_NS --force --grace-period=0 2>/dev/null; \
echo "Installed: $(ARGOCD_CLI_DIR)/argocd"; \
$(ARGOCD_CLI_DIR)/argocd version --client | head -1
.PHONY: argocd-login
argocd-login: ## Extract ArgoCD credentials from cluster and log in with argocd CLI
@ARGOCD_NS=$$(oc get argocd -A -o jsonpath='{.items[0].metadata.namespace}' 2>/dev/null) && \
ARGOCD_NAME=$$(oc get argocd -n $$ARGOCD_NS -o jsonpath='{.items[0].metadata.name}' 2>/dev/null) && \
ARGOCD_ROUTE=$$(oc get route $${ARGOCD_NAME}-server -n $$ARGOCD_NS -o jsonpath='{.spec.host}' 2>/dev/null) && \
ARGOCD_PASS=$$(oc get secret $${ARGOCD_NAME}-cluster -n $$ARGOCD_NS -o jsonpath='{.data.admin\.password}' 2>/dev/null | base64 -d) && \
echo "ArgoCD URL: https://$$ARGOCD_ROUTE" && \
echo "Username: admin" && \
echo "Password: $$ARGOCD_PASS" && \
echo "" && \
if command -v argocd >/dev/null 2>&1; then \
oc config set-context --current --namespace=$$ARGOCD_NS && \
argocd login --core && \
echo "" && \
echo "Logged in (core mode, namespace $$ARGOCD_NS)." && \
echo "Usage: argocd app list"; \
else \
echo "argocd CLI not installed. To install:" && \
echo " curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64" && \
echo " chmod +x /usr/local/bin/argocd" && \
echo "" && \
echo "Or use the web UI at: https://$$ARGOCD_ROUTE"; \
fi
##@ Hardware Detection
.PHONY: get-pccs-node
get-pccs-node: ## Detect a node with Intel TDX support for PCCS deployment (requires KUBECONFIG or oc login)
@NODE=$$(oc get nodes -l intel.feature.node.kubernetes.io/tdx=true \
-o jsonpath='{.items[0].metadata.name}' 2>/dev/null); \
if [ -z "$$NODE" ]; then \
echo "ERROR: No TDX-capable nodes found" >&2; \
exit 1; \
fi; \
echo "$$NODE"
.PHONY: detect-hardware
detect-hardware: ## Detect hardware profile from cluster nodes (requires KUBECONFIG or oc login)
@echo "Detecting hardware profile from cluster nodes..."
@echo "---"
@CPU_VENDOR=$$(oc get nodes -o jsonpath='{.items[0].metadata.labels.feature\.node\.kubernetes\.io/cpu-model\.vendor_id}' 2>/dev/null) && \
TDX_ENABLED=$$(oc get nodes -o jsonpath='{.items[0].metadata.labels.feature\.node\.kubernetes\.io/cpu-security\.tdx\.enabled}' 2>/dev/null) && \
SNP_ENABLED=$$(oc get nodes -o jsonpath='{.items[0].metadata.labels.feature\.node\.kubernetes\.io/cpu-security\.sev\.snp}' 2>/dev/null) && \
GPU_PRESENT=$$(oc get nodes -o jsonpath='{.items[0].metadata.labels.nvidia\.com/gpu\.present}' 2>/dev/null) && \
echo "CPU Vendor: $${CPU_VENDOR:-unknown}" && \
echo "TDX Enabled: $${TDX_ENABLED:-false}" && \
echo "SNP Enabled: $${SNP_ENABLED:-false}" && \
echo "GPU Present: $${GPU_PRESENT:-false}" && \
echo "---" && \
if [ "$${CPU_VENDOR}" = "Intel" ] && [ "$${TDX_ENABLED}" = "true" ]; then \
if [ "$${GPU_PRESENT}" = "true" ]; then \
echo "Recommended profile: intel-tdx-gpu"; \
else \
echo "Recommended profile: intel-tdx"; \
fi; \
elif [ "$${CPU_VENDOR}" = "AuthenticAMD" ] || [ "$${SNP_ENABLED}" = "true" ]; then \
if [ "$${GPU_PRESENT}" = "true" ]; then \
echo "Recommended profile: amd-snp-gpu"; \
else \
echo "Recommended profile: amd-snp"; \
fi; \
else \
echo "Could not determine hardware profile."; \
echo "Ensure NFD operator is running and node labels are populated."; \
echo "Set global.hardware.profile manually in values-global.yaml"; \
fi && \
echo "" && \
echo "To apply: edit values-global.yaml and set global.hardware.profile to the recommended value."
##@ Chart Management
KYVERNO_VERSION ?= 3.7.2
KYVERNO_REPO ?= https://kyverno.github.io/kyverno/
.PHONY: update-kyverno-chart
update-kyverno-chart: ## Pull and embed upstream Kyverno Helm chart (requires internet)
@echo "Pulling kyverno chart v$(KYVERNO_VERSION)..."
@rm -rf charts/vendor/kyverno
@helm pull kyverno --repo $(KYVERNO_REPO) --version $(KYVERNO_VERSION) --untar -d charts/vendor/
@find charts/vendor/kyverno -name "README.md" -o -name "README.md.gotmpl" | xargs rm -f
@echo "Embedded charts/vendor/kyverno (v$(KYVERNO_VERSION))"
@echo "Next: commit, push, and sync ArgoCD"