# EXAMPLE — a mocked component. Copy, rename, replace. # # A stub that answers on the right name and port with canned responses. No image # to build: the script is mounted from the ConfigMap, so changing the behaviour # is a kubectl apply, not a rebuild. # # Deliberately boring and readable. This is onboarding material — someone should # be able to read the generated object and recognise what it is. apiVersion: v1 kind: ConfigMap metadata: name: example-service-stub data: # Canned responses by path. Add entries as the contract becomes clear; # anything unmatched returns 404 so a missing route is visible, not silent. routes.json: | { "/health": {"status": 200, "body": {"status": "ok"}}, "/v1/example": {"status": 200, "body": {"items": [], "mocked": true}} } serve.py: | import json, os from http.server import BaseHTTPRequestHandler, HTTPServer ROUTES = json.load(open("/etc/stub/routes.json")) NAME = os.environ.get("STUB_NAME", "stub") class H(BaseHTTPRequestHandler): def do_GET(self): r = ROUTES.get(self.path) if r is None: self.send_response(404) self.end_headers() # Say which stub rejected it — with everything mocked, "404" # alone tells you nothing about where the call actually landed. self.wfile.write(json.dumps( {"error": "no canned route", "stub": NAME, "path": self.path} ).encode()) return body = json.dumps(r["body"]).encode() self.send_response(r["status"]) self.send_header("Content-Type", "application/json") self.send_header("X-Mocked-By", NAME) self.end_headers() self.wfile.write(body) def log_message(self, fmt, *args): print("%s %s" % (NAME, fmt % args), flush=True) HTTPServer(("0.0.0.0", 8080), H).serve_forever() --- apiVersion: apps/v1 kind: Deployment metadata: name: example-service labels: app: example-service rig.component/impl: mock # so `kubectl get deploy -L rig.component/impl` # shows at a glance what is real and what is not spec: replicas: 1 selector: matchLabels: app: example-service template: metadata: labels: app: example-service spec: containers: - name: stub image: python:3.12-slim command: ["python3", "/etc/stub/serve.py"] env: - name: STUB_NAME value: example-service ports: - containerPort: 8080 volumeMounts: - name: stub mountPath: /etc/stub readinessProbe: httpGet: { path: /health, port: 8080 } initialDelaySeconds: 2 # Small enough that a whole estate of these fits alongside the real # thing you are working on. resources: requests: { memory: 32Mi, cpu: 10m } limits: { memory: 64Mi } volumes: - name: stub configMap: name: example-service-stub --- apiVersion: v1 kind: Service metadata: name: example-service spec: selector: app: example-service ports: - port: 80 targetPort: 8080