OPA REGO:如何在另一本词典中查找所有不匹配的项目?

OPA REGO: How to find all not matching items in another dictionary?

输入如下:

{
    "source": "serverA",
    "destination": "serverB",
    "rules": {
        "tcp": {
            "ssh": [
                22
            ],
            "https": [
                8443
            ]
        },
        "udp": [
            53
        ]
    }
}

及数据来源:

{
    "allowedProtocolTypeToPortMapping": {
        "tcp": {
            "ssh": [22],
            "https": [443]
        },
        "udp": {
            "dns": [53]
        },
        "icmp": {
            "type": [0]
        }
    }
}

我想创建一个检查所有规则并显示不符合数据源的规则的策略。在此示例中,端口 8443 的协议类型 https 不兼容(仅允许 443)。使用 rego 语言实现它的最佳方法是什么?

这是一种方法。

package play

violations[msg] {
    # Traverse input object stopping only at array values
    walk(input.rules, [path, value])
    is_array(value)
    
    # Get corresponding list of allowed ports from matching path
    allowedPorts := select(data.allowedProtocolTypeToPortMapping, path)
    
    # At this point, we have one array of ports from the input (value)
    # and one array of allowed ports. Converting both to sets would allow
    # us to compare the two using simple set intersection - i.e. checking
    # that all ports in the input are also in the allowed ports.
    ip := {port | port := value[_]}
    ap := {port | port := allowedPorts[_]}
    
    # Unless all ports in the input array are in both the input and the
    # allowed ports, it's a violation
    count(ip) != count(ip & ap)
    
    msg := concat(".", path)
}
 
select(o, path) = value {
    walk(o, [path, value])
}

Rego 游乐场示例可用 here