如何用Rego编写Gatekeeper规则检测EnvoyFilter废弃参数
解决Gatekeeper检查废弃EnvoyFilter参数的Rego问题
背景与需求
需要通过Gatekeeper检查EnvoyFilter资源中是否使用了指定的废弃过滤器参数,要求如下:
- 若资源中任意
spec.configPatches[*].match.listener.filterChain.filter.name匹配约束参数里parameters.envoyfilters[*].deprecated的值,触发违规 - 违规提示需包含对应的推荐替代过滤器(即参数中的
canonical字段) - 无法更新OPA/Gatekeeper,不能使用
import future.keywords
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"
待检查的EnvoyFilter资源
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
原有未生效的Rego代码
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 }
修正后的Rego代码
violation[{"msg": msg}] { # 遍历所有configPatches条目,获取对应的filter name patch := input.review.object.spec.configPatches[_] filter_name := patch.match.listener.filterChain.filter.name # 遍历参数中的废弃过滤器,匹配废弃值 deprecated_filter := input.parameters.envoyfilters[_] deprecated_filter.deprecated == filter_name # 生成违规提示,包含废弃值和推荐的canonical替代项 msg := sprintf("使用了废弃的过滤器 %q,请替换为推荐的 %q", [filter_name, deprecated_filter.canonical]) }
代码说明
- 路径访问修正:原代码错误使用了非标准的嵌套数组访问方式,正确做法是通过
[_]遍历数组后,逐层访问对象属性。 - 简化匹配逻辑:无需额外定义辅助函数,直接通过双层遍历完成匹配——先遍历资源中的所有configPatches获取过滤器名称,再遍历参数中的废弃过滤器进行值匹配。
- 精准提示生成:匹配成功后直接关联对应
canonical字段,生成清晰的替代建议,满足合规提示需求。
内容的提问来源于stack exchange,提问作者carrotcakeslayer
相关产品推荐
相关产品推荐

