carrotcakeslayer
carrotcakeslayer

Reputation: 1008

Rego to check if a map, contains a key that is defined in a separate list

Given a map, we would like to check if any of the keys in that map matches any item in a list.

In the case of kubernetes annotations being the "map":

metadata:
  annotations:
    external-dns.alpha.kubernetes.io/hostname: something
    external-dns.alpha.kubernetes.io/ttl: 60

Let's say that we want to trigger a violation if external-dns.alpha.kubernetes.io/ttl is used. For that, we would add that item in a list of denied annotations. The value is not relevant.

denied:
  - external-dns.alpha.kubernetes.io/ttl
  - other-denied-annotation-1
  - other-denied-annotation-2

Violation should trigger if any of the denied annotations is present in the .metadata.annotations of the resource.

Although I searched and tried it, I was not able to. The already asked questions do not address this exactly and I was not able to make it work. We are using Gatekeeper.

Upvotes: 0

Views: 2507

Answers (1)

Devoops
Devoops

Reputation: 2315

You'd normally use a set for the "deny" list, and then simply check each annotation for membership:

package play

import future.keywords

denied_annotations := {
    "external-dns.alpha.kubernetes.io/ttl",
    "other-denied-annotation-1",
    "other-denied-annotation-2",
}

deny[reason] {
    # iterate over all annotations in input
    input.review.object.metadata.annotations[key] 

    # for each key, check if it's present in deny list -
    # if using older OPA, you may need to use
    # `denied_annotations[key]` instead, which does the same
    key in denied_annotations       
    
    reason = sprintf("%s in denied annotations", [key])
}

Playground example here.

Upvotes: 1

Related Questions