Can I loop over keys and values of an object in OPA to validate if they adhere to a certain format (CamelCase)

非 Y 不嫁゛ 提交于 2021-02-08 06:51:19

问题


We are using conftest to validate if our terraform changeset applies to certain rules & compliances. One thing we want to validate is wether our AWS resources are tagged according to the AWS tagging convention, which specifies certain tags to use (e.g. Owner, ApplicationRole, Project) and specifies that all tags and values are in CamelCase.

in terraform the changeset is portrayed in the following (simplified) json output:

{
   "resource_changes":{
      "provider_name":"aws",
      "change":{
         "before":{

         },
         "after":{
            "tags":{
               "ApplicationRole":"SomeValue",
               "Owner":"SomeValue",
               "Project":"SomeValue"
            }
         }
      }
   }
}

What I am now trying to do is to validate the following:

  1. Check wether tags are set.
  2. Validate if the keys and values are all camelcase.
  3. Check that the keys include the set (ApplicationRole, Owner, Project) in the minimum.

However, I am having trouble defining that in Rego (I am quite new to OPA).

Is there a way to "loop" over the keys and values of an object, and validate if they are formatted correctly?

in pseudo code:

for key, value in tags {
  re_match(`([A-Z][a-z0-9]+)+`, key)
  re_match(`([A-Z][a-z0-9]+)+`, value)
}

I have tried the following:

tags_camel_case(tags) {
    some key
    val := tags[key]
    re_match(`^([A-Z][a-z0-9]+)+`, key) # why is key not evaluated?
    re_match(`^([A-Z][a-z0-9]+)+`, val)
}

However, when evaluating against the following test json:

{
  "AppRole": "SomeValue",
  "appRole": "SomeValue"
}

the rule returns true, even though I am checking both key and value vs the regex


回答1:


The tags_camel_case(tags) function returns true for the input with two keys because (by default) variables in Rego are existentially quantified. This means rule bodies are satisfied if for some set of variable bindings, the statements in the rule body are true. In the example above, the rule body would be satisfied by {key=AppRole, val=SomeValue}.

To express for all you can use a simple trick. First write a rule to check if any of the tags ARE NOT camel case. Second write the rule to check if the first rule is not satisfied.

For example:

# checks if all tags are camel case
tags_camel_case(tags) {
  not any_tags_not_camel_case(tags)
}

# checks if any tags are NOT camel case
any_tags_not_camel_case(tags) {
    some key
    val := tags[key]
    not is_camel_case(key, val)
}

# checks if a and b are both camel case
is_camel_case(a, b) {
  re_match(`^([A-Z][a-z0-9]+)+`, a)
  re_match(`^([A-Z][a-z0-9]+)+`, b)
}

For more info on expression 'for all' in Rego see https://www.openpolicyagent.org/docs/latest/how-do-i-write-policies/#universal-quantification-for-all



来源:https://stackoverflow.com/questions/56663463/can-i-loop-over-keys-and-values-of-an-object-in-opa-to-validate-if-they-adhere-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!