Update helm chart to detach integrations pod (#3204)
Depends on https://github.com/grafana/oncall/pull/3203 Related to https://github.com/grafana/oncall/issues/3162
This commit is contained in:
parent
68c1b2efba
commit
24357f5ff0
21 changed files with 548 additions and 29 deletions
41
engine/engine/tests/test_views.py
Normal file
41
engine/engine/tests/test_views.py
Normal file
|
|
@ -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
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django import urls
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.http import HttpResponse, JsonResponse
|
from django.http import HttpResponse, JsonResponse
|
||||||
|
|
@ -43,7 +44,13 @@ class StartupProbeView(View):
|
||||||
dangerously_bypass_middlewares = True
|
dangerously_bypass_middlewares = True
|
||||||
|
|
||||||
def get(self, request):
|
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()
|
AlertChannelDefiningMixin().update_alert_receive_channel_cache()
|
||||||
|
|
||||||
cache.set("healthcheck", "healthcheck", 30) # Checking cache connectivity
|
cache.set("healthcheck", "healthcheck", 30) # Checking cache connectivity
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
1. Create the cluster with [kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)
|
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
|
```bash
|
||||||
kind create cluster --image kindest/node:v1.24.7 --config kind.yml
|
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
|
2. (Optional) Build oncall image locally and load it to kind cluster
|
||||||
|
|
||||||
3. ```bash
|
```bash
|
||||||
docker build ../engine -t oncall/engine:latest --target dev
|
docker build ../engine -t oncall/engine:latest --target dev
|
||||||
kind load docker-image oncall/engine:latest
|
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
|
```bash
|
||||||
helm install helm-testing \
|
helm install helm-testing \
|
||||||
|
|
@ -24,14 +38,14 @@
|
||||||
./oncall
|
./oncall
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Get credentials
|
4. Get credentials
|
||||||
|
|
||||||
```bash
|
```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 "\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"
|
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
|
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.
|
the auto-generated password on disk, and the next `helm install` will fail.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ nodes:
|
||||||
hostPort: 30001
|
hostPort: 30001
|
||||||
- containerPort: 30002
|
- containerPort: 30002
|
||||||
hostPort: 30002
|
hostPort: 30002
|
||||||
|
- containerPort: 30003
|
||||||
|
hostPort: 30003
|
||||||
# https://stackoverflow.com/a/62695918
|
# https://stackoverflow.com/a/62695918
|
||||||
extraMounts:
|
extraMounts:
|
||||||
# this basically mounts our local ./grafana-plugin (frontend) directory into the kind node
|
# this basically mounts our local ./grafana-plugin (frontend) directory into the kind node
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
value: "admin"
|
value: "admin"
|
||||||
- name: OSS
|
- name: OSS
|
||||||
value: "True"
|
value: "True"
|
||||||
|
- name: DETACHED_INTEGRATIONS_SERVER
|
||||||
|
value: {{ .Values.detached_integrations.enabled | toString | title | quote }}
|
||||||
{{- include "snippet.oncall.uwsgi" . }}
|
{{- include "snippet.oncall.uwsgi" . }}
|
||||||
- name: BROKER_TYPE
|
- name: BROKER_TYPE
|
||||||
value: {{ .Values.broker.type | default "rabbitmq" }}
|
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 }}
|
value: {{ .Values.oncall.exporter.enabled | toString | title | quote }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- 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 }}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,11 @@ Create the name of the service account to use
|
||||||
{{- printf "%s-%s" .Release.Name "redis" | trunc 63 | trimSuffix "-" }}
|
{{- printf "%s-%s" .Release.Name "redis" | trunc 63 | trimSuffix "-" }}
|
||||||
{{- end }}
|
{{- 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" }}
|
{{- define "oncall.initContainer" }}
|
||||||
- name: wait-for-db
|
- name: wait-for-db
|
||||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ spec:
|
||||||
- name: {{ .Chart.Name }}
|
- name: {{ .Chart.Name }}
|
||||||
securityContext:
|
securityContext:
|
||||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
image: {{ include "oncall.engine.image" . }}
|
||||||
{{- if .Values.oncall.devMode }}
|
{{- if .Values.oncall.devMode }}
|
||||||
command: ["python", "manage.py", "start_celery"]
|
command: ["python", "manage.py", "start_celery"]
|
||||||
{{- else }}
|
{{- else }}
|
||||||
|
|
@ -60,14 +60,7 @@ spec:
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
env:
|
env:
|
||||||
{{- include "snippet.celery.env" . | nindent 12 }}
|
{{- include "snippet.celery.env" . | nindent 12 }}
|
||||||
{{- include "snippet.oncall.env" . | nindent 12 }}
|
{{- include "snippet.oncall.engine.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 }}
|
|
||||||
{{- if .Values.celery.livenessProbe.enabled }}
|
{{- if .Values.celery.livenessProbe.enabled }}
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
exec:
|
exec:
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ spec:
|
||||||
- name: {{ .Chart.Name }}
|
- name: {{ .Chart.Name }}
|
||||||
securityContext:
|
securityContext:
|
||||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
image: {{ include "oncall.engine.image" . }}
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
{{- if .Values.oncall.devMode }}
|
{{- if .Values.oncall.devMode }}
|
||||||
command: ["sh", "-c", "uwsgi --disable-logging --py-autoreload 3 --ini uwsgi.ini"]
|
command: ["sh", "-c", "uwsgi --disable-logging --py-autoreload 3 --ini uwsgi.ini"]
|
||||||
|
|
@ -44,15 +44,7 @@ spec:
|
||||||
containerPort: 8080
|
containerPort: 8080
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
env:
|
env:
|
||||||
{{- include "snippet.oncall.env" . | nindent 12 }}
|
{{- include "snippet.oncall.engine.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 }}
|
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /health/
|
path: /health/
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ spec:
|
||||||
- name: {{ .Chart.Name }}-migrate
|
- name: {{ .Chart.Name }}-migrate
|
||||||
securityContext:
|
securityContext:
|
||||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
image: {{ include "oncall.engine.image" . }}
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
command:
|
command:
|
||||||
- /bin/sh
|
- /bin/sh
|
||||||
|
|
|
||||||
|
|
@ -53,4 +53,13 @@ spec:
|
||||||
port:
|
port:
|
||||||
number: 80
|
number: 80
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{ if .Values.detached_integrations.enabled }}
|
||||||
|
- path: /integrations
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: {{ include "oncall.detached_integrations.fullname" . }}
|
||||||
|
port:
|
||||||
|
number: 8080
|
||||||
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
|
||||||
26
helm/oncall/templates/integrations/_helpers.tpl
Normal file
26
helm/oncall/templates/integrations/_helpers.tpl
Normal file
|
|
@ -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 }}
|
||||||
99
helm/oncall/templates/integrations/deployment.yaml
Normal file
99
helm/oncall/templates/integrations/deployment.yaml
Normal file
|
|
@ -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 -}}
|
||||||
24
helm/oncall/templates/integrations/service-external.yaml
Normal file
24
helm/oncall/templates/integrations/service-external.yaml
Normal file
|
|
@ -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 }}
|
||||||
15
helm/oncall/templates/integrations/service-internal.yaml
Normal file
15
helm/oncall/templates/integrations/service-internal.yaml
Normal file
|
|
@ -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 }}
|
||||||
|
|
@ -28,7 +28,7 @@ spec:
|
||||||
- name: telegram-polling
|
- name: telegram-polling
|
||||||
securityContext:
|
securityContext:
|
||||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
image: {{ include "oncall.engine.image" . }}
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
command: ['sh', '-c', 'python manage.py start_telegram_polling']
|
command: ['sh', '-c', 'python manage.py start_telegram_polling']
|
||||||
env:
|
env:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -25,6 +25,8 @@ telegramPolling.enabled=true -> should create telegram polling deployment:
|
||||||
value: admin
|
value: admin
|
||||||
- name: OSS
|
- name: OSS
|
||||||
value: "True"
|
value: "True"
|
||||||
|
- name: DETACHED_INTEGRATIONS_SERVER
|
||||||
|
value: "False"
|
||||||
- name: UWSGI_LISTEN
|
- name: UWSGI_LISTEN
|
||||||
value: "1024"
|
value: "1024"
|
||||||
- name: BROKER_TYPE
|
- name: BROKER_TYPE
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ database.type=mysql -> should create initContainer for MySQL database (default):
|
||||||
value: admin
|
value: admin
|
||||||
- name: OSS
|
- name: OSS
|
||||||
value: "True"
|
value: "True"
|
||||||
|
- name: DETACHED_INTEGRATIONS_SERVER
|
||||||
|
value: "False"
|
||||||
- name: UWSGI_LISTEN
|
- name: UWSGI_LISTEN
|
||||||
value: "1024"
|
value: "1024"
|
||||||
- name: BROKER_TYPE
|
- name: BROKER_TYPE
|
||||||
|
|
@ -111,6 +113,8 @@ database.type=mysql -> should create initContainer for MySQL database (default):
|
||||||
value: admin
|
value: admin
|
||||||
- name: OSS
|
- name: OSS
|
||||||
value: "True"
|
value: "True"
|
||||||
|
- name: DETACHED_INTEGRATIONS_SERVER
|
||||||
|
value: "False"
|
||||||
- name: UWSGI_LISTEN
|
- name: UWSGI_LISTEN
|
||||||
value: "1024"
|
value: "1024"
|
||||||
- name: BROKER_TYPE
|
- name: BROKER_TYPE
|
||||||
|
|
@ -197,6 +201,8 @@ database.type=mysql -> should create initContainer for MySQL database (default):
|
||||||
value: admin
|
value: admin
|
||||||
- name: OSS
|
- name: OSS
|
||||||
value: "True"
|
value: "True"
|
||||||
|
- name: DETACHED_INTEGRATIONS_SERVER
|
||||||
|
value: "False"
|
||||||
- name: UWSGI_LISTEN
|
- name: UWSGI_LISTEN
|
||||||
value: "1024"
|
value: "1024"
|
||||||
- name: BROKER_TYPE
|
- name: BROKER_TYPE
|
||||||
|
|
@ -284,6 +290,8 @@ database.type=postgresql -> should create initContainer for PostgreSQL database:
|
||||||
value: admin
|
value: admin
|
||||||
- name: OSS
|
- name: OSS
|
||||||
value: "True"
|
value: "True"
|
||||||
|
- name: DETACHED_INTEGRATIONS_SERVER
|
||||||
|
value: "False"
|
||||||
- name: UWSGI_LISTEN
|
- name: UWSGI_LISTEN
|
||||||
value: "1024"
|
value: "1024"
|
||||||
- name: BROKER_TYPE
|
- name: BROKER_TYPE
|
||||||
|
|
@ -372,6 +380,8 @@ database.type=postgresql -> should create initContainer for PostgreSQL database:
|
||||||
value: admin
|
value: admin
|
||||||
- name: OSS
|
- name: OSS
|
||||||
value: "True"
|
value: "True"
|
||||||
|
- name: DETACHED_INTEGRATIONS_SERVER
|
||||||
|
value: "False"
|
||||||
- name: UWSGI_LISTEN
|
- name: UWSGI_LISTEN
|
||||||
value: "1024"
|
value: "1024"
|
||||||
- name: BROKER_TYPE
|
- name: BROKER_TYPE
|
||||||
|
|
@ -460,6 +470,8 @@ database.type=postgresql -> should create initContainer for PostgreSQL database:
|
||||||
value: admin
|
value: admin
|
||||||
- name: OSS
|
- name: OSS
|
||||||
value: "True"
|
value: "True"
|
||||||
|
- name: DETACHED_INTEGRATIONS_SERVER
|
||||||
|
value: "False"
|
||||||
- name: UWSGI_LISTEN
|
- name: UWSGI_LISTEN
|
||||||
value: "1024"
|
value: "1024"
|
||||||
- name: BROKER_TYPE
|
- name: BROKER_TYPE
|
||||||
|
|
|
||||||
52
helm/oncall/tests/integrations_deployment_test.yaml
Normal file
52
helm/oncall/tests/integrations_deployment_test.yaml
Normal file
|
|
@ -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
|
||||||
|
|
@ -95,6 +95,82 @@ engine:
|
||||||
# - mountPath: /mnt/redis-tls
|
# - mountPath: /mnt/redis-tls
|
||||||
# name: 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 workers pods configuration
|
||||||
celery:
|
celery:
|
||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,13 @@ grafana:
|
||||||
service:
|
service:
|
||||||
type: NodePort
|
type: NodePort
|
||||||
nodePort: 30002
|
nodePort: 30002
|
||||||
|
detached_integrations:
|
||||||
|
enabled: true
|
||||||
|
detached_integrations_service:
|
||||||
|
enabled: true
|
||||||
|
type: NodePort
|
||||||
|
port: 8080
|
||||||
|
nodePort: 30003
|
||||||
database:
|
database:
|
||||||
# can be either mysql or postgresql
|
# can be either mysql or postgresql
|
||||||
type: postgresql
|
type: postgresql
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue