All Policies

Kubeops Config Syncer Secret Generation From Rancher CAPI Secret

This policy generates and synchronizes a Kubeops Config Syncer merged kubeconfig Secret from Rancher managed cluster CAPI secrets. This kubeconfig Secret is required by the Kubeops Config Syncer for it to sync ConfigMaps/Secrets from the Rancher management cluster to downstream clusters.

Policy Definition

/kubeops/config-syncer-secret-generation-from-rancher-capi/config-syncer-secret-generation-from-rancher-capi.yaml

 1apiVersion: kyverno.io/v1
 2kind: ClusterPolicy
 3metadata:
 4  name: config-syncer-secret-generation-from-rancher-capi
 5  annotations:
 6    policies.kyverno.io/title: Kubeops Config Syncer Secret Generation From Rancher CAPI Secret
 7    policies.kyverno.io/category: Kubeops
 8    policies.kyverno.io/severity: medium
 9    policies.kyverno.io/subject: Secret
10    kyverno.io/kyverno-version: 1.8.0
11    policies.kyverno.io/minversion: 1.7.1
12    kyverno.io/kubernetes-version: "1.23"
13    policies.kyverno.io/description: >-
14      This policy generates and synchronizes a Kubeops Config Syncer merged kubeconfig
15      Secret from Rancher managed cluster CAPI secrets. This kubeconfig Secret is
16      required by the Kubeops Config Syncer for it to sync ConfigMaps/Secrets from
17      the Rancher management cluster to downstream clusters.
18spec:
19  generateExisting: true
20  rules:
21  - name: source-rancher-non-local-cluster-and-capi-secret
22    match:
23      all:
24      - resources:
25          kinds:
26          - provisioning.cattle.io/v1/Cluster
27    exclude:
28      any:
29      - resources:
30          namespaces:
31          - fleet-local
32    context:
33    - name: currentKubeconfigData
34      apiCall:
35        urlPath: "/api/v1/namespaces/kubed/secrets"
36        jmesPath: "items[?metadata.name == 'kubed'] | [0].data.kubeconfig || ''"
37    - name: secretList
38      apiCall:
39        urlPath: "/api/v1/namespaces/{{request.object.metadata.namespace}}/secrets"
40        jmesPath: "items[?metadata.name.contains(@, '-kubeconfig')]"
41    - name: kubeconfigClustersData
42      variable:
43        value: |
44          {{ secretList | [].{
45              "name": replace_all(metadata.name, '-kubeconfig', ''),
46              "cluster": data.value | base64_decode(@) | parse_yaml(@).clusters[].cluster[] | [0] } || '\[\]'
47          }}
48        jmesPath: 'to_string(@)'
49    - name: kubeconfigUsersData
50      variable:
51        value: |
52          {{ secretList | [].{
53              "name": replace_all(metadata.name, '-kubeconfig', ''),
54              "user": data.value | base64_decode(@) | parse_yaml(@).users[].user[] | [0] } || '\[\]'
55          }}
56        jmesPath: 'to_string(@)'
57#    - name: kubeconfigContextsData # Enable when Kyverno variable substitution bug is resolved
58#      variable:
59#        value: |
60#          {{ secretList | [].{
61#              "name": replace_all(metadata.name, '-kubeconfig', ''),
62#              "context": { "cluster": metadata.name, "user": metadata.name } }
63#          }}
64#        jmesPath: 'to_string(@)'
65    - name: kubeconfigContextsData # Use until Kyverno variable substitition bug is resolved
66      variable:
67        value: |
68          {{ secretList | [].{
69              "name": replace_all(metadata.name, '-kubeconfig', ''),
70              "context": ['CLUSTER_BEGIN', replace_all(metadata.name, '-kubeconfig', ''), 'CLUSTER_END', 'USER_BEGIN', replace_all(metadata.name, '-kubeconfig', ''), 'USER_END'] } || '\[\]'
71          }}
72        jmesPath: "to_string(@) | replace_all(@, '[\"CLUSTER_BEGIN\",', '{\"cluster\":') | replace_all(@, '\"CLUSTER_END\",\"USER_BEGIN\",', '\"user\":') | replace_all(@, ',\"USER_END\"]', '}')"
73    - name: kubeconfigData
74      variable:
75        value: |
76          {
77            "apiVersion": "v1",
78            "kind": "Config",
79            "clusters": {{ kubeconfigClustersData }},
80            "contexts": {{ kubeconfigContextsData }},
81            "users": {{ kubeconfigUsersData }}
82          }
83        jmesPath: 'to_string(@)'
84    preconditions:
85      any:
86      - key: '{{ kubeconfigData || '''' | base64_encode(@) }}'
87        operator: NotEquals
88        value: '{{ currentKubeconfigData }}'
89    generate:
90      synchronize: true
91      apiVersion: v1
92      kind: Secret
93      name: kubed
94      namespace: kubed
95      data:
96        type: Opaque
97        data:
98          kubeconfig: '{{ kubeconfigData || '''' | base64_encode(@) }}'