Skip to content

Commit b0d6ae6

Browse files
committed
examples/kms-health-kind: <DROP> add KIND harness
Self-contained throwaway harness for validating the health package against a real KIND cluster. Defaults to cluster name kms-health-claude. fake-plugin/ ~90-line k8s.io/kms/pkg/service.Service with AES-GCM and a file-marker unhealthy toggle. cmd/monitor/ wraps health.NewCommand. cmd/render-container/ wraps health.GenerateContainerTemplate; the harness Deployment mirrors its output. manifests/ fake-plugin runs as a static pod in kube-system; monitor runs as a Deployment in kms-health-test pinned to the control-plane node; both share the host's /tmp bind-mounted at /var/run/kmsplugin-fake/ for the UDS. RBAC splits into two rules since k8s ignores create on rules with resourceNames. verify.sh six end-to-end assertions. Drop this commit before merging to keep examples/ out of the library.
1 parent 27214dd commit b0d6ae6

15 files changed

Lines changed: 761 additions & 0 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Disposable image for the KIND harness. Build from the LIBRARY-GO
2+
# MODULE ROOT so the context includes vendor/ and go.mod:
3+
# docker build -f examples/kms-health-kind/Dockerfile.fake-plugin -t kms-health-kind-fake-plugin:dev .
4+
FROM golang:1.25 AS build
5+
WORKDIR /src
6+
COPY . .
7+
RUN CGO_ENABLED=0 GOFLAGS=-mod=vendor \
8+
go build -trimpath -ldflags='-s -w' \
9+
-o /out/fake-plugin \
10+
./examples/kms-health-kind/fake-plugin
11+
12+
FROM gcr.io/distroless/static:nonroot
13+
COPY --from=build /out/fake-plugin /fake-plugin
14+
USER nonroot:nonroot
15+
ENTRYPOINT ["/fake-plugin"]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Disposable image for the KIND harness. Build from the LIBRARY-GO
2+
# MODULE ROOT so the context includes vendor/ and go.mod:
3+
# docker build -f examples/kms-health-kind/Dockerfile.monitor -t kms-health-kind-monitor:dev .
4+
FROM golang:1.25 AS build
5+
WORKDIR /src
6+
COPY . .
7+
RUN CGO_ENABLED=0 GOFLAGS=-mod=vendor \
8+
go build -trimpath -ldflags='-s -w' \
9+
-o /out/monitor \
10+
./examples/kms-health-kind/cmd/monitor
11+
12+
FROM gcr.io/distroless/static:nonroot
13+
COPY --from=build /out/monitor /monitor
14+
USER nonroot:nonroot
15+
ENTRYPOINT ["/monitor"]

examples/kms-health-kind/Makefile

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# KMSv2 health-monitor KIND harness. Disposable.
2+
#
3+
# All targets should be run from the library-go module root:
4+
# make -C examples/kms-health-kind kind-verify
5+
6+
CLUSTER ?= kms-health-claude
7+
IMAGE_FAKE_PLUGIN ?= kms-health-kind-fake-plugin:dev
8+
IMAGE_MONITOR ?= kms-health-kind-monitor:dev
9+
CTX := kind-$(CLUSTER)
10+
NODE := $(CLUSTER)-control-plane
11+
FAKE_POD := kms-fake-plugin-$(NODE)
12+
13+
# Dockerfile build context = library-go module root (need vendor/, go.mod).
14+
REPO_ROOT := $(shell cd ../.. && pwd -P)
15+
HARNESS_DIR := $(shell pwd -P)
16+
17+
.PHONY: build-images
18+
build-images:
19+
docker build -t $(IMAGE_FAKE_PLUGIN) \
20+
-f $(HARNESS_DIR)/Dockerfile.fake-plugin \
21+
$(REPO_ROOT)
22+
docker build -t $(IMAGE_MONITOR) \
23+
-f $(HARNESS_DIR)/Dockerfile.monitor \
24+
$(REPO_ROOT)
25+
26+
.PHONY: kind-up
27+
kind-up:
28+
CLUSTER=$(CLUSTER) $(HARNESS_DIR)/bin/up.sh
29+
30+
.PHONY: kind-down
31+
kind-down:
32+
CLUSTER=$(CLUSTER) $(HARNESS_DIR)/bin/down.sh
33+
34+
## Distroless fake-plugin has no touch/rm; flip via node /tmp (bind-mounted
35+
## to /var/run/kmsplugin-fake/ in both pods).
36+
.PHONY: flip-unhealthy
37+
flip-unhealthy:
38+
docker exec $(NODE) touch /tmp/kms-unhealthy
39+
40+
.PHONY: flip-healthy
41+
flip-healthy:
42+
docker exec $(NODE) rm -f /tmp/kms-unhealthy
43+
44+
## Drift check: diff output against monitor-deployment.yaml's container block.
45+
.PHONY: render-container
46+
render-container:
47+
go run $(REPO_ROOT)/examples/kms-health-kind/cmd/render-container \
48+
--kms-plugin-name=fake \
49+
--image=$(IMAGE_MONITOR) \
50+
--command=/usr/bin/kms-health-monitor \
51+
--probe-interval=2s \
52+
--probe-interval-unhealthy=1s \
53+
--probe-timeout=1s \
54+
--write-timeout=5s \
55+
--configmap-namespace=kms-health-test
56+
57+
.PHONY: verify
58+
verify:
59+
CLUSTER=$(CLUSTER) $(HARNESS_DIR)/verify.sh
60+
61+
.PHONY: kind-verify
62+
kind-verify: build-images kind-up verify
63+
@echo ""
64+
@echo "================================================="
65+
@echo " kind-verify PASSED on cluster ${CLUSTER}"
66+
@echo " tear down with: make kind-down"
67+
@echo "================================================="
68+
69+
.PHONY: cm
70+
cm:
71+
kubectl --context $(CTX) -n kms-health-test get cm kms-health-fake -o yaml
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Tear down the KIND cluster created by up.sh. Safe to re-run.
4+
5+
set -o errexit
6+
set -o nounset
7+
set -o pipefail
8+
9+
unset KIND_EXPERIMENTAL_PROVIDER
10+
11+
CLUSTER="${CLUSTER:-kms-health-claude}"
12+
13+
if kind get clusters 2>/dev/null | grep -qx "${CLUSTER}"; then
14+
echo "[down.sh] deleting kind cluster ${CLUSTER}"
15+
kind delete cluster --name "${CLUSTER}"
16+
else
17+
echo "[down.sh] cluster ${CLUSTER} not found — nothing to do"
18+
fi

examples/kms-health-kind/bin/up.sh

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Create a KIND cluster named ${CLUSTER} (default: kms-health-claude)
4+
# with a KMSv2 fake plugin (static pod) and a health-monitor Deployment
5+
# pinned to the control-plane node. Self-contained — doesn't depend on
6+
# kubernetes/kubernetes/hack/local-up-kms.
7+
#
8+
# Run from the library-go module root.
9+
10+
set -o errexit
11+
set -o nounset
12+
set -o pipefail
13+
14+
# Force docker — this harness's Dockerfiles build with `docker build`
15+
# and `kind load docker-image` needs the same backend. User may have
16+
# KIND_EXPERIMENTAL_PROVIDER=podman set globally; unset locally.
17+
unset KIND_EXPERIMENTAL_PROVIDER
18+
19+
CLUSTER="${CLUSTER:-kms-health-claude}"
20+
KIND_NODE_IMAGE="${KIND_NODE_IMAGE:-kindest/node:v1.33.0}"
21+
22+
HARNESS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
23+
24+
echo "[up.sh] cluster=${CLUSTER} node=${KIND_NODE_IMAGE}"
25+
echo "[up.sh] harness-dir=${HARNESS_DIR}"
26+
27+
# kind.yaml uses paths relative to the harness dir (manifests/...).
28+
cd "${HARNESS_DIR}"
29+
30+
# 1) Create the cluster (idempotent).
31+
if kind get clusters 2>/dev/null | grep -qx "${CLUSTER}"; then
32+
echo "[up.sh] cluster ${CLUSTER} already exists, reusing"
33+
else
34+
echo "[up.sh] creating kind cluster ${CLUSTER}"
35+
kind create cluster \
36+
--name "${CLUSTER}" \
37+
--image "${KIND_NODE_IMAGE}" \
38+
--config manifests/kind.yaml
39+
fi
40+
41+
CTX="kind-${CLUSTER}"
42+
NODE="${CLUSTER}-control-plane"
43+
STATIC_POD="kms-fake-plugin-${NODE}"
44+
45+
# 2) Load our local images.
46+
echo "[up.sh] loading images into cluster"
47+
kind load docker-image kms-health-kind-fake-plugin:dev --name "${CLUSTER}"
48+
kind load docker-image kms-health-kind-monitor:dev --name "${CLUSTER}"
49+
50+
# 3) Force the static pod to restart so it picks up the freshly-loaded
51+
# image (kubelet may have cached an ErrImageNeverPull from before).
52+
echo "[up.sh] bouncing fake-plugin container so it picks up loaded image"
53+
FAKE_CID="$(docker exec "${NODE}" crictl ps --name fake-plugin -q 2>/dev/null | head -1 || true)"
54+
if [ -n "${FAKE_CID}" ]; then
55+
docker exec "${NODE}" crictl stop "${FAKE_CID}" >/dev/null || true
56+
fi
57+
58+
# 4) Apply namespace + RBAC + monitor Deployment. The status ConfigMap
59+
# is created by the writer itself on first observation; nothing
60+
# pre-creates it.
61+
echo "[up.sh] applying namespace, RBAC, monitor Deployment"
62+
kubectl --context "${CTX}" apply -f manifests/namespace.yaml
63+
kubectl --context "${CTX}" apply -f manifests/rbac.yaml
64+
kubectl --context "${CTX}" apply -f manifests/monitor-deployment.yaml
65+
66+
# 5) Wait for the monitor Deployment to be Available. Apiserver is NOT
67+
# wired to KMS here (see manifests/kind.yaml) — we're only
68+
# validating the monitor, not apiserver/KMS integration.
69+
echo "[up.sh] waiting for monitor Deployment"
70+
kubectl --context "${CTX}" -n kms-health-test rollout status deployment/kms-health-monitor-fake --timeout=120s
71+
72+
MONITOR_POD="$(kubectl --context "${CTX}" -n kms-health-test get pod \
73+
-l app=kms-health-monitor-fake \
74+
-o jsonpath='{.items[0].metadata.name}')"
75+
echo "[up.sh] done."
76+
echo " cluster: ${CLUSTER}"
77+
echo " monitor pod: ${MONITOR_POD} (kms-health-test)"
78+
echo " status cm: kms-health-fake (kms-health-test)"
79+
echo " fake plugin: ${STATIC_POD} (kube-system, static)"
80+
echo ""
81+
echo "Try:"
82+
echo " kubectl --context ${CTX} -n kms-health-test get cm kms-health-fake -o yaml"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Command monitor is the throwaway KIND-stage binary that bundles
2+
// library-go's health.NewCommand(). Production builds come from the
3+
// OpenShift operator repos; this main exists only so the KIND harness
4+
// has something to put in a Dockerfile.
5+
package main
6+
7+
import (
8+
"fmt"
9+
"os"
10+
11+
genericapiserver "k8s.io/apiserver/pkg/server"
12+
"k8s.io/klog/v2"
13+
14+
"github.com/openshift/library-go/pkg/operator/encryption/kms/health"
15+
)
16+
17+
func main() {
18+
ctx := genericapiserver.SetupSignalContext()
19+
cmd := health.NewCommand(ctx)
20+
if err := cmd.ExecuteContext(ctx); err != nil {
21+
fmt.Fprintln(os.Stderr, err)
22+
klog.Flush()
23+
os.Exit(1)
24+
}
25+
klog.Flush()
26+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Disposable CLI: prints what health.GenerateContainerTemplate emits, so
2+
// the KIND harness validates the production template end-to-end.
3+
package main
4+
5+
import (
6+
"flag"
7+
"fmt"
8+
"os"
9+
"strings"
10+
"time"
11+
12+
"sigs.k8s.io/yaml"
13+
14+
"github.com/openshift/library-go/pkg/operator/encryption/kms/health"
15+
)
16+
17+
func main() {
18+
var (
19+
pluginName = flag.String("kms-plugin-name", "",
20+
"DNS-1123 label identifying the plugin instance (required)")
21+
image = flag.String("image", "", "operator image (required)")
22+
cmdStr = flag.String("command", "",
23+
"operator binary command, comma-separated (required), e.g. /usr/bin/kms-health-monitor")
24+
probeInterval = flag.Duration("probe-interval", 60*time.Second, "")
25+
probeIntervalUnhealthy = flag.Duration("probe-interval-unhealthy", 10*time.Second, "")
26+
probeTimeout = flag.Duration("probe-timeout", 3*time.Second, "")
27+
writeTimeout = flag.Duration("write-timeout", 5*time.Second, "")
28+
ns = flag.String("configmap-namespace", "",
29+
"operand namespace (required)")
30+
)
31+
flag.Parse()
32+
33+
var cmdParts []string
34+
if *cmdStr != "" {
35+
cmdParts = strings.Split(*cmdStr, ",")
36+
}
37+
38+
container, err := health.GenerateContainerTemplate(health.ContainerOptions{
39+
KMSPluginName: *pluginName,
40+
OperatorImage: *image,
41+
OperatorCommand: cmdParts,
42+
ProbeInterval: *probeInterval,
43+
ProbeIntervalUnhealthy: *probeIntervalUnhealthy,
44+
ProbeTimeout: *probeTimeout,
45+
WriteTimeout: *writeTimeout,
46+
ConfigMapNamespace: *ns,
47+
})
48+
if err != nil {
49+
fmt.Fprintln(os.Stderr, "render-container:", err)
50+
os.Exit(1)
51+
}
52+
53+
out, err := yaml.Marshal(&container)
54+
if err != nil {
55+
fmt.Fprintln(os.Stderr, "render-container: marshal:", err)
56+
os.Exit(1)
57+
}
58+
if _, err := os.Stdout.Write(out); err != nil {
59+
fmt.Fprintln(os.Stderr, "render-container: write:", err)
60+
os.Exit(1)
61+
}
62+
}

0 commit comments

Comments
 (0)