Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
# Stage complete OpenCost retirement only for the explicit Coroot fixtures.
# Real provider payloads keep the legacy surface until a later activation.
patches:
- target:
version: v1
kind: Namespace
name: opencost
patch: |
$patch: delete
apiVersion: v1
kind: Namespace
metadata:
name: opencost
Comment thread
devantler marked this conversation as resolved.
Resolved
- target:
group: source.toolkit.fluxcd.io
version: v1
kind: HelmRepository
name: opencost
namespace: opencost
patch: |
$patch: delete
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: opencost
namespace: opencost
- target:
group: helm.toolkit.fluxcd.io
version: v2
kind: HelmRelease
name: opencost
namespace: opencost
patch: |
$patch: delete
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: opencost
namespace: opencost
- target:
group: gateway.networking.k8s.io
version: v1
kind: HTTPRoute
name: opencost
namespace: opencost
patch: |
$patch: delete
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: opencost
namespace: opencost
- target:
group: cilium.io
version: v2
kind: CiliumNetworkPolicy
name: allow-opencost
namespace: opencost
patch: |
$patch: delete
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-opencost
namespace: opencost
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
---
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
# Remove cross-namespace consumers and exemptions alongside the explicit
# Coroot fixtures' OpenCost workload retirement. Targets absent from a layer
# are ignored; the executable contract rejects any surviving reference.
patches:
- target:
version: v1
kind: ConfigMap
name: auth-proxy-config
namespace: oauth2-proxy
patch: |
- op: replace
path: /data/dynamic.yaml
value: |
http:
routers:
homepage:
rule: "Host(`${domain}`)"
entryPoints: ["web"]
service: homepage
hubble:
rule: "Host(`hubble.${domain}`)"
entryPoints: ["web"]
service: hubble-ui
prometheus:
rule: "Host(`prometheus.${domain}`)"
entryPoints: ["web"]
service: prometheus
alertmanager:
rule: "Host(`alertmanager.${domain}`)"
entryPoints: ["web"]
service: alertmanager
services:
homepage:
loadBalancer:
servers:
- url: "http://homepage.homepage.svc.cluster.local:80"
hubble-ui:
loadBalancer:
servers:
- url: >-
http://keda-add-ons-http-interceptor-proxy.keda.svc.cluster.local:8080
prometheus:
loadBalancer:
servers:
- url: >-
http://kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090
alertmanager:
loadBalancer:
servers:
- url: >-
http://kube-prometheus-stack-alertmanager.monitoring.svc.cluster.local:9093
- target:
group: cilium.io
version: v2
kind: CiliumNetworkPolicy
name: allow-auth-proxy
namespace: oauth2-proxy
patch: |
- op: test
path: /spec/egress/3
value:
toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: opencost
toPorts:
- ports:
- port: "9090"
protocol: TCP
- op: remove
path: /spec/egress/3
- target:
group: cilium.io
version: v2
kind: CiliumNetworkPolicy
name: allow-monitoring
namespace: monitoring
patch: |
- op: test
path: /spec/ingress/1
value:
fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: opencost
toPorts:
- ports:
- port: "9090"
protocol: TCP
- op: remove
path: /spec/ingress/1
- target:
group: gateway.networking.k8s.io
version: v1beta1
kind: ReferenceGrant
name: allow-oauth2-proxy-backends
namespace: oauth2-proxy
patch: |
- op: test
path: /spec/from/4
value:
group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: opencost
- op: remove
path: /spec/from/4
- target:
group: kubescape.io
version: v1beta1
kind: ClusterSecurityException
name: controller-rbac
patch: |
- op: test
path: /spec/match/namespaceSelector/matchExpressions/0/values/16
value: opencost
- op: remove
path: /spec/match/namespaceSelector/matchExpressions/0/values/16
- op: test
path: /spec/reason
value: >-
Infrastructure controllers and platform middleware require broad RBAC
to manage their target resources cluster-wide. This includes GitOps
(Flux), policy engines (Kyverno), certificate managers (cert-manager),
database operators (CNPG), backup controllers (Velero), autoscalers
(KEDA), monitoring (Prometheus/opencost), virtualisation (KubeVirt,
CDI), storage (Longhorn), cluster dashboards (headlamp), service
discovery (homepage), identity (dex), auth proxies (oauth2-proxy),
and config watchers (reloader).
- op: replace
path: /spec/reason
value: >-
Infrastructure controllers and platform middleware require broad RBAC
to manage their target resources cluster-wide. This includes GitOps
(Flux), policy engines (Kyverno), certificate managers (cert-manager),
database operators (CNPG), backup controllers (Velero), autoscalers
(KEDA), monitoring (Prometheus), virtualisation (KubeVirt, CDI),
storage (Longhorn), cluster dashboards (headlamp), service discovery
(homepage), identity (dex), auth proxies (oauth2-proxy), and config
watchers (reloader).
- target:
group: kubescape.io
version: v1beta1
kind: ClusterSecurityException
name: service-account-tokens
patch: |
- op: test
path: /spec/match/namespaceSelector/matchExpressions/0/values/18
value: opencost
- op: remove
path: /spec/match/namespaceSelector/matchExpressions/0/values/18
- target:
group: kubescape.io
version: v1beta1
kind: ClusterSecurityException
name: health-probes
patch: |
- op: test
path: /spec/match/namespaceSelector/matchExpressions/0/values/14
value: opencost
- op: remove
path: /spec/match/namespaceSelector/matchExpressions/0/values/14
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../../providers/docker/infrastructure/controllers/
- ../../../../bases/infrastructure/controllers/coroot/
components:
- ../../components/remove-controller-opencost/
- ../../components/remove-opencost-references/
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../../providers/docker/infrastructure/
- ../../../../bases/infrastructure/coroot/
components:
- ../../components/remove-opencost-references/
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../../providers/hetzner/infrastructure/controllers/
- ../../../../bases/infrastructure/controllers/coroot/
components:
- ../../components/remove-controller-opencost/
- ../../components/remove-opencost-references/
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../../providers/hetzner/infrastructure/
- ../../../../bases/infrastructure/coroot/
- ../../../../bases/infrastructure/audit-log-forwarder/
components:
- ../../components/remove-opencost-references/
84 changes: 83 additions & 1 deletion scripts/validate-observability-option.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,21 @@ resource_count() {
--arg kind "${kind}" \
--arg namespace "${namespace}" \
--arg name "${name}" \
'[.[] | select(type == "object" and .kind == $kind and .metadata.namespace == $namespace and .metadata.name == $name)] | length'
'[.[] | select(type == "object" and .kind == $kind and (.metadata.namespace // "") == $namespace and .metadata.name == $name)] | length'
}

opencost_resource_count() {
local rendered_path="$1"

yq eval-all -o=json '.' "${rendered_path}" |
jq -s '[.[] | select(type == "object" and ((.kind == "Namespace" and .metadata.name == "opencost") or .metadata.namespace == "opencost"))] | length'
Comment thread
devantler marked this conversation as resolved.
Resolved
}

opencost_reference_count() {
local rendered_path="$1"

yq eval-all -o=json '.' "${rendered_path}" |
jq -s '[.[] | select(type == "object" and (tojson | test("opencost"; "i")))] | length'
}

assert_resource_count() {
Expand All @@ -54,6 +68,59 @@ assert_default_off() {
assert_resource_count "${rendered_path}" CiliumNetworkPolicy observability allow-coroot 0
}

assert_opencost_present() {
local rendered_path="$1"

assert_resource_count "${rendered_path}" Namespace "" opencost 1
assert_resource_count "${rendered_path}" HelmRepository opencost opencost 1
assert_resource_count "${rendered_path}" HelmRelease opencost opencost 1
assert_resource_count "${rendered_path}" HTTPRoute opencost opencost 1
assert_resource_count "${rendered_path}" CiliumNetworkPolicy opencost allow-opencost 1
}

assert_opencost_resources_absent() {
local rendered_path="$1"
local actual

actual="$(opencost_resource_count "${rendered_path}")"
if [[ "${actual}" != "0" ]]; then
echo "expected no OpenCost resources in ${rendered_path}, found ${actual}" >&2
return 1
fi
}

assert_opencost_absent() {
local rendered_path="$1"
local actual

assert_opencost_resources_absent "${rendered_path}"
actual="$(opencost_reference_count "${rendered_path}")"
if [[ "${actual}" != "0" ]]; then
echo "expected no OpenCost references in ${rendered_path}, found ${actual} resource(s)" >&2
return 1
fi
}

assert_auth_proxy_without_opencost() {
local default_rendered_path="$1"
local opt_in_rendered_path="$2"
local expected
local actual

expected="$(
yq eval-all -o=json 'select(.kind == "ConfigMap" and .metadata.namespace == "oauth2-proxy" and .metadata.name == "auth-proxy-config") | .data."dynamic.yaml" | from_yaml' "${default_rendered_path}" |
jq -S -c 'del(.http.routers.opencost, .http.services.opencost)'
)"
actual="$(
yq eval-all -o=json 'select(.kind == "ConfigMap" and .metadata.namespace == "oauth2-proxy" and .metadata.name == "auth-proxy-config") | .data."dynamic.yaml" | from_yaml' "${opt_in_rendered_path}" |
jq -S -c '.'
)"
if [[ "${actual}" != "${expected}" ]]; then
echo "opt-in auth-proxy config must equal its provider default minus the OpenCost router and service" >&2
return 1
fi
}

local_controllers_default="${tmp_dir}/local-controllers-default.yaml"
local_infrastructure_default="${tmp_dir}/local-infrastructure-default.yaml"
prod_controllers_default="${tmp_dir}/prod-controllers-default.yaml"
Expand All @@ -79,25 +146,40 @@ for rendered_path in \
assert_default_off "${rendered_path}"
done

# The default provider payloads retain the complete legacy OpenCost surface.
# Only the explicit Coroot fixtures stage its retirement.
for rendered_path in "${local_controllers_default}" "${prod_controllers_default}"; do
assert_opencost_present "${rendered_path}"
done
for rendered_path in "${local_infrastructure_default}" "${prod_infrastructure_default}"; do
assert_opencost_resources_absent "${rendered_path}"
done

render k8s/testdata/observability-option/docker/controllers/ "${docker_controllers}"
render k8s/testdata/observability-option/docker/infrastructure/ "${docker_infrastructure}"
render k8s/testdata/observability-option/hetzner/controllers/ "${hetzner_controllers}"
render k8s/testdata/observability-option/hetzner/infrastructure/ "${hetzner_infrastructure}"

assert_auth_proxy_without_opencost "${local_controllers_default}" "${docker_controllers}"
assert_auth_proxy_without_opencost "${prod_controllers_default}" "${hetzner_controllers}"

for rendered_path in "${docker_controllers}" "${hetzner_controllers}"; do
assert_resource_count "${rendered_path}" HelmRelease observability coroot-operator 1
assert_resource_count "${rendered_path}" Coroot observability coroot 0
assert_resource_count "${rendered_path}" HelmRelease observability audit-log-forwarder 0
assert_resource_count "${rendered_path}" CiliumNetworkPolicy observability allow-coroot 1
assert_opencost_absent "${rendered_path}"
done

assert_resource_count "${docker_infrastructure}" HelmRelease observability coroot-operator 0
assert_resource_count "${docker_infrastructure}" Coroot observability coroot 1
assert_resource_count "${docker_infrastructure}" HelmRelease observability audit-log-forwarder 0
assert_opencost_absent "${docker_infrastructure}"

assert_resource_count "${hetzner_infrastructure}" HelmRelease observability coroot-operator 0
assert_resource_count "${hetzner_infrastructure}" Coroot observability coroot 1
assert_resource_count "${hetzner_infrastructure}" HelmRelease observability audit-log-forwarder 1
assert_opencost_absent "${hetzner_infrastructure}"

coroot_key_contract="$(
yq eval-all -o=json '.' "${hetzner_infrastructure}" |
Expand Down
Loading