我想检查渲染的Helm图表中的每个Service是否都有一个匹配的Pod。
当Servicesspec.selector
对象中指定的每个条目都反映在Podsmetadata.labels
对象中(该对象可以具有额外的密钥(时,就存在Pod到服务的关联。
以下策略通过运行conftest test --combine {YAML_FILE}
使用Conftest进行测试,并检查每个服务是否至少有一个匹配的Pod。我完全不确定如何转换它,以便它检查是否正好一个匹配的Pod。
package main
import future.keywords.every
in_set(e, s) { s[e] }
get_pod(resource) := pod {
in_set(resource.kind, {"Deployment", "StatefulSet", "Job"})
pod := resource.spec.template
}
# ensure that every service has at least one matching pod
# TODO: ensure that every service has exactly one matching pod
deny_service_without_matching_pod[msg] {
service := input[_].contents
service.kind == "Service"
selector := object.get(service, ["spec", "selector"], {})
pods := { p | p := get_pod(input[_].contents) }
every pod in pods {
labels := object.get(pod, ["metadata", "labels"], {})
matches := { key | some key; labels[key] == selector[key] }
count(matches) != count(selector)
}
msg := sprintf("service %s has no matching pod", [service.metadata.name])
}
旁注:get_pod
函数不会检索Helm图中可能出现的所有PodTemplates。其他检查也在进行,以保持Helm图表的Kubernetes API表面较小,因此在这种情况下,Pods只能出现在Deployment、StatefulSet和Job中。
也许这里有一些rego专家可以提供帮助。非常感谢!😀
由于没有提供样本数据,因此这是未经测试的代码。它应该工作:(
package main
import future.keywords.in
pods := { pod |
resource := input[_].contents
resource.kind in {"Deployment", "StatefulSet", "Job"}
pod := resource.spec.template
}
services := { service |
service := input[_].contents
service.kind == "Service"
}
pods_matching_selector(selector) := { pod |
selector != {}
some pod in pods
labels := pod.metadata.labels
some key
labels[key] == selector[key]
}
deny_service_without_one_matching_pod[msg] {
some service in services
selector := object.get(service, ["spec", "selector"], {})
matching_pods := count(pods_matching_selector(selector))
matching_pods != 1
msg := sprintf(
"service %s has %d matching pods, must have exactly one",
[service.metadata.name, matching_pods]
)
}