diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl index c510dc1c..a2e46f4b 100644 --- a/helm/templates/_helpers.tpl +++ b/helm/templates/_helpers.tpl @@ -48,6 +48,47 @@ Chart label {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} +{{/* +Secret name — existingSecret if set, otherwise auto-generated name. +*/}} +{{- define "open-git.secretName" -}} +{{- if .Values.secrets.existingSecret }} +{{- .Values.secrets.existingSecret }} +{{- else }} +{{- printf "%s-secrets" (include "open-git.fullname" .) }} +{{- end }} +{{- end }} + +{{/* +ServiceAccount name +*/}} +{{- define "open-git.serviceAccountName" -}} +{{- if .Values.serviceAccount.name }} +{{- .Values.serviceAccount.name }} +{{- else if .Values.serviceAccount.create }} +{{- include "open-git.fullname" . }} +{{- else }} +{{- "default" }} +{{- end }} +{{- end }} + +{{/* +Pod-level security context +*/}} +{{- define "open-git.podSecurityContext" -}} +runAsNonRoot: {{ .Values.securityContext.runAsNonRoot | default true }} +runAsUser: {{ .Values.securityContext.runAsUser | default 1000 }} +fsGroup: {{ .Values.securityContext.fsGroup | default (.Values.securityContext.runAsUser | default 1000) }} +{{- end }} + +{{/* +Container-level security context +*/}} +{{- define "open-git.containerSecurityContext" -}} +allowPrivilegeEscalation: false +readOnlyRootFilesystem: true +{{- end }} + {{/* Validated Git repository mount path from values. */}} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index 35dffa7f..a9b402ad 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -17,10 +17,26 @@ spec: {{- include "open-git.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: backend spec: + serviceAccountName: {{ include "open-git.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- include "open-git.podSecurityContext" . | nindent 8 }} containers: - name: backend image: "{{ .Values.image.backend.repository }}:{{ .Values.image.backend.tag }}" imagePullPolicy: {{ .Values.image.backend.pullPolicy }} + securityContext: + {{- include "open-git.containerSecurityContext" . | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp + {{- if (.Values.persistence.repositories.enabled | default true) }} + - name: repositories + mountPath: {{ include "open-git.repositoriesMountPath" . | quote }} + {{- end }} ports: - name: http containerPort: 8080 @@ -66,33 +82,45 @@ spec: - name: MINIO_BUCKET value: {{ .Values.minio.bucket | quote }} {{- end }} + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: jwt-secret + - name: OAUTH_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: oauth-client-secret + - name: WEBHOOK_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: webhook-secret readinessProbe: httpGet: - path: /health + path: /readyz port: 8080 initialDelaySeconds: 5 periodSeconds: 10 failureThreshold: 3 livenessProbe: httpGet: - path: /health + path: /healthz port: 8080 initialDelaySeconds: 15 periodSeconds: 20 failureThreshold: 3 - {{- if (.Values.persistence.repositories.enabled | default true) }} - volumeMounts: - - name: repositories - mountPath: {{ include "open-git.repositoriesMountPath" . | quote }} - {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} - {{- if (.Values.persistence.repositories.enabled | default true) }} volumes: + - name: tmp + emptyDir: {} + {{- if (.Values.persistence.repositories.enabled | default true) }} - name: repositories persistentVolumeClaim: claimName: {{ include "open-git.fullname" . }}-repositories - {{- end }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} @@ -125,13 +153,42 @@ spec: {{- include "open-git.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: frontend spec: + serviceAccountName: {{ include "open-git.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- include "open-git.podSecurityContext" . | nindent 8 }} containers: - name: frontend image: "{{ .Values.image.frontend.repository }}:{{ .Values.image.frontend.tag }}" imagePullPolicy: {{ .Values.image.frontend.pullPolicy }} + securityContext: + {{- include "open-git.containerSecurityContext" . | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp ports: - name: http containerPort: 3000 protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 3000 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + livenessProbe: + httpGet: + path: /healthz + port: 3000 + initialDelaySeconds: 15 + periodSeconds: 20 + failureThreshold: 3 resources: {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: tmp + emptyDir: {} diff --git a/helm/templates/rbac.yaml b/helm/templates/rbac.yaml new file mode 100644 index 00000000..295bf6bf --- /dev/null +++ b/helm/templates/rbac.yaml @@ -0,0 +1,39 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "open-git.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "open-git.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets"] + resourceNames: + - {{ include "open-git.secretName" . | quote }} + {{- if eq .Values.db.type "postgres" }} + - {{ printf "%s-db" (include "open-git.fullname" .) | quote }} + {{- end }} + {{- if .Values.minio.enabled }} + - {{ printf "%s-minio" (include "open-git.fullname" .) | quote }} + {{- end }} + verbs: ["get"] + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "open-git.fullname" . }} + labels: + {{- include "open-git.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "open-git.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "open-git.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/templates/secret.yaml b/helm/templates/secret.yaml new file mode 100644 index 00000000..f4a0e756 --- /dev/null +++ b/helm/templates/secret.yaml @@ -0,0 +1,23 @@ +{{- if not .Values.secrets.existingSecret }} +{{- $secret := lookup "v1" "Secret" .Release.Namespace (include "open-git.secretName" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "open-git.secretName" . }} + labels: + {{- include "open-git.labels" . | nindent 4 }} + app.kubernetes.io/component: secrets +type: Opaque +data: + {{- if $secret }} + db-password: {{ index $secret.data "db-password" | default (randAlphaNum 32 | b64enc) | quote }} + jwt-secret: {{ index $secret.data "jwt-secret" | default (randAlphaNum 32 | b64enc) | quote }} + oauth-client-secret: {{ index $secret.data "oauth-client-secret" | default (randAlphaNum 32 | b64enc) | quote }} + webhook-secret: {{ index $secret.data "webhook-secret" | default (randAlphaNum 32 | b64enc) | quote }} + {{- else }} + db-password: {{ randAlphaNum 32 | b64enc | quote }} + jwt-secret: {{ randAlphaNum 32 | b64enc | quote }} + oauth-client-secret: {{ randAlphaNum 32 | b64enc | quote }} + webhook-secret: {{ randAlphaNum 32 | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/helm/templates/serviceaccount.yaml b/helm/templates/serviceaccount.yaml new file mode 100644 index 00000000..0a9105ed --- /dev/null +++ b/helm/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "open-git.serviceAccountName" . }} + labels: + {{- include "open-git.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: false +{{- end }} diff --git a/helm/templates/worker-deployment.yaml b/helm/templates/worker-deployment.yaml index 59b1f03f..f311deb5 100644 --- a/helm/templates/worker-deployment.yaml +++ b/helm/templates/worker-deployment.yaml @@ -17,10 +17,22 @@ spec: {{- include "open-git.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: worker spec: + serviceAccountName: {{ include "open-git.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- include "open-git.podSecurityContext" . | nindent 8 }} containers: - name: worker image: "{{ .Values.image.backend.repository }}:{{ .Values.image.backend.tag }}" imagePullPolicy: {{ .Values.image.backend.pullPolicy }} + securityContext: + {{- include "open-git.containerSecurityContext" . | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp args: - "--worker-only" env: @@ -59,8 +71,21 @@ spec: - name: MINIO_BUCKET value: {{ .Values.minio.bucket | quote }} {{- end }} + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: jwt-secret + - name: WEBHOOK_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: webhook-secret resources: {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: tmp + emptyDir: {} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }}