diff --git a/class/defaults.yml b/class/defaults.yml index a6905ec..eadb553 100644 --- a/class/defaults.yml +++ b/class/defaults.yml @@ -1,4 +1,30 @@ parameters: upgrade_controller: =_metadata: {} + namespace: syn-upgrade-controller + + images: + upgrade_controller: + registry: docker.io + repository: rancher/system-upgrade-controller + tag: v0.13.2 + kubectl: + registry: docker.io + repository: rancher/kubectl + tag: v1.28.4 + k3s_upgrade: + registry: docker.io + repository: rancher/k3s-upgrade + + replicaCount: 1 + + resources: + requests: + cpu: 10m + memory: 64Mi + limits: + cpu: 500m + memory: 512Mi + + release: '' diff --git a/component/main.jsonnet b/component/main.jsonnet index 837fff8..dc5638a 100644 --- a/component/main.jsonnet +++ b/component/main.jsonnet @@ -2,9 +2,197 @@ local kap = import 'lib/kapitan.libjsonnet'; local kube = import 'lib/kube.libjsonnet'; local inv = kap.inventory(); + // The hiera parameters for the component local params = inv.parameters.upgrade_controller; +local appName = 'upgrade-conttroller'; + +local namespace = kube.Namespace(params.namespace) { + metadata+: { + labels+: { + 'app.kubernetes.io/name': params.namespace, + 'pod-security.kubernetes.io/enforce': 'privileged', + }, + }, +}; + + +// RBAC + +local serviceAccount = kube.ServiceAccount(appName) { + metadata+: { + namespace: params.namespace, + }, +}; + +local clusterRoleBinding = kube.ClusterRoleBinding(appName) { + subjects_: [ serviceAccount ], + roleRef: { + apiGroup: 'rbac.authorization.k8s.io', + kind: 'ClusterRole', + name: 'cluster-admin', + }, +}; + + +// Deployment + +local deployment = kube.Deployment(appName) { + spec+: { + replicas: params.replicaCount, + template+: { + spec+: { + serviceAccountName: appName, + securityContext: { + seccompProfile: { type: 'RuntimeDefault' }, + }, + affinity: { + nodeAffinity: { + requiredDuringSchedulingIgnoredDuringExecution: { + nodeSelectorTerms: [ { + matchExpressions: [ { + key: 'node-role.kubernetes.io/control-plane', + operator: 'Exists', + } ], + } ], + }, + }, + }, + containers_:: { + default: kube.Container(appName) { + image: '%(registry)s/%(repository)s:%(tag)s' % params.images.upgrade_controller, + env_:: { + SYSTEM_UPGRADE_CONTROLLER_NAME: { fieldRef: { apiVersion: 'v1', fieldPath: 'metadata.labels[\'name\']' } }, + SYSTEM_UPGRADE_CONTROLLER_NAMESPACE: { fieldRef: { apiVersion: 'v1', fieldPath: 'metadata.namespace' } }, + }, + envFrom: [ + { configMapRef: { name: appName } }, + ], + volumeMounts_:: { + 'etc-ssl': { mountPath: '/etc/ssl', readOnly: true }, + 'etc-pki': { mountPath: '/etc/pki', readOnly: true }, + 'etc-ca-certificates': { mountPath: '/etc/ca-certificates', readOnly: true }, + tmp: { mountPath: '/tmp' }, + }, + resources: params.resources, + securityContext: { + runAsNonRoot: true, + allowPrivilegeEscalation: false, + capabilities: { drop: [ 'ALL' ] }, + }, + }, + }, + tolerations: [ + { + key: 'CriticalAddonsOnly', + operator: 'Exists', + }, + { + key: 'node-role.kubernetes.io/master', + operator: 'Exists', + effect: 'NoSchedule', + }, + { + key: 'node-role.kubernetes.io/controlplane', + operator: 'Exists', + effect: 'NoSchedule', + }, + { + key: 'node-role.kubernetes.io/control-plane', + operator: 'Exists', + effect: 'NoSchedule', + }, + { + key: 'node-role.kubernetes.io/etcd', + operator: 'Exists', + effect: 'NoExecute', + }, + ], + volumes_:: { + 'etc-ssl': { hostpath: { path: '/etc/ssl', type: 'DirectoryOrCreate' } }, + 'etc-pki': { hostpath: { path: '/etc/pki', type: 'DirectoryOrCreate' } }, + 'etc-ca-certificates': { hostpath: { path: '/etc/ca-certificates', type: 'DirectoryOrCreate' } }, + tmp: { emptyDir: {} }, + }, + }, + }, + }, +}; + +local configmap = kube.ConfigMap(appName) { + metadata+: { + namespace: params.namespace, + }, + data: { + SYSTEM_UPGRADE_CONTROLLER_DEBUG: 'false', + SYSTEM_UPGRADE_CONTROLLER_THREADS: '2', + SYSTEM_UPGRADE_JOB_ACTIVE_DEADLINE_SECONDS: '900', + SYSTEM_UPGRADE_JOB_BACKOFF_LIMIT: '99', + SYSTEM_UPGRADE_JOB_IMAGE_PULL_POLICY: 'Always', + SYSTEM_UPGRADE_JOB_KUBECTL_IMAGE: '%(registry)s/%(repository)s:%(tag)s' % params.images.kubectl, + SYSTEM_UPGRADE_JOB_PRIVILEGED: 'true', + SYSTEM_UPGRADE_JOB_TTL_SECONDS_AFTER_FINISH: '900', + SYSTEM_UPGRADE_PLAN_POLLING_INTERVAL: '15m', + }, +}; + + +// Plan + +local plan(name) = kube._Object('upgrade.cattle.io/v1', 'Plan', name) { + metadata+: { + namespace: params.namespace, + }, + spec: { + version: params.release, + concurrency: 1, + cordon: true, + upgrade: { + image: '%(registry)s/%(repository)s' % params.images.k3s_upgrade, + }, + nodeSelector: { + matchExpressions: [ { + key: 'k3s-upgrade', + operator: 'NotIn', + values: [ 'disabled', 'false' ], + } ], + }, + tolerations: [ + { + key: 'CriticalAddonsOnly', + operator: 'Exists', + }, + { + key: 'node-role.kubernetes.io/master', + operator: 'Exists', + effect: 'NoSchedule', + }, + { + key: 'node-role.kubernetes.io/controlplane', + operator: 'Exists', + effect: 'NoSchedule', + }, + { + key: 'node-role.kubernetes.io/control-plane', + operator: 'Exists', + effect: 'NoSchedule', + }, + { + key: 'node-role.kubernetes.io/etcd', + operator: 'Exists', + effect: 'NoExecute', + }, + ], + serviceAccountName: appName, + }, +}; + // Define outputs below { + '00_namespace': namespace, + '10_deployment': deployment, + '10_configmap': configmap, + '10_rbac': [ serviceAccount, clusterRoleBinding ], + [if params.release != '' then '20_plan']: plan('release-%s' % params.release), } diff --git a/tests/golden/defaults/upgrade-controller/upgrade-controller/00_namespace.yaml b/tests/golden/defaults/upgrade-controller/upgrade-controller/00_namespace.yaml new file mode 100644 index 0000000..e6ad5ad --- /dev/null +++ b/tests/golden/defaults/upgrade-controller/upgrade-controller/00_namespace.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + annotations: {} + labels: + app.kubernetes.io/name: syn-upgrade-controller + name: syn-upgrade-controller + pod-security.kubernetes.io/enforce: privileged + name: syn-upgrade-controller diff --git a/tests/golden/defaults/upgrade-controller/upgrade-controller/10_configmap.yaml b/tests/golden/defaults/upgrade-controller/upgrade-controller/10_configmap.yaml new file mode 100644 index 0000000..dca2b7b --- /dev/null +++ b/tests/golden/defaults/upgrade-controller/upgrade-controller/10_configmap.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +data: + SYSTEM_UPGRADE_CONTROLLER_DEBUG: 'false' + SYSTEM_UPGRADE_CONTROLLER_THREADS: '2' + SYSTEM_UPGRADE_JOB_ACTIVE_DEADLINE_SECONDS: '900' + SYSTEM_UPGRADE_JOB_BACKOFF_LIMIT: '99' + SYSTEM_UPGRADE_JOB_IMAGE_PULL_POLICY: Always + SYSTEM_UPGRADE_JOB_KUBECTL_IMAGE: docker.io/rancher/kubectl:v1.28.4 + SYSTEM_UPGRADE_JOB_PRIVILEGED: 'true' + SYSTEM_UPGRADE_JOB_TTL_SECONDS_AFTER_FINISH: '900' + SYSTEM_UPGRADE_PLAN_POLLING_INTERVAL: 15m +kind: ConfigMap +metadata: + annotations: {} + labels: + name: upgrade-conttroller + name: upgrade-conttroller + namespace: syn-upgrade-controller diff --git a/tests/golden/defaults/upgrade-controller/upgrade-controller/10_deployment.yaml b/tests/golden/defaults/upgrade-controller/upgrade-controller/10_deployment.yaml new file mode 100644 index 0000000..e602b3f --- /dev/null +++ b/tests/golden/defaults/upgrade-controller/upgrade-controller/10_deployment.yaml @@ -0,0 +1,116 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + name: upgrade-conttroller + name: upgrade-conttroller +spec: + minReadySeconds: 30 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + name: upgrade-conttroller + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + annotations: {} + labels: + name: upgrade-conttroller + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: Exists + containers: + - args: [] + env: + - name: SYSTEM_UPGRADE_CONTROLLER_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.labels['name'] + - name: SYSTEM_UPGRADE_CONTROLLER_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + envFrom: + - configMapRef: + name: upgrade-conttroller + image: docker.io/rancher/system-upgrade-controller:v0.13.2 + imagePullPolicy: IfNotPresent + name: upgrade-conttroller + ports: [] + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + stdin: false + tty: false + volumeMounts: + - mountPath: /etc/ca-certificates + name: etc-ca-certificates + readOnly: true + - mountPath: /etc/pki + name: etc-pki + readOnly: true + - mountPath: /etc/ssl + name: etc-ssl + readOnly: true + - mountPath: /tmp + name: tmp + imagePullSecrets: [] + initContainers: [] + securityContext: + seccompProfile: + type: RuntimeDefault + serviceAccountName: upgrade-conttroller + terminationGracePeriodSeconds: 30 + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/controlplane + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + operator: Exists + - effect: NoExecute + key: node-role.kubernetes.io/etcd + operator: Exists + volumes: + - hostpath: + path: /etc/ca-certificates + type: DirectoryOrCreate + name: etc-ca-certificates + - hostpath: + path: /etc/pki + type: DirectoryOrCreate + name: etc-pki + - hostpath: + path: /etc/ssl + type: DirectoryOrCreate + name: etc-ssl + - emptyDir: {} + name: tmp diff --git a/tests/golden/defaults/upgrade-controller/upgrade-controller/10_rbac.yaml b/tests/golden/defaults/upgrade-controller/upgrade-controller/10_rbac.yaml new file mode 100644 index 0000000..aa88036 --- /dev/null +++ b/tests/golden/defaults/upgrade-controller/upgrade-controller/10_rbac.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + name: upgrade-conttroller + name: upgrade-conttroller + namespace: syn-upgrade-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + annotations: {} + labels: + name: upgrade-conttroller + name: upgrade-conttroller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: + - kind: ServiceAccount + name: upgrade-conttroller + namespace: syn-upgrade-controller