diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 0b7e6b4e..0ca0dec6 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -58,7 +58,7 @@ jobs: environment: test tag: ${{ needs.semantic-version.outputs.semanticVersion }} # this is without v release_name: pubcode-test - params: --set-string api.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" --set-string frontend.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" + params: --set-string database.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" --set-string database.initContainers[0].tag="${{ needs.semantic-version.outputs.tag }}" --set-string api.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" --set-string frontend.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" tests: name: Tests needs: [deploys] @@ -76,7 +76,7 @@ jobs: environment: prod tag: ${{ needs.semantic-version.outputs.semanticVersion }} release_name: pubcode - params: --set-string api.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" --set-string frontend.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" + params: --set-string database.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" --set-string database.initContainers[0].tag="${{ needs.semantic-version.outputs.tag }}" --set-string api.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" --set-string frontend.containers[0].tag="${{ needs.semantic-version.outputs.tag }}" github_release: name: Create Release needs: [semantic-version, deploys-prod] diff --git a/.github/workflows/pr-close.yml b/.github/workflows/pr-close.yml index ad95c085..62b5b234 100644 --- a/.github/workflows/pr-close.yml +++ b/.github/workflows/pr-close.yml @@ -20,5 +20,4 @@ jobs: oc_token: ${{ secrets.OC_TOKEN }} with: cleanup: helm - packages: api frontend - + packages: api frontend database diff --git a/.github/workflows/pr-open.yml b/.github/workflows/pr-open.yml index 01c549da..618495c8 100644 --- a/.github/workflows/pr-open.yml +++ b/.github/workflows/pr-open.yml @@ -44,7 +44,7 @@ jobs: packages: write strategy: matrix: - package: [api, frontend] + package: [api, database, frontend] steps: - uses: actions/checkout@v6 - uses: bcgov/action-builder-ghcr@2b24ac7f95e6a019064151498660437cca3202c5 # v4.2.1 @@ -72,6 +72,8 @@ jobs: release_name: pubcode-${{ github.event.number }} params: | --set-string global.repository=${{ github.repository }} \ + --set-string database.containers[0].tag="${{ github.sha }}" \ + --set-string database.initContainers[0].tag="${{ github.sha }}" \ --set-string api.containers[0].tag="${{ github.sha }}" \ --set-string api.containers[0].resources.requests.cpu="30m" \ --set-string api.containers[0].resources.requests.memory="50Mi" \ diff --git a/charts/pubcode/Chart.lock b/charts/pubcode/Chart.lock deleted file mode 100644 index 0adf2836..00000000 --- a/charts/pubcode/Chart.lock +++ /dev/null @@ -1,12 +0,0 @@ -dependencies: -- name: component - repository: https://bcgov.github.io/helm-service/ - version: 0.3.3 -- name: component - repository: https://bcgov.github.io/helm-service/ - version: 0.3.3 -- name: component - repository: https://bcgov.github.io/helm-service/ - version: 0.3.3 -digest: sha256:d1cd17e5ba97860d19a838a3b8dd85f9601c6053a9791d339c05cb06d64a7087 -generated: "2025-03-15T01:56:59.766695711Z" diff --git a/charts/pubcode/Chart.yaml b/charts/pubcode/Chart.yaml index eec7e328..b08a8f7b 100644 --- a/charts/pubcode/Chart.yaml +++ b/charts/pubcode/Chart.yaml @@ -23,22 +23,3 @@ version: 0.1.0 # It is recommended to use it with quotes. appVersion: "0.1.0" -dependencies: - - - name: component - condition: api.enabled - version: 0.3.3 - repository: https://bcgov.github.io/helm-service/ - alias: api - - - name: component - condition: frontend.enabled - version: 0.3.3 - repository: https://bcgov.github.io/helm-service/ - alias: frontend - - - name: component - condition: database.enabled - version: 0.3.3 - repository: https://bcgov.github.io/helm-service/ - alias: database diff --git a/charts/pubcode/templates/api/templates/_helpers.tpl b/charts/pubcode/templates/api/templates/_helpers.tpl new file mode 100644 index 00000000..b4ea3409 --- /dev/null +++ b/charts/pubcode/templates/api/templates/_helpers.tpl @@ -0,0 +1,41 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "api.name" -}} +{{- printf "api" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "api.fullname" -}} +{{- $componentName := include "api.name" . }} +{{- if .Values.api.fullnameOverride }} +{{- .Values.api.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "api.labels" -}} +{{ include "api.selectorLabels" . }} +{{- if .Values.global.tag }} +app.kubernetes.io/image-version: {{ .Values.global.tag | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/short-name: {{ include "api.name" . }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "api.selectorLabels" -}} +app.kubernetes.io/name: {{ include "api.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + diff --git a/charts/pubcode/templates/api/templates/deployment.yml b/charts/pubcode/templates/api/templates/deployment.yml new file mode 100644 index 00000000..f8a7e1c0 --- /dev/null +++ b/charts/pubcode/templates/api/templates/deployment.yml @@ -0,0 +1,86 @@ +{{- if and .Values.api.enabled .Values.api.deployment.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "api.labels" . | nindent 4 }} +spec: + {{- if not .Values.api.autoscaling.enabled }} + replicas: {{ default 1 .Values.api.autoscaling.minReplicas }} + {{- end }} + selector: + matchLabels: + {{- include "api.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + rollme: {{ randAlphaNum 5 | quote }} + {{- if .Values.api.podAnnotations }} + {{- tpl .Values.api.podAnnotations $ | nindent 8 }} + {{- end }} + labels: + {{- include "api.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + containers: + {{- range $c := .Values.api.containers }} + - name: {{ $c.name }} + image: "{{- if and $c.registry $c.repository -}}{{ tpl $c.registry $ }}/{{ tpl $c.repository $ }}/{{ tpl $c.image $ }}{{- else if $c.registry -}}{{ tpl $c.registry $ }}/{{ tpl $c.image $ }}{{- else -}}{{ tpl $c.image $ }}{{- end -}}{{- if $c.tag -}}:{{ tpl (printf "%v" $c.tag) $ }}{{- end -}}" + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + {{- if and $c.envFrom $c.envFrom.secretRef $c.envFrom.secretRef.name }} + envFrom: + - secretRef: + name: {{ tpl $c.envFrom.secretRef.name $ }} + {{- end }} + {{- if $c.env }} + env: + {{- if and (kindIs "map" $c.env) $c.env.fromValues }} + {{- range $e := $c.env.fromValues }} + - name: {{ $e.name }} + value: {{ tpl (printf "%v" $e.value) $ | quote }} + {{- end }} + {{- else if kindIs "slice" $c.env }} + {{- tpl (toYaml $c.env) $ | nindent 12 }} + {{- end }} + {{- end }} + {{- if $c.ports }} + ports: + {{- tpl (toYaml $c.ports) $ | nindent 12 }} + {{- end }} + {{- if $c.resources }} + resources: + {{- toYaml $c.resources | nindent 12 }} + {{- end }} + {{- if $c.readinessProbe }} + readinessProbe: + {{- toYaml $c.readinessProbe | nindent 12 }} + {{- end }} + {{- if $c.livenessProbe }} + livenessProbe: + {{- toYaml $c.livenessProbe | nindent 12 }} + {{- end }} + {{- end }} + + {{- with .Values.api.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.api.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.api.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/pubcode/templates/api/templates/hpa.yml b/charts/pubcode/templates/api/templates/hpa.yml new file mode 100644 index 00000000..d417655d --- /dev/null +++ b/charts/pubcode/templates/api/templates/hpa.yml @@ -0,0 +1,53 @@ +{{- if and .Values.api.autoscaling .Values.api.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "api.fullname" . }} + labels: + {{- include "api.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "api.fullname" . }} + minReplicas: {{ .Values.api.autoscaling.minReplicas }} + maxReplicas: {{ .Values.api.autoscaling.maxReplicas }} + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Percent + value: 10 + periodSeconds: 60 + - type: Pods + value: 2 + periodSeconds: 60 + selectPolicy: Min + scaleUp: + stabilizationWindowSeconds: 0 + policies: + - type: Percent + value: 100 + periodSeconds: 30 + - type: Pods + value: 2 + periodSeconds: 30 + selectPolicy: Max + metrics: + {{- if .Values.api.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.api.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.api.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.api.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/pubcode/templates/api/templates/ingress.yaml b/charts/pubcode/templates/api/templates/ingress.yaml new file mode 100644 index 00000000..339eea15 --- /dev/null +++ b/charts/pubcode/templates/api/templates/ingress.yaml @@ -0,0 +1,30 @@ +{{- if and .Values.api.enabled .Values.api.route .Values.api.route.enabled }} +{{- $svcName := include "api.fullname" . -}} +{{- $defaultSvcPort := 80 -}} +{{- if and .Values.api.service .Values.api.service.ports (gt (len .Values.api.service.ports) 0) -}} +{{- $defaultSvcPort = (index .Values.api.service.ports 0).port | default 80 -}} +{{- end -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $svcName }} + labels: + {{- include "api.labels" . | nindent 4 }} + {{- if .Values.api.route.annotations }} + annotations: + {{- tpl (toYaml .Values.api.route.annotations) $ | nindent 4 }} + {{- end }} +spec: + ingressClassName: {{ default "openshift-default" .Values.api.route.className }} + rules: + - host: {{ tpl (default (printf "%s.%s" $svcName .Values.global.domain) (printf "%v" .Values.api.route.host)) $ | quote }} + http: + paths: + - path: "/" + pathType: ImplementationSpecific + backend: + service: + name: {{ $svcName }} + port: + number: {{ $defaultSvcPort }} +{{- end }} diff --git a/charts/pubcode/templates/api/templates/pdb.yml b/charts/pubcode/templates/api/templates/pdb.yml new file mode 100644 index 00000000..7e8f57ef --- /dev/null +++ b/charts/pubcode/templates/api/templates/pdb.yml @@ -0,0 +1,14 @@ +{{- if and .Values.api.pdb .Values.api.pdb.enabled }} +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "api.fullname" . }} + labels: + {{- include "api.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "api.selectorLabels" . | nindent 6 }} + minAvailable: {{ .Values.api.pdb.minAvailable }} +{{- end }} \ No newline at end of file diff --git a/charts/pubcode/templates/api/templates/service.yml b/charts/pubcode/templates/api/templates/service.yml new file mode 100644 index 00000000..272762ba --- /dev/null +++ b/charts/pubcode/templates/api/templates/service.yml @@ -0,0 +1,20 @@ +{{- if .Values.api.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "api.fullname" . }} + labels: + {{- include "api.labels" . | nindent 4 }} +spec: + type: {{ default "ClusterIP" .Values.api.service.type }} + ports: + {{- range $p := .Values.api.service.ports }} + - name: {{ default "http" $p.name }} + port: {{ $p.port }} + targetPort: {{ $p.targetPort }} + protocol: {{ default "TCP" $p.protocol }} + {{- end }} + selector: + {{- include "api.selectorLabels" . | nindent 4 }} +{{- end }} \ No newline at end of file diff --git a/charts/pubcode/templates/database/templates/_helpers.tpl b/charts/pubcode/templates/database/templates/_helpers.tpl new file mode 100644 index 00000000..7e19cd12 --- /dev/null +++ b/charts/pubcode/templates/database/templates/_helpers.tpl @@ -0,0 +1,55 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "database.name" -}} +{{- printf "database" }} +{{- end }} + +{{/* +Compatibility helpers. + +values.yaml references "component.*" helpers for the database component. +Define them here so tpl() evaluation works without requiring values changes. +*/}} +{{- define "component.name" -}} +{{- include "database.name" . -}} +{{- end }} + +{{- define "component.fullname" -}} +{{- include "database.fullname" . -}} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "database.fullname" -}} +{{- $componentName := include "database.name" . }} +{{- if .Values.database.fullnameOverride }} +{{- .Values.database.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "database.labels" -}} +{{ include "database.selectorLabels" . }} +{{- if .Values.global.tag }} +app.kubernetes.io/image-version: {{ .Values.global.tag | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/short-name: {{ include "database.name" . }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "database.selectorLabels" -}} +app.kubernetes.io/name: {{ include "database.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + diff --git a/charts/pubcode/templates/database/templates/pvc.yml b/charts/pubcode/templates/database/templates/pvc.yml new file mode 100644 index 00000000..0fb33c53 --- /dev/null +++ b/charts/pubcode/templates/database/templates/pvc.yml @@ -0,0 +1,22 @@ +{{- if and .Values.database.enabled .Values.database.pvc.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ .Release.Name }}-database + namespace: {{ .Release.Namespace }} + labels: + {{- include "database.labels" . | nindent 4 }} +spec: + {{- if .Values.database.pvc.storageClassName }} + storageClassName: {{ .Values.database.pvc.storageClassName }} + {{- end }} + accessModes: + {{- if kindIs "slice" .Values.database.pvc.accessModes }} + {{- toYaml .Values.database.pvc.accessModes | nindent 4 }} + {{- else }} + - {{ default "ReadWriteOnce" .Values.database.pvc.accessModes }} + {{- end }} + resources: + requests: + storage: {{ default "1Gi" .Values.database.pvc.size }} +{{- end }} diff --git a/charts/pubcode/templates/database/templates/service.yml b/charts/pubcode/templates/database/templates/service.yml new file mode 100644 index 00000000..0444553c --- /dev/null +++ b/charts/pubcode/templates/database/templates/service.yml @@ -0,0 +1,20 @@ +{{- if and .Values.database.enabled .Values.database.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "database.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "database.labels" . | nindent 4 }} +spec: + type: {{ default "ClusterIP" .Values.database.service.type }} + selector: + {{- include "database.selectorLabels" . | nindent 4 }} + ports: + {{- range $p := .Values.database.service.ports }} + - name: {{ default "mongo" $p.name }} + port: {{ $p.port }} + targetPort: {{ $p.targetPort }} + protocol: {{ default "TCP" $p.protocol }} + {{- end }} +{{- end }} diff --git a/charts/pubcode/templates/database/templates/sfs.yml b/charts/pubcode/templates/database/templates/sfs.yml new file mode 100644 index 00000000..1d624347 --- /dev/null +++ b/charts/pubcode/templates/database/templates/sfs.yml @@ -0,0 +1,110 @@ +{{- if .Values.database.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "database.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "database.labels" . | nindent 4 }} +spec: + serviceName: {{ include "database.fullname" . }} + replicas: {{ default 1 .Values.database.autoscaling.minReplicas }} + selector: + matchLabels: + {{- include "database.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + rollme: {{ randAlphaNum 5 | quote }} + labels: + {{- include "database.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + {{- if .Values.database.initContainers }} + initContainers: + {{- range $ic := .Values.database.initContainers }} + - name: {{ $ic.name }} + image: "{{- if and $ic.registry $ic.repository -}}{{ tpl $ic.registry $ }}/{{ tpl $ic.repository $ }}/{{ tpl $ic.image $ }}{{- else if $ic.registry -}}{{ tpl $ic.registry $ }}/{{ tpl $ic.image $ }}{{- else -}}{{ tpl $ic.image $ }}{{- end -}}{{- if $ic.tag -}}:{{ tpl (printf "%v" $ic.tag) $ }}{{- end -}}" + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + {{- if $ic.command }} + command: + {{- tpl (toYaml $ic.command) $ | nindent 12 }} + {{- end }} + {{- if $ic.args }} + args: + {{- tpl (toYaml $ic.args) $ | nindent 12 }} + {{- end }} + {{- if $ic.resources }} + resources: + {{- toYaml $ic.resources | nindent 12 }} + {{- end }} + {{- if $ic.volumeMounts }} + volumeMounts: + {{- tpl (toYaml $ic.volumeMounts) $ | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + + containers: + {{- range $c := .Values.database.containers }} + - name: {{ $c.name }} + image: "{{- if and $c.registry $c.repository -}}{{ tpl $c.registry $ }}/{{ tpl $c.repository $ }}/{{ tpl $c.image $ }}{{- else if $c.registry -}}{{ tpl $c.registry $ }}/{{ tpl $c.image $ }}{{- else -}}{{ tpl $c.image $ }}{{- end -}}{{- if $c.tag -}}:{{ tpl (printf "%v" $c.tag) $ }}{{- end -}}" + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + {{- if and $c.envFrom $c.envFrom.secretRef $c.envFrom.secretRef.name }} + envFrom: + - secretRef: + name: {{ tpl $c.envFrom.secretRef.name $ }} + {{- end }} + {{- if $c.ports }} + ports: + {{- tpl (toYaml $c.ports) $ | nindent 12 }} + {{- end }} + {{- if $c.resources }} + resources: + {{- toYaml $c.resources | nindent 12 }} + {{- end }} + {{- if $c.readinessProbe }} + readinessProbe: + {{- toYaml $c.readinessProbe | nindent 12 }} + {{- end }} + {{- if $c.livenessProbe }} + livenessProbe: + {{- toYaml $c.livenessProbe | nindent 12 }} + {{- end }} + {{- if $c.volumeMounts }} + volumeMounts: + {{- tpl (toYaml $c.volumeMounts) $ | nindent 12 }} + {{- end }} + {{- end }} + + {{- if .Values.database.volumes }} + volumes: + {{- tpl (toYaml .Values.database.volumes) $ | nindent 8 }} + {{- end }} + + {{- with .Values.database.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.database.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.database.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/pubcode/templates/frontend/templates/_helpers.tpl b/charts/pubcode/templates/frontend/templates/_helpers.tpl new file mode 100644 index 00000000..524c972f --- /dev/null +++ b/charts/pubcode/templates/frontend/templates/_helpers.tpl @@ -0,0 +1,43 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "frontend.name" -}} +{{- printf "frontend" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "frontend.fullname" -}} +{{- $componentName := include "frontend.name" . }} +{{- if .Values.frontend.fullnameOverride }} +{{- .Values.frontend.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + + +{{/* +Common labels +*/}} +{{- define "frontend.labels" -}} +{{ include "frontend.selectorLabels" . }} +{{- if .Values.global.tag }} +app.kubernetes.io/image-version: {{ .Values.global.tag | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/short-name: {{ include "frontend.name" . }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "frontend.selectorLabels" -}} +app.kubernetes.io/name: {{ include "frontend.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + + diff --git a/charts/pubcode/templates/frontend/templates/deployment.yaml b/charts/pubcode/templates/frontend/templates/deployment.yaml new file mode 100644 index 00000000..d0f9ab80 --- /dev/null +++ b/charts/pubcode/templates/frontend/templates/deployment.yaml @@ -0,0 +1,93 @@ +{{- if and .Values.frontend.enabled .Values.frontend.deployment.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "frontend.labels" . | nindent 4 }} +spec: + {{- if not .Values.frontend.autoscaling.enabled }} + replicas: {{ default 1 .Values.frontend.autoscaling.minReplicas }} + {{- end }} + selector: + matchLabels: + {{- include "frontend.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + rollme: {{ randAlphaNum 5 | quote }} + {{- if .Values.frontend.podAnnotations }} + {{- tpl .Values.frontend.podAnnotations $ | nindent 8 }} + {{- end }} + labels: + {{- include "frontend.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + containers: + {{- range $c := .Values.frontend.containers }} + - name: {{ $c.name }} + securityContext: + allowPrivilegeEscalation: {{ default false $c.securityContext.allowPrivilegeEscalation }} + runAsNonRoot: {{ default true $c.securityContext.runAsNonRoot }} + {{- if hasKey $c.securityContext "readOnlyRootFilesystem" }} + readOnlyRootFilesystem: {{ $c.securityContext.readOnlyRootFilesystem }} + {{- end }} + capabilities: + drop: + - ALL + {{- if and $c.securityContext $c.securityContext.capabilities $c.securityContext.capabilities.add }} + add: + {{- toYaml $c.securityContext.capabilities.add | nindent 16 }} + {{- end }} + image: "{{- if and $c.registry $c.repository -}}{{ tpl $c.registry $ }}/{{ tpl $c.repository $ }}/{{ tpl $c.image $ }}{{- else if $c.registry -}}{{ tpl $c.registry $ }}/{{ tpl $c.image $ }}{{- else -}}{{ tpl $c.image $ }}{{- end -}}{{- if $c.tag -}}:{{ tpl (printf "%v" $c.tag) $ }}{{- end -}}" + {{- if and $c.envFrom $c.envFrom.secretRef $c.envFrom.secretRef.name }} + envFrom: + - secretRef: + name: {{ tpl $c.envFrom.secretRef.name $ }} + {{- end }} + {{- if $c.env }} + env: + {{- if and (kindIs "map" $c.env) $c.env.fromValues }} + {{- range $e := $c.env.fromValues }} + - name: {{ $e.name }} + value: {{ tpl (printf "%v" $e.value) $ | quote }} + {{- end }} + {{- else if kindIs "slice" $c.env }} + {{- tpl (toYaml $c.env) $ | nindent 12 }} + {{- end }} + {{- end }} + {{- if $c.ports }} + ports: + {{- tpl (toYaml $c.ports) $ | nindent 12 }} + {{- end }} + {{- if $c.resources }} + resources: + {{- toYaml $c.resources | nindent 12 }} + {{- end }} + {{- if $c.readinessProbe }} + readinessProbe: + {{- toYaml $c.readinessProbe | nindent 12 }} + {{- end }} + {{- if $c.livenessProbe }} + livenessProbe: + {{- toYaml $c.livenessProbe | nindent 12 }} + {{- end }} + {{- end }} + + {{- with .Values.frontend.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.frontend.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.frontend.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/pubcode/templates/frontend/templates/hpa.yaml b/charts/pubcode/templates/frontend/templates/hpa.yaml new file mode 100644 index 00000000..6c7acfbd --- /dev/null +++ b/charts/pubcode/templates/frontend/templates/hpa.yaml @@ -0,0 +1,53 @@ +{{- if and .Values.frontend.autoscaling .Values.frontend.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "frontend.fullname" . }} + labels: + {{- include "frontend.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "frontend.fullname" . }} + minReplicas: {{ .Values.frontend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.frontend.autoscaling.maxReplicas }} + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Percent + value: 10 + periodSeconds: 60 + - type: Pods + value: 2 + periodSeconds: 60 + selectPolicy: Min + scaleUp: + stabilizationWindowSeconds: 0 + policies: + - type: Percent + value: 100 + periodSeconds: 30 + - type: Pods + value: 2 + periodSeconds: 30 + selectPolicy: Max + metrics: + {{- if .Values.frontend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.frontend.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.frontend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.frontend.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/pubcode/templates/frontend/templates/ingress.yaml b/charts/pubcode/templates/frontend/templates/ingress.yaml new file mode 100644 index 00000000..b78b7d1a --- /dev/null +++ b/charts/pubcode/templates/frontend/templates/ingress.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.frontend.enabled .Values.frontend.ingress .Values.frontend.ingress.enabled }} +{{- $svcName := include "frontend.fullname" . -}} +{{- $defaultSvcPort := 80 -}} +{{- if and .Values.frontend.service .Values.frontend.service.ports (gt (len .Values.frontend.service.ports) 0) -}} +{{- $defaultSvcPort = (index .Values.frontend.service.ports 0).port | default 80 -}} +{{- end -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $svcName }} + labels: + {{- include "frontend.labels" . | nindent 4 }} + {{- if .Values.frontend.ingress.annotations }} + annotations: + {{- tpl (toYaml .Values.frontend.ingress.annotations) $ | nindent 4 }} + {{- end }} +spec: + ingressClassName: {{ default "openshift-default" .Values.frontend.ingress.className }} + rules: + {{- if and .Values.frontend.ingress.hosts (gt (len .Values.frontend.ingress.hosts) 0) }} + {{- range $h := .Values.frontend.ingress.hosts }} + - host: {{ tpl $h.host $ | quote }} + http: + paths: + {{- range $p := $h.paths }} + - path: {{ default "/" $p.path | quote }} + pathType: {{ default "ImplementationSpecific" $p.pathType }} + backend: + service: + name: {{ $svcName }} + port: + number: {{ $defaultSvcPort }} + {{- end }} + {{- end }} + {{- else }} + - host: {{ printf "%s.%s" $svcName .Values.global.domain | quote }} + http: + paths: + - path: "/" + pathType: ImplementationSpecific + backend: + service: + name: {{ $svcName }} + port: + number: {{ $defaultSvcPort }} + {{- end }} +{{- end }} diff --git a/charts/pubcode/templates/frontend/templates/pdb.yaml b/charts/pubcode/templates/frontend/templates/pdb.yaml new file mode 100644 index 00000000..b7067bf5 --- /dev/null +++ b/charts/pubcode/templates/frontend/templates/pdb.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.frontend.pdb .Values.frontend.pdb.enabled }} +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "frontend.fullname" . }} + labels: + {{- include "frontend.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "frontend.selectorLabels" . | nindent 6 }} + minAvailable: {{ .Values.frontend.pdb.minAvailable }} +{{- end }} diff --git a/charts/pubcode/templates/frontend/templates/service.yaml b/charts/pubcode/templates/frontend/templates/service.yaml new file mode 100644 index 00000000..bcd35175 --- /dev/null +++ b/charts/pubcode/templates/frontend/templates/service.yaml @@ -0,0 +1,20 @@ +{{- if .Values.frontend.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "frontend.fullname" . }} + labels: + {{- include "frontend.labels" . | nindent 4 }} +spec: + type: {{ default "ClusterIP" .Values.frontend.service.type }} + ports: + {{- range $p := .Values.frontend.service.ports }} + - name: {{ default "http" $p.name }} + port: {{ $p.port }} + targetPort: {{ $p.targetPort }} + protocol: {{ default "TCP" $p.protocol }} + {{- end }} + selector: + {{- include "frontend.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/pubcode/templates/secret.yaml b/charts/pubcode/templates/secret.yaml index af5509cb..cddc19fd 100644 --- a/charts/pubcode/templates/secret.yaml +++ b/charts/pubcode/templates/secret.yaml @@ -32,5 +32,5 @@ metadata: name: {{ .Release.Name }}-frontend labels: {{- include "selectorLabels" . | nindent 4 }} data: - VITE_POWERBI_URL: {{ tpl .Values.global.secrets.powerBIURL $ | b64enc | quote }} + VITE_POWERBI_URL: {{ tpl (default "" .Values.global.secrets.powerBIURL) $ | b64enc | quote }} {{- end }} diff --git a/charts/pubcode/values.yaml b/charts/pubcode/values.yaml index d0ff9a12..0722ad75 100644 --- a/charts/pubcode/values.yaml +++ b/charts/pubcode/values.yaml @@ -199,10 +199,10 @@ database: name: '{{ include "component.fullname" . }}' initContainers: - name: database-init - registry: 'ghcr.io' # example, it includes registry - repository: 'bcgov/nr-containers' # example, it includes repository - image: mongo # the exact component name, be it backend, api-1 etc... - tag: 7.0.20 # the tag of the image, it can be latest, 1.0.0 etc..., or the sha256 hash + registry: '{{ .Values.global.registry }}' # example, it includes registry + repository: '{{ .Values.global.repository }}' # example, it includes repository + image: database # the exact component name, be it backend, api-1 etc... + tag: prod # the tag of the image, it can be latest, 1.0.0 etc..., or the sha256 hash command: - "sh" - "-c" @@ -216,10 +216,10 @@ database: mountPath: /data/db containers: - name: database - registry: 'ghcr.io' # example, it includes registry - repository: 'bcgov/nr-containers' # example, it includes repository - image: mongo # the exact component name, be it backend, api-1 etc... - tag: 7.0.20 # the tag of the image, it can be latest, 1.0.0 etc..., or the sha256 hash + registry: '{{ .Values.global.registry }}' # example, it includes registry + repository: '{{ .Values.global.repository }}' # example, it includes repository + image: database # the exact component name, be it backend, api-1 etc... + tag: prod # the tag of the image, it can be latest, 1.0.0 etc..., or the sha256 hash envFrom: secretRef: name: '{{ .Release.Name }}'