如何检查给定字符串是否包含在标签中

How to check if given string is contained in tags

假设我有以下测试输入,我希望能够编写一个测试来检查字符串 Application 是否包含在任何标签键中。这个想法是这个检查将能够跨资源匹配具有不同命名约定的标签。

知道如何完成这个吗?

{
    "resource": {
        "aws_vpc": {
            "_type": "AWS.EC2.Vpc",
            "cidr_block": "10.0.0.0/16",
            "id": "vpc-abc123",
            "tags": {
                "MyApplication": "Test",
                "Application": "Test",
                "Name": "my-vpc"
            }
        }
    }
}

TLDR;将变量插入引用以迭代数据中的值:

some key
val := input.resource.aws_vpc.tags[key]
contains(key, "Application")

当您将变量插入到引用中时,OPA/Rego 会找到满足规则中表达式的那些变量的所有赋值。例如,如果规则只是:

check {
  some key
  input.resource.aws_vpc.tags[key]
}

如果 input.resource.aws_vpc_tags 包含至少一个值(不是 false),则 check 为真。有关迭代的更多信息,请参阅 Rego 介绍文档中的 this 部分。在你的情况下,你想测试是否有任何键包含 "Application" 所以你只需在规则中添加一个额外的语句:

check {
  some key
  input.resource.aws_vpc.tags[key]
  contains(key, "Application")
}

现在,如果至少有一个值的键包含字符串 "Application",则 check 为真。如果您只需要一个简单的布尔检查,那么这就可以了。在某些情况下,您可能需要包含 "Application" 的键的 。在这些情况下,您可以使用 Set Comprehension:

vals := {val |
  some key
  val := input.resource.aws_vpc.tags[key]
  contains(key, "Application") 
}

如果您根据测试输入评估后者,则输出为:

["Test"]

Technically the output would be a set but since JSON does not support sets, OPA renders them as arrays for external callers.

这是 playground 中的相同示例(输入略有不同):https://play.openpolicyagent.org/p/KfbrwYDxIJ

如果您正在寻找有关如何使用 OPA/Rego 的更多示例和教程,请查看 this 在线课程(披露:我在 Styra 工作)。