For several rules, we need to define the same set of variables. In the example, these are "ns", "externaldns", "svc", "nssvc". How could we take these definitions away from each rule, maybe into a function, and then just call the function once in every rule?
violation[{"msg": msg}] {
ns := input.review.object.metadata.namespace
externaldns := input.review.object.metadata.annotations["external-dns.alpha.kubernetes.io/hostname"]
svc := input.review.object.metadata.name
nssvc := sprintf("%v-%v", [ns,svc])
not startswith(externaldns, svc)
startswith(svc, ns)
not endswith(ns, "-system")
msg := "some message"
}
You could just move the common variables/rules out of the rule body, like:
ns := input.review.object.metadata.namespace
externaldns := input.review.object.metadata.annotations["external-dns.alpha.kubernetes.io/hostname"]
svc := input.review.object.metadata.name
nssvc := sprintf("%v-%v", [ns,svc])
violation[{"msg": msg}] {
not startswith(externaldns, svc)
startswith(svc, ns)
not endswith(ns, "-system")
msg := "some message"
}
If you'd like to move some of into functions, that would be doable too, i.e:
annotation(key) = value {
value = input.review.object.metadata.annotations[key]
}
violation[{"msg": msg}] {
externaldns := annotation("external-dns.alpha.kubernetes.io/hostname")
# ...
}