Use same Flux versions in chart and kustomization
[icn.git] / deploy / cluster / cluster.sh
1 #!/usr/bin/env bash
2 set -eux -o pipefail
3
4 SCRIPTDIR="$(readlink -f $(dirname ${BASH_SOURCE[0]}))"
5 LIBDIR="$(dirname $(dirname ${SCRIPTDIR}))/env/lib"
6
7 source $LIBDIR/logging.sh
8 source $LIBDIR/common.sh
9
10 function build_source_flannel {
11     curl -sL https://raw.githubusercontent.com/coreos/flannel/${FLANNEL_VERSION}/Documentation/kube-flannel.yml -o ${SCRIPTDIR}/addons/flannel.yaml
12     cat <<EOF >${SCRIPTDIR}/templates/flannel-addon.yaml
13 {{- if eq .Values.cni "flannel" }}
14 ---
15 $(kubectl create configmap flannel-addon --from-file=${SCRIPTDIR}/addons/flannel.yaml -o yaml --dry-run=client)
16 {{- end }}
17 EOF
18     sed -i -e 's/  name: flannel-addon/  name: {{ .Values.clusterName }}-flannel-addon/' ${SCRIPTDIR}/templates/flannel-addon.yaml
19     sed -i -e 's/10.244.0.0\/16/{{ .Values.podCidr }}/' ${SCRIPTDIR}/templates/flannel-addon.yaml
20 }
21
22 function build_source_flux {
23     # NOTE: This reaches outside this directory to
24     # deploy/site/cluster-addons/flux-system.  This is to ensure that
25     # the day-0 config of a cluster using deploy/site/cluster-addons
26     # is in sync with the chart.
27     flux install --export >${SCRIPTDIR}/../site/cluster-addons/flux-system/gotk-components.yaml
28     kustomize build ${SCRIPTDIR}/../site/cluster-addons/flux-system >${SCRIPTDIR}/addons/flux-system.yaml
29     cat <<EOF >>${SCRIPTDIR}/addons/flux-system.yaml
30 ---
31 apiVersion: rbac.authorization.k8s.io/v1
32 kind: RoleBinding
33 metadata:
34   name: psp:privileged:flux-system
35   namespace: flux-system
36 roleRef:
37   apiGroup: rbac.authorization.k8s.io
38   kind: ClusterRole
39   name: psp:privileged
40 subjects:
41 - kind: Group
42   name: system:serviceaccounts:flux-system
43   apiGroup: rbac.authorization.k8s.io
44 EOF
45     # The name "sync" must be sorted after "flux-system" to ensure
46     # CRDs are instantiated first
47     cat <<'EOF' >${SCRIPTDIR}/addons/sync.yaml
48 {{- if .Values.flux.decryptionSecret }}
49 ---
50 apiVersion: v1
51 type: Opaque
52 kind: Secret
53 metadata:
54   name: {{ .Values.flux.repositoryName }}-{{ .Values.flux.branch }}-sops-gpg
55   namespace: flux-system
56 data:
57   sops.asc: {{ .Values.flux.decryptionSecret | b64enc }}
58 {{- end }}
59 ---
60 apiVersion: source.toolkit.fluxcd.io/v1beta1
61 kind: GitRepository
62 metadata:
63   name: {{ .Values.flux.repositoryName }}
64   namespace: flux-system
65 spec:
66   gitImplementation: go-git
67   interval: 1m0s
68   ref:
69     branch: {{ .Values.flux.branch }}
70   timeout: 20s
71   url: {{ .Values.flux.url }}
72 ---
73 apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
74 kind: Kustomization
75 metadata:
76   name: {{ .Values.clusterName }}-flux-sync
77   namespace: flux-system
78 spec:
79   interval: 10m0s
80   path: {{ .Values.flux.path }}
81   prune: true
82   sourceRef:
83     kind: GitRepository
84     name: {{ .Values.flux.repositoryName }}
85 {{- if .Values.flux.decryptionSecret }}
86   decryption:
87     provider: sops
88     secretRef:
89       name: {{ .Values.flux.repositoryName }}-{{ .Values.flux.branch }}-sops-gpg
90 {{- end }}
91 EOF
92     cat <<EOF >${SCRIPTDIR}/templates/flux-addon.yaml
93 {{- if .Values.flux }}
94 ---
95 $(kubectl create configmap flux-addon --from-file=${SCRIPTDIR}/addons/flux-system.yaml,${SCRIPTDIR}/addons/sync.yaml -o yaml --dry-run=client)
96 {{- end }}
97 EOF
98     sed -i -e 's/  name: flux-addon/  name: {{ .Values.clusterName }}-flux-addon/' ${SCRIPTDIR}/templates/flux-addon.yaml
99 }
100
101 function build_source_podsecurity {
102     # PodSecurityPolicy is being replaced in future versions of K8s.
103     # The recommended practice is described by K8s at
104     # - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#recommended-practice
105     # - https://kubernetes.io/docs/concepts/security/pod-security-standards/
106     # and provides three levels: privileged, baseline, and restricted.
107     #
108     # The question to answer here is how to reconcile the K8s levels
109     # against the Akraino security requirements.
110     #
111     # For the time being, the below populates the cluster with the K8s
112     # recommended levels and provides an additional policy (icn) bound
113     # to the system:authenticated group to meet the Akraino
114     # requirements.
115     cat <<EOF >${SCRIPTDIR}/addons/podsecurity.yaml
116 ---
117 $(curl -sL https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/policy/privileged-psp.yaml)
118 ---
119 $(curl -sL https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/policy/baseline-psp.yaml)
120 ---
121 $(curl -sL https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/policy/restricted-psp.yaml)
122 ---
123 $(curl -sL https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/policy/privileged-psp.yaml |
124   sed -e 's/  name: privileged/  name: icn/' |
125   sed -e '/^  allowedCapabilities:/,/^  [!-]/d')
126   allowedCapabilities:
127     - 'NET_ADMIN'
128     - 'SYS_ADMIN'
129     - 'SYS_NICE'
130     - 'SYS_PTRACE'
131   requiredDropCapabilities:
132     - 'NET_RAW'
133 ---
134 apiVersion: rbac.authorization.k8s.io/v1
135 kind: ClusterRole
136 metadata:
137   name: psp:privileged
138   labels:
139     addonmanager.kubernetes.io/mode: Reconcile
140 rules:
141 - apiGroups:
142   - policy
143   resourceNames:
144   - privileged
145   resources:
146   - podsecuritypolicies
147   verbs:
148   - use
149 ---
150 apiVersion: rbac.authorization.k8s.io/v1
151 kind: ClusterRole
152 metadata:
153   name: psp:baseline
154   labels:
155     addonmanager.kubernetes.io/mode: Reconcile
156 rules:
157 - apiGroups:
158   - policy
159   resourceNames:
160   - baseline
161   resources:
162   - podsecuritypolicies
163   verbs:
164   - use
165 ---
166 apiVersion: rbac.authorization.k8s.io/v1
167 kind: ClusterRole
168 metadata:
169   name: psp:icn
170   labels:
171     addonmanager.kubernetes.io/mode: Reconcile
172 rules:
173 - apiGroups:
174   - policy
175   resourceNames:
176   - icn
177   resources:
178   - podsecuritypolicies
179   verbs:
180   - use
181 ---
182 apiVersion: rbac.authorization.k8s.io/v1
183 kind: ClusterRole
184 metadata:
185   name: psp:restricted
186   labels:
187     addonmanager.kubernetes.io/mode: Reconcile
188 rules:
189 - apiGroups:
190   - policy
191   resourceNames:
192   - restricted
193   resources:
194   - podsecuritypolicies
195   verbs:
196   - use
197 ---
198 apiVersion: rbac.authorization.k8s.io/v1
199 kind: RoleBinding
200 metadata:
201   name: psp:privileged:nodes
202   namespace: kube-system
203   labels:
204     addonmanager.kubernetes.io/mode: Reconcile
205 roleRef:
206   apiGroup: rbac.authorization.k8s.io
207   kind: ClusterRole
208   name: psp:privileged
209 subjects:
210 - kind: Group
211   name: system:nodes
212   apiGroup: rbac.authorization.k8s.io
213 ---
214 apiVersion: rbac.authorization.k8s.io/v1
215 kind: RoleBinding
216 metadata:
217   name: psp:privileged:kube-system
218   namespace: kube-system
219 roleRef:
220   apiGroup: rbac.authorization.k8s.io
221   kind: ClusterRole
222   name: psp:privileged
223 subjects:
224 - kind: Group
225   name: system:serviceaccounts:kube-system
226   apiGroup: rbac.authorization.k8s.io
227 ---
228 apiVersion: rbac.authorization.k8s.io/v1
229 kind: ClusterRoleBinding
230 metadata:
231   name: psp:icn:any
232 roleRef:
233   kind: ClusterRole
234   name: psp:icn
235   apiGroup: rbac.authorization.k8s.io
236 subjects:
237 - kind: Group
238   name: system:authenticated
239   apiGroup: rbac.authorization.k8s.io
240 EOF
241     cat <<EOF >${SCRIPTDIR}/templates/podsecurity-addon.yaml
242 ---
243 $(kubectl create configmap podsecurity-addon --from-file=${SCRIPTDIR}/addons/podsecurity.yaml -o yaml --dry-run=client)
244 EOF
245     sed -i -e 's/  name: podsecurity-addon/  name: {{ .Values.clusterName }}-podsecurity-addon/' ${SCRIPTDIR}/templates/podsecurity-addon.yaml
246 }
247
248 function build_source_calico {
249     mkdir -p ${SCRIPTDIR}/addons/calico
250     curl -sL https://docs.projectcalico.org/archive/${CALICO_VERSION%.*}/manifests/calico.yaml -o ${SCRIPTDIR}/addons/calico/calico.yaml
251     # Remove trailing whitespace so that kubectl create configmap
252     # doesn't insert explicit newlines
253     sed -i -r 's/\s+$//g' ${SCRIPTDIR}/addons/calico/calico.yaml
254     cat <<EOF >${SCRIPTDIR}/addons/calico/ip-autodetection-method-patch.yaml
255 kind: DaemonSet
256 apiVersion: apps/v1
257 metadata:
258   name: calico-node
259   namespace: kube-system
260 spec:
261   template:
262     spec:
263       containers:
264         - name: calico-node
265           env:
266             - name: IP_AUTODETECTION_METHOD
267               value: can-reach=www.google.com
268 EOF
269     cat <<EOF >${SCRIPTDIR}/addons/calico/kustomization.yaml
270 resources:
271 - calico.yaml
272 patches:
273 - path: ip-autodetection-method-patch.yaml
274 EOF
275     kustomize build ${SCRIPTDIR}/addons/calico >${SCRIPTDIR}/addons/calico.yaml
276     cat <<EOF >${SCRIPTDIR}/templates/calico-addon.yaml
277 {{- if eq .Values.cni "calico" }}
278 ---
279 $(kubectl create configmap calico-addon --from-file=${SCRIPTDIR}/addons/calico.yaml -o yaml --dry-run=client)
280 {{- end }}
281 EOF
282     sed -i -e 's/  name: calico-addon/  name: {{ .Values.clusterName }}-calico-addon/' ${SCRIPTDIR}/templates/calico-addon.yaml
283 }
284
285 # This may be used to update the in-place addon YAML files from the
286 # upstream projects
287 function build_source {
288     mkdir -p ${SCRIPTDIR}/addons
289     build_source_calico
290     build_source_flannel
291     build_source_flux
292     build_source_podsecurity
293 }
294
295 case $1 in
296     "build-source") build_source ;;
297     "foo") build_source_calico ;;
298     *) cat <<EOF
299 Usage: $(basename $0) COMMAND
300
301 Commands:
302   build-source  - Rebuild the in-tree addon YAML files
303 EOF
304        ;;
305 esac