All Policies

Require Unique Service Selector

Services select eligible Pods by way of label matches. Having multiple Service apply based on same labels can cause conflicts and have unintended consequences. This policy ensures that within the same Namespace a Service has a unique set of labels as a selector.

Policy Definition

/other/require-unique-service-selector/require-unique-service-selector.yaml

 1apiVersion: kyverno.io/v1
 2kind: ClusterPolicy
 3metadata:
 4  name: require-unique-service-selector
 5  annotations:
 6    policies.kyverno.io/title: Require Unique Service Selector
 7    policies.kyverno.io/category: Other
 8    kyverno.io/kyverno-version: 1.9.0
 9    kyverno.io/kubernetes-version: "1.24"
10    policies.kyverno.io/subject: Service
11    policies.kyverno.io/description: >-
12      Services select eligible Pods by way of label matches. Having multiple
13      Service apply based on same labels can cause conflicts and have unintended
14      consequences. This policy ensures that within the same Namespace a Service has
15      a unique set of labels as a selector.      
16spec:
17  validationFailureAction: audit
18  background: false
19  rules:
20    - name: check-service-selector
21      match:
22        any:
23          - resources:
24              kinds:
25                - Service
26      preconditions:
27        all:
28          - key: "{{request.operation || 'BACKGROUND'}}"
29            operator: NotEquals
30            value: DELETE
31      context:
32        - name: services
33          apiCall:
34            urlPath: "/api/v1/namespaces/{{request.namespace}}/services"
35            jmesPath: "items[?spec.selector]"
36        - name: service_count
37          variable:
38            jmesPath: "services[?label_match(spec.selector, `{{request.object.spec.selector}}`)] | length(@)"
39      validate:
40        message: "There is already a matching selector for this Service."
41        deny:
42          conditions:
43            any:
44              - key: "{{service_count}}"
45                operator: GreaterThan
46                value: 0