簡體   English   中英

rego 檢查列表中的項目是否存在於另一個列表中的項目中

[英]rego check if item in list exists in item in another list

我們有一個資源中需要檢查的項目列表,以防它們使用已棄用的給定參數之一。 在 Gatekeeper 中,帶有參數的約束如下所示:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: SOMEKind
metadata:
  name: somename
spec:
  match:
    kinds:
    - apiGroups: ["networking.istio.io"]
      kinds: ["EnvoyFilter"]
  parameters:
    envoyfilters:
    - http_squash:
      canonical: "envoy.filters.http.squash"
      deprecated: "envoy.squash"
    - listener_http_inspector:
      canonical: "envoy.filters.listener.http_inspector"
      deprecated: "envoy.listener.http_inspector"

要檢查的資源如下所示:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: envoyfilter
spec:
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_OUTBOUND
      listener:
        filterChain:
          filter:
            name: envoy.listener.http_inspector
            subFilter:
              name: envoy.filters.http.router

如果該名稱與任何給定的“parameters.envoyfilters[ ].deprecated given ,就會發生違規。

由於限制,我們目前無法更新 opa/gk,因此我們無法使用“import future.keywords”。

列表中包含“規范”的原因是因為我們希望提供“良好”的 alertnative fitler 以在違規的消息中使用。

我們正在嘗試不同的方法,但這是最新的(無效的)方法:

      violation[{"msg": msg}] {
        config_patches := input.review.object.spec.configPatches[match][listener][filterchain][filter][_].name
        deprecated_envoyfilters := input.parameters.envoyfilters
        use_deprecated_envoyfilters(config_patches,deprecated_envoyfilters)
        msg := sprintf("REVIEW OBJECT: %v", [config_patches])
      }

      contains(filters, filter) {
        filters[_] = filter
      }

      use_deprecated_envoyfilters(config_patches,deprecated_envoyfilters) = true {
        counter := [ef | efs := config_patches ; contains(efs,deprecated_envoyfilters[_].deprecated) ]
        count(counter) > 0

首先,您真的是指這些參數嗎?

  parameters:
    envoyfilters:
    - http_squash:
      canonical: "envoy.filters.http.squash"
      deprecated: "envoy.squash"
    - listener_http_inspector:
      canonical: "envoy.filters.listener.http_inspector"
      deprecated: "envoy.listener.http_inspector"

因為它們轉化為,例如,

{
  "http_squash": null,
  "canonical": "envoy.filters.http.squash",
  "deprecated": "envoy.squash"
},

所以我認為一些 key/val 結構更適合在這里使用,讓我們使用 go :

  envoyfilters:
    http_squash:
      canonical: "envoy.filters.http.squash"
      deprecated: "envoy.squash"
    listener_http_inspector:
      canonical: "envoy.filters.listener.http_inspector"
      deprecated: "envoy.listener.http_inspector"

通過kube-review將您的 yaml 轉換為 GK 輸入並將參數添加到輸入后,我在操場上放置了這個示例: https://play.openpolicyagent.org/p/o8QrD3xj1y

歸結為:

package play

violation[{"msg": msg}] {
    config_patch := input.review.object.spec.configPatches[match][listener][filterchain][filter][_].name
    some depr_name # name of deprecation
    input.parameters.envoyfilters[depr_name].deprecated == config_patch
    better := input.parameters.envoyfilters[depr_name].canonical

    msg := sprintf("REVIEW OBJECT: %s, violation %s, use %s instead", [config_patch, depr_name, better])
}

Rego 試圖滿足隱式地循環不同的配置補丁

    config_patch := input.review.object.spec.configPatches[match][listener][filterchain][filter][_].name

然后如果要應用的補丁之一被棄用,我們需要在我們的參數中查找:

    some depr_name # name of deprecation
    input.parameters.envoyfilters[depr_name].deprecated == config_patch
    better := input.parameters.envoyfilters[depr_name].canonical

當您使用deprecated:= input.parameters.envoyfilters[_].deprecated之類的循環構造時,它不會返回列表,而是將deprecated的變量分配給與表達式匹配的每個項目。 因此,您的政策可以簡化為:

violation[{"msg": msg}] {
    config_patch := input.review.object.spec.configPatches[match][listener][filterchain][filter][_].name
    deprecated := input.parameters.envoyfilters[_].deprecated
    
    config_patch == deprecated

    msg := sprintf("deprecated config patch: %v", [config_patch])
}

Rego Playground上的完整示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM