diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f92de4ed3bc43b1337bb35a71a18ba444c412ae2..4d9f84270a8ec852f15baeae653bcc34c2ac7a27 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,6 @@ variables: HELPERS_FILE: docker-build.yml + HELM_HELPERS_FILE: helm.yml APP_HELM_NAME: policy DOCKER_FILE: deployment/ci/Dockerfile @@ -7,13 +8,15 @@ stages: - compile - test - build - - manifest + - helm - deploy include: - project: "${HELPERS_PATH}" file: "${HELPERS_FILE}" - template: "Workflows/Branch-Pipelines.gitlab-ci.yml" + - project: "$HELM_HELPERS_PATH}" + file: "${HELM_HELPERS_FILE}" lint: image: golangci/golangci-lint:latest @@ -71,14 +74,8 @@ dockerize sync: - tags - integration -manifest: - extends: .manifest-amd64 - stage: manifest - -cloud: - extends: .manifest-cloud - stage: manifest - -release: - extends: .manifest-release - stage: manifest +helm-lint: + extends: .helm-lint + stage: helm + tags: + - amd64-docker diff --git a/deployment/helm/Chart.yaml b/deployment/helm/Chart.yaml new file mode 100644 index 0000000000000000000000000000000000000000..44e3e394afedc623d50736306dcfcb89dc9fd92b --- /dev/null +++ b/deployment/helm/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +appVersion: v1.0.2 +description: policy deployment +name: policy +version: 1.0.2 +icon: "https://www.vereign.com/wp-content/themes/vereign2020/images/vereign-logo.svg" diff --git a/deployment/helm/LICENSE b/deployment/helm/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..11c295a57a2debfc1e272b1d9d5fc1bb6bf09561 --- /dev/null +++ b/deployment/helm/LICENSE @@ -0,0 +1,16 @@ +Deployment recipe for TSA policy service + + +Copyright 2022 Vereign AG + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/deployment/helm/README.md b/deployment/helm/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9e811191336dbe8364e6ed6fa3452f889adbc26a --- /dev/null +++ b/deployment/helm/README.md @@ -0,0 +1,63 @@ +# policy + +  + +policy deployment + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| addresses.cache | string | `"http://cache:8080"` | | +| addresses.didResolver | string | `"http://didresolver:8080"` | | +| addresses.ocm | string | `"https://gaiax.vereign.com/ocm"` | | +| addresses.signer | string | `"http://signer:8080"` | | +| addresses.task | string | `"http://task:8080"` | | +| autoscaling.enabled | bool | `false` | Enable autoscaling | +| autoscaling.maxReplicas | int | `3` | Maximum replicas | +| autoscaling.minReplicas | int | `1` | Minimum replicas | +| autoscaling.targetCPUUtilizationPercentage | int | `70` | CPU target for autoscaling trigger | +| autoscaling.targetMemoryUtilizationPercentage | int | `70` | Memory target for autoscaling trigger | +| image.name | string | `"gaiax/policy"` | Image name | +| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | +| image.pullSecrets | string | `"deployment-key-light"` | Image pull secret when internal image is used | +| image.repository | string | `"eu.gcr.io/vrgn-infra-prj"` | | +| image.sha | string | `""` | Image sha, usually generated by the CI Uses image.tag if empty | +| image.tag | string | `""` | Image tag Uses .Chart.AppVersion if empty | +| ingress.annotations."cert-manager.io/cluster-issuer" | string | `"letsencrypt-production-http"` | | +| ingress.annotations."kubernetes.io/ingress.class" | string | `"nginx"` | | +| ingress.annotations."kubernetes.io/ingress.global-static-ip-name" | string | `"dev-light-public"` | | +| ingress.annotations."nginx.ingress.kubernetes.io/rewrite-target" | string | `"/$2"` | | +| ingress.enabled | bool | `true` | | +| ingress.frontendDomain | string | `"gaiax.vereign.com"` | | +| ingress.frontendTlsSecretName | string | `"cert-manager-tls"` | | +| ingress.tlsEnabled | bool | `true` | | +| log.encoding | string | `"json"` | | +| log.level | string | `"debug"` | | +| metrics.enabled | bool | `true` | Enable prometheus metrics | +| metrics.port | int | `2112` | Port for prometheus metrics | +| mongo.addr | string | `"mongodb://mongodb-mongodb-replicaset.infra:27017/policy?replicaSet=rs0&authSource=admin"` | | +| mongo.collection | string | `"policies"` | | +| mongo.dbname | string | `"policy"` | | +| mongo.pass | string | `""` | | +| mongo.user | string | `""` | | +| name | string | `"policy"` | Application name | +| nameOverride | string | `""` | Ovverwrites application name | +| podAnnotations | object | `{}` | | +| policy.http.host | string | `""` | | +| policy.http.port | int | `8080` | | +| policy.http.timeout.idle | string | `"120s"` | | +| policy.http.timeout.read | string | `"10s"` | | +| policy.http.timeout.write | string | `"10s"` | | +| replicaCount | int | `1` | Default number of instances to start | +| resources.limits.cpu | string | `"150m"` | | +| resources.limits.memory | string | `"128Mi"` | | +| resources.requests.cpu | string | `"25m"` | | +| resources.requests.memory | string | `"64Mi"` | | +| security.runAsGid | int | `0` | Group used by the apps | +| security.runAsNonRoot | bool | `false` | by default, apps run as non-root | +| security.runAsUid | int | `0` | User used by the apps | +| service.port | int | `8080` | | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.10.0](https://github.com/norwoodj/helm-docs/releases/v1.10.0) diff --git a/deployment/helm/templates/_helpers.tpl b/deployment/helm/templates/_helpers.tpl new file mode 100644 index 0000000000000000000000000000000000000000..6955ccba19a0e68b2918305e46546f4741fea0aa --- /dev/null +++ b/deployment/helm/templates/_helpers.tpl @@ -0,0 +1,88 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "app.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "app.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" $name .Release.Namespace | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create instance name based on app version and short image sha. +*/}} +{{- define "app.revision" -}} +{{- default .Release.Name .Values.appRel | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "app.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "app.labels" -}} +helm.sh/chart: {{ include "app.chart" . }} +{{ include "app.selectorLabels" . }} +app.kubernetes.io/version: {{ .Chart.AppVersion }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "app.selectorLabels" -}} +app.kubernetes.io/name: {{ include "app.name" . }} +app.kubernetes.io/component: {{ include "app.fullname" . }} +{{- end -}} + +{{/* +Metrics Annotations +*/}} +{{- define "app.metricsAnnotations" -}} +{{- if .Values.metrics.enabled -}} +prometheus.io/scrape: "true" +prometheus.io/port: "{{ .Values.metrics.port }}" +prometheus.io/path: {{ .Values.metrics.path | default "/metrics" | quote }} +{{- end -}} +{{- end -}} + +{{/* +Image string +*/}} +{{- define "app.image" -}} +{{- if .Values.image.sha -}} +{{ .Values.image.repository }}/{{ .Values.image.name }}@{{ .Values.image.sha }} +{{- else -}} +{{ .Values.image.repository }}/{{ .Values.image.name }}:{{ default .Chart.AppVersion .Values.image.tag }} +{{- end -}} +{{- end -}} + +{{/* +Security context +*/}} +{{- define "app.securitycontext" -}} +runAsNonRoot: {{ .Values.security.runAsNonRoot | default false }} +runAsGroup: {{ .Values.security.runAsGid | default 0 }} +runAsUser: {{ .Values.security.runAsUid | default 0 }} +fsGroup: {{ .Values.security.runAsGid | default 0 }} +{{- end -}} + +{{/* +PostgreSQL Connection string URI +*/}} +{{- define "app.postgresql.connectionstring" -}} +postgresql://{{ .Values.connectionManager.database.user }}:{{ .Values.connectionManager.database.password }}@{{ .Values.connectionManager.database.host }}:{{ .Values.connectionManager.database.port }}/{{ .Release.Namespace }}_{{ include "app.name" . | replace "-" "_" }}?schema={{ .Values.connectionManager.database.schema }} +{{- end -}} + diff --git a/deployment/helm/templates/deployment.yaml b/deployment/helm/templates/deployment.yaml new file mode 100644 index 0000000000000000000000000000000000000000..77c1bb8695ead82d57217c16b2f05b2e71689511 --- /dev/null +++ b/deployment/helm/templates/deployment.yaml @@ -0,0 +1,93 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ template "app.name" . }}" + namespace: {{ .Release.Namespace }} + labels: + {{- include "app.labels" . | nindent 4 }} + app.kubernetes.io/instance: {{ include "app.revision" . }} + app.kubernetes.io/part-of: rse +spec: + replicas: {{ .Values.replicaCount }} + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + selector: + matchLabels: + {{- include "app.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "app.labels" . | nindent 8 }} + annotations: + {{- include "app.metricsAnnotations" . | nindent 8 }} +{{- if .Values.podAnnotations }} +{{ toYaml .Values.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: +{{- include "app.securitycontext" . | nindent 8 }} + imagePullSecrets: + - name: {{ .Values.image.pullSecrets }} + containers: + - name: {{ template "app.name" . }} + image: "{{ .Values.image.repository }}/{{ .Values.image.name }}:{{ default .Chart.AppVersion .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + env: + - name: MONGO_ADDR + value: {{ .Values.mongo.addr | quote }} + - name: MONGO_USER + value: {{ .Values.mongo.user | quote }} + - name: MONGO_PASS + value: {{ .Values.mongo.pass | quote }} + - name: MONGO_DB + value: {{ .Values.mongo.dbname | quote }} + - name: MONGO_EXPIRATION + value: {{ .Values.mongo.collection | quote }} + - name: LOG_LEVEL + value: {{ .Values.log.level | default "INFO" }} + - name: LOG_ENCODING + value: {{ .Values.log.encoding | default "json" }} + - name: HTTP_HOST + value: {{ .Values.policy.http.host | quote }} + - name: HTTP_PORT + value: {{ .Values.policy.http.port | quote }} + - name: HTTP_IDLE_TIMEOUT + value: {{ .Values.policy.http.timeout.idle | quote }} + - name: HTTP_READ_TIMEOUT + value: {{ .Values.policy.http.timeout.read | quote }} + - name: HTTP_WRITE_TIMEOUT + value: {{ .Values.policy.http.timeout.write | quote }} + - name: CACHE_ADDR + value: {{ .Values.addresses.cache | quote }} + - name: TASK_ADDR + value: {{ .Values.addresses.task | quote }} + - name: DID_RESOLVER_ADDR + value: {{ .Values.addresses.didResolver | quote }} + - name: SIGNER_ADDR + value: {{ .Values.addresses.signer | quote }} + - name: OCM_ADDR + value: {{ .Values.addresses.ocm | quote }} + {{- if .Values.extraVars }} + {{- toYaml .Values.extraVars | indent 10 }} + {{- end }} + ports: + {{- if .Values.metrics.enabled }} + - name: monitoring + containerPort: {{ .Values.metrics.port }} + {{- end }} + - name: http + containerPort: {{ .Values.policy.http.port }} + readinessProbe: + httpGet: + path: /readiness + port: {{ .Values.policy.http.port }} + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 2 + failureThreshold: 2 + timeoutSeconds: 5 + resources: +{{ toYaml .Values.resources | indent 10 }} diff --git a/deployment/helm/templates/hpa.yaml b/deployment/helm/templates/hpa.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fc5c29e7463c24756cfa83754e8ab9336be7b8c2 --- /dev/null +++ b/deployment/helm/templates/hpa.yaml @@ -0,0 +1,27 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + labels: + {{- include "app.labels" . | nindent 4 }} + name: {{ template "app.name" . }} + namespace: {{ .Release.Namespace }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "app.name" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: +{{- with .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu +{{- end }} +{{- with .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory +{{- end }} +{{- end }} \ No newline at end of file diff --git a/deployment/helm/templates/ingress.yaml b/deployment/helm/templates/ingress.yaml new file mode 100644 index 0000000000000000000000000000000000000000..23487ccf94950a184832d2e2eeb819bea29f529a --- /dev/null +++ b/deployment/helm/templates/ingress.yaml @@ -0,0 +1,29 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ template "app.name" . }} + namespace: {{ .Release.Namespace }} + annotations: +{{ toYaml .Values.ingress.annotations | indent 4 }} + labels: + {{- include "app.labels" . | nindent 4 }} +spec: +{{- if .Values.ingress.tlsEnabled }} + tls: + - hosts: + - {{ .Values.ingress.frontendDomain }} + secretName: {{ .Values.ingress.frontendTlsSecretName }} +{{- end }} + rules: + - host: {{ .Values.ingress.frontendDomain }} + http: + paths: + - path: /{{ template "app.name" . }}(/|$)(.*) + pathType: Prefix + backend: + service: + name: {{ template "app.name" . }} + port: + number: {{ .Values.service.port }} +{{- end }} \ No newline at end of file diff --git a/deployment/helm/templates/service.yaml b/deployment/helm/templates/service.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5e3f51a323dc3c9e4d0b59750fd40744e3f5d5ba --- /dev/null +++ b/deployment/helm/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "app.name" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "app.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: http + targetPort: {{ .Values.service.port }} + port: {{ .Values.policy.http.port }} + selector: + {{- include "app.selectorLabels" . | nindent 4 }} diff --git a/deployment/helm/values.yaml b/deployment/helm/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9d1cc67ecad09f15496b9db8e4faa0401d4246a5 --- /dev/null +++ b/deployment/helm/values.yaml @@ -0,0 +1,119 @@ +# -- Default number of instances to start +replicaCount: 1 +# -- Application name +name: policy +# -- Ovverwrites application name +nameOverride: "" + +image: + repository: registry.gitlab.com/gaia-x/data-infrastructure-federation-services/tsa + # -- Image name + name: policy + # -- Image tag + # Uses .Chart.AppVersion if empty + tag: "" + # -- Image sha, usually generated by the CI + # Uses image.tag if empty + sha: "" + # -- Image pull policy + pullPolicy: IfNotPresent + # -- Image pull secret when internal image is used + pullSecrets: deployment-key-light + + +podAnnotations: {} +## +## Pass extra environment variables to the container. +## +# extraVars: +# - name: EXTRA_VAR_1 +# value: extra-var-value-1 +# - name: EXTRA_VAR_2 +# value: extra-var-value-2 +## +## Create new service when true, and use the specified uner name when set to the name specified +## + +resources: + requests: + cpu: 25m + memory: 64Mi + limits: + cpu: 150m + memory: 128Mi + +## Configure pod autoscaling +## + +autoscaling: + # -- Enable autoscaling + enabled: false + # -- Minimum replicas + minReplicas: 1 + # -- Maximum replicas + maxReplicas: 3 + # -- CPU target for autoscaling trigger + targetCPUUtilizationPercentage: 70 + # -- Memory target for autoscaling trigger + targetMemoryUtilizationPercentage: 70 +## +## Prometheus Exporter / Metrics +## + +metrics: + # -- Enable prometheus metrics + enabled: true + # -- Port for prometheus metrics + port: 2112 + +log: + level: "debug" + encoding: json + +## +## Kubernetes [SecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) object. +## + +security: + # -- by default, apps run as non-root + runAsNonRoot: false + # -- User used by the apps + runAsUid: 0 + # -- Group used by the apps + runAsGid: 0 +## +## +service: + port: 8080 + +policy: + http: + host: "" + port: 8080 + timeout: + idle: 120s + read: 10s + write: 10s + +mongo: + addr: "mongodb://mongodb-mongodb-replicaset.infra:27017/policy?replicaSet=rs0&authSource=admin" + user: "" + pass: "" + dbname: policy + collection: policies + +addresses: + cache: http://cache:8080 + task: http://task:8080 + didResolver: http://didresolver:8080 + signer: http://signer:8080 + ocm: https://gaiax.vereign.com/ocm + +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/rewrite-target: /$2 + tlsEnabled: true + frontendDomain: gaiax.vereign.com + frontendTlsSecretName: cert-manager-tls