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