Kyverno: Validate ports are allowed only for k8s Service type LoadBalancer

203 views Asked by At

I'm trying to achieve a specific case to be done with Kyverno, but can't find a good way to do that. Also, I'm not sure if it's possible to do it with Kyverno.

I want to allow assign the port 8000 only for Service type LoadBalancer for all namespaces. But allow assign all ports for Service type LoadBalancer in a specific namespace "ingress"

I tried to achieve this with validate and preconditions, but it doesn't work as expected.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: allowed-ports-loadbalancer
spec:
  background: false
  validationFailureAction: enforce
rules:
  name: Validate ports are in the allowed range
  match:
    resources:
      kinds:
        - Service
  preconditions:
    all:
      - key: "{ { request.object.spec.type } }"
        operator: Equals
        value: "LoadBalancer"
  validate:
    pattern:
      spec:
        ports:
          - port: 8000
  exclude:
    resources:
      namespaces:
        - ingress
1

There are 1 answers

4
Chip Zoller On

You were pretty close, except in this case you want to invert the preconditions and the actual pattern because the first evaluation you want to make is on the ports, and the second is on the type. The below should take care of you.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: allowed-ports-loadbalancer
spec:
  background: false
  validationFailureAction: enforce
  rules:
  - name: Validate ports are in the allowed range
    match:
      any:
      - resources:
          kinds:
            - Service
    exclude:
      any:
      - resources:
          namespaces:
            - ingress
    preconditions:
      all:
        - key: 8000
          operator: AnyIn
          value: "{{ request.object.spec.ports[].port }}"
    validate:
      message: Port 8000 may only be set for LoadBalancer type Services outside the Namespace called `ingress`.
      pattern:
        spec:
          type: LoadBalancer