#!/usr/bin/env bash # This file is intentionally sourceable. Assertions have no cluster or network side # effects; executable rendering is guarded at the bottom of the file. observability_expected_helm_version() { printf '%s\n' 'v3.19.4'; } observability_expected_kustomize_version() { printf '%s\n' 'v5.8.1'; } observability_helm_kube_version() { printf '%s\n' '1.36.2'; } chart_pin_rows() { cat <<'ROWS' prometheus-operator-crds https://prometheus-community.github.io/helm-charts prometheus-operator-crds 31.0.0 v0.93.0 5d11cac50321bc7ae56b35d2701e56f21fe079ca3aea872abb28a3e2119d5cfd infrastructure/controllers/prometheus-operator-crds kube-prometheus-stack https://prometheus-community.github.io/helm-charts kube-prometheus-stack 88.0.1 v0.93.0 0998b3fae8660cd9ea224caa1c7c4b5d2040d5a02c64e3cdfd3f48d184b50117 services/observability/kube-prometheus-stack loki https://grafana-community.github.io/helm-charts loki 18.7.1 3.7.4 de9ab59827f2ed24634e94db120ea2467f5d08b02e8d7c250e6bf88c17bfb48d services/observability/loki tempo https://grafana-community.github.io/helm-charts tempo 2.2.3 2.10.7 14c52efe5d0cad5456ffa5a8be1e5107be47d184be3e209f748be51a7b0316fe services/observability/tempo alloy https://grafana.github.io/helm-charts alloy 1.11.0 v1.18.0 11d253b62e47beeacd89eb4283fc056962ecbf143984863c1998be13da0772dd services/observability/alloy prometheus-node-exporter https://prometheus-community.github.io/helm-charts prometheus-node-exporter 4.56.1 1.12.1 70fab291e00a34c58fd943bb075fecc2e2e73fa95db1bcbbe7cdfe008795354a services/observability/node-exporter grafana https://grafana-community.github.io/helm-charts grafana 12.10.1 13.1.1 ff865a8b9d1d7563901b8e6aa653b4f345bd4d88344c149065bd23958e2beeb8 services/observability/grafana prometheus-blackbox-exporter https://prometheus-community.github.io/helm-charts prometheus-blackbox-exporter 11.16.0 v0.28.0 932aa65df0538d9dc003c46bb663ebe44a06078af7a6a54577af5339668ac65b services/observability/blackbox-exporter ROWS } image_pin_rows() { cat <<'ROWS' quay.io/prometheus-operator/prometheus-operator:v0.93.0 sha256:64eb7914e4705dbb64438e3b3193da1226ad2ea4db2924983693999888cda9b2 quay.io/prometheus-operator/prometheus-config-reloader:v0.93.0 sha256:65b90f44d5535b106015ac60bafb57803f65dc928c187874de6cd7a9ec6c8905 quay.io/prometheus/prometheus:v3.13.2-distroless sha256:ce95cfa77eff5aad28bd7a65aff19868cf78d9e17e4c254da7dfe22ade78318b quay.io/prometheus/alertmanager:v0.33.1 sha256:a89f8d4520954079275441eecdb71444328bd90633dd4eddfc33b9ed657f349b registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.19.1 sha256:7661da8c99b733d43117e4cba12bd9865d335e5777191d0af3d789807aded9f4 quay.io/prometheus/node-exporter:v1.12.1 sha256:da83fae85603c4e47e6c68369a7d746e2dda683dc35ea2e234b4f171e0d92798 docker.io/grafana/loki:3.7.4 sha256:d80be589cf74b6d92747a1b155bec6f07bdd65e261f797fe93a78fb4e833032e docker.io/grafana/tempo:2.10.7 sha256:6616b00287a4d7001951b5de117828ad5c6f93744935c1b7a5e044736373352c docker.io/grafana/alloy:v1.18.0 sha256:eb21f4c0858edffcdd1b385910ddeef26f692fc2c282f61baa724fc09d274a17 ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:v0.153.0 sha256:9708a1d33398c8725549104d1f6009be62569e47e094430543da0f66758cc522 docker.io/library/busybox:1.37.0 sha256:7a3ebe5bfd1a4a19797d20b0c0bb39d44393e9a03fd852c0865b0f540d868df0 quay.io/minio/aistor/mc sha256:c5ec777c080fd6292b7529309a0f311c58c3a92e268c9c57c0901da86881949b docker.io/grafana/grafana:13.1.1 sha256:f33c692ba1a5ee15724cf6b22db65e9de39dde14d80f7d73a9546e3fc917270b quay.io/kiwigrid/k8s-sidecar:2.10.0 sha256:129877c81acf2bc8c3fa000e89a62e020eb89d41ceb94767c657aef5bb0cc0d3 quay.io/prometheus/blackbox-exporter:v0.28.0 sha256:43027b43fb785b7c5adc53bd3b5dbc1a258270a2e8aff24f477b45c4e38dac68 ROWS } render_root_rows() { cat <<'ROWS' infrastructure/namespaces/observability infrastructure/controllers/prometheus-operator-crds infrastructure/storage/observability-local-pv services/observability/kube-prometheus-stack services/observability/loki services/observability/tempo services/observability/alloy services/observability/node-exporter services/observability/grafana services/observability/blackbox-exporter services/observability/network-policies services/observability/targets services/observability/rules/platform services/observability/alerting services/observability/dashboards/platform services/observability ROWS } _observability_image_allowlist() { image_pin_rows | awk -F '\t' ' { tagged=$1 base=$1 sub(/:[^/:]+$/, "", base) print base "@" $2 if (tagged != base) { print tagged "@" $2 } } ' } _observability_yaml_assert() { local mode="$1" shift python3 - "$mode" "$@" <<'PY' import base64 import binascii import json import os import re import sys import yaml class ObservabilitySafeLoader(yaml.SafeLoader): pass # The pinned Prometheus Operator CRDs contain the valid scalar enum value "=". # PyYAML resolves that token to its YAML value tag but does not provide a safe # constructor for it, so accept only that scalar tag without enabling unsafe # object construction. ObservabilitySafeLoader.add_constructor( "tag:yaml.org,2002:value", lambda loader, node: loader.construct_scalar(node), ) def reject(reason): print(f"REJECT: observability render assertion failed: {reason}", file=sys.stderr) raise SystemExit(23) def documents(paths): result = [] try: for path in paths: with open(path, "r", encoding="utf-8") as stream: for value in yaml.load_all(stream, Loader=ObservabilitySafeLoader): if value is not None: if not isinstance(value, dict): reject("YAML document is not an object") result.append(value) except (OSError, yaml.YAMLError): reject("manifest is unreadable or invalid YAML") return result def pod_specs(items): def inherited_metadata(parent, template): result = dict(template or {}) for key in ("name", "namespace"): if not result.get(key) and (parent or {}).get(key): result[key] = parent[key] return result for item in items: kind = str(item.get("kind", "")) metadata = item.get("metadata") or {} spec = item.get("spec") or {} if kind == "Pod": yield metadata, spec elif kind in {"Deployment", "DaemonSet", "StatefulSet", "Job", "ReplicaSet", "ReplicationController"}: template = spec.get("template") or {} yield inherited_metadata(metadata, template.get("metadata")), template.get("spec") or {} elif kind == "CronJob": template = (((spec.get("jobTemplate") or {}).get("spec") or {}).get("template") or {}) yield inherited_metadata(metadata, template.get("metadata")), template.get("spec") or {} def walk(value): yield value if isinstance(value, dict): for child in value.values(): yield from walk(child) elif isinstance(value, list): for child in value: yield from walk(child) mode = sys.argv[1] paths = sys.argv[2:] items = documents(paths) if mode == "pinned_images": allowed = set(filter(None, os.environ.get("OBSERVABILITY_ALLOWED_IMAGES", "").splitlines())) if not allowed: reject("image pin table is empty") images = [] for _, spec in pod_specs(items): for key in ("initContainers", "containers", "ephemeralContainers"): for container in spec.get(key) or []: image = container.get("image") if not isinstance(image, str) or not image: reject("container image is missing") images.append(image) for image in images: if not re.fullmatch(r"[^\s@]+@sha256:[0-9a-f]{64}", image): reject("an image is not pinned by amd64 digest") if image not in allowed: reject("an image is absent from the fixed image table") elif mode == "no_credentials": sensitive_name = re.compile(r"(?:password|passwd|secret|token|access[_-]?key|secret[_-]?key|private[_-]?key)", re.I) safe_reference = re.compile(r"^(?:\$\{[^}]+\}|\$\([^)]*\)|<[^>]+>)$") for item in items: if item.get("kind") == "Secret": metadata = item.get("metadata") or {} data = item.get("data") or {} string_data = item.get("stringData") or {} allowed_alertmanager_config = ( metadata.get("namespace") == "observability" and metadata.get("name") == "alertmanager-observability-core-kube-pr-alertmanager" and item.get("type") in (None, "Opaque") and set(data) == {"alertmanager.yaml"} and not string_data ) if not allowed_alertmanager_config: reject("Secret resources are forbidden") try: raw_config = base64.b64decode(data["alertmanager.yaml"], validate=True) parsed_config = yaml.load(raw_config, Loader=ObservabilitySafeLoader) except (binascii.Error, UnicodeError, yaml.YAMLError): reject("allowed Alertmanager config Secret is malformed") if not isinstance(parsed_config, dict): reject("allowed Alertmanager config Secret is not an object") receivers = parsed_config.get("receivers") route = parsed_config.get("route") or {} if receivers != [{"name": "null"}] or route.get("receiver") != "null" or route.get("routes") != []: reject("allowed Alertmanager config Secret is not credential-free") if re.search( rb"(?i)(?:password|passwd|secret|token|api[_-]?url|webhook|access[_-]?key|private[_-]?key)", raw_config, ): reject("allowed Alertmanager config Secret contains a credential field") for _, spec in pod_specs([item]): for key in ("initContainers", "containers", "ephemeralContainers"): for container in spec.get(key) or []: for env in container.get("env") or []: if sensitive_name.search(str(env.get("name", ""))) and "value" in env: reject("literal credential environment value is forbidden") for node in walk(item): if not isinstance(node, dict): continue for key, value in node.items(): if not sensitive_name.fullmatch(str(key)) or not isinstance(value, str) or not value: continue if not safe_reference.fullmatch(value): reject("literal credential payload is forbidden") elif mode == "namespace_security": for metadata, spec in pod_specs(items): namespace = str(metadata.get("namespace", "")) if namespace not in {"observability", "observability-agent"}: reject("Pod namespace must be observability or observability-agent") automount = spec.get("automountServiceAccountToken") api_reader_allowlist = { ("observability", "observability-core-kube-pr-operator"), ("observability", "observability-core-kube-state-metrics"), } identity = (namespace, str(metadata.get("name", ""))) if identity in api_reader_allowlist: if automount is not True: reject("allowlisted API reader must explicitly mount its service-account token") elif automount is not False: reject("Pod service-account automount must be explicit false") for field in ("hostNetwork", "hostPID", "hostIPC"): if spec.get(field) is True: reject(f"{field} is forbidden") containers = [] for key in ("initContainers", "containers", "ephemeralContainers"): containers.extend(spec.get(key) or []) for container in containers: if (container.get("securityContext") or {}).get("privileged") is True: reject("privileged containers are forbidden") for port in container.get("ports") or []: if port.get("hostPort") not in (None, 0): reject("hostPort is forbidden") host_volumes = {} for volume in spec.get("volumes") or []: host_path = volume.get("hostPath") if isinstance(host_path, dict): host_volumes[str(volume.get("name", ""))] = str(host_path.get("path", "")) if namespace == "observability" and host_volumes: reject("hostPath is forbidden in observability") if namespace == "observability-agent": identity_parts = [str(metadata.get("name", ""))] identity_parts.extend(str(v) for v in (metadata.get("labels") or {}).values()) identity = " ".join(identity_parts).lower() if "alloy" in identity: allowed_paths = {"/var/log/pods"} elif "node-exporter" in identity or "node_exporter" in identity: allowed_paths = {"/proc", "/sys", "/"} else: allowed_paths = set() for volume_name, host_path in host_volumes.items(): if host_path not in allowed_paths: reject("agent hostPath is outside the workload allowlist") mounts = [ mount for container in containers for mount in (container.get("volumeMounts") or []) if mount.get("name") == volume_name ] if not mounts or any(mount.get("readOnly") is not True for mount in mounts): reject("agent hostPath mounts must be read-only") elif mode == "no_public_exposure": for item in items: kind = str(item.get("kind", "")) if kind == "Ingress": metadata = item.get("metadata") or {} spec = item.get("spec") or {} expected_spec = { "ingressClassName": "traefik", "rules": [ { "host": "grafana.learn.hyeonworks.com", "http": { "paths": [ { "backend": { "service": { "name": "grafana", "port": {"number": 80}, } }, "path": "/", "pathType": "Prefix", } ] }, } ], } if ( metadata.get("namespace") != "observability" or metadata.get("name") != "grafana" or spec != expected_spec ): reject("only the exact Host-Nginx-fronted Grafana Ingress is allowed") if kind == "Service": service_type = str((item.get("spec") or {}).get("type", "ClusterIP")) if service_type in {"NodePort", "LoadBalancer", "ExternalName"}: reject("non-ClusterIP Service is forbidden") spec = item.get("spec") or {} if spec.get("externalIPs") or spec.get("externalName"): reject("external Service routing is forbidden") elif mode == "no_loki_auxiliary": forbidden = re.compile(r"(?:^|[-_.])(gateway|canary|chunks-cache|results-cache|test|minio)(?:$|[-_.])", re.I) for item in items: metadata = item.get("metadata") or {} identity = " ".join([str(metadata.get("name", ""))] + [str(v) for v in (metadata.get("labels") or {}).values()]) if forbidden.search(identity) or str(item.get("kind", "")).lower() == "minio": reject("forbidden Loki auxiliary resource is present") elif mode == "tempo_topology": forbidden = re.compile(r"(?:metrics-generator|tempo-query|query-frontend)", re.I) for item in items: metadata = item.get("metadata") or {} identity = " ".join([str(metadata.get("name", ""))] + [str(v) for v in (metadata.get("labels") or {}).values()]) if forbidden.search(identity): reject("forbidden Tempo auxiliary resource is present") def inspect_config(value): if isinstance(value, dict): receivers = value.get("receivers") if isinstance(receivers, dict): for receiver_name, receiver in receivers.items(): if not str(receiver_name).lower().startswith("otlp") or not isinstance(receiver, dict): continue protocols = receiver.get("protocols") or {} if "http" in protocols: reject("Tempo OTLP HTTP receiver is forbidden") if set(protocols) - {"grpc"}: reject("Tempo has an unexpected OTLP protocol") for child in value.values(): inspect_config(child) elif isinstance(value, list): for child in value: inspect_config(child) elif isinstance(value, str) and ("receivers:" in value or "4318" in value): if re.search(r"(?m)^\s*http\s*:", value) or re.search(r"(?{{ end }}\n\n{{ end }}\n · ","footer":"hyeonworks observability · Alertmanager"}]}]}}''') if configs != [expected_config]: reject("platform AlertmanagerConfig is not the exact global Slack contract") policies = [ item for item in items if item.get("kind") == "NetworkPolicy" and (item.get("metadata") or {}).get("name") == "observability-allow-alertmanager-public-https" ] expected_policy = { "apiVersion": "networking.k8s.io/v1", "kind": "NetworkPolicy", "metadata": { "name": "observability-allow-alertmanager-public-https", "namespace": "observability", }, "spec": { "podSelector": { "matchLabels": { "app.kubernetes.io/name": "alertmanager", "app.kubernetes.io/instance": "observability-core-kube-pr-alertmanager", } }, "policyTypes": ["Egress"], "egress": [ { "to": [ { "ipBlock": { "cidr": "0.0.0.0/0", "except": [ "10.0.0.0/8", "100.64.0.0/10", "172.16.0.0/12", "192.168.0.0/16", ], } } ], "ports": [{"protocol": "TCP", "port": 443}], } ], }, } if policies != [expected_policy]: reject("Alertmanager public HTTPS policy is not exact") elif mode == "no_crds": if any(item.get("kind") == "CustomResourceDefinition" for item in items): reject("CRD is present in a workload render") elif mode == "unique_local_pv_storage_classes": seen = {} for item in items: if item.get("kind") != "PersistentVolume": continue spec = item.get("spec") or {} if "local" not in spec: continue storage_class = str(spec.get("storageClassName", "")) if not storage_class: reject("Local PV StorageClass is missing") seen[storage_class] = seen.get(storage_class, 0) + 1 if any(count > 1 for count in seen.values()): reject("a Local PV StorageClass is shared") elif mode == "no_unscoped_monitors_rules": monitored_kinds = {"ServiceMonitor", "PodMonitor", "Probe", "PrometheusRule"} forbidden = re.compile(r"(?:spring|kafka|batch|backup)", re.I) for item in items: if item.get("kind") not in monitored_kinds: continue metadata = item.get("metadata") or {} if forbidden.search(str(metadata.get("name", ""))): reject("out-of-scope monitor or rule is present") if item.get("kind") == "PrometheusRule": for node in walk((item.get("spec") or {}).get("groups") or []): if isinstance(node, dict): for key in ("alert", "record"): if forbidden.search(str(node.get(key, ""))): reject("out-of-scope monitor or rule is present") else: reject("unknown assertion mode") PY } assert_pinned_images() { local allowed allowed="$(_observability_image_allowlist)" || return OBSERVABILITY_ALLOWED_IMAGES="$allowed" _observability_yaml_assert pinned_images "$@" } assert_no_credentials() { _observability_yaml_assert no_credentials "$@"; } assert_namespace_pod_security() { _observability_yaml_assert namespace_security "$@"; } assert_no_public_exposure() { _observability_yaml_assert no_public_exposure "$@"; } assert_no_loki_auxiliary() { _observability_yaml_assert no_loki_auxiliary "$@"; } assert_tempo_topology() { _observability_yaml_assert tempo_topology "$@"; } assert_selector_values() { _observability_yaml_assert selector_values "$@"; } assert_prometheus_selectors() { _observability_yaml_assert prometheus_selectors "$@"; } assert_alertmanager_routing_contract() { _observability_yaml_assert alertmanager_routing "$@"; } assert_no_crds() { _observability_yaml_assert no_crds "$@"; } assert_unique_local_pv_storage_classes() { _observability_yaml_assert unique_local_pv_storage_classes "$@"; } assert_no_unscoped_monitors_rules() { _observability_yaml_assert no_unscoped_monitors_rules "$@"; } validate_chart_metadata() { local chart_yaml="$1" local expected_name="$2" local expected_version="$3" local expected_app_version="$4" python3 - "$chart_yaml" "$expected_name" "$expected_version" "$expected_app_version" <<'PY' import sys import yaml try: with open(sys.argv[1], "r", encoding="utf-8") as stream: chart = yaml.safe_load(stream) except (OSError, yaml.YAMLError): print("REJECT: Chart.yaml is unreadable or invalid", file=sys.stderr) raise SystemExit(23) expected = {"name": sys.argv[2], "version": sys.argv[3], "appVersion": sys.argv[4]} if not isinstance(chart, dict) or any(str(chart.get(key, "")) != value for key, value in expected.items()): print("REJECT: chart name/version/appVersion does not match the fixed table", file=sys.stderr) raise SystemExit(23) PY } validate_render_roots() { local root="$1" shift python3 - "$root" "$@" <<'PY' import os import stat import sys def reject(reason): print(f"REJECT: render root preflight failed: {reason}", file=sys.stderr) raise SystemExit(23) def physical_directory(path): current = os.sep for component in path.split(os.sep)[1:]: if not component: reject("path is not normalized") current = os.path.join(current, component) try: metadata = os.lstat(current) except OSError: reject("required directory is missing") if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode): reject("directory lineage is not physical") root = sys.argv[1] if not os.path.isabs(root) or os.path.normpath(root) != root: reject("workspace root must be a normalized absolute path") physical_directory(root) if os.path.realpath(root) != root: reject("workspace root lineage is not physical") roots = sys.argv[2:] if not roots: reject("render root list is empty") for relative in roots: parts = relative.split("/") if not relative or relative.startswith("/") or any(part in {"", ".", ".."} for part in parts): reject("relative render root is unsafe") target = os.path.join(root, *parts) physical_directory(target) if os.path.realpath(target) != target: reject("render root lineage is not physical") PY } _observability_handoff_operation() { local action="$1" local directory="$2" local identity="${3:-}" local work="${4:-}" python3 - "$action" "$directory" "$identity" "$work" <<'PY' import hashlib import os import stat import sys EXPECTED_NAMES = ( "namespaces.yaml", "crds.yaml", "storage.yaml", "kps.yaml", "loki.yaml", "tempo.yaml", "alloy.yaml", "node-exporter.yaml", "grafana.yaml", "blackbox.yaml", "core-policies.yaml", "targets.yaml", "core-rules.yaml", "alerting.yaml", "dashboards.yaml", "aggregate.yaml", "resource-index.tsv", ) PREFIX = "platform-observability-core-apply." class Rejected(Exception): pass def reject(reason): raise Rejected(reason) def path_metadata(directory, require_empty): if os.path.dirname(directory) != "/tmp": reject("handoff must be a direct /tmp child") name = os.path.basename(directory) if not name.startswith(PREFIX) or len(name) == len(PREFIX): reject("handoff suffix is missing") try: tmp_metadata = os.lstat("/tmp") metadata = os.lstat(directory) except OSError: reject("handoff directory is missing") if stat.S_ISLNK(tmp_metadata.st_mode) or not stat.S_ISDIR(tmp_metadata.st_mode): reject("/tmp is not a physical directory") if os.path.realpath("/tmp") != "/tmp": reject("/tmp lineage is not physical") if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode): reject("handoff is not a physical directory") if metadata.st_uid != os.getuid() or stat.S_IMODE(metadata.st_mode) != 0o700: reject("handoff owner or mode differs") if require_empty and os.listdir(directory): reject("handoff directory is not empty") return metadata def parse_identity(value): fields = value.split(":") if len(fields) != 2 or any(not field.isdigit() for field in fields): reject("handoff identity is malformed") return tuple(int(field) for field in fields) def same_identity(metadata, expected): return (metadata.st_dev, metadata.st_ino) == expected def open_pinned_directory(directory, identity): expected = parse_identity(identity) metadata = path_metadata(directory, False) if not same_identity(metadata, expected): reject("handoff directory identity changed") try: descriptor = os.open(directory, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW) except OSError: reject("handoff directory cannot be opened safely") opened = os.fstat(descriptor) if not same_identity(opened, expected): os.close(descriptor) reject("opened handoff identity differs") return descriptor, expected def sha256_descriptor(descriptor): digest = hashlib.sha256() while True: chunk = os.read(descriptor, 1024 * 1024) if not chunk: return digest.hexdigest() digest.update(chunk) def validate_entries(directory, identity): descriptor, expected = open_pinned_directory(directory, identity) try: names = os.listdir(descriptor) if set(names) != set(EXPECTED_NAMES) or len(names) != len(EXPECTED_NAMES): reject("handoff entry set differs") for name in EXPECTED_NAMES: metadata = os.stat(name, dir_fd=descriptor, follow_symlinks=False) if not stat.S_ISREG(metadata.st_mode) or metadata.st_uid != os.getuid(): reject("handoff entry type or owner differs") if stat.S_IMODE(metadata.st_mode) != 0o600: reject("handoff entry mode differs") current = os.lstat(directory) if not same_identity(current, expected): reject("handoff path identity changed") finally: os.close(descriptor) def publish(directory, identity, work): descriptor, expected = open_pinned_directory(directory, identity) created = [] temporary_created = [] sources = {} try: if os.listdir(descriptor): reject("handoff directory is not empty immediately before publication") try: work_metadata = os.lstat(work) except OSError: reject("verified render directory is missing") if stat.S_ISLNK(work_metadata.st_mode) or not stat.S_ISDIR(work_metadata.st_mode): reject("verified render directory is not physical") for name in EXPECTED_NAMES: source = os.path.join(work, name) try: source_metadata = os.lstat(source) except OSError: reject("verified output is missing") if stat.S_ISLNK(source_metadata.st_mode) or not stat.S_ISREG(source_metadata.st_mode): reject("verified output type differs") source_descriptor = os.open(source, os.O_RDONLY | os.O_NOFOLLOW) try: sources[name] = sha256_descriptor(source_descriptor) finally: os.close(source_descriptor) for position, name in enumerate(EXPECTED_NAMES): source = os.path.join(work, name) temporary_name = f".handoff-{os.getpid()}-{position}" try: target_descriptor = os.open( temporary_name, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600, dir_fd=descriptor, ) except OSError: reject("handoff staging no-clobber creation failed") temporary_created.append(temporary_name) try: source_descriptor = os.open(source, os.O_RDONLY | os.O_NOFOLLOW) try: while True: chunk = os.read(source_descriptor, 1024 * 1024) if not chunk: break view = memoryview(chunk) while view: written = os.write(target_descriptor, view) view = view[written:] finally: os.close(source_descriptor) os.fchmod(target_descriptor, 0o600) os.fsync(target_descriptor) finally: os.close(target_descriptor) try: os.link( temporary_name, name, src_dir_fd=descriptor, dst_dir_fd=descriptor, follow_symlinks=False, ) except OSError: reject("handoff output atomic no-clobber publication failed") created.append(name) os.unlink(temporary_name, dir_fd=descriptor) temporary_created.remove(temporary_name) os.fsync(descriptor) if set(os.listdir(descriptor)) != set(EXPECTED_NAMES): reject("handoff entry set changed during publication") for name in EXPECTED_NAMES: metadata = os.stat(name, dir_fd=descriptor, follow_symlinks=False) if not stat.S_ISREG(metadata.st_mode) or metadata.st_uid != os.getuid(): reject("published handoff entry is unsafe") if stat.S_IMODE(metadata.st_mode) != 0o600: reject("published handoff entry mode differs") target_descriptor = os.open(name, os.O_RDONLY | os.O_NOFOLLOW, dir_fd=descriptor) try: if sha256_descriptor(target_descriptor) != sources[name]: reject("published handoff content differs") finally: os.close(target_descriptor) current = os.lstat(directory) if not same_identity(current, expected): reject("handoff path identity changed during publication") except BaseException: for name in reversed(created): try: os.unlink(name, dir_fd=descriptor) except OSError: pass for name in reversed(temporary_created): try: os.unlink(name, dir_fd=descriptor) except OSError: pass raise finally: os.close(descriptor) action, directory, identity, work = sys.argv[1:5] try: if action == "validate": path_metadata(directory, True) elif action == "pin": metadata = path_metadata(directory, True) print(f"{metadata.st_dev}:{metadata.st_ino}") elif action == "entries": validate_entries(directory, identity) elif action == "publish": publish(directory, identity, work) else: reject("unknown handoff operation") except Rejected as error: print(f"REJECT: handoff validation failed: {error}", file=sys.stderr) raise SystemExit(23) except OSError: print("REJECT: handoff validation failed: filesystem operation failed", file=sys.stderr) raise SystemExit(23) PY } validate_handoff_directory() { _observability_handoff_operation validate "$1"; } pin_handoff_directory() { _observability_handoff_operation pin "$1"; } validate_handoff_entry_set() { _observability_handoff_operation entries "$1" "$2"; } publish_verified_handoff() { _observability_handoff_operation publish "$1" "$2" "$3"; } build_resource_index() { local output="$1" shift python3 - "$output" "$@" <<'PY' import hashlib import json import os import sys import tempfile import yaml class ResourceIndexSafeLoader(yaml.SafeLoader): pass ResourceIndexSafeLoader.add_constructor( "tag:yaml.org,2002:value", lambda loader, node: loader.construct_scalar(node), ) def fail(reason): print(f"REJECT: resource index failed: {reason}", file=sys.stderr) raise SystemExit(23) def read_objects(source_specs): objects = [] tuples = set() try: for source_spec in source_specs: if ":" not in source_spec: fail("source specification is malformed") source, path = source_spec.split(":", 1) if not source or not path: fail("source specification is malformed") with open(path, "r", encoding="utf-8") as stream: for document in yaml.load_all(stream, Loader=ResourceIndexSafeLoader): if document is None: continue if not isinstance(document, dict): fail("YAML document is not an object") metadata = document.get("metadata") or {} identity = ( str(document.get("apiVersion", "")), str(document.get("kind", "")), str(metadata.get("namespace", "")), str(metadata.get("name", "")), ) if not all((identity[0], identity[1], identity[3])): fail("resource identity is incomplete") if identity in tuples: fail("duplicate resource tuple") tuples.add(identity) canonical = json.dumps(document, sort_keys=True, separators=(",", ":"), ensure_ascii=False) digest = hashlib.sha256(canonical.encode("utf-8")).hexdigest() objects.append((source, identity, digest)) except (OSError, yaml.YAMLError): fail("manifest is unreadable or invalid YAML") return objects output = sys.argv[1] objects = read_objects(sys.argv[2:]) directory = os.path.dirname(output) or "." fd, temporary = tempfile.mkstemp(prefix=".resource-index.", dir=directory, text=True) try: with os.fdopen(fd, "w", encoding="utf-8") as stream: stream.write("order\tartifact\tapiVersion\tkind\tnamespace\tname\tcanonicalSha256\n") for order, (source, identity, digest) in enumerate(objects, 1): stream.write("\t".join((str(order), source, *identity, digest)) + "\n") os.chmod(temporary, 0o600) os.replace(temporary, output) except BaseException: try: os.unlink(temporary) except OSError: pass raise PY } assert_child_aggregate_equivalence() { local aggregate="$1" shift python3 - "$aggregate" "$@" <<'PY' import hashlib import json import sys import yaml class AggregateSafeLoader(yaml.SafeLoader): pass AggregateSafeLoader.add_constructor( "tag:yaml.org,2002:value", lambda loader, node: loader.construct_scalar(node), ) def fail(reason): print(f"REJECT: aggregate equivalence failed: {reason}", file=sys.stderr) raise SystemExit(23) def object_map(paths): result = {} try: for path in paths: with open(path, "r", encoding="utf-8") as stream: for document in yaml.load_all(stream, Loader=AggregateSafeLoader): if document is None: continue if not isinstance(document, dict): fail("YAML document is not an object") metadata = document.get("metadata") or {} identity = ( str(document.get("apiVersion", "")), str(document.get("kind", "")), str(metadata.get("namespace", "")), str(metadata.get("name", "")), ) if not all((identity[0], identity[1], identity[3])): fail("resource identity is incomplete") if identity in result: fail("duplicate resource tuple") canonical = json.dumps(document, sort_keys=True, separators=(",", ":"), ensure_ascii=False) result[identity] = hashlib.sha256(canonical.encode("utf-8")).hexdigest() except (OSError, yaml.YAMLError): fail("manifest is unreadable or invalid YAML") return result aggregate_path = sys.argv[1] child_paths = [] for source_spec in sys.argv[2:]: if ":" not in source_spec: fail("source specification is malformed") source, path = source_spec.split(":", 1) if not source or not path: fail("source specification is malformed") child_paths.append(path) children = object_map(child_paths) aggregate = object_map([aggregate_path]) if children.keys() != aggregate.keys(): fail("child and aggregate resource sets differ") if children != aggregate: fail("child and aggregate canonical object hashes differ") PY } _observability_fail() { printf 'ERROR: %s\n' "$*" >&2 return 1 } _observability_reject() { printf 'REJECT: %s\n' "$*" >&2 return 23 } _observability_preflight_chart_cache() { local relative_root="$1" local chart="$2" local version="$3" local relative_parent cache validate_render_roots "$_OBS_ROOT" "$relative_root" || return for relative_parent in "$relative_root/.helm" "$relative_root/.helm/charts"; do cache="$_OBS_ROOT/$relative_parent" if [[ -e "$cache" || -L "$cache" ]]; then validate_render_roots "$_OBS_ROOT" "$relative_parent" || return fi done cache="$_OBS_ROOT/$relative_root/.helm/charts/$chart-$version" [[ ! -e "$cache" && ! -L "$cache" ]] || \ _observability_reject 'exact chart cache already exists' } _observability_record_cache_directory() { local directory="$1" local cleanup_type="$2" local identity identity="$(stat --format='%d:%i' "$directory")" || return _OBS_CREATED_CACHE_DIRS+=("$directory") _OBS_CREATED_CACHE_IDENTITIES+=("$identity") _OBS_CREATED_CACHE_TYPES+=("$cleanup_type") } _observability_create_cache_directory() { local relative_root="$1" local chart="$2" local version="$3" local created_rows directory identity cleanup_type [[ -v _OBS_CREATED_CACHE_DIRS ]] || _OBS_CREATED_CACHE_DIRS=() [[ -v _OBS_CREATED_CACHE_IDENTITIES ]] || _OBS_CREATED_CACHE_IDENTITIES=() [[ -v _OBS_CREATED_CACHE_TYPES ]] || _OBS_CREATED_CACHE_TYPES=() _observability_preflight_chart_cache "$relative_root" "$chart" "$version" || return created_rows="$(python3 - "$_OBS_ROOT" "$relative_root" "$chart-$version" <<'PY' import errno import os import stat import sys class Rejected(Exception): pass def reject(reason): raise Rejected(reason) def open_directory(name, parent=None): flags = os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW try: if parent is None: return os.open(name, flags) return os.open(name, flags, dir_fd=parent) except OSError: reject("cache directory lineage is not physical") root, relative_root, exact_name = sys.argv[1:4] parts = relative_root.split("/") if not os.path.isabs(root) or os.path.normpath(root) != root: reject("workspace root is unsafe") if not relative_root or any(part in {"", ".", ".."} for part in parts): reject("cache root is unsafe") if not exact_name or "/" in exact_name or exact_name in {".", ".."}: reject("exact cache name is unsafe") descriptors = [] created = [] cache_parts = [] try: current = open_directory("/") descriptors.append(current) for component in root.split("/")[1:]: next_descriptor = open_directory(component, current) descriptors.append(next_descriptor) current = next_descriptor for component in parts: next_descriptor = open_directory(component, current) descriptors.append(next_descriptor) current = next_descriptor for name, cleanup_type in ((".helm", "empty"), ("charts", "empty")): try: next_descriptor = os.open( name, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=current ) except FileNotFoundError: try: os.mkdir(name, 0o700, dir_fd=current) except OSError: reject("exclusive cache parent creation failed") next_descriptor = open_directory(name, current) metadata = os.fstat(next_descriptor) full_path = os.path.join(root, relative_root, *cache_parts, name) created.append((current, name, full_path, metadata.st_dev, metadata.st_ino, cleanup_type)) except OSError: reject("cache parent is not a physical directory") descriptors.append(next_descriptor) current = next_descriptor cache_parts.append(name) try: os.mkdir(exact_name, 0o700, dir_fd=current) except OSError: reject("exclusive exact cache creation failed") exact_descriptor = open_directory(exact_name, current) descriptors.append(exact_descriptor) metadata = os.fstat(exact_descriptor) exact_path = os.path.join(root, relative_root, ".helm", "charts", exact_name) created.append((current, exact_name, exact_path, metadata.st_dev, metadata.st_ino, "tree")) for _, _, path, device, inode, cleanup_type in created: print(f"{path}\t{device}:{inode}\t{cleanup_type}") except Rejected as error: for parent, name, _, _, _, _ in reversed(created): try: os.rmdir(name, dir_fd=parent) except OSError: pass print(f"REJECT: cache creation failed: {error}", file=sys.stderr) raise SystemExit(23) finally: for descriptor in reversed(descriptors): try: os.close(descriptor) except OSError: pass PY )" || return while IFS=$'\t' read -r directory identity cleanup_type; do [[ -n "$directory" && -n "$identity" && -n "$cleanup_type" ]] || \ _observability_reject 'cache creation result is incomplete' || return _OBS_CREATED_CACHE_DIRS+=("$directory") _OBS_CREATED_CACHE_IDENTITIES+=("$identity") _OBS_CREATED_CACHE_TYPES+=("$cleanup_type") _OBS_LAST_CACHE_PATH="$directory" _OBS_LAST_CACHE_IDENTITY="$identity" done <<<"$created_rows" } _observability_cache_identity_matches() { local directory="$1" local identity="$2" [[ -d "$directory" && ! -L "$directory" ]] || return 1 [[ "$(stat --format='%d:%i' "$directory")" == "$identity" ]] } _observability_cleanup_owned_cache_directory() { local directory="$1" local identity="$2" local cleanup_type="$3" local race_hook="${4:-}" python3 - "$_OBS_ROOT" "$directory" "$identity" "$cleanup_type" "$race_hook" <<'PY' import ctypes import errno import os import secrets import stat import subprocess import sys RENAME_NOREPLACE = 1 class Rejected(Exception): pass def reject(reason): raise Rejected(reason) def parse_identity(value): fields = value.split(":") if len(fields) != 2 or any(not field.isdigit() for field in fields): reject("tracked identity is malformed") return tuple(int(field) for field in fields) def identity(metadata): return metadata.st_dev, metadata.st_ino libc = ctypes.CDLL(None, use_errno=True) try: renameat2 = libc.renameat2 except AttributeError: reject("renameat2 is unavailable") renameat2.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p, ctypes.c_uint] renameat2.restype = ctypes.c_int def rename_no_replace(parent_descriptor, source, target): result = renameat2( parent_descriptor, os.fsencode(source), parent_descriptor, os.fsencode(target), RENAME_NOREPLACE, ) if result != 0: error = ctypes.get_errno() raise OSError(error, os.strerror(error)) def random_name(): return f".observability-cleanup-{os.getpid()}-{secrets.token_hex(16)}" def restore_if_possible(parent_descriptor, quarantine, original): try: rename_no_replace(parent_descriptor, quarantine, original) return True except OSError: return False def quarantine_entry(parent_descriptor, name): try: original_metadata = os.stat(name, dir_fd=parent_descriptor, follow_symlinks=False) except OSError: reject("tracked entry disappeared") quarantine = random_name() try: rename_no_replace(parent_descriptor, name, quarantine) except OSError: reject("tracked entry quarantine failed") try: moved_metadata = os.stat(quarantine, dir_fd=parent_descriptor, follow_symlinks=False) except OSError: reject("quarantined entry disappeared") if identity(moved_metadata) != identity(original_metadata): restore_if_possible(parent_descriptor, quarantine, name) reject("entry identity changed during quarantine") return quarantine, moved_metadata def remove_owned_entry(parent_descriptor, name): quarantine, metadata = quarantine_entry(parent_descriptor, name) try: if stat.S_ISDIR(metadata.st_mode) and not stat.S_ISLNK(metadata.st_mode): child_descriptor = os.open( quarantine, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=parent_descriptor, ) try: if identity(os.fstat(child_descriptor)) != identity(metadata): reject("opened child identity differs") clear_owned_directory(child_descriptor) finally: os.close(child_descriptor) current = os.stat(quarantine, dir_fd=parent_descriptor, follow_symlinks=False) if identity(current) != identity(metadata): reject("child identity changed before removal") os.rmdir(quarantine, dir_fd=parent_descriptor) else: current = os.stat(quarantine, dir_fd=parent_descriptor, follow_symlinks=False) if identity(current) != identity(metadata): reject("entry identity changed before removal") os.unlink(quarantine, dir_fd=parent_descriptor) except BaseException: restore_if_possible(parent_descriptor, quarantine, name) raise def clear_owned_directory(descriptor): for name in os.listdir(descriptor): remove_owned_entry(descriptor, name) os.fsync(descriptor) def open_physical_parent(path): parent = os.path.dirname(path) descriptor = os.open("/", os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW) try: for component in parent.split("/")[1:]: if not component: reject("cleanup path is not normalized") next_descriptor = os.open( component, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=descriptor, ) os.close(descriptor) descriptor = next_descriptor return descriptor except BaseException: os.close(descriptor) raise root, directory, expected_value, cleanup_type, race_hook = sys.argv[1:6] parent_descriptor = None owned_descriptor = None top_quarantine = None top_name = os.path.basename(directory) try: if not os.path.isabs(root) or os.path.normpath(root) != root: reject("workspace root is unsafe") if not os.path.isabs(directory) or os.path.normpath(directory) != directory: reject("cleanup path is unsafe") if os.path.commonpath((root, directory)) != root or directory == root: reject("cleanup path escapes workspace root") if cleanup_type == "tree": if "/.helm/charts/" not in directory: reject("recursive cleanup target is not an exact chart cache") elif cleanup_type == "empty": if not (directory.endswith("/.helm") or directory.endswith("/.helm/charts")): reject("empty cleanup target is not a cache parent") else: reject("cleanup type is invalid") expected = parse_identity(expected_value) parent_descriptor = open_physical_parent(directory) metadata = os.stat(top_name, dir_fd=parent_descriptor, follow_symlinks=False) if not stat.S_ISDIR(metadata.st_mode) or stat.S_ISLNK(metadata.st_mode): reject("tracked cache is not a physical directory") if identity(metadata) != expected: reject("tracked cache identity differs") top_quarantine, quarantined_metadata = quarantine_entry(parent_descriptor, top_name) if identity(quarantined_metadata) != expected: restore_if_possible(parent_descriptor, top_quarantine, top_name) reject("tracked cache identity changed during quarantine") owned_descriptor = os.open( top_quarantine, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=parent_descriptor, ) if identity(os.fstat(owned_descriptor)) != expected: reject("opened tracked cache identity differs") if race_hook: hook_metadata = os.lstat(race_hook) if ( stat.S_ISLNK(hook_metadata.st_mode) or not stat.S_ISREG(hook_metadata.st_mode) or hook_metadata.st_uid != os.getuid() or not os.access(race_hook, os.X_OK) ): reject("cleanup race hook is unsafe") result = subprocess.run( [race_hook, directory], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False, ) if result.returncode != 0: reject("cleanup race hook failed") if cleanup_type == "tree": clear_owned_directory(owned_descriptor) elif os.listdir(owned_descriptor): reject("tracked cache parent is not empty") os.close(owned_descriptor) owned_descriptor = None current = os.stat(top_quarantine, dir_fd=parent_descriptor, follow_symlinks=False) if identity(current) != expected: reject("quarantined cache identity changed before removal") os.rmdir(top_quarantine, dir_fd=parent_descriptor) top_quarantine = None except (Rejected, OSError) as error: if owned_descriptor is not None: try: os.close(owned_descriptor) except OSError: pass if top_quarantine is not None and parent_descriptor is not None: restore_if_possible(parent_descriptor, top_quarantine, top_name) if isinstance(error, Rejected): reason = str(error) else: reason = "descriptor-relative filesystem operation failed" print(f"REJECT: cache cleanup failed: {reason}", file=sys.stderr) raise SystemExit(23) finally: if parent_descriptor is not None: try: os.close(parent_descriptor) except OSError: pass PY } _observability_cleanup_cache_dirs() { local index directory identity cleanup_type cleanup_rc=0 [[ -v _OBS_CREATED_CACHE_DIRS ]] || return 0 for ((index=${#_OBS_CREATED_CACHE_DIRS[@]} - 1; index >= 0; index--)); do directory="${_OBS_CREATED_CACHE_DIRS[$index]}" identity="${_OBS_CREATED_CACHE_IDENTITIES[$index]}" cleanup_type="${_OBS_CREATED_CACHE_TYPES[$index]}" _observability_cleanup_owned_cache_directory \ "$directory" "$identity" "$cleanup_type" || cleanup_rc=23 done _OBS_CREATED_CACHE_DIRS=() _OBS_CREATED_CACHE_IDENTITIES=() _OBS_CREATED_CACHE_TYPES=() return "$cleanup_rc" } _observability_prepare_chart() { local label="$1" local repo="$2" local chart="$3" local version="$4" local app_version="$5" local expected_sha="$6" local relative_root="$7" local cache="$_OBS_ROOT/$relative_root/.helm/charts/$chart-$version" local archive="$_OBS_WORK/$chart-$version.tgz" local actual_sha chart_yaml cache_identity cache_fd cache_fd_identity _observability_preflight_chart_cache "$relative_root" "$chart" "$version" || return "$_OBS_HELM" pull "$chart" --repo "$repo" --version "$version" --destination "$_OBS_WORK" [[ -f "$archive" && ! -L "$archive" ]] || _observability_fail "$label archive is missing" || return actual_sha="$(sha256sum "$archive" | awk '{print $1}')" [[ "$actual_sha" == "$expected_sha" ]] || _observability_fail "$label archive SHA-256 mismatch" || return if ! tar -tzf "$archive" | awk -v prefix="$chart/" ' $0 == "" || $0 ~ /^\// || $0 ~ /(^|\/)\.\.($|\/)/ || index($0, prefix) != 1 { bad=1 } END { exit bad ? 1 : 0 } '; then _observability_fail "$label archive layout is unsafe" return fi _observability_create_cache_directory "$relative_root" "$chart" "$version" || return cache="$_OBS_LAST_CACHE_PATH" cache_identity="$_OBS_LAST_CACHE_IDENTITY" _observability_cache_identity_matches "$cache" "$cache_identity" || \ _observability_reject 'exact cache identity changed before extraction' || return exec {cache_fd}<"$cache" || _observability_reject 'exact cache cannot be pinned for extraction' || return cache_fd_identity="$(stat --dereference --format='%d:%i' "/proc/$$/fd/$cache_fd")" if [[ "$cache_fd_identity" != "$cache_identity" ]]; then exec {cache_fd}<&- _observability_reject 'opened cache identity differs before extraction' return fi if ! tar --extract --gzip --file "$archive" --directory "/proc/$$/fd/$cache_fd" --keep-old-files; then exec {cache_fd}<&- _observability_reject 'chart extraction failed' return fi cache_fd_identity="$(stat --dereference --format='%d:%i' "/proc/$$/fd/$cache_fd")" exec {cache_fd}<&- [[ "$cache_fd_identity" == "$cache_identity" ]] || \ _observability_reject 'opened cache identity changed during extraction' || return _observability_cache_identity_matches "$cache" "$cache_identity" || \ _observability_reject 'exact cache identity changed during extraction' || return chart_yaml="$cache/$chart/Chart.yaml" [[ -f "$chart_yaml" && ! -L "$chart_yaml" ]] || _observability_fail "$label Chart.yaml is missing" || return validate_chart_metadata "$chart_yaml" "$chart" "$version" "$app_version" printf 'Verified %-28s SHA-256 %s\n' "$label" "$actual_sha" } _observability_render_plain() { local output_name="$1" local relative_root="$2" kubectl kustomize "$_OBS_ROOT/$relative_root" >"$_OBS_WORK/$output_name.yaml" [[ -s "$_OBS_WORK/$output_name.yaml" ]] || _observability_fail "$output_name render is empty" } _observability_render_with_helm() { local output_name="$1" local relative_root="$2" kubectl kustomize --enable-helm --helm-command "$_OBS_HELM" \ --helm-kube-version "$(observability_helm_kube_version)" \ "$_OBS_ROOT/$relative_root" >"$_OBS_WORK/$output_name.yaml" [[ -s "$_OBS_WORK/$output_name.yaml" ]] || _observability_fail "$output_name render is empty" } _observability_cleanup() { local rc=$? local cache_cleanup_rc=0 set +e _observability_cleanup_cache_dirs || cache_cleanup_rc=$? case "${_OBS_WORK:-}" in /tmp/platform-observability-core-render.*) rm -rf -- "$_OBS_WORK" ;; esac if [[ "$rc" == 0 && "$cache_cleanup_rc" != 0 ]]; then rc="$cache_cleanup_rc" fi exit "$rc" } _observability_usage() { cat <<'USAGE' Usage: PLATFORM_HELM_BIN=/home/donghyeon/.local/bin/helm \ bash scripts/validate/render-observability-core.sh Verified apply handoff (internal interface): bash scripts/validate/render-observability-core.sh \ --verified-output-dir /tmp/platform-observability-core-apply.XXXXXX This command performs static rendering only. It never applies resources. USAGE } observability_render_main() { local command_name kustomize_version label repo chart version app_version expected_sha relative_root local output_name bytes digest handoff_identity local -a all_manifests workload_manifests child_specs output_names render_roots if (( $# == 0 )); then _OBS_OUT="" elif (( $# == 2 )) && [[ "$1" == "--verified-output-dir" ]]; then _OBS_OUT="$2" else _observability_usage >&2 return 2 fi _OBS_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd -P)" for command_name in awk cat chmod cmp dirname find install kubectl mktemp python3 rm rmdir sed sha256sum stat tar tr wc; do command -v "$command_name" >/dev/null 2>&1 || _observability_fail "$command_name command is required" || return done python3 -c 'import yaml' >/dev/null 2>&1 || _observability_fail 'Python PyYAML is required' || return if [[ -v PLATFORM_HELM_BIN ]]; then [[ "$PLATFORM_HELM_BIN" == /* && -f "$PLATFORM_HELM_BIN" && ! -L "$PLATFORM_HELM_BIN" && -x "$PLATFORM_HELM_BIN" ]] || \ _observability_fail 'PLATFORM_HELM_BIN must be an executable, non-symlink regular file at an absolute path' || return _OBS_HELM="$PLATFORM_HELM_BIN" else command -v helm >/dev/null 2>&1 || _observability_fail 'helm command is required' || return _OBS_HELM="$(command -v helm)" fi [[ "$("$_OBS_HELM" version --template '{{.Version}}')" == "$(observability_expected_helm_version)" ]] || \ _observability_fail "Helm must be exactly $(observability_expected_helm_version)" || return kustomize_version="$(kubectl version --client --output=yaml | sed -n 's/^kustomizeVersion: //p')" [[ "$kustomize_version" == "$(observability_expected_kustomize_version)" ]] || \ _observability_fail "Kustomize must be exactly $(observability_expected_kustomize_version)" || return if [[ -n "$_OBS_OUT" ]]; then handoff_identity="$(pin_handoff_directory "$_OBS_OUT")" fi mapfile -t render_roots < <(render_root_rows) validate_render_roots "$_OBS_ROOT" "${render_roots[@]}" umask 077 _OBS_WORK="$(mktemp -d /tmp/platform-observability-core-render.XXXXXX)" chmod 0700 "$_OBS_WORK" _OBS_CREATED_CACHE_DIRS=() _OBS_CREATED_CACHE_IDENTITIES=() _OBS_CREATED_CACHE_TYPES=() trap _observability_cleanup EXIT trap 'exit 130' INT trap 'exit 143' TERM while IFS=$'\t' read -r label repo chart version app_version expected_sha relative_root; do _observability_prepare_chart "$label" "$repo" "$chart" "$version" "$app_version" \ "$expected_sha" "$relative_root" done < <(chart_pin_rows) _observability_render_plain namespaces infrastructure/namespaces/observability _observability_render_with_helm crds infrastructure/controllers/prometheus-operator-crds _observability_render_plain storage infrastructure/storage/observability-local-pv _observability_render_with_helm kps services/observability/kube-prometheus-stack _observability_render_with_helm loki services/observability/loki _observability_render_with_helm tempo services/observability/tempo _observability_render_with_helm alloy services/observability/alloy _observability_render_with_helm node-exporter services/observability/node-exporter _observability_render_with_helm grafana services/observability/grafana _observability_render_with_helm blackbox services/observability/blackbox-exporter _observability_render_plain core-policies services/observability/network-policies _observability_render_plain targets services/observability/targets _observability_render_plain core-rules services/observability/rules/platform _observability_render_plain alerting services/observability/alerting _observability_render_plain dashboards services/observability/dashboards/platform _observability_render_with_helm aggregate services/observability all_manifests=( "$_OBS_WORK/namespaces.yaml" "$_OBS_WORK/crds.yaml" "$_OBS_WORK/storage.yaml" "$_OBS_WORK/kps.yaml" "$_OBS_WORK/loki.yaml" "$_OBS_WORK/tempo.yaml" "$_OBS_WORK/alloy.yaml" "$_OBS_WORK/node-exporter.yaml" "$_OBS_WORK/grafana.yaml" "$_OBS_WORK/blackbox.yaml" "$_OBS_WORK/core-policies.yaml" "$_OBS_WORK/targets.yaml" "$_OBS_WORK/core-rules.yaml" "$_OBS_WORK/alerting.yaml" "$_OBS_WORK/dashboards.yaml" ) workload_manifests=( "$_OBS_WORK/kps.yaml" "$_OBS_WORK/loki.yaml" "$_OBS_WORK/tempo.yaml" "$_OBS_WORK/alloy.yaml" "$_OBS_WORK/node-exporter.yaml" "$_OBS_WORK/grafana.yaml" "$_OBS_WORK/blackbox.yaml" "$_OBS_WORK/core-policies.yaml" "$_OBS_WORK/targets.yaml" "$_OBS_WORK/core-rules.yaml" "$_OBS_WORK/alerting.yaml" "$_OBS_WORK/dashboards.yaml" ) assert_pinned_images "${workload_manifests[@]}" assert_no_credentials "${all_manifests[@]}" "$_OBS_WORK/aggregate.yaml" assert_namespace_pod_security "${workload_manifests[@]}" assert_no_public_exposure "${workload_manifests[@]}" assert_no_loki_auxiliary "$_OBS_WORK/loki.yaml" assert_tempo_topology "$_OBS_WORK/tempo.yaml" assert_selector_values "$_OBS_ROOT/services/observability/kube-prometheus-stack/values/home.yaml" assert_prometheus_selectors "$_OBS_WORK/kps.yaml" assert_alertmanager_routing_contract "$_OBS_WORK/kps.yaml" "$_OBS_WORK/alerting.yaml" assert_no_crds "$_OBS_WORK/kps.yaml" "$_OBS_WORK/aggregate.yaml" assert_unique_local_pv_storage_classes "$_OBS_WORK/storage.yaml" assert_no_unscoped_monitors_rules "${workload_manifests[@]}" child_specs=( "kps:$_OBS_WORK/kps.yaml" "loki:$_OBS_WORK/loki.yaml" "tempo:$_OBS_WORK/tempo.yaml" "alloy:$_OBS_WORK/alloy.yaml" "node-exporter:$_OBS_WORK/node-exporter.yaml" "grafana:$_OBS_WORK/grafana.yaml" "blackbox:$_OBS_WORK/blackbox.yaml" "core-policies:$_OBS_WORK/core-policies.yaml" "targets:$_OBS_WORK/targets.yaml" "core-rules:$_OBS_WORK/core-rules.yaml" "alerting:$_OBS_WORK/alerting.yaml" "dashboards:$_OBS_WORK/dashboards.yaml" ) assert_child_aggregate_equivalence "$_OBS_WORK/aggregate.yaml" "${child_specs[@]}" build_resource_index "$_OBS_WORK/resource-index.tsv" \ "namespaces:$_OBS_WORK/namespaces.yaml" \ "crds:$_OBS_WORK/crds.yaml" \ "storage:$_OBS_WORK/storage.yaml" \ "${child_specs[@]}" output_names=(namespaces crds storage kps loki tempo alloy node-exporter grafana blackbox core-policies targets core-rules alerting dashboards aggregate) for output_name in "${output_names[@]}"; do bytes="$(wc -c <"$_OBS_WORK/$output_name.yaml" | tr -d '[:space:]')" digest="$(sha256sum "$_OBS_WORK/$output_name.yaml" | awk '{print $1}')" printf 'Rendered %-18s %8s bytes SHA-256 %s\n' "$output_name" "$bytes" "$digest" done if [[ -n "$_OBS_OUT" ]]; then publish_verified_handoff "$_OBS_OUT" "$handoff_identity" "$_OBS_WORK" validate_handoff_entry_set "$_OBS_OUT" "$handoff_identity" fi printf 'OBSERVABILITY CORE STATIC RENDER PASS\n' } if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then set -Eeuo pipefail observability_render_main "$@" fi