Безопасная оценка входных данных нескольких типов — OPA Gatekeeper/Rego

#kubernetes #opa #kubernetes-apiserver #rego

Вопрос:

Я пытаюсь развернуть шаблон ограничения в своем кластере Kubernetes для принудительного PodDisriptionBudgets использования, содержащий maxUnavailable процент, превышающий заданный процент, и отрицающий целочисленные значения.

Однако я не уверен, как безопасно оценивать maxUnavailable , поскольку это может быть целое число или строка. Вот шаблон ограничения, который я использую:

 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]) lt; 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 , что правило пытается оценить строку. Есть ли какой-нибудь способ обойти это в Гейткипере? Оба PDB, которые я указал, являются допустимыми манифестами Kubernetes. Я не хочу возвращать эту запутанную ошибку нашим конечным пользователям и хотел бы уточнить, что они не могут использовать целые числа.

Ответ №1:

Я полагаю, что это было решено в другом месте, но для потомков одним из решений этой проблемы было бы просто преобразовать значение типа переменной в известный тип (например, строку) перед выполнением сравнения или операции.

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

maxUnavailable теперь можно безопасно обрабатывать как строку независимо от исходного типа.