# _helpers.tpl
{{/* vim: set filetype=mustache: */}}
{{/*
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).
*/}}
{{- define "locust.fullname" -}}
{{- printf "%s-%s" .Release.Name "locust" | trunc 63 -}}
{{- end -}}

{{- define "locust.master-svc" -}}
{{- printf "%s-%s" .Release.Name "master-svc" | trunc 63 -}}
{{- end -}}

{{- define "locust.master" -}}
{{- printf "%s-%s" .Release.Name "master" | trunc 63 -}}
{{- end -}}

{{- define "locust.worker" -}}
{{- printf "%s-%s" .Release.Name "worker" | trunc 63 -}}
{{- end -}}

{{/*
Create fully qualified configmap name.
*/}}
{{- define "locust.worker-configmap" -}}
{{ if .Values.worker.config.configmapName }}
{{- printf .Values.worker.config.configmapName -}}
{{ else }}
{{- printf "%s-%s" .Release.Name "worker" -}}
{{ end }}
{{- end -}}

{{/*
Common labels
*/}}
{{- define "locust.labels" -}}
helm.sh/chart: {{ include "locust.chart" . }}
{{ include "locust.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}

{{/*
Selector labels
*/}}
{{- define "locust.selectorLabels" -}}
app.kubernetes.io/name: {{ include "locust.fullname" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
 # master-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "locust.master" . }}
  labels:
    app: {{ template "locust.fullname" . }}
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    component: master
spec:
  replicas: 1
  selector:
    matchLabels:
      {{- include "locust.selectorLabels" . | nindent 6 }}
      component: "master"
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: {{ default 1 .Values.master.maxSurge }}
      maxUnavailable: {{ default 1 .Values.master.maxUnavailable }}
  template:
    metadata:
      labels:
        {{- include "locust.selectorLabels" . | nindent 8 }}
        component: "master"
    spec:
    {{- if .Values.image.pullSecrets }}
      imagePullSecrets:
{{ toYaml .Values.image.pullSecrets | indent 8 }}
    {{- end }}
      containers:
      - name: locust
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        resources:
{{ toYaml .Values.master.resources | indent 10 }}
        env:
        {{- range $key, $value :=  .Values.master.config }}
        - name: {{ $key | upper | replace "-" "_" }}
          value: {{ $value | quote }}
        {{- end }}
        - name: LOCUST_MODE
          value: "master"
        - name: LOCUST_SCRIPT
          value: {{ index .Values.worker.config "locust-script" | quote }}
{{- if .Values.extraEnvs }}
{{ toYaml .Values.extraEnvs | indent 8 }}
{{- end }}
        ports:
        - containerPort: {{ .Values.service.internalPort }}
          name: loc-master-web
          protocol: TCP
        - containerPort: 5557
          name: loc-master-p1
          protocol: TCP
        - containerPort: 5558
          name: loc-master-p2
          protocol: TCP
        volumeMounts:
          - name: locust-tasks
            mountPath: /locust-tasks/
{{- if .Values.extraVolumeMounts }}
{{ toYaml .Values.extraVolumeMounts | indent 10 }}
{{- end }}
        livenessProbe:
          periodSeconds: 30
          httpGet:
            path: /
            port: {{ .Values.service.internalPort }}
        readinessProbe:
          periodSeconds: 30
          httpGet:
            path: /
            port: {{ .Values.service.internalPort }}
      volumes:
      - name: "locust-tasks"
        configMap:
          name: {{ template "locust.worker-configmap" . }}
{{- if .Values.extraVolumes }}
{{ toYaml .Values.extraVolumes | indent 6 }}
{{- end }}
      restartPolicy: Always
{{- with .Values.master.nodeSelector }}
      nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.master.tolerations }}
      tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
 # master-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ template "locust.master-svc" . }}
  labels:
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    app: {{ template "locust.fullname" . }}
    component: "master"
    {{- range $key, $value :=  .Values.service.extraLabels }}
    {{ $key }}: {{ $value | quote }}
    {{- end }}
  {{- if .Values.service.annotations }}
  annotations:
  {{- range $key, $value :=  .Values.service.annotations }}
    {{ $key }}: {{ $value | quote }}
  {{- end }}
  {{- end }}
spec:
  type: {{ .Values.service.type }}
  ports:
  - name: {{ .Values.service.name }}
    port: {{ .Values.service.externalPort }}
    targetPort: {{ .Values.service.internalPort }}
    nodePort: {{ .Values.service.nodePort }}
    protocol: TCP
  - name: master-p1
    port: 5557
    protocol: TCP
    targetPort: 5557
  - name: master-p2
    port: 5558
    protocol: TCP
    targetPort: 5558
  selector:
    app.kubernetes.io/name: {{ include "locust.fullname" . }}
    component: "master"
  sessionAffinity: None
 # worker-cm.yaml
{{ if not .Values.worker.config.configmapName }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ template "locust.worker-configmap" . }}
  labels:
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    app: {{ template "locust.fullname" . }}
data:
{{ (.Files.Glob "tasks/*").AsConfig | indent 2 }}
{{ end }} # worker-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "locust.worker" . }}
  labels:
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    app: {{ template "locust.fullname" . }}
    component: worker
spec:
  replicas: {{ default 2 .Values.worker.replicaCount }}
  selector:
    matchLabels:
      {{- include "locust.selectorLabels" . | nindent 6 }}
      component: worker
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: {{ default 1 .Values.worker.maxSurge }}
      maxUnavailable: {{ default 1 .Values.worker.maxUnavailable }}
  template:
    metadata:
      labels:
        {{- include "locust.selectorLabels" . | nindent 8 }}
        component: worker
    spec:
    {{- if .Values.image.pullSecrets }}
      imagePullSecrets:
{{ toYaml .Values.image.pullSecrets | indent 8 }}
    {{- end }}
      containers:
      - name: locust
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        volumeMounts:
          - name: locust-tasks
            mountPath: /locust-tasks/
{{- if .Values.extraVolumeMounts }}
{{ toYaml .Values.extraVolumeMounts | indent 10 }}
{{- end }}
        env:
        {{- range $key, $value :=  .Values.worker.config }}
        - name: {{ $key | upper | replace "-" "_" }}
          value: {{ $value | quote }}
        {{- end }}
        - name: LOCUST_MODE
          value: "worker"
        - name: LOCUST_MASTER
          value: {{ template "locust.master-svc" . }}
        - name: LOCUST_MASTER_WEB
          value: "{{ .Values.service.internalPort }}"
        - name: TARGET_HOST
          value: {{ index .Values.master.config "target-host" | quote }}
{{- if .Values.extraEnvs }}
{{ toYaml .Values.extraEnvs | indent 8 }}
{{- end }}
        resources:
{{ toYaml .Values.worker.resources | indent 10 }}
      restartPolicy: Always
      volumes:
        - name: "locust-tasks"
          configMap:
            name: {{ template "locust.worker-configmap" . }}
{{- if .Values.extraVolumes }}
{{ toYaml .Values.extraVolumes | indent 8 }}
{{- end }}
{{- with .Values.worker.nodeSelector }}
      nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.worker.tolerations }}
      tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.worker.affinity }}
      affinity:
{{ toYaml . | indent 8 }}
{{- end }}
Name: locust

image:
  repository: greenbirdit/locust
  tag: 0.9.0
  pullPolicy: IfNotPresent
  pullSecrets: []

service:
  name: master-web
  type: NodePort
  externalPort: 8089
  internalPort: 8089
  nodePort: 0
  annotations: {}
  extraLabels: {}

# extra volumes, volumeMounts and envs for both worker and master pods
extraVolumes: []
# extraVolumes:
# - name: mySecretVolume
#   secret:
#     secretName: mySecret
# - name: myConfigMapVolume
#   configMap:
#     name: myConfigMap
extraVolumeMounts: []
# extraVolumeMounts:
# - name: mySecretVolume
#   mountPath: /locust/secrets/mySecretVolume/
extraEnvs: []
# extraEnvs:
# - name: HELLO
#   value: WORLD
# - name: MY_SECRET
#   valueFrom:
#     secretKeyRef:
#       name: mySecret
#       key: mySecretKey

master:
  config:
    target-host: https://site.example.com
  resources:
    limits:
      cpu: 100m
      memory: 128Mi
    requests:
      cpu: 100m
      memory: 128Mi
  nodeSelector: {}
    # kops.k8s.io/instancegroup: master
  tolerations: []
  # - key: "application"
  #   operator: "Equal"
  #   value: "api"
  #   effect: "NoSchedule"
worker:
  config:

    # Optional parameter to use an existing configmap instead of deploying one with the Chart
    # configmapName: locust-worker-configs

    # all files from specified configmap (or tasks folder) are mounted under `/locust-tasks`
    locust-script: "/locust-tasks/tasks.py"
  replicaCount: 2
  resources:
    limits:
      cpu: 100m
      memory: 128Mi
    requests:
      cpu: 100m
      memory: 128Mi
  nodeSelector: {}
    # kops.k8s.io/instancegroup: worker
  tolerations: []
  # - key: "application"
  #   operator: "Equal"
  #   value: "api"
  #   effect: "NoSchedule"
  #
  #
  affinity: {}
  #  podAntiAffinity:
  #    requiredDuringSchedulingIgnoredDuringExecution:
  #    - topologyKey: kubernetes.io/hostname
  #      labelSelector:
  #        matchLabels:
  #          component: worker
