Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions charts/headlamp/templates/clusterrolebinding.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "headlamp.fullname" . }}-admin
name: {{ .Values.clusterRoleBinding.name | default (printf "%s-admin" (include "headlamp.fullname" .)) }}
labels:
{{- include "headlamp.labels" . | nindent 4 }}
{{- with .Values.clusterRoleBinding.annotations }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
annotations:
meta.helm.sh/release-name: {{ .Release.Name }}
meta.helm.sh/release-namespace: {{ .Release.Namespace }}
{{- with .Values.clusterRoleBinding.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ .Values.clusterRoleBinding.clusterRoleName }}
subjects:
- kind: ServiceAccount
name: {{ include "headlamp.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
- kind: ServiceAccount
name: {{ include "headlamp.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end }}
11 changes: 11 additions & 0 deletions charts/headlamp/templates/configmap-plugins.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{- if .Values.pluginInstaller.config.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.pluginInstaller.config.name }}
labels:
{{- include "headlamp.labels" . | nindent 4 }}
data:
plugins.yaml: |
{{- .Values.pluginInstaller.config.content | toYaml | nindent 4 }}
{{- end }}
164 changes: 76 additions & 88 deletions charts/headlamp/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ spec:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- if .Values.pluginInstaller.config.enabled }}
checksum/plugin-config: {{ include (print $.Template.BasePath "/configmap-plugins.yaml") . | sha256sum }}
{{- end }}
{{- end }}
labels:
{{- include "headlamp.selectorLabels" . | nindent 8 }}
Expand All @@ -50,133 +53,122 @@ spec:
serviceAccountName: {{ include "headlamp.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- with .Values.initContainers }}
initContainers:
{{ toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.pluginInstaller.config.enabled }}
- name: plugin-installer
image: "{{ .Values.pluginInstaller.image.repository }}:{{ .Values.pluginInstaller.image.tag }}"
imagePullPolicy: {{ .Values.pluginInstaller.image.pullPolicy }}
env:
- name: PLUGINS_DIR
value: "/headlamp/plugins"
- name: CONFIG_DIR
value: "/config"
- name: LOG_LEVEL
value: "info"
volumeMounts:
- name: plugins
mountPath: /headlamp/plugins
- name: plugin-config
mountPath: /config
readOnly: true
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
{{- end }}
{{- with .Values.initContainers }}
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.registry}}/{{ .Values.image.repository }}:{{ .Values.image.tag | default (printf "v%s" .Chart.AppVersion) }}"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{ if or $oidc .Values.env }}
{{- if $oidc.externalSecret.enabled }}
# Check if externalSecret is enabled
envFrom:
- secretRef:
name: {{ $oidc.externalSecret.name }}
{{- if .Values.env }}
env:
{{- toYaml .Values.env | nindent 12 }}
{{- end }}
{{- else }}
env:
{{- if $oidc.secret.create }}
{{- if $oidc.clientID }}
{{- if .Values.config.baseURL }}
- name: BASE_URL
value: {{ .Values.config.baseURL | quote }}
{{- end }}
{{- if .Values.config.oidc.secret.create }}
- name: OIDC_CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ $oidc.secret.name }}
name: {{ .Values.config.oidc.secret.name }}
key: clientID
{{- end }}
{{- if $oidc.clientSecret }}
- name: OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ $oidc.secret.name }}
name: {{ .Values.config.oidc.secret.name }}
key: clientSecret
{{- end }}
{{- if $oidc.issuerURL }}
- name: OIDC_ISSUER_URL
valueFrom:
secretKeyRef:
name: {{ $oidc.secret.name }}
name: {{ .Values.config.oidc.secret.name }}
key: issuerURL
{{- end }}
{{- if $oidc.scopes }}
- name: OIDC_SCOPES
valueFrom:
secretKeyRef:
name: {{ $oidc.secret.name }}
name: {{ .Values.config.oidc.secret.name }}
key: scopes
{{- else if .Values.config.oidc.externalSecret.enabled }}
- name: OIDC_CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ .Values.config.oidc.externalSecret.name }}
key: clientID
- name: OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.config.oidc.externalSecret.name }}
key: clientSecret
- name: OIDC_ISSUER_URL
valueFrom:
secretKeyRef:
name: {{ .Values.config.oidc.externalSecret.name }}
key: issuerURL
- name: OIDC_SCOPES
valueFrom:
secretKeyRef:
name: {{ .Values.config.oidc.externalSecret.name }}
key: scopes
{{- end }}
{{- else }}
{{- if $oidc.clientID }}
{{- if .Values.config.oidc.clientID }}
- name: OIDC_CLIENT_ID
value: {{ $oidc.clientID }}
value: {{ .Values.config.oidc.clientID | quote }}
{{- end }}
{{- if $oidc.clientSecret }}
{{- if .Values.config.oidc.clientSecret }}
- name: OIDC_CLIENT_SECRET
value: {{ $oidc.clientSecret }}
value: {{ .Values.config.oidc.clientSecret | quote }}
{{- end }}
{{- if $oidc.issuerURL }}
{{- if .Values.config.oidc.issuerURL }}
- name: OIDC_ISSUER_URL
value: {{ $oidc.issuerURL }}
value: {{ .Values.config.oidc.issuerURL | quote }}
{{- end }}
{{- if $oidc.scopes }}
{{- if .Values.config.oidc.scopes }}
- name: OIDC_SCOPES
value: {{ $oidc.scopes }}
value: {{ .Values.config.oidc.scopes | quote }}
{{- end }}
{{- end }}
{{- if .Values.env }}
{{- toYaml .Values.env | nindent 12 }}
{{- end }}
{{- end }}
{{- end }}
args:
- "-in-cluster"
{{- with .Values.config.pluginsDir}}
- "-plugins-dir={{ . }}"
{{- end }}
{{- if not $oidc.externalSecret.enabled}}
# Check if externalSecret is disabled
{{- if or (ne $oidc.clientID "") (ne $clientID "") }}
# Check if clientID is non empty either from env or oidc.config
- "-oidc-client-id=$(OIDC_CLIENT_ID)"
{{- end }}
{{- if or (ne $oidc.clientSecret "") (ne $clientSecret "") }}
# Check if clientSecret is non empty either from env or oidc.config
- "-oidc-client-secret=$(OIDC_CLIENT_SECRET)"
{{- end }}
{{- if or (ne $oidc.issuerURL "") (ne $issuerURL "") }}
# Check if issuerURL is non empty either from env or oidc.config
- "-oidc-idp-issuer-url=$(OIDC_ISSUER_URL)"
{{- end }}
{{- if or (ne $oidc.scopes "") (ne $scopes "") }}
# Check if scopes are non empty either from env or oidc.config
- "-oidc-scopes=$(OIDC_SCOPES)"
{{- end }}
{{- else }}
- "-oidc-client-id=$(OIDC_CLIENT_ID)"
- "-oidc-client-secret=$(OIDC_CLIENT_SECRET)"
- "-oidc-idp-issuer-url=$(OIDC_ISSUER_URL)"
- "-oidc-scopes=$(OIDC_SCOPES)"
{{- if .Values.config.pluginsDir }}
- name: PLUGINS_DIR
value: {{ .Values.config.pluginsDir | quote }}
{{- end }}
{{- with .Values.config.baseURL }}
- "-base-url={{ . }}"
{{- end }}
{{- with .Values.config.extraArgs }}
{{- toYaml . | nindent 12 }}
{{- with .Values.env }}
{{- toYaml . | nindent 12 }}
{{- end }}
ports:
- name: http
containerPort: 4466
protocol: TCP
livenessProbe:
httpGet:
path: "{{ .Values.config.baseURL }}/"
port: http
readinessProbe:
httpGet:
path: "{{ .Values.config.baseURL }}/"
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.volumeMounts }}
volumeMounts:
{{- toYaml . | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.volumes }}
volumes:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
Expand All @@ -189,7 +181,3 @@ spec:
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.volumes}}
volumes:
{{- toYaml . | nindent 8 }}
{{- end }}
39 changes: 37 additions & 2 deletions charts/headlamp/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,31 @@ image:
# -- Container image tag, If "" uses appVersion in Chart.yaml
tag: ""

pluginInstaller:
# -- Container image for plugin installer
image:
registry: ghcr.io
repository: headlamp-k8s/plugin-installer
tag: latest
pullPolicy: IfNotPresent

# -- Plugin configuration
config:
# -- Create ConfigMap for plugin configuration
enabled: false
# -- Name of the ConfigMap to use
name: headlamp-plugins-config
# -- Plugin configuration content
content: {}
# Example:
# content:
# proxy-urls:
# - "https://artifacthub.io/*"
# plugins:
# - name: test-app-catalog
# source: https://artifacthub.io/packages/headlamp/test-123/appcatalog_headlamp_plugin
# version: 0.5.0

# -- An optional list of references to secrets in the same namespace to use for pulling any of the images used
imagePullSecrets: []
# -- Overrides the name of the chart
Expand Down Expand Up @@ -144,10 +169,20 @@ service:
nodePort: null

# -- Headlamp containers volume mounts
volumeMounts: []
volumeMounts:
- name: plugins
mountPath: /headlamp/plugins
- name: plugin-config
mountPath: /config
readOnly: true

# -- Headlamp pod's volumes
volumes: []
volumes:
- name: plugins
emptyDir: {}
- name: plugin-config
configMap:
name: headlamp-plugins-config

persistentVolumeClaim:
# -- Enable Persistent Volume Claim
Expand Down
65 changes: 65 additions & 0 deletions plugins/headlamp-plugin/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Stage 1: Build Stage
FROM node:20-alpine3.19 AS build

# Install build dependencies
RUN apk add --no-cache \
python3 \
make \
g++ \
git \
yaml-dev

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./

# Install production dependencies
RUN npm install --omit=dev && \
npm install --save \
js-yaml@latest \
winston@latest \
ajv@latest \
yaml-validator@latest

# Copy source files
COPY bin ./bin
COPY config ./config
COPY plugin-management ./plugin-management
COPY src ./src

# Stage 2: Production Stage
FROM node:20-alpine3.19

# Install runtime dependencies
RUN apk add --no-cache \
yaml \
tini

# Set working directory
WORKDIR /app

# Copy only the necessary files from the build stage
COPY --from=build /app /app

# Create required directories
RUN mkdir -p /headlamp/plugins && \
mkdir -p /config && \
mkdir -p /logs

# Set environment variables
ENV NODE_ENV=production \
PLUGINS_DIR=/headlamp/plugins \
CONFIG_DIR=/config \
LOG_DIR=/logs \
LOG_LEVEL=info

# Add volume mount points
VOLUME ["/headlamp/plugins", "/config", "/logs"]

# Use tini as init process
ENTRYPOINT ["/sbin/tini", "--"]

# Set the default command to run the plugin installer and post-install script
CMD ["sh", "-c", "node bin/headlamp-plugin.js install --config /config/plugins.yaml && cd /headlamp/plugins/app-catalog && mv appcatalog_headlamp_plugin/* . && rmdir appcatalog_headlamp_plugin"]
Loading