Enable easy plugin loading (#859)
* Enable easy plugin loading customPluings have to be loaded into the main container somehow. Extend the existing cel plugin loader to allow users to easily specify an image to load it from. Signed-off-by: Kevin Fox <[email protected]> * Add some missing bits Signed-off-by: Kevin Fox <[email protected]> * Incorperate feedback Signed-off-by: Kevin Fox <[email protected]> * Fix formatting Signed-off-by: Kevin Fox <[email protected]> * Fix formatting Signed-off-by: Kevin Fox <[email protected]> --------- Signed-off-by: Kevin Fox <[email protected]>
This commit is contained in:
@@ -200,14 +200,20 @@ Take a copy of the config and merge in .Values.customPlugins and .Values.unsuppo
|
||||
*/}}
|
||||
{{- define "spire-lib.config_merge" }}
|
||||
{{- $pluginsToMerge := dict "plugins" dict }}
|
||||
{{- range $type, $val := .root.Values.customPlugins }}
|
||||
{{- if . }}
|
||||
{{- if eq $type "svidStore" }}
|
||||
{{- $_ := set $pluginsToMerge.plugins "SVIDStore" (deepCopy $val) }}
|
||||
{{- else }}
|
||||
{{- $nt := printf "%s%s" (substr 0 1 $type | upper) (substr 1 -1 $type) }}
|
||||
{{- $_ := set $pluginsToMerge.plugins $nt (deepCopy $val) }}
|
||||
{{- range $type, $instances := .root.Values.customPlugins }}
|
||||
{{- if $instances }}
|
||||
{{- $nt := (eq $type "svidStore") | ternary "SVIDStore" (printf "%s%s" (substr 0 1 $type | upper) (substr 1 -1 $type)) }}
|
||||
{{- $processedInstances := dict }}
|
||||
{{- range $instanceName, $config := $instances }}
|
||||
{{- $pluginData := deepCopy $config }}
|
||||
{{- $hasImage := hasKey $pluginData "image" }}
|
||||
{{- $_ := unset $pluginData "image" }}
|
||||
{{- if and $hasImage $pluginData.plugin_cmd }}
|
||||
{{- $_ := set $pluginData "plugin_cmd" (printf "/plugins/%s/%s" $type $instanceName) }}
|
||||
{{- end }}
|
||||
{{- $_ := set $processedInstances $instanceName $pluginData }}
|
||||
{{- end }}
|
||||
{{- $_ := set $pluginsToMerge.plugins $nt $processedInstances }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $type, $val := .root.Values.unsupportedBuiltInPlugins }}
|
||||
@@ -224,6 +230,22 @@ Take a copy of the config and merge in .Values.customPlugins and .Values.unsuppo
|
||||
{{- $newConfig | toYaml }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Find all customPlugins that specify an image, and build a list of binaries to copy into the plugin volume in the plugin loader.
|
||||
*/}}
|
||||
{{- define "spire-lib.extract_custom_plugin_images" }}
|
||||
{{- $pluginList := list }}
|
||||
{{- range $type, $instances := .Values.customPlugins }}
|
||||
{{- range $instanceName, $config := $instances }}
|
||||
{{- if $config.image }}
|
||||
{{- $entry := dict "plugin_cmd" $config.plugin_cmd "image" $config.image "name" (printf "%s/%s" $type $instanceName) }}
|
||||
{{- $pluginList = append $pluginList $entry }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $pluginList | toYaml }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Take a copy of the plugin section and return a yaml string based version
|
||||
reformatted from a dict of dicts to a dict of lists of dicts
|
||||
|
||||
@@ -165,6 +165,10 @@ A Helm chart to install the SPIRE agent.
|
||||
| `tools.kubectl.image.repository` | The repository within the registry | `kubectl` |
|
||||
| `tools.kubectl.image.pullPolicy` | The image pull policy | `IfNotPresent` |
|
||||
| `tools.kubectl.image.tag` | Overrides the image tag whose default is the chart appVersion | `""` |
|
||||
| `tools.busybox.image.registry` | The OCI registry to pull the image from | `""` |
|
||||
| `tools.busybox.image.repository` | The repository within the registry | `busybox` |
|
||||
| `tools.busybox.image.pullPolicy` | The image pull policy | `IfNotPresent` |
|
||||
| `tools.busybox.image.tag` | Overrides the image tag whose default is the chart appVersion | `1.37.0-uclibc` |
|
||||
| `sockets.hostBasePath` | Path on which the agent socket is made available when admin.mountOnHost is true | `/run/spire/agent/sockets` |
|
||||
| `sockets.admin.enabled` | Enable the admin socket. Useful for admin tasks or the Delegated Identity API. | `false` |
|
||||
| `sockets.admin.mountOnHost` | Enable the admin socket to be visible on the host. | `false` |
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
{{- fail (printf "plugin_checksum is a required field.") }}
|
||||
{{- end }}
|
||||
{{- range $sname, $svals := $nval }}
|
||||
{{- if not (has $sname (list "plugin_cmd" "plugin_checksum" "plugin_data")) }}
|
||||
{{- if not (has $sname (list "plugin_cmd" "plugin_checksum" "plugin_data" "image")) }}
|
||||
{{- fail (printf "Unknown plugin setting specified: %s" $sname) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
{{- end }}
|
||||
{{- $socketAlternateNames := index (include "spire-agent.socket-alternate-names" . | fromYaml) "names" }}
|
||||
{{- $socketPath := include "spire-agent.socket-path" . }}
|
||||
{{- $pluginsToLoad := include "spire-lib.extract_custom_plugin_images" . | fromYamlArray }}
|
||||
{{- $pluginLoaderNeeded := gt (len $pluginsToLoad) 0 }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
@@ -100,6 +102,56 @@ spec:
|
||||
{{- toYaml .Values.hostAliases | nindent 8 }}
|
||||
{{- end }}
|
||||
initContainers:
|
||||
{{- if $pluginLoaderNeeded }}
|
||||
- name: init-plugins
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" . | nindent 12 }}
|
||||
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tools.busybox.image "global" .Values.global) }}
|
||||
# SPIRE must be able to fork the plugin directly within its container. First copy a busybox so that the plugin can be copied into the right place.
|
||||
command:
|
||||
- busybox
|
||||
- sh
|
||||
- -ec
|
||||
- |
|
||||
cp -a /bin/busybox /plugins/busybox
|
||||
volumeMounts:
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
imagePullPolicy: {{ .Values.tools.busybox.image.pullPolicy }}
|
||||
{{- end }}
|
||||
{{- range $idx, $plugin := $pluginsToLoad }}
|
||||
- name: {{ printf "init-plugin-%d" $idx }}
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" $ | nindent 12 }}
|
||||
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" $plugin.image "global" $.Values.global) }}
|
||||
command:
|
||||
- /plugins/busybox
|
||||
- sh
|
||||
- -ec
|
||||
- |
|
||||
/plugins/busybox mkdir -p /plugins/{{ dir $plugin.name }}
|
||||
/plugins/busybox cp -a {{ $plugin.plugin_cmd }} /plugins/{{ $plugin.name }}
|
||||
volumeMounts:
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
imagePullPolicy: {{ $plugin.image.pullPolicy }}
|
||||
{{- end }}
|
||||
{{- if $pluginLoaderNeeded }}
|
||||
- name: finalize-plugins
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" . | nindent 12 }}
|
||||
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tools.busybox.image "global" .Values.global) }}
|
||||
command:
|
||||
- busybox
|
||||
- sh
|
||||
- -ec
|
||||
- |
|
||||
rm -f /plugins/busybox
|
||||
volumeMounts:
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
imagePullPolicy: {{ .Values.tools.busybox.image.pullPolicy }}
|
||||
{{- end }}
|
||||
{{- if or (eq .Values.workloadAttestors.k8s.verification.type "hostCert") (eq .Values.workloadAttestors.k8s.verification.type "auto") }}
|
||||
- name: gather-host-cert
|
||||
securityContext:
|
||||
@@ -326,6 +378,11 @@ spec:
|
||||
mountPath: /run/spire/bundle
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $pluginLoaderNeeded }}
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
|
||||
- name: tpm-direct
|
||||
mountPath: /tpm
|
||||
@@ -419,6 +476,11 @@ spec:
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $pluginLoaderNeeded }}
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.sockets.admin.mountOnHost }}
|
||||
- name: spire-agent-admin-socket-dir
|
||||
hostPath:
|
||||
|
||||
@@ -447,6 +447,17 @@ tools:
|
||||
repository: kubectl
|
||||
pullPolicy: IfNotPresent
|
||||
tag: ""
|
||||
busybox:
|
||||
## @param tools.busybox.image.registry The OCI registry to pull the image from
|
||||
## @param tools.busybox.image.repository The repository within the registry
|
||||
## @param tools.busybox.image.pullPolicy The image pull policy
|
||||
## @param tools.busybox.image.tag Overrides the image tag whose default is the chart appVersion
|
||||
##
|
||||
image:
|
||||
registry: ""
|
||||
repository: busybox
|
||||
pullPolicy: IfNotPresent
|
||||
tag: 1.37.0-uclibc
|
||||
|
||||
sockets:
|
||||
## @param sockets.hostBasePath Path on which the agent socket is made available when admin.mountOnHost is true
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
{{- fail (printf "plugin_checksum is a required field.") }}
|
||||
{{- end }}
|
||||
{{- range $sname, $svals := $nval }}
|
||||
{{- if not (has $sname (list "plugin_cmd" "plugin_checksum" "plugin_data")) }}
|
||||
{{- if not (has $sname (list "plugin_cmd" "plugin_checksum" "plugin_data" "image")) }}
|
||||
{{- fail (printf "Unknown plugin setting specified: %s" $sname) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
{{- fail "clientKeyPath can only be set with database type mysql or aws_mysql." }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $pluginsToLoad := include "spire-lib.extract_custom_plugin_images" . | fromYamlArray }}
|
||||
{{- $pluginLoaderNeeded := or .Values.credentialComposer.cel.enabled (gt (len $pluginsToLoad) 0) }}
|
||||
{{- if not .Values.externalServer }}
|
||||
apiVersion: apps/v1
|
||||
{{- if eq .Values.kind "statefulset" }}
|
||||
@@ -121,10 +123,10 @@ spec:
|
||||
securityContext:
|
||||
{{- $podSecurityContext | toYaml | nindent 8 }}
|
||||
{{- include "spire-lib.default_cluster_priority_class_name" . | nindent 6 }}
|
||||
{{- if or (gt (len .Values.initContainers) 0) (and .Values.upstreamAuthority.certManager.enabled .Values.upstreamAuthority.certManager.ca.create) .Values.nodeAttestor.tpmDirect.enabled .Values.credentialComposer.cel.enabled $needsChown }}
|
||||
{{- if or (gt (len .Values.initContainers) 0) (and .Values.upstreamAuthority.certManager.enabled .Values.upstreamAuthority.certManager.ca.create) .Values.nodeAttestor.tpmDirect.enabled $pluginLoaderNeeded $needsChown }}
|
||||
initContainers:
|
||||
{{- if .Values.credentialComposer.cel.enabled }}
|
||||
- name: init-cel
|
||||
{{- if $pluginLoaderNeeded }}
|
||||
- name: init-plugins
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" . | nindent 12 }}
|
||||
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tools.busybox.image "global" .Values.global) }}
|
||||
@@ -134,28 +136,62 @@ spec:
|
||||
- sh
|
||||
- -ec
|
||||
- |
|
||||
cp -a /bin/busybox /cel/busybox
|
||||
cp -a /bin/busybox /plugins/busybox
|
||||
volumeMounts:
|
||||
- name: cel
|
||||
mountPath: /cel
|
||||
imagePullPolicy: {{ .Values.credentialComposer.cel.image.pullPolicy }}
|
||||
- name: init-cel2
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
imagePullPolicy: {{ .Values.tools.busybox.image.pullPolicy }}
|
||||
{{- end }}
|
||||
{{- if .Values.credentialComposer.cel.enabled }}
|
||||
- name: init-cel
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" . | nindent 12 }}
|
||||
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.credentialComposer.cel.image "global" .Values.global) }}
|
||||
# Second, use the previously copied busybox to copy the plugin into a volume that can be mounted where SPIRE can execute it.
|
||||
command:
|
||||
- /cel/busybox
|
||||
- /plugins/busybox
|
||||
- sh
|
||||
- -ec
|
||||
- |
|
||||
/cel/busybox cp -a {{ .Values.credentialComposer.cel.pluginPath }} /cel/credentialcomposer-cel
|
||||
/cel/busybox rm -f /cel/busybox
|
||||
/plugins/busybox cp -a {{ .Values.credentialComposer.cel.pluginPath }} /plugins/credentialcomposer-cel
|
||||
volumeMounts:
|
||||
- name: cel
|
||||
mountPath: /cel
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
imagePullPolicy: {{ .Values.credentialComposer.cel.image.pullPolicy }}
|
||||
{{- end }}
|
||||
{{- range $idx, $plugin := $pluginsToLoad }}
|
||||
- name: {{ printf "init-plugin-%d" $idx }}
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" $ | nindent 12 }}
|
||||
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" $plugin.image "global" $.Values.global) }}
|
||||
command:
|
||||
- /plugins/busybox
|
||||
- sh
|
||||
- -ec
|
||||
- |
|
||||
/plugins/busybox mkdir -p /plugins/{{ dir $plugin.name }}
|
||||
/plugins/busybox cp -a {{ $plugin.plugin_cmd }} /plugins/{{ $plugin.name }}
|
||||
volumeMounts:
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
imagePullPolicy: {{ $plugin.image.pullPolicy }}
|
||||
{{- end }}
|
||||
{{- if $pluginLoaderNeeded }}
|
||||
- name: finalize-plugins
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" . | nindent 12 }}
|
||||
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tools.busybox.image "global" .Values.global) }}
|
||||
command:
|
||||
- busybox
|
||||
- sh
|
||||
- -ec
|
||||
- |
|
||||
rm -f /plugins/busybox
|
||||
volumeMounts:
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
imagePullPolicy: {{ .Values.tools.busybox.image.pullPolicy }}
|
||||
{{- end }}
|
||||
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
|
||||
- name: init-tpm-direct
|
||||
securityContext:
|
||||
@@ -337,9 +373,9 @@ spec:
|
||||
mountPath: /kubeconfigs
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.credentialComposer.cel.enabled }}
|
||||
- name: cel
|
||||
mountPath: /cel
|
||||
{{- if $pluginLoaderNeeded }}
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
|
||||
@@ -546,8 +582,8 @@ spec:
|
||||
secret:
|
||||
secretName: {{ include "spire-server.fullname" . }}-kubeconfigs
|
||||
{{- end }}
|
||||
{{- if .Values.credentialComposer.cel.enabled }}
|
||||
- name: cel
|
||||
{{- if $pluginLoaderNeeded }}
|
||||
- name: plugins
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
|
||||
|
||||
@@ -18,6 +18,11 @@ spire-server:
|
||||
customPlugins:
|
||||
nodeAttestor:
|
||||
tpm:
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: <your repo here>
|
||||
tag: <your tag here>
|
||||
pullPolicy: Always
|
||||
plugin_cmd: /bin/tpm_attestor_server
|
||||
plugin_checksum: 97442358ae946e3fb8f2464432b8c23efdc0b5d44ec1eea27babe59ef646cc2f
|
||||
plugin_data:
|
||||
@@ -32,6 +37,11 @@ spire-agent:
|
||||
customPlugins:
|
||||
nodeAttestor:
|
||||
tpm:
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: <your repo here>
|
||||
tag: <your tag here>
|
||||
pullPolicy: Always
|
||||
plugin_cmd: /bin/tpm_attestor_agent
|
||||
plugin_checksum: bb7be714c27452231a6c7764b65912ce0cdeb66ff2a2c688d3e88bd0bd17d138
|
||||
plugin_data: {}
|
||||
|
||||
Reference in New Issue
Block a user