418 lines
12 KiB
Smarty

{{/*
Create a cluster name. The name of the cluster is just the release name.
*/}}
{{- define "openstack-cluster.clusterName" -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- end }}
{{/*
Create a name for a cluster component.
*/}}
{{- define "openstack-cluster.componentName" -}}
{{- $ctx := index . 0 -}}
{{- $componentName := index . 1 -}}
{{- printf "%s-%s" $ctx.Release.Name $componentName | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "openstack-cluster.chart" -}}
{{-
printf "%s-%s" .Chart.Name .Chart.Version |
replace "+" "_" |
trunc 63 |
trimSuffix "-" |
trimSuffix "." |
trimSuffix "_"
}}
{{- end }}
{{/*
Common labels
*/}}
{{- define "openstack-cluster.commonLabels" -}}
helm.sh/chart: {{ include "openstack-cluster.chart" . }}
{{ .Values.projectPrefix }}/managed-by: {{ .Release.Service }}
{{ .Values.projectPrefix }}/infrastructure-provider: openstack
{{- end -}}
{{/*
Selector labels for cluster-level resources
*/}}
{{- define "openstack-cluster.selectorLabels" -}}
{{ .Values.projectPrefix }}/cluster: {{ include "openstack-cluster.clusterName" . }}
{{- end -}}
{{/*
Labels for cluster-level resources
*/}}
{{- define "openstack-cluster.labels" -}}
{{ include "openstack-cluster.commonLabels" . }}
{{ include "openstack-cluster.selectorLabels" . }}
{{- end -}}
{{/*
Selector labels for component-level resources
*/}}
{{- define "openstack-cluster.componentSelectorLabels" -}}
{{- $ctx := index . 0 -}}
{{- $componentName := index . 1 -}}
{{ include "openstack-cluster.selectorLabels" $ctx }}
{{ $ctx.Values.projectPrefix }}/component: {{ $componentName }}
{{- end -}}
{{/*
Labels for component-level resources
*/}}
{{- define "openstack-cluster.componentLabels" -}}
{{ include "openstack-cluster.commonLabels" (index . 0) }}
{{ include "openstack-cluster.componentSelectorLabels" . }}
{{- end -}}
{{/*
Name of the secret containing the cloud credentials.
*/}}
{{- define "openstack-cluster.cloudCredentialsSecretName" -}}
{{- if .Values.cloudCredentialsSecretName -}}
{{- .Values.cloudCredentialsSecretName -}}
{{- else -}}
{{ include "openstack-cluster.componentName" (list . "cloud-credentials") -}}
{{- end -}}
{{- end -}}
{{/*
Template that merges two variables with the latter taking precedence and outputs the result as YAML.
Lists are merged by concatenating them rather than overwriting.
*/}}
{{- define "openstack-cluster.mergeConcat" -}}
{{- $left := index . 0 }}
{{- $right := index . 1 }}
{{- if kindIs (kindOf list) $left }}
{{- if kindIs (kindOf list) $right }}
{{ concat $left $right | toYaml }}
{{- else }}
{{ default $left $right | toYaml }}
{{- end }}
{{- else if kindIs (kindOf dict) $left }}
{{- if kindIs (kindOf dict) $right }}
{{- range $key := concat (keys $left) (keys $right) | uniq }}
{{- if and (hasKey $left $key) (hasKey $right $key) }}
{{- $merged := include "openstack-cluster.mergeConcat" (list (index $left $key) (index $right $key)) }}
{{ $key }}: {{ $merged | nindent 2 }}
{{- else if hasKey $left $key }}
{{ index $left $key | dict $key | toYaml }}
{{- else }}
{{ index $right $key | dict $key | toYaml }}
{{- end }}
{{- end }}
{{- else }}
{{ default $left $right | toYaml }}
{{- end }}
{{- else }}
{{ default $left $right | toYaml }}
{{- end }}
{{- end }}
{{/*
Applies a list of templates to an input object sequentially.
*/}}
{{- define "openstack-cluster.mergeConcatMany" -}}
{{- $obj := first . }}
{{- range $overrides := rest . }}
{{- $obj = include "openstack-cluster.mergeConcat" (list $obj $overrides) | fromYaml }}
{{- end }}
{{- toYaml $obj }}
{{- end }}
{{/*
Outputs the node registration object for setting node labels.
*/}}
{{- define "openstack-cluster.nodeRegistration.nodeLabels" -}}
nodeRegistration:
kubeletExtraArgs:
node-labels: "{{ range $i, $k := (keys . | sortAlpha) }}{{ if ne $i 0 }},{{ end }}{{ $k }}={{ index $ $k }}{{ end }}"
{{- end }}
{{/*
Outputs the content for a containerd registry file containing mirror configuration.
*/}}
{{- define "openstack-cluster.registryFile" -}}
{{- $registry := index . 0 -}}
{{- $registrySpec := index . 1 -}}
{{-
$defaultUpstream :=
eq $registry "docker.io" |
ternary "registry-1.docker.io" $registry |
printf "https://%s"
-}}
{{-
$upstream :=
kindIs "map" $registrySpec |
ternary $registrySpec dict |
dig "upstream" $defaultUpstream
-}}
{{-
$mirrors :=
kindIs "map" $registrySpec |
ternary $registrySpec (dict "mirrors" $registrySpec) |
dig "mirrors" list
-}}
{{- with $upstream }}
server = "{{ . }}"
{{- end }}
{{- range $mirror := $mirrors }}
{{-
$url :=
kindIs "map" $mirror |
ternary $mirror (dict "url" $mirror) |
dig "url" "" |
required "unable to determine mirror url"
}}
{{-
$capabilities :=
kindIs "map" $mirror |
ternary $mirror (dict "capabilities" list) |
dig "capabilities" list |
default (list "pull" "resolve")
}}
{{-
$skipVerify :=
kindIs "map" $mirror |
ternary $mirror (dict "skipVerify" false) |
dig "skipVerify" false
}}
{{-
$overridePath :=
kindIs "map" $mirror |
ternary $mirror (dict "overridePath" true) |
dig "overridePath" true
}}
[host."{{ $url }}"]
capabilities = [{{ range $i, $cap := $capabilities }}{{ if gt $i 0 }}, {{ end }}"{{ . }}"{{ end }}]
skip_verify = {{ ternary "true" "false" $skipVerify }}
override_path = {{ ternary "true" "false" $overridePath }}
{{- end }}
{{- end }}
{{/*
Produces the kubeadmConfigSpec required to configure containerd.
*/}}
{{- define "openstack-cluster.kubeadmConfigSpec.containerd" -}}
files:
- path: /etc/containerd/conf.d/.keepdir
content: |
# This file is created by the capi-helm-chart to ensure that its parent directory exists
owner: root:root
permissions: "0644"
- path: /etc/containerd/certs.d/.keepdir
content: |
# This file is created by the capi-helm-chart to ensure that its parent directory exists
owner: root:root
permissions: "0644"
{{- if ne .Values.osDistro "flatcar" }}
- path: /etc/containerd/config.toml
content: |
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
owner: root:root
permissions: "0644"
append: true
{{- end }}
{{- with .Values.registryMirrors }}
{{- range $registry, $registrySpec := . }}
- path: /etc/containerd/certs.d/{{ $registry }}/hosts.toml
content: |
{{- include "openstack-cluster.registryFile" (list $registry $registrySpec) | nindent 6 }}
owner: root:root
permissions: "0644"
{{- end }}
{{- end }}
{{- if .Values.registryAuth }}
- path: /etc/containerd/conf.d/auth.toml
contentFrom:
secret:
name: {{ include "openstack-cluster.componentName" (list . "containerd-auth") }}
key: "auth.toml"
owner: root:root
permissions: "0644"
{{- end }}
{{- end }}
{{/*
Produces the kubeadmConfigSpec required to configure additional trusted CAs for cluster nodes,
e.g. for private registries.
*/}}
{{- define "openstack-cluster.kubeadmConfigSpec.trustedCAs" -}}
{{- with .Values.trustedCAs }}
files:
{{- range $name, $certificate := . }}
- path: /usr/local/share/ca-certificates/{{ $name }}.crt
content: |
{{- nindent 6 $certificate }}
owner: root:root
permissions: "0644"
{{- end }}
preKubeadmCommands:
- update-ca-certificates
{{- end }}
{{- end }}
{{/*
Produces the kubeadmConfigSpec required to install additional packages.
*/}}
{{- define "openstack-cluster.kubeadmConfigSpec.additionalPackages" -}}
{{- with .Values.additionalPackages }}
preKubeadmCommands:
- apt update -y
- apt install -y {{ join " " . }}
{{- end }}
{{- end }}
{{/*
Produces the spec for a KubeadmConfig object.
*/}}
{{- define "openstack-cluster.kubeadmConfigSpec" -}}
{{- $ctx := index . 0 }}
{{- $kubeadmConfigSpec := index . 1 }}
{{-
list
(include "openstack-cluster.kubeadmConfigSpec.trustedCAs" $ctx | fromYaml)
(include "openstack-cluster.kubeadmConfigSpec.containerd" $ctx | fromYaml)
(include "openstack-cluster.kubeadmConfigSpec.additionalPackages" $ctx | fromYaml)
$kubeadmConfigSpec |
include "openstack-cluster.mergeConcatMany"
}}
{{- end }}
{{/*
Produces the spec for an Ignition based OS specific KubeadmConfig object conditional on osDistro set to "flatcar".
*/}}
{{- define "openstack-cluster.flatcarKubeadmConfigSpec" -}}
initConfiguration:
nodeRegistration:
name: ${COREOS_OPENSTACK_HOSTNAME}
joinConfiguration:
nodeRegistration:
name: ${COREOS_OPENSTACK_HOSTNAME}
preKubeadmCommands:
- export COREOS_OPENSTACK_HOSTNAME=${COREOS_OPENSTACK_HOSTNAME%.*}
- envsubst < /etc/kubeadm.yml > /etc/kubeadm.yml.tmp
- mv /etc/kubeadm.yml.tmp /etc/kubeadm.yml
format: ignition
ignition:
containerLinuxConfig:
additionalConfig: |
systemd:
units:
- name: coreos-metadata-sshkeys@.service
enabled: true
- name: kubeadm.service
enabled: true
dropins:
- name: 10-flatcar.conf
contents: |
[Unit]
Requires=containerd.service coreos-metadata.service
After=containerd.service coreos-metadata.service
[Service]
EnvironmentFile=/run/metadata/flatcar
{{- end }}
{{- define "openstack-cluster.osDistroKubeadmConfigSpec" }}
{{- $ctx := index . 0 }}
{{- $osDistro := $ctx.Values.osDistro }}
{{- if eq $osDistro "flatcar" }}
{{- include "openstack-cluster.flatcarKubeadmConfigSpec" $ctx }}
{{- end }}
{{- end }}
{{/*
Create folders necessary for webhook integration.
*/}}
{{- define "openstack-cluster.webhookPatches" }}
preKubeadmCommands:
- mkdir -p /etc/kubernetes/webhooks
- mkdir -p /etc/kubernetes/patches
{{- end }}
{{/*
Supplement kubeadmConfig with apiServer config and webhook patches as needed. Authentication
webhooks and policies for audit logging can be added here.
*/}}
{{- define "openstack-cluster.patchConfigSpec" -}}
{{- $ctx := index . 0 }}
{{- $authWebhook := $ctx.Values.authWebhook }}
clusterConfiguration:
apiServer:
extraArgs:
{{- if $authWebhook }}
authorization-mode: Node,Webhook,RBAC
{{- if eq $authWebhook "k8s-keystone-auth" }}
authentication-token-webhook-config-file: /etc/kubernetes/webhooks/keystone_webhook_config.yaml
authorization-webhook-config-file: /etc/kubernetes/webhooks/keystone_webhook_config.yaml
{{/*
Add else if blocks with other webhooks and apiServer arguments (i.e. audit logging)
in future
*/}}
{{- end }}
initConfiguration:
patches:
directory: /etc/kubernetes/patches
joinConfiguration:
patches:
directory: /etc/kubernetes/patches
{{- include "openstack-cluster.webhookPatches" $ctx }}
{{- if eq $authWebhook "k8s-keystone-auth" }}
{{- include "openstack-cluster.k8sKeystoneAuthWebhook" $ctx }}
{{/*
Add else if blocks with other webhooks or policy files in future.
*/}}
{{- end }}
{{- end }}
{{- end }}
{{/*
Produces integration for k8s-keystone-auth webhook on apiserver
*/}}
{{- define "openstack-cluster.k8sKeystoneAuthWebhook" }}
files:
- path: /etc/kubernetes/patches/kube-apiserver0+strategic.yaml
permissions: "0644"
owner: root:root
content: |
spec:
containers:
- name: kube-apiserver
volumeMounts:
- mountPath: /etc/kubernetes/webhooks
name: kube-webhooks
readOnly: true
volumes:
- hostPath:
path: /etc/kubernetes/webhooks
type: DirectoryOrCreate
name: kube-webhooks
- path: /etc/kubernetes/webhooks/keystone_webhook_config.yaml
content: |
---
apiVersion: v1
kind: Config
preferences: {}
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://127.0.0.1:8443/webhook
name: webhook
users:
- name: webhook
contexts:
- context:
cluster: webhook
user: webhook
name: webhook
current-context: webhook
owner: root:root
permissions: "0644"
{{- end }}