diff --git a/mender/templates/admin-panel-gui/deployment.yaml b/mender/templates/admin-panel-gui/deployment.yaml new file mode 100644 index 00000000..436bb667 --- /dev/null +++ b/mender/templates/admin-panel-gui/deployment.yaml @@ -0,0 +1,109 @@ +{{- if and .Values.admin_panel_gui.enabled .Values.global.enterprise }} +{{- $context := dict "dot" . "component" "admin-panel-gui" "override" .Values.admin_panel_gui -}} +{{- $merged := merge (deepCopy .Values.admin_panel_gui) (deepCopy (default (dict) .Values.default)) -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "mender.fullname" . }}-admin-panel-gui + namespace: {{ .Release.Namespace }} + labels: + {{- include "mender.labels" . | nindent 4 }} + app.kubernetes.io/name: {{ include "mender.fullname" . }}-admin-panel-gui + app.kubernetes.io/component: admin-panel-gui +spec: + {{- if not (or .Values.admin_panel_gui.hpa .Values.default.hpa ) }} + replicas: {{ .Values.admin_panel_gui.replicas }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "mender.fullname" . }}-admin-panel-gui + + progressDeadlineSeconds: 600 + + {{- $updateStrategy := coalesce .Values.admin_panel_gui.updateStrategy .Values.default.updateStrategy }} + {{- if $updateStrategy }} + strategy: {{- toYaml $updateStrategy | nindent 4 }} + {{- end }} + + {{- $minReadySeconds := coalesce .Values.admin_panel_gui.minReadySeconds .Values.default.minReadySeconds }} + {{- if $minReadySeconds }} + minReadySeconds: {{ $minReadySeconds }} + {{- end }} + + template: + metadata: + {{- with .Values.admin_panel_gui.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + app.kubernetes.io/name: {{ include "mender.fullname" . }}-admin-panel-gui + {{- include "mender.labels" . | nindent 8 }} + app.kubernetes.io/component: admin-panel-gui + spec: + serviceAccountName: {{ include "mender.serviceAccountName" . }} + {{- with $merged.affinity }} + affinity: {{ tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with $merged.tolerations }} + tolerations: {{ tpl (toYaml .) $ | nindent 8 }} + {{- end }} +{{- if .Values.admin_panel_gui.podSecurityContext.enabled }} + securityContext: {{- omit .Values.admin_panel_gui.podSecurityContext "enabled" | toYaml | nindent 8 }} +{{- end }} + + containers: + - name: admin-panel-gui + image: {{ include "mender.image" $context }} + imagePullPolicy: {{ include "mender.imagePullPolicy" $context }} +{{- if .Values.admin_panel_gui.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.admin_panel_gui.containerSecurityContext "enabled" | toYaml | nindent 10 }} +{{- end }} + {{- with include "mender.resources" (list .Values.default.resources .Values.admin_panel_gui.resources) }} + resources: {{- nindent 10 . }} + {{- end }} + + livenessProbe: + tcpSocket: + port: {{ .Values.admin_panel_gui.httpPort }} + {{- with include "mender.probesOverrides" (dict "default" .Values.default.probesOverrides "override" .Values.admin_panel_gui.probesOverrides ) }} + {{- nindent 10 . }} + {{- end }} + readinessProbe: + tcpSocket: + port: {{ .Values.admin_panel_gui.httpPort }} + {{- with include "mender.probesOverrides" (dict "default" .Values.default.probesOverrides "override" .Values.admin_panel_gui.probesOverrides ) }} + {{- nindent 10 . }} + {{- end }} + startupProbe: + tcpSocket: + port: {{ .Values.admin_panel_gui.httpPort }} + {{- with include "mender.probesOverrides" (dict "default" .Values.default.probesOverrides "override" .Values.admin_panel_gui.probesOverrides ) }} + {{- nindent 10 . }} + {{- end }} + + {{- with include "mender.customEnvs" (merge (deepCopy .Values.admin_panel_gui) (deepCopy (default (dict) .Values.default))) }} + env: + {{- nindent 8 . }} + {{- end }} + +{{- if and .Values.global.image .Values.global.image.username }} + imagePullSecrets: + - name: docker-registry +{{- else }} +{{- $ips := coalesce .Values.admin_panel_gui.imagePullSecrets .Values.default.imagePullSecrets }} +{{- if $ips }} + imagePullSecrets: +{{- toYaml $ips | nindent 6 }} +{{- end }} +{{- end }} + +{{- $pcn := coalesce .Values.admin_panel_gui.priorityClassName .Values.global.priorityClassName -}} +{{- if $pcn }} + priorityClassName: {{ $pcn }} +{{- end }} + +{{- with (coalesce .Values.admin_panel_gui.nodeSelector .Values.default.nodeSelector) }} + nodeSelector: {{ toYaml . | nindent 8 }} +{{- end }} +{{- end }} diff --git a/mender/templates/admin-panel-gui/hpa.yaml b/mender/templates/admin-panel-gui/hpa.yaml new file mode 100644 index 00000000..db9056d3 --- /dev/null +++ b/mender/templates/admin-panel-gui/hpa.yaml @@ -0,0 +1,5 @@ +{{- if and .Values.admin_panel_gui.enabled .Values.global.enterprise }} +{{- $servicename := "admin-panel-gui" }} +{{- $context := (dict "default" .Values.default "override" .Values.admin_panel_gui "name" (printf "%s-%s" (include "mender.fullname" . ) $servicename ) ) -}} +{{- include "mender.autoscaler" $context }} +{{- end }} diff --git a/mender/templates/admin-panel-gui/service.yaml b/mender/templates/admin-panel-gui/service.yaml new file mode 100644 index 00000000..3e9b915c --- /dev/null +++ b/mender/templates/admin-panel-gui/service.yaml @@ -0,0 +1,38 @@ +{{- if and .Values.admin_panel_gui.enabled .Values.global.enterprise }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.admin_panel_gui.service.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "mender.labels" . | nindent 4 }} + app.kubernetes.io/name: admin-panel-gui-svc + app.kubernetes.io/component: admin-panel-gui +{{- with .Values.admin_panel_gui.service.annotations }} + annotations: {{ tpl (toYaml .) $ | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.admin_panel_gui.service.type }} + {{- if and (eq .Values.admin_panel_gui.service.type "ClusterIP") .Values.admin_panel_gui.service.clusterIP }} + clusterIP: {{ .Values.admin_panel_gui.service.clusterIP }} + {{- end }} + {{- if and (eq .Values.admin_panel_gui.service.type "LoadBalancer") .Values.admin_panel_gui.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.admin_panel_gui.service.loadBalancerIP }} + {{- end }} + {{- if .Values.admin_panel_gui.service.externalIPs }} + externalIPs: {{ toYaml .Values.admin_panel_gui.service.externalIPs | nindent 4 }} + {{- end }} + {{- if .Values.admin_panel_gui.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- toYaml .Values.admin_panel_gui.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} + ports: + - port: {{ .Values.admin_panel_gui.service.port }} + name: http + protocol: TCP + targetPort: {{ .Values.admin_panel_gui.httpPort }} + {{- if .Values.admin_panel_gui.service.nodePort }} + nodePort: {{ .Values.admin_panel_gui.service.nodePort }} + {{- end }} + selector: + app.kubernetes.io/name: {{ include "mender.fullname" . }}-admin-panel-gui +{{- end }} diff --git a/mender/templates/admin-panel/deployment.yaml b/mender/templates/admin-panel/deployment.yaml new file mode 100644 index 00000000..381da6e3 --- /dev/null +++ b/mender/templates/admin-panel/deployment.yaml @@ -0,0 +1,134 @@ +{{- if and .Values.admin_panel.enabled .Values.global.enterprise }} +{{- $context := dict "dot" . "component" "admin-panel" "override" .Values.admin_panel -}} +{{- $merged := merge (deepCopy .Values.admin_panel) (deepCopy (default (dict) .Values.default)) -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "mender.fullname" . }}-admin-panel + namespace: {{ .Release.Namespace }} + labels: + {{- include "mender.labels" . | nindent 4 }} + app.kubernetes.io/name: {{ include "mender.fullname" . }}-admin-panel + app.kubernetes.io/component: admin-panel +spec: + {{- if not (or .Values.admin_panel.hpa .Values.default.hpa ) }} + replicas: {{ .Values.admin_panel.replicas }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "mender.fullname" . }}-admin-panel + + progressDeadlineSeconds: 600 + + {{- $updateStrategy := coalesce .Values.admin_panel.updateStrategy .Values.default.updateStrategy }} + {{- if $updateStrategy }} + strategy: {{- toYaml $updateStrategy | nindent 4 }} + {{- end }} + + {{- $minReadySeconds := coalesce .Values.admin_panel.minReadySeconds .Values.default.minReadySeconds }} + {{- if $minReadySeconds }} + minReadySeconds: {{ $minReadySeconds }} + {{- end }} + + template: + metadata: + {{- with .Values.admin_panel.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + app.kubernetes.io/name: {{ include "mender.fullname" . }}-admin-panel + {{- include "mender.labels" . | nindent 8 }} + app.kubernetes.io/component: admin-panel + spec: + serviceAccountName: {{ include "mender.serviceAccountName" . }} + {{- with $merged.affinity }} + affinity: {{ tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with $merged.tolerations }} + tolerations: {{ tpl (toYaml .) $ | nindent 8 }} + {{- end }} +{{- if .Values.admin_panel.podSecurityContext.enabled }} + securityContext: {{- omit .Values.admin_panel.podSecurityContext "enabled" | toYaml | nindent 8 }} +{{- end }} + + containers: + - name: admin-panel + image: {{ include "mender.image" $context }} + imagePullPolicy: {{ include "mender.imagePullPolicy" $context }} +{{- if .Values.admin_panel.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.admin_panel.containerSecurityContext "enabled" | toYaml | nindent 10 }} +{{- end }} + {{- with include "mender.resources" (list .Values.default.resources .Values.admin_panel.resources) }} + resources: {{- nindent 10 . }} + {{- end }} + + args: ["server"] + + readinessProbe: + httpGet: + path: /api/internal/v1/admin-panel/health + port: 8080 + periodSeconds: 15 + {{- with include "mender.probesOverrides" (dict "default" .Values.default.probesOverrides "override" .Values.admin_panel.probesOverrides ) }} + {{- nindent 10 . }} + {{- end }} + livenessProbe: + httpGet: + path: /api/internal/v1/admin-panel/alive + port: 8080 + periodSeconds: 5 + {{- with include "mender.probesOverrides" (dict "default" .Values.default.probesOverrides "override" .Values.admin_panel.probesOverrides ) }} + {{- nindent 10 . }} + {{- end }} + startupProbe: + httpGet: + path: /api/internal/v1/admin-panel/alive + port: 8080 + failureThreshold: 36 + periodSeconds: 5 + + env: + - name: ADMIN_PANEL_TENANTADM_ADDRESS + value: {{ printf "http://%s:%v" .Values.tenantadm.service.name .Values.tenantadm.service.port }} + - name: ADMIN_PANEL_USERADM_ADDRESS + value: {{ printf "http://%s:%v" .Values.useradm.service.name .Values.useradm.service.port }} + - name: ADMIN_PANEL_DEVICEAUTH_ADDRESS + value: {{ printf "http://%s:%v" .Values.device_auth.service.name .Values.device_auth.service.port }} + - name: ADMIN_PANEL_DEPLOYMENTS_ADDRESS + value: {{ printf "http://%s:%v" .Values.deployments.service.name .Values.deployments.service.port }} + - name: ADMIN_PANEL_INVENTORY_ADDRESS + value: {{ printf "http://%s:%v" .Values.inventory.service.name .Values.inventory.service.port }} + # the chart names the workflows service '-server', so the service default of 'mender-workflows' does not resolve here + - name: ADMIN_PANEL_WORKFLOWS_ADDRESS + value: {{ printf "http://%s:%v" .Values.workflows.service.name .Values.workflows.service.port }} + {{- include "mender.customEnvs" (merge (deepCopy .Values.admin_panel) (deepCopy (default (dict) .Values.default))) | nindent 8 }} + # The OAuth credentials and the session secret have no defaults and the service refuses to start without them, + # so they are expected to come in through customEnvs or the secret below. + {{- with .Values.admin_panel.existingSecret }} + envFrom: + - prefix: ADMIN_PANEL_ + secretRef: + name: {{ . }} + {{- end }} + +{{- if and .Values.global.image .Values.global.image.username }} + imagePullSecrets: + - name: docker-registry +{{- else }} +{{- $ips := coalesce .Values.admin_panel.imagePullSecrets .Values.default.imagePullSecrets }} +{{- if $ips }} + imagePullSecrets: +{{- toYaml $ips | nindent 6 }} +{{- end }} +{{- end }} + +{{- $pcn := coalesce .Values.admin_panel.priorityClassName .Values.global.priorityClassName -}} +{{- if $pcn }} + priorityClassName: {{ $pcn }} +{{- end }} + +{{- with (coalesce .Values.admin_panel.nodeSelector .Values.default.nodeSelector) }} + nodeSelector: {{ toYaml . | nindent 8 }} +{{- end }} +{{- end }} diff --git a/mender/templates/admin-panel/hpa.yaml b/mender/templates/admin-panel/hpa.yaml new file mode 100644 index 00000000..f4715f04 --- /dev/null +++ b/mender/templates/admin-panel/hpa.yaml @@ -0,0 +1,5 @@ +{{- if and .Values.admin_panel.enabled .Values.global.enterprise }} +{{- $servicename := "admin-panel" }} +{{- $context := (dict "default" .Values.default "override" .Values.admin_panel "name" (printf "%s-%s" (include "mender.fullname" . ) $servicename ) ) -}} +{{- include "mender.autoscaler" $context }} +{{- end }} diff --git a/mender/templates/admin-panel/service.yaml b/mender/templates/admin-panel/service.yaml new file mode 100644 index 00000000..28647130 --- /dev/null +++ b/mender/templates/admin-panel/service.yaml @@ -0,0 +1,38 @@ +{{- if and .Values.admin_panel.enabled .Values.global.enterprise }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.admin_panel.service.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "mender.labels" . | nindent 4 }} + app.kubernetes.io/name: admin-panel-svc + app.kubernetes.io/component: admin-panel +{{- with .Values.admin_panel.service.annotations }} + annotations: {{ tpl (toYaml .) $ | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.admin_panel.service.type }} + {{- if and (eq .Values.admin_panel.service.type "ClusterIP") .Values.admin_panel.service.clusterIP }} + clusterIP: {{ .Values.admin_panel.service.clusterIP }} + {{- end }} + {{- if and (eq .Values.admin_panel.service.type "LoadBalancer") .Values.admin_panel.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.admin_panel.service.loadBalancerIP }} + {{- end }} + {{- if .Values.admin_panel.service.externalIPs }} + externalIPs: {{ toYaml .Values.admin_panel.service.externalIPs | nindent 4 }} + {{- end }} + {{- if .Values.admin_panel.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- toYaml .Values.admin_panel.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} + ports: + - port: {{ .Values.admin_panel.service.port }} + name: http + protocol: TCP + targetPort: 8080 + {{- if .Values.admin_panel.service.nodePort }} + nodePort: {{ .Values.admin_panel.service.nodePort }} + {{- end }} + selector: + app.kubernetes.io/name: {{ include "mender.fullname" . }}-admin-panel +{{- end }} diff --git a/mender/templates/api-gateway/configmap.yaml b/mender/templates/api-gateway/configmap.yaml index 57dfdbf7..c6e5ba79 100644 --- a/mender/templates/api-gateway/configmap.yaml +++ b/mender/templates/api-gateway/configmap.yaml @@ -41,6 +41,48 @@ data: service: ping@internal priority: 20 +{{- if and .Values.admin_panel.enabled .Values.global.enterprise }} + adminPanel: + entrypoints: {{ $scheme }} + middlewares: + - ratelimit + - sec-headers +{{- if .Values.api_gateway.compression }} + - compression +{{- end }} + rule: "PathRegexp(`^/api/sudo/v[0-9a-z]+/admin-panel`)" + service: admin-panel + tls: {{ $isTls }} + adminPanelAuth: + entrypoints: {{ $scheme }} + middlewares: +{{- if .Values.api_gateway.authRateLimit }} + - authRateLimit +{{- else }} + - ratelimit +{{- end }} + - sec-headers +{{- if .Values.api_gateway.compression }} + - compression +{{- end }} + rule: "PathRegexp(`^/api/sudo/v[0-9a-z]+/admin-panel/auth`)" + service: admin-panel + tls: {{ $isTls }} +{{- end }} +{{- if and .Values.admin_panel_gui.enabled .Values.global.enterprise }} + adminPanelGui: + entrypoints: {{ $scheme }} + middlewares: + - ratelimit + - sec-headers +{{- if .Values.api_gateway.compression }} + - compression +{{- end }} + rule: "PathPrefix(`/admin`)" + service: admin-panel-gui + tls: {{ $isTls }} +{{- end }} + # # auditlogs # @@ -401,6 +443,20 @@ data: # services: +{{- if and .Values.admin_panel.enabled .Values.global.enterprise }} + admin-panel: + loadBalancer: + servers: + - url: "http://{{ .Values.admin_panel.service.name }}:{{ .Values.admin_panel.service.port }}" +{{- end }} +{{- if and .Values.admin_panel_gui.enabled .Values.global.enterprise }} + + admin-panel-gui: + loadBalancer: + servers: + - url: "http://{{ .Values.admin_panel_gui.service.name }}:{{ .Values.admin_panel_gui.service.port }}" +{{- end }} + auditlogs: loadBalancer: servers: diff --git a/mender/values.yaml b/mender/values.yaml index 233a44cb..66be6aa5 100644 --- a/mender/values.yaml +++ b/mender/values.yaml @@ -1529,6 +1529,119 @@ devicemonitor: # successThreshold: 2 # failureThreshold: 6 +# The admin panel is an internal, Northern.tech only tool: it drives the +# privileged endpoints of the other services, so it stays off unless a +# deployment asks for it explicitly. +admin_panel: + enabled: false + podAnnotations: {} + replicas: 1 + resources: + limits: + cpu: 50m + memory: 128Mi + requests: + cpu: 50m + memory: 128Mi + affinity: {} + # image: + # registry: "" + # repository: "" + # tag: "" + # pullPolicy: IfNotPresent + imagePullSecrets: [] + nodeSelector: {} + service: + name: mender-admin-panel + annotations: {} + type: ClusterIP + port: 8080 + podSecurityContext: + enabled: false + runAsNonRoot: true + runAsUser: 65534 + containerSecurityContext: + enabled: false + allowPrivilegeEscalation: false + runAsUser: 65534 + priorityClassName: "" + + # The service refuses to start without OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET + # and SESSION_SECRET, so this - or customEnvs - has to provide them. + existingSecret: "" + + customEnvs: [] + # - name: ADMIN_PANEL_BASE_URL + # value: https://hosted.mender.io + # - name: ADMIN_PANEL_ALLOWED_EMAIL_DOMAINS + # value: northern.tech + + # updateStrategy: + # rollingUpdate: + # maxSurge: 25% + # maxUnavailable: 25% + + probesOverrides: + {} + # timeoutSeconds: 2 + # successThreshold: 2 + # failureThreshold: 6 + + hpa: {} + +admin_panel_gui: + enabled: false + podAnnotations: {} + replicas: 1 + resources: + limits: + cpu: 20m + memory: 64Mi + requests: + cpu: 5m + memory: 16Mi + affinity: {} + # image: + # registry: "" + # repository: "" + # tag: "" + # pullPolicy: IfNotPresent + imagePullSecrets: [] + nodeSelector: {} + service: + name: mender-admin-panel-gui + annotations: {} + type: ClusterIP + port: 80 + httpPort: 8090 + podSecurityContext: + enabled: false + runAsNonRoot: true + runAsUser: 65534 + containerSecurityContext: + enabled: false + allowPrivilegeEscalation: false + runAsUser: 65534 + priorityClassName: "" + + customEnvs: [] + # - name: LOG_LEVEL + # value: DEBUG + + # updateStrategy: + # rollingUpdate: + # maxSurge: 25% + # maxUnavailable: 25% + + probesOverrides: + initialDelaySeconds: 2 + periodSeconds: 5 + # timeoutSeconds: 2 + # successThreshold: 2 + # failureThreshold: 6 + + hpa: {} + # This is a sample redis deployment single instance included in the # helm chart for convinence. Not recommended in production. redis: @@ -1592,4 +1705,3 @@ dbmigration: enabled: false runAsNonRoot: true runAsUser: 999 -