diff --git a/engine/engine/tests/test_views.py b/engine/engine/tests/test_views.py new file mode 100644 index 00000000..27eeed7a --- /dev/null +++ b/engine/engine/tests/test_views.py @@ -0,0 +1,41 @@ +import sys +from importlib import import_module, reload +from unittest.mock import patch + +import pytest +from django.conf import settings +from django.urls import clear_url_caches +from rest_framework import status +from rest_framework.test import APIClient + + +def reload_urlconf(): + clear_url_caches() + if settings.ROOT_URLCONF in sys.modules: + reload(sys.modules[settings.ROOT_URLCONF]) + return import_module(settings.ROOT_URLCONF) + + +@pytest.mark.parametrize( + "detached_integrations,urlconf,is_cache_updated", + [ + (False, None, True), + (True, None, False), + (True, "engine.integrations_urls", True), + ], +) +def test_startupprobe_populates_integrations_cache(settings, detached_integrations, urlconf, is_cache_updated): + settings.DETACHED_INTEGRATIONS_SERVER = detached_integrations + if urlconf: + settings.ROOT_URLCONF = urlconf + reload_urlconf() + + client = APIClient() + + with patch( + "apps.integrations.mixins.AlertChannelDefiningMixin.update_alert_receive_channel_cache" + ) as mock_update_cache: + response = client.get("/startupprobe/") + + assert response.status_code == status.HTTP_200_OK + assert mock_update_cache.called == is_cache_updated diff --git a/engine/engine/views.py b/engine/engine/views.py index 7f3e2f5d..0022d02f 100644 --- a/engine/engine/views.py +++ b/engine/engine/views.py @@ -1,3 +1,4 @@ +from django import urls from django.conf import settings from django.core.cache import cache from django.http import HttpResponse, JsonResponse @@ -43,7 +44,13 @@ class StartupProbeView(View): dangerously_bypass_middlewares = True def get(self, request): - if cache.get(AlertChannelDefiningMixin.CACHE_KEY_DB_FALLBACK) is None: + # enable integrations cache if current engine instance is serving them + integrations_enabled = True + if settings.DETACHED_INTEGRATIONS_SERVER: + url_resolver = urls.get_resolver(urls.get_urlconf()) + integrations_enabled = url_resolver.namespace_dict.get("integrations") + + if integrations_enabled and cache.get(AlertChannelDefiningMixin.CACHE_KEY_DB_FALLBACK) is None: AlertChannelDefiningMixin().update_alert_receive_channel_cache() cache.set("healthcheck", "healthcheck", 30) # Checking cache connectivity diff --git a/helm/README.md b/helm/README.md index 8e9a4de2..f3fce708 100644 --- a/helm/README.md +++ b/helm/README.md @@ -2,7 +2,8 @@ 1. Create the cluster with [kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) - > Make sure ports 30001 and 30002 are free on your machine + > Make sure ports 30001, 30002 (Grafana, optional) and + > 30003 (detached integrations server, optional) are free on your machine ```bash kind create cluster --image kindest/node:v1.24.7 --config kind.yml @@ -10,12 +11,25 @@ 2. (Optional) Build oncall image locally and load it to kind cluster -3. ```bash - docker build ../engine -t oncall/engine:latest --target dev - kind load docker-image oncall/engine:latest + ```bash + docker build ../engine -t oncall/engine:latest --target dev + kind load docker-image oncall/engine:latest ``` -4. Install the helm chart + Also make sure to add the following lines to your `simple.yml` (you may also need to enable `devMode`): + + ```yaml + image: + repository: oncall/engine + tag: latest + pullPolicy: IfNotPresent + oncall: + devMode: true + ``` + + Alternatively you can also pass an extra `--values ./local_image.yml` in the command below. + +3. Install the helm chart ```bash helm install helm-testing \ @@ -24,14 +38,14 @@ ./oncall ``` -5. Get credentials +4. Get credentials ```bash echo "\n\nOpen Grafana on localhost:30002 with credentials - user: admin, password: $(kubectl get secret --namespace default helm-testing-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo)" echo "Open Plugins -> Grafana OnCall -> fill form: backend url: http://host.docker.internal:30001" ``` -6. Clean up +5. Clean up If you happen to `helm uninstall helm-testing` be sure to delete all the Persistent Volume Claims, as Postgres stores the auto-generated password on disk, and the next `helm install` will fail. diff --git a/helm/kind.yml b/helm/kind.yml index 0cb7db53..4b564559 100644 --- a/helm/kind.yml +++ b/helm/kind.yml @@ -8,6 +8,8 @@ nodes: hostPort: 30001 - containerPort: 30002 hostPort: 30002 + - containerPort: 30003 + hostPort: 30003 # https://stackoverflow.com/a/62695918 extraMounts: # this basically mounts our local ./grafana-plugin (frontend) directory into the kind node diff --git a/helm/oncall/templates/_env.tpl b/helm/oncall/templates/_env.tpl index 72f7d4c8..56dff3e5 100644 --- a/helm/oncall/templates/_env.tpl +++ b/helm/oncall/templates/_env.tpl @@ -19,6 +19,8 @@ value: "admin" - name: OSS value: "True" +- name: DETACHED_INTEGRATIONS_SERVER + value: {{ .Values.detached_integrations.enabled | toString | title | quote }} {{- include "snippet.oncall.uwsgi" . }} - name: BROKER_TYPE value: {{ .Values.broker.type | default "rabbitmq" }} @@ -640,3 +642,15 @@ when broker.type != rabbitmq, we do not need to include rabbitmq environment var value: {{ .Values.oncall.exporter.enabled | toString | title | quote }} {{- end }} {{- end }} + +{{- define "snippet.oncall.engine.env" -}} +{{ include "snippet.oncall.env" . }} +{{ include "snippet.oncall.slack.env" . }} +{{ include "snippet.oncall.telegram.env" . }} +{{ include "snippet.oncall.smtp.env" . }} +{{ include "snippet.oncall.twilio.env" . }} +{{ include "snippet.oncall.exporter.env" . }} +{{ include "snippet.db.env" . }} +{{ include "snippet.broker.env" . }} +{{ include "oncall.extraEnvs" . }} +{{- end }} diff --git a/helm/oncall/templates/_helpers.tpl b/helm/oncall/templates/_helpers.tpl index 8a602cc6..6486bfe5 100644 --- a/helm/oncall/templates/_helpers.tpl +++ b/helm/oncall/templates/_helpers.tpl @@ -85,6 +85,11 @@ Create the name of the service account to use {{- printf "%s-%s" .Release.Name "redis" | trunc 63 | trimSuffix "-" }} {{- end }} +{{/* Generate engine image name */}} +{{- define "oncall.engine.image" -}} +{{- printf "%s:%s" .Values.image.repository (.Values.image.tag | default .Chart.AppVersion) }} +{{- end }} + {{- define "oncall.initContainer" }} - name: wait-for-db image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" diff --git a/helm/oncall/templates/celery/deployment.yaml b/helm/oncall/templates/celery/deployment.yaml index fcf1877e..32b4245c 100644 --- a/helm/oncall/templates/celery/deployment.yaml +++ b/helm/oncall/templates/celery/deployment.yaml @@ -51,7 +51,7 @@ spec: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + image: {{ include "oncall.engine.image" . }} {{- if .Values.oncall.devMode }} command: ["python", "manage.py", "start_celery"] {{- else }} @@ -60,14 +60,7 @@ spec: imagePullPolicy: {{ .Values.image.pullPolicy }} env: {{- include "snippet.celery.env" . | nindent 12 }} - {{- include "snippet.oncall.env" . | nindent 12 }} - {{- include "snippet.oncall.slack.env" . | nindent 12 }} - {{- include "snippet.oncall.telegram.env" . | nindent 12 }} - {{- include "snippet.oncall.smtp.env" . | nindent 12 }} - {{- include "snippet.oncall.exporter.env" . | nindent 12 }} - {{- include "snippet.db.env" . | nindent 12 }} - {{- include "snippet.broker.env" . | nindent 12 }} - {{- include "oncall.extraEnvs" . | nindent 12 }} + {{- include "snippet.oncall.engine.env" . | nindent 12 }} {{- if .Values.celery.livenessProbe.enabled }} livenessProbe: exec: diff --git a/helm/oncall/templates/engine/deployment.yaml b/helm/oncall/templates/engine/deployment.yaml index 1f80c137..e94df2ba 100644 --- a/helm/oncall/templates/engine/deployment.yaml +++ b/helm/oncall/templates/engine/deployment.yaml @@ -34,7 +34,7 @@ spec: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + image: {{ include "oncall.engine.image" . }} imagePullPolicy: {{ .Values.image.pullPolicy }} {{- if .Values.oncall.devMode }} command: ["sh", "-c", "uwsgi --disable-logging --py-autoreload 3 --ini uwsgi.ini"] @@ -44,15 +44,7 @@ spec: containerPort: 8080 protocol: TCP env: - {{- include "snippet.oncall.env" . | nindent 12 }} - {{- include "snippet.oncall.slack.env" . | nindent 12 }} - {{- include "snippet.oncall.telegram.env" . | nindent 12 }} - {{- include "snippet.oncall.smtp.env" . | nindent 12 }} - {{- include "snippet.oncall.twilio.env" . | nindent 12 }} - {{- include "snippet.oncall.exporter.env" . | nindent 12 }} - {{- include "snippet.db.env" . | nindent 12 }} - {{- include "snippet.broker.env" . | nindent 12 }} - {{- include "oncall.extraEnvs" . | nindent 12 }} + {{- include "snippet.oncall.engine.env" . | nindent 12 }} livenessProbe: httpGet: path: /health/ diff --git a/helm/oncall/templates/engine/job-migrate.yaml b/helm/oncall/templates/engine/job-migrate.yaml index 861c8308..5f1b716e 100644 --- a/helm/oncall/templates/engine/job-migrate.yaml +++ b/helm/oncall/templates/engine/job-migrate.yaml @@ -58,7 +58,7 @@ spec: - name: {{ .Chart.Name }}-migrate securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + image: {{ include "oncall.engine.image" . }} imagePullPolicy: {{ .Values.image.pullPolicy }} command: - /bin/sh diff --git a/helm/oncall/templates/ingress-regular.yaml b/helm/oncall/templates/ingress-regular.yaml index d29756aa..9a5357ff 100644 --- a/helm/oncall/templates/ingress-regular.yaml +++ b/helm/oncall/templates/ingress-regular.yaml @@ -53,4 +53,13 @@ spec: port: number: 80 {{- end }} + {{ if .Values.detached_integrations.enabled }} + - path: /integrations + pathType: Prefix + backend: + service: + name: {{ include "oncall.detached_integrations.fullname" . }} + port: + number: 8080 + {{- end }} {{- end }} diff --git a/helm/oncall/templates/integrations/_helpers.tpl b/helm/oncall/templates/integrations/_helpers.tpl new file mode 100644 index 00000000..6727ed42 --- /dev/null +++ b/helm/oncall/templates/integrations/_helpers.tpl @@ -0,0 +1,26 @@ +{{/* +Maximum of 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "oncall.detached_integrations.name" -}} +{{ include "oncall.name" . | trunc 55 }}-integrations +{{- end }} + +{{- define "oncall.detached_integrations.fullname" -}} +{{ include "oncall.fullname" . | trunc 55 }}-integrations +{{- end }} + +{{/* +Integrations common labels +*/}} +{{- define "oncall.detached_integrations.labels" -}} +{{ include "oncall.labels" . }} +app.kubernetes.io/component: integrations +{{- end }} + +{{/* +Integrations selector labels +*/}} +{{- define "oncall.detached_integrations.selectorLabels" -}} +{{ include "oncall.selectorLabels" . }} +app.kubernetes.io/component: integrations +{{- end }} diff --git a/helm/oncall/templates/integrations/deployment.yaml b/helm/oncall/templates/integrations/deployment.yaml new file mode 100644 index 00000000..5e08eaf7 --- /dev/null +++ b/helm/oncall/templates/integrations/deployment.yaml @@ -0,0 +1,99 @@ +{{- if .Values.detached_integrations.enabled -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "oncall.detached_integrations.fullname" . }} + labels: + {{- include "oncall.detached_integrations.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.detached_integrations.replicaCount }} + selector: + matchLabels: + {{- include "oncall.detached_integrations.selectorLabels" . | nindent 6 }} + strategy: + {{- toYaml .Values.detached_integrations.updateStrategy | nindent 4 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + random-annotation: {{ randAlphaNum 10 | lower }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "oncall.detached_integrations.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "oncall.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + initContainers: + {{- include "oncall.initContainer" . | indent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: {{ include "oncall.engine.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.oncall.devMode }} + command: ["sh", "-c", "uwsgi --disable-logging --py-autoreload 3 --ini uwsgi.ini"] + {{- end }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + env: + {{- include "snippet.oncall.engine.env" . | nindent 12 }} + - name: ROOT_URLCONF + value: "engine.integrations_urls" + livenessProbe: + httpGet: + path: /health/ + port: http + periodSeconds: 60 + timeoutSeconds: 3 + readinessProbe: + httpGet: + path: /ready/ + port: http + periodSeconds: 60 + timeoutSeconds: 3 + startupProbe: + httpGet: + path: /startupprobe/ + port: http + periodSeconds: 10 + timeoutSeconds: 3 + resources: + {{- toYaml .Values.detached_integrations.resources | nindent 12 }} + {{- with .Values.detached_integrations.extraVolumeMounts }} + volumeMounts: {{- . | toYaml | nindent 12 }} + {{- end }} + {{- with .Values.detached_integrations.extraContainers }} + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.detached_integrations.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.detached_integrations.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.detached_integrations.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.detached_integrations.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.detached_integrations.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.detached_integrations.extraVolumes }} + volumes: {{- . | toYaml | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/helm/oncall/templates/integrations/service-external.yaml b/helm/oncall/templates/integrations/service-external.yaml new file mode 100644 index 00000000..455d4aa0 --- /dev/null +++ b/helm/oncall/templates/integrations/service-external.yaml @@ -0,0 +1,24 @@ +{{- if .Values.detached_integrations_service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "oncall.detached_integrations.fullname" . }}-external + labels: + {{- include "oncall.detached_integrations.labels" . | nindent 4 }} + {{- with .Values.detached_integrations_service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.detached_integrations_service.type }} + ports: + - port: {{ .Values.detached_integrations_service.port }} + targetPort: http + protocol: TCP + name: http + {{- if and (eq .Values.detached_integrations_service.type "NodePort") (.Values.detached_integrations_service.nodePort) }} + nodePort: {{ .Values.detached_integrations_service.nodePort }} + {{- end }} + selector: + {{- include "oncall.detached_integrations.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/oncall/templates/integrations/service-internal.yaml b/helm/oncall/templates/integrations/service-internal.yaml new file mode 100644 index 00000000..ed14d92f --- /dev/null +++ b/helm/oncall/templates/integrations/service-internal.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "oncall.detached_integrations.fullname" . }} + labels: + {{- include "oncall.detached_integrations.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + selector: + {{- include "oncall.detached_integrations.selectorLabels" . | nindent 4 }} diff --git a/helm/oncall/templates/telegram-polling/deployment.yaml b/helm/oncall/templates/telegram-polling/deployment.yaml index aba55385..acf90c97 100644 --- a/helm/oncall/templates/telegram-polling/deployment.yaml +++ b/helm/oncall/templates/telegram-polling/deployment.yaml @@ -28,7 +28,7 @@ spec: - name: telegram-polling securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + image: {{ include "oncall.engine.image" . }} imagePullPolicy: {{ .Values.image.pullPolicy }} command: ['sh', '-c', 'python manage.py start_telegram_polling'] env: diff --git a/helm/oncall/tests/__snapshot__/integrations_deployment_test.yaml.snap b/helm/oncall/tests/__snapshot__/integrations_deployment_test.yaml.snap new file mode 100644 index 00000000..b2b31638 --- /dev/null +++ b/helm/oncall/tests/__snapshot__/integrations_deployment_test.yaml.snap @@ -0,0 +1,129 @@ +detached_integrations.enabled=true -> should create integrations deployment: + 1: | + - env: + - name: BASE_URL + value: https://example.com + - name: SECRET_KEY + valueFrom: + secretKeyRef: + key: SECRET_KEY + name: oncall + - name: MIRAGE_SECRET_KEY + valueFrom: + secretKeyRef: + key: MIRAGE_SECRET_KEY + name: oncall + - name: MIRAGE_CIPHER_IV + value: 1234567890abcdef + - name: DJANGO_SETTINGS_MODULE + value: settings.helm + - name: AMIXR_DJANGO_ADMIN_PATH + value: admin + - name: OSS + value: "True" + - name: DETACHED_INTEGRATIONS_SERVER + value: "True" + - name: UWSGI_LISTEN + value: "1024" + - name: BROKER_TYPE + value: rabbitmq + - name: GRAFANA_API_URL + value: http://oncall-grafana + - name: FEATURE_SLACK_INTEGRATION_ENABLED + value: "False" + - name: FEATURE_TELEGRAM_INTEGRATION_ENABLED + value: "False" + - name: FEATURE_EMAIL_INTEGRATION_ENABLED + value: "True" + - name: EMAIL_HOST + value: null + - name: EMAIL_PORT + value: "587" + - name: EMAIL_HOST_USER + value: null + - name: EMAIL_HOST_PASSWORD + valueFrom: + secretKeyRef: + key: smtp-password + name: oncall-smtp + optional: true + - name: EMAIL_USE_TLS + value: "True" + - name: EMAIL_FROM_ADDRESS + value: null + - name: EMAIL_NOTIFICATIONS_LIMIT + value: "200" + - name: FEATURE_PROMETHEUS_EXPORTER_ENABLED + value: "False" + - name: MYSQL_HOST + value: oncall-mariadb + - name: MYSQL_PORT + value: "3306" + - name: MYSQL_DB_NAME + value: oncall + - name: MYSQL_USER + value: root + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: mariadb-root-password + name: oncall-mariadb + - name: REDIS_PROTOCOL + value: redis + - name: REDIS_HOST + value: oncall-redis-master + - name: REDIS_PORT + value: "6379" + - name: REDIS_DATABASE + value: "0" + - name: REDIS_USERNAME + value: "" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: redis-password + name: oncall-redis + - name: RABBITMQ_USERNAME + value: user + - name: RABBITMQ_PASSWORD + valueFrom: + secretKeyRef: + key: rabbitmq-password + name: oncall-rabbitmq + - name: RABBITMQ_HOST + value: oncall-rabbitmq + - name: RABBITMQ_PORT + value: "5672" + - name: RABBITMQ_PROTOCOL + value: amqp + - name: RABBITMQ_VHOST + value: "" + - name: ROOT_URLCONF + value: engine.integrations_urls + image: grafana/oncall:v1.3.39 + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /health/ + port: http + periodSeconds: 60 + timeoutSeconds: 3 + name: oncall + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /ready/ + port: http + periodSeconds: 60 + timeoutSeconds: 3 + resources: {} + securityContext: {} + startupProbe: + httpGet: + path: /startupprobe/ + port: http + periodSeconds: 10 + timeoutSeconds: 3 diff --git a/helm/oncall/tests/__snapshot__/telegram_polling_deployment_test.yaml.snap b/helm/oncall/tests/__snapshot__/telegram_polling_deployment_test.yaml.snap index c59eac17..341fa32d 100644 --- a/helm/oncall/tests/__snapshot__/telegram_polling_deployment_test.yaml.snap +++ b/helm/oncall/tests/__snapshot__/telegram_polling_deployment_test.yaml.snap @@ -25,6 +25,8 @@ telegramPolling.enabled=true -> should create telegram polling deployment: value: admin - name: OSS value: "True" + - name: DETACHED_INTEGRATIONS_SERVER + value: "False" - name: UWSGI_LISTEN value: "1024" - name: BROKER_TYPE diff --git a/helm/oncall/tests/__snapshot__/wait_for_db_test.yaml.snap b/helm/oncall/tests/__snapshot__/wait_for_db_test.yaml.snap index 7403070b..2cee70e7 100644 --- a/helm/oncall/tests/__snapshot__/wait_for_db_test.yaml.snap +++ b/helm/oncall/tests/__snapshot__/wait_for_db_test.yaml.snap @@ -25,6 +25,8 @@ database.type=mysql -> should create initContainer for MySQL database (default): value: admin - name: OSS value: "True" + - name: DETACHED_INTEGRATIONS_SERVER + value: "False" - name: UWSGI_LISTEN value: "1024" - name: BROKER_TYPE @@ -111,6 +113,8 @@ database.type=mysql -> should create initContainer for MySQL database (default): value: admin - name: OSS value: "True" + - name: DETACHED_INTEGRATIONS_SERVER + value: "False" - name: UWSGI_LISTEN value: "1024" - name: BROKER_TYPE @@ -197,6 +201,8 @@ database.type=mysql -> should create initContainer for MySQL database (default): value: admin - name: OSS value: "True" + - name: DETACHED_INTEGRATIONS_SERVER + value: "False" - name: UWSGI_LISTEN value: "1024" - name: BROKER_TYPE @@ -284,6 +290,8 @@ database.type=postgresql -> should create initContainer for PostgreSQL database: value: admin - name: OSS value: "True" + - name: DETACHED_INTEGRATIONS_SERVER + value: "False" - name: UWSGI_LISTEN value: "1024" - name: BROKER_TYPE @@ -372,6 +380,8 @@ database.type=postgresql -> should create initContainer for PostgreSQL database: value: admin - name: OSS value: "True" + - name: DETACHED_INTEGRATIONS_SERVER + value: "False" - name: UWSGI_LISTEN value: "1024" - name: BROKER_TYPE @@ -460,6 +470,8 @@ database.type=postgresql -> should create initContainer for PostgreSQL database: value: admin - name: OSS value: "True" + - name: DETACHED_INTEGRATIONS_SERVER + value: "False" - name: UWSGI_LISTEN value: "1024" - name: BROKER_TYPE diff --git a/helm/oncall/tests/integrations_deployment_test.yaml b/helm/oncall/tests/integrations_deployment_test.yaml new file mode 100644 index 00000000..51559f17 --- /dev/null +++ b/helm/oncall/tests/integrations_deployment_test.yaml @@ -0,0 +1,52 @@ +suite: test integrations deployment +templates: + - integrations/deployment.yaml +release: + name: oncall +chart: + appVersion: v1.3.39 +tests: + - it: detached_integrations.enabled=false -> should not create deployment (default) + asserts: + - hasDocuments: + count: 0 + + - it: detached_integrations.enabled=true -> should create integrations deployment + set: + detached_integrations.enabled: true + asserts: + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + metadata.name: oncall-integrations + - isSubset: + path: metadata.labels + content: + app.kubernetes.io/component: integrations + app.kubernetes.io/instance: oncall + app.kubernetes.io/name: oncall + - isSubset: + path: spec.selector.matchLabels + content: + app.kubernetes.io/component: integrations + app.kubernetes.io/instance: oncall + app.kubernetes.io/name: oncall + - isSubset: + path: spec.template.metadata.labels + content: + app.kubernetes.io/component: integrations + app.kubernetes.io/instance: oncall + app.kubernetes.io/name: oncall + - equal: + path: spec.replicas + value: 1 + - equal: + path: spec.template.spec.serviceAccountName + value: oncall + - contains: + path: spec.template.spec.initContainers + content: + name: wait-for-db + any: true + - matchSnapshot: + path: spec.template.spec.containers diff --git a/helm/oncall/values.yaml b/helm/oncall/values.yaml index 7d7a5bae..29f715f1 100644 --- a/helm/oncall/values.yaml +++ b/helm/oncall/values.yaml @@ -95,6 +95,82 @@ engine: # - mountPath: /mnt/redis-tls # name: redis-tls + +detached_integrations_service: + enabled: false + type: LoadBalancer + port: 8080 + annotations: {} + +# Integrations pods configuration +detached_integrations: + enabled: false + replicaCount: 1 + resources: + {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + ## Deployment update strategy + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy + updateStrategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 0 + type: RollingUpdate + + ## Affinity for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + affinity: {} + + ## Node labels for pod assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + nodeSelector: {} + + ## Tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: [] + + ## Topology spread constraints for pod assignment + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ + topologySpreadConstraints: [] + + ## Priority class for the pods + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/ + priorityClassName: "" + + # Extra containers which runs as sidecar + extraContainers: "" + # extraContainers: | + # - name: cloud-sql-proxy + # image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.1.2 + # args: + # - --private-ip + # - --port=5432 + # - example:europe-west3:grafana-oncall-db + + # Extra volume mounts for the container + extraVolumeMounts: [] + # - name: postgres-tls + # configMap: + # name: my-postgres-tls + # defaultMode: 0640 + # - name: redis-tls + # configMap: + # name: my-redis-tls + # defaultMode: 0640 + + # Extra volumes for the pod + extraVolumes: [] + # - mountPath: /mnt/postgres-tls + # name: postgres-tls + # - mountPath: /mnt/redis-tls + # name: redis-tls + # Celery workers pods configuration celery: replicaCount: 1 diff --git a/helm/simple.yml b/helm/simple.yml index 84456649..219c7a11 100644 --- a/helm/simple.yml +++ b/helm/simple.yml @@ -14,6 +14,13 @@ grafana: service: type: NodePort nodePort: 30002 +detached_integrations: + enabled: true +detached_integrations_service: + enabled: true + type: NodePort + port: 8080 + nodePort: 30003 database: # can be either mysql or postgresql type: postgresql