Rego校验Helm Values文件全局环境变量值引号合规问题求助
问题:校验Helm Values中global段env开头变量的引号规范
需求
作为Rego新手,需要校验Helm模板Values文件global段下所有以env开头的项(如env、envMap、envNginxSocket等)的取值必须带有引号(例如REDIS_PORT: 6379这类无引号的数值类型不被允许,必须写成REDIS_PORT: "6379")。
Values文件示例
global: release: &release "{{ .ReleaseTag }}" env: "{{ .Environment }}" namespace: &namespace "{{ .Namespace }}" cluster: "{{ .Cluster }}" envMap: &service-env APP_ENV: "prod" APP_DEBUG: "0" WEB_HOST: "https://example.com" ENDPOINT_PATH: "/api" JWT_SECRET_KEY: "%kernel.project_dir%/config/jwt/private.pem" JWT_PUBLIC_KEY: "%kernel.project_dir%/config/jwt/public.pem" JWT_TOKEN_TTL: "86400" REFRESH_JWT_TOKEN_TTL: "2592000" LOG_ENVIRONMENT: "prod" REDIS_HOST: "redis.service.consul" REDIS_PORT: "6379" ... envNginxSocket: &nginx-socket-env BACKEND_LISTEN: "unix:/tmp/php/php.socket" FCGI_CONNECT: "/tmp/php/php.socket" PHP_FPM_SCRAPE_URI: "unix:///tmp/php/php.socket;/status" ... envPhpSocket: &php-socket-env PHP_WWW_PM_MAX_CHILD: "32" PHP_WWW_LISTEN: "/tmp/php/php.socket" FCGI_CONNECT: "/tmp/php/php.socket" ...
现有尝试与问题
思路
- 输入
global段内容 - 筛选出仅以
env开头的项 - 校验这些项的取值
现有Rego代码
violation[msg] { some key k8s_values := input.global[key] c := split(concat(",", [ v | v := key ]), ",") arr := [cont | cont = c[i] ; regex.match(".*env.*", c[i])] 1 + 0 != 0 # only for check result msg := sprintf("%v | Values",[arr]) }
执行结果
+---------+-----------------------------+-----------+-----------------------------+ | RESULT | FILE | NAMESPACE | MESSAGE | +---------+-----------------------------+-----------+-----------------------------+ | failure | deployment/values-prod.yaml | main | ["env"] | Values | | failure | deployment/values-prod.yaml | main | ["envMap"] | Values | | failure | deployment/values-prod.yaml | main | ["envNginxSocket"] | Values | | failure | deployment/values-prod.yaml | main | ["envPhpSocket"] | Values | | failure | deployment/values-prod.yaml | main | [] | Values | +---------+-----------------------------+-----------+-----------------------------+
现有代码仅完成了键的筛选(还不准确,会匹配包含env的任意键),未实现取值的引号校验逻辑。
解决方案
核心逻辑
Values中不带引号的数值/布尔会被解析为非字符串类型,带引号的内容会被解析为字符串类型。因此校验的核心是:所有env开头项的取值(包括嵌套map内的子项)必须为字符串类型。
修正后的Rego代码
# 校验顶层env开头的非map值必须为字符串 violation[msg] { some key value := input.global[key] startswith(key, "env") not is_object(value) not is_string(value) msg := sprintf("global.%s 的值 %v 未使用引号包裹(必须为字符串类型)", [key, value]) } # 校验env开头的map内所有子项值必须为字符串 violation[msg] { some key, sub_key env_map := input.global[key] startswith(key, "env") is_object(env_map) value := env_map[sub_key] not is_string(value) msg := sprintf("global.%s.%s 的值 %v 未使用引号包裹(必须为字符串类型)", [key, sub_key, value]) }
代码说明
- 精准筛选键:用
startswith(key, "env")替代正则,只匹配以env开头的键,避免误匹配包含env的其他键。 - 分类型校验:
- 对于顶层非map类型的
env开头项(如env: "{{ .Environment }}"),直接校验是否为字符串。 - 对于map类型的
env开头项(如envMap),遍历其内部所有键值对,校验每个子值是否为字符串。
- 对于顶层非map类型的
- 清晰报错:通过
sprintf生成包含错误路径的提示信息,方便快速定位问题。
内容的提问来源于stack exchange,提问作者unitrade
相关产品推荐
相关产品推荐

