Introduction of Tornjak to SPIRE Server helm charts (#144)
This PR introduces a simplified version of [Tornjak](https://github.com/spiffe/tornjak) to support UI and SPIRE control plane. It extends the `/charts/spire-server` sub-chart by injecting *tornjak* container to the *spire-server* pod. Tornjak image consists of Tornjak API (Tornjak Backend), Tornjak UI (Frontend), and database for storing Tornjak specific information. Tornjak Backend communicates with SPIRE API via SPIRE Server socket. Since Tornjak UI (Frontend) is a React code that renders in a browser, it needs to communicate with Tornjak APIs, and that requires communication ports to be open, either via Ingress (in Cloud deployment) or via port forwarding in local deployments (e.g. kind, minikube etc). Typically port 10000 is used for HTTP connection to Backend, and port 3000 for the HTTP connection to Frontend. End user management, TLS, and mTLS connections will be addressed by future PRs. This PR resolves issue #31 --------- Signed-off-by: Mariusz Sabath <[email protected]> Signed-off-by: Marco Franssen <[email protected]> Co-authored-by: Kevin Fox <[email protected]> Co-authored-by: Marco Franssen <[email protected]> Co-authored-by: Pete Cable <[email protected]> Co-authored-by: Dennis Gove <[email protected]>
This commit is contained in:
co-authored by
Kevin Fox
Marco Franssen
Pete Cable
Dennis Gove
parent
b25dc773bc
commit
05d0f4778d
@@ -89,6 +89,14 @@ A Helm chart to install the SPIRE server.
|
||||
| telemetry.prometheus.enabled | bool | `false` | |
|
||||
| tolerations | list | `[]` | |
|
||||
| topologySpreadConstraints | list | `[]` | |
|
||||
| tornjak.config.backend.dataStore.driver | string | `"sqlite3"` | |
|
||||
| tornjak.config.backend.dataStore.file | string | `"/run/spire/data/tornjak.sqlite3"` | |
|
||||
| tornjak.config.frontend.apiServerURL | string | `"http://localhost:10000"` | |
|
||||
| tornjak.enabled | bool | `true` | |
|
||||
| tornjak.image.pullPolicy | string | `"IfNotPresent"` | |
|
||||
| tornjak.image.registry | string | `"ghcr.io"` | |
|
||||
| tornjak.image.repository | string | `"spiffe/tornjak"` | |
|
||||
| tornjak.image.version | string | `"latest"` | |
|
||||
| trustDomain | string | `"example.org"` | |
|
||||
| upstreamAuthority.certManager.enabled | bool | `false` | |
|
||||
| upstreamAuthority.certManager.issuer_group | string | `"cert-manager.io"` | |
|
||||
|
||||
@@ -4,3 +4,21 @@ Installed {{ .Chart.Name }}…
|
||||
|
||||
kubectl exec -n {{ .Release.Namespace }} {{ include "spire-server.fullname" . }}-0 -c spire-server -- \
|
||||
spire-server entry show
|
||||
|
||||
{{- if eq (.Values.tornjak.enabled | toString) "true" }}
|
||||
|
||||
### WARNING ###
|
||||
This Tornjak is configured without authentication and it is intended for
|
||||
testing only. Please do not use this version in production.
|
||||
|
||||
Tornjak APIs (Backend):
|
||||
kubectl -n {{ include "spire-server.namespace" . }} port-forward {{ include "spire-server.fullname" . }}-0 10000:10000
|
||||
|
||||
Tornjak UI (Frontend):
|
||||
kubectl -n {{ include "spire-server.namespace" . }} port-forward {{ include "spire-server.fullname" . }}-0 3000:3000
|
||||
|
||||
Tornjak API access: {{ include "tornjak.apiURL" . }}
|
||||
Tornjak UI access: {{ include "tornjak.FrontendURL" . }}
|
||||
|
||||
Installed {{ include "spire-tornjak.fullname" . }}…
|
||||
{{- end }}
|
||||
|
||||
@@ -84,7 +84,6 @@ Create the name of the service account to use
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- define "spire-server.upstream-ca-secret" -}}
|
||||
{{- $root := . }}
|
||||
{{- with .Values.upstreamAuthority.disk -}}
|
||||
@@ -111,3 +110,35 @@ Create the name of the service account to use
|
||||
[{{ printf "%s:%s-agent" .Release.Namespace .Release.Name | quote }}]
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Tornjak specific section
|
||||
*/}}
|
||||
|
||||
{{- define "spire-tornjak.fullname" -}}
|
||||
{{ include "spire-server.fullname" . | trimSuffix "-server" }}-tornjak
|
||||
{{- end }}
|
||||
{{- define "spire-tornjak.config" -}}
|
||||
{{ include "spire-tornjak.fullname" . }}-config
|
||||
{{- end }}
|
||||
{{- define "spire-tornjak.frontend" -}}
|
||||
{{ include "spire-tornjak.fullname" . }}-fe
|
||||
{{- end }}
|
||||
{{- define "spire-tornjak.backend" -}}
|
||||
{{ include "spire-tornjak.fullname" . }}-be
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create URL for accessing Tornjak Backend
|
||||
*/}}
|
||||
{{- define "tornjak.apiURL" -}}
|
||||
{{- default .Values.tornjak.config.frontend.apiServerURL }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create URL for accessing Tornjak Frontend
|
||||
*/}}
|
||||
{{- define "tornjak.FrontendURL" -}}
|
||||
{{- $feurl := print "http://localhost:3000" }}
|
||||
{{- $feurl }}
|
||||
{{- end }}
|
||||
@@ -26,3 +26,36 @@ spec:
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "spire-server.selectorLabels" . | nindent 4 }}
|
||||
|
||||
{{- if eq (.Values.tornjak.enabled | toString) "true" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
namespace: {{ include "spire-server.namespace" . }}
|
||||
name: {{ include "spire-tornjak.frontend" . }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }} # ClusterIP
|
||||
selector:
|
||||
{{- include "spire-server.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- name: {{ include "spire-tornjak.frontend" . }}
|
||||
port: 3000
|
||||
targetPort: 3000
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
namespace: {{ include "spire-server.namespace" . }}
|
||||
name: {{ include "spire-tornjak.backend" . }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }} # ClusterIP
|
||||
selector:
|
||||
{{- include "spire-server.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- name: {{ include "spire-tornjak.backend" . }}
|
||||
port: 10000
|
||||
targetPort: 10000
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
@@ -1,5 +1,6 @@
|
||||
{{- $configSum := (include (print $.Template.BasePath "/configmap.yaml") . | sha256sum) }}
|
||||
{{- $configSum2 := (include (print $.Template.BasePath "/controller-manager-configmap.yaml") . | sha256sum) }}
|
||||
{{- $configSumTornjak := (include (print $.Template.BasePath "/tornjak-config.yaml") . | sha256sum) }}
|
||||
{{- $fullname := include "spire-server.fullname" . }}
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
@@ -21,6 +22,7 @@ spec:
|
||||
annotations:
|
||||
checksum/config: {{ $configSum }}
|
||||
checksum/config2: {{ $configSum2 }}
|
||||
checksum/configTornjak: {{ $configSumTornjak }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -144,6 +146,51 @@ spec:
|
||||
mountPath: /tmp
|
||||
readOnly: false
|
||||
{{- end }}
|
||||
|
||||
{{- if eq (.Values.tornjak.enabled | toString) "true" }}
|
||||
- name: tornjak
|
||||
securityContext:
|
||||
{{- toYaml .Values.controllerManager.securityContext | nindent 12 }}
|
||||
image: {{ template "spire-server.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tornjak.image) }}
|
||||
imagePullPolicy: {{ .Values.tornjak.image.pullPolicy }}
|
||||
startupProbe:
|
||||
httpGet:
|
||||
scheme: HTTP
|
||||
port: 3000
|
||||
failureThreshold: 6
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 10
|
||||
env:
|
||||
{{- if .Values.tornjak.config.frontend }}
|
||||
- name: REACT_APP_API_SERVER_URI
|
||||
value: {{ include "tornjak.apiURL" . | required "Either .Values.tornjak.config.backend.ingress or .Values.tornjak.config.frontend.apiServerURL is required." }}
|
||||
{{- end }}
|
||||
args:
|
||||
- -c
|
||||
- /run/spire/config/server.conf
|
||||
- -t
|
||||
- /run/spire/tornjak-config/server.conf
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: {{ include "spire-tornjak.config" . }}
|
||||
mountPath: /run/spire/tornjak-config
|
||||
- name: spire-server-socket
|
||||
mountPath: /tmp/spire-server/private
|
||||
readOnly: true
|
||||
- name: spire-config
|
||||
mountPath: /run/spire/config
|
||||
readOnly: true
|
||||
{{- if eq (.Values.dataStorage.enabled | toString) "true" }}
|
||||
- name: spire-data
|
||||
mountPath: /run/spire/data
|
||||
readOnly: false
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if gt (len .Values.extraContainers) 0 }}
|
||||
{{- toYaml .Values.extraContainers | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -181,6 +228,14 @@ spec:
|
||||
configMap:
|
||||
name: {{ include "spire-controller-manager.fullname" . }}
|
||||
{{- end }}
|
||||
{{- if eq (.Values.tornjak.enabled | toString) "true" }}
|
||||
{{- if .Values.tornjak.config }}
|
||||
- name: {{ include "spire-tornjak.config" . }}
|
||||
configMap:
|
||||
defaultMode: 420
|
||||
name: {{ include "spire-tornjak.config" . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if gt (len .Values.extraVolumes) 0 }}
|
||||
{{- toYaml .Values.extraVolumes | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
{{- if eq (.Values.tornjak.enabled | toString) "true" }}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "spire-tornjak.fullname" . }}-test-connection"
|
||||
namespace: {{ include "spire-server.namespace" . }}
|
||||
labels:
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 4 }}
|
||||
containers:
|
||||
- name: wget-tornjak-backend
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['--no-check-certificate', '-O', '/dev/null', 'http://{{ include "spire-tornjak.backend" . }}:10000/api/tornjak/serverinfo']
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 8 }}
|
||||
- name: wget-tornjak-frontend
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['--no-check-certificate', '-O', '/dev/null', 'http://{{ include "spire-tornjak.frontend" . }}:3000']
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 8 }}
|
||||
restartPolicy: Never
|
||||
{{- end }}
|
||||
@@ -0,0 +1,23 @@
|
||||
{{- if eq (.Values.tornjak.enabled | toString) "true" }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "spire-tornjak.config" . }}
|
||||
namespace: {{ include "spire-server.namespace" . }}
|
||||
data:
|
||||
server.conf: |
|
||||
server {
|
||||
metadata = "insert metadata"
|
||||
}
|
||||
|
||||
plugins {
|
||||
{{- if .Values.tornjak.config.backend.dataStore }}
|
||||
DataStore "sql" {
|
||||
plugin_data {
|
||||
drivername = "{{ .Values.tornjak.config.backend.dataStore.driver }}"
|
||||
filename = "{{ .Values.tornjak.config.backend.dataStore.file }}"
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
@@ -203,3 +203,26 @@ nodeAttestor:
|
||||
k8sPsat:
|
||||
enabled: true
|
||||
serviceAccountAllowList: []
|
||||
|
||||
# tornjak - Tornjak specific configuration
|
||||
tornjak:
|
||||
enabled: true
|
||||
# image - Tornjak image (frontend + backend) if not separated above
|
||||
image: # ghcr.io/spiffe/tornjak
|
||||
registry: ghcr.io
|
||||
repository: spiffe/tornjak
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
# TODO we should use a specific Tornjak version instead of 'latest'
|
||||
version: "latest"
|
||||
config:
|
||||
# Front-end specific configuration:
|
||||
frontend:
|
||||
# apiServerURL - URL of the Tornjak back-end
|
||||
apiServerURL: "http://localhost:10000" # 👈 Use it for minikube or kind
|
||||
# Back-end specific configuration
|
||||
backend:
|
||||
# dataStore - persistent DB for storing Tornjak specific information
|
||||
dataStore:
|
||||
driver: "sqlite3"
|
||||
file: "/run/spire/data/tornjak.sqlite3"
|
||||
Reference in New Issue
Block a user