0

我正在尝试将约束模板部署到我的 Kubernetes 集群,以强制PodDisriptionBudgets包含maxUnavailable高于给定百分比的百分比,并拒绝整数值。

但是,我不确定如何安全评估maxUnavailable,因为它可以是integer 或 string。这是我正在使用的约束模板:

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: pdbrequiredtolerance
spec:
  crd:
    spec:
      names:
        kind: PdbRequiredTolerance
      validation:
        # Schema for the `parameters` field
        openAPIV3Schema:
          properties:
            minAllowed:
              type: integer
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package pdbrequiredtolerance

        # Check that maxUnavailable exists
        violation[{"msg": msg }] {
          not input.review.object.spec.maxUnavailable
          msg := "You must use maxUnavailable on your PDB"
        }

        # Check that maxUnavailable is a string
        violation[{"msg": msg}] {
          not is_string(input.review.object.spec.maxUnavailable)
          msg := "maxUnavailable must be a string"
        }

        # Check that maxUnavailable is a percentage
        violation[{"msg": msg}] {
          not endswith(input.review.object.spec.maxUnavailable,"%")
          msg := "maxUnavailable must be a string ending with %"
        }

        # Check that maxUnavailable is in the accpetable range
        violation[{"msg": msg}] {
          percentage := split(input.review.object.spec.maxUnavailable, "%")
          to_number(percentage[0]) < input.parameters.minAllowed
          msg := sprintf("You must have maxUnavailable of %v percent or higher", [input.parameters.minAllowed])
        }

当我输入一个值太高的 PDB 时,我收到了预期的错误:

Error from server ([pdb-must-have-max-unavailable] You must have maxUnavailable of 30 percent or higher)

但是,当我使用具有整数值的 PDB 时:

Error from server (admission.k8s.gatekeeper.sh: __modset_templates["admission.k8s.gatekeeper.sh"]["PdbRequiredTolerance"]_idx_0:14: eval_type_error: endswith: operand 1 must be string but got number)

这是因为endswith规则试图评估一个字符串。Gatekeeper有什么办法解决这个问题吗?我指定的两个 PDB 都是有效的 Kubernetes 清单。我不希望将这个令人困惑的错误返回给我们的最终用户,而是希望澄清他们不能使用整数。

4

1 回答 1

0

我相信这在其他地方已经解决了,但对于后代来说,一个解决方案是在进行比较或操作之前简单地将变量类型的值转换为已知类型(如字符串)。

maxUnavailable := sprintf("%v", [input.review.object.spec.maxUnavailable])

maxUnavailable无论原始类型如何,现在都可以安全地作为字符串处理。

于 2021-12-20T12:13:55.333 回答