From c8d4246ed9238f09f41476f58ef1f48e6589c8ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Denquin?= Date: Mon, 30 Dec 2024 13:25:11 +0100 Subject: [PATCH] feat(workers): Add dedicated billing worker (#130) --- templates/api-deployment.yaml | 4 +- templates/billing-worker-deployment.yaml | 239 +++++++++++++++++++++++ templates/clock-deployment.yaml | 3 +- templates/events-worker-deployment.yaml | 5 +- templates/migrate-job.yaml | 5 +- templates/webhook-worker-deployment.yaml | 5 +- templates/worker-deployment.yaml | 5 +- values.yaml | 31 ++- 8 files changed, 281 insertions(+), 16 deletions(-) create mode 100644 templates/billing-worker-deployment.yaml diff --git a/templates/api-deployment.yaml b/templates/api-deployment.yaml index d89efe6..9f160a4 100644 --- a/templates/api-deployment.yaml +++ b/templates/api-deployment.yaml @@ -71,7 +71,7 @@ spec: - --for=condition=complete - --timeout=180s containers: - - args: ["bundle", "exec", "rails", "s", "-b", "::"] + - args: ["./scripts/start.api.sh"] env: - name: RAILS_ENV value: {{ .Values.api.rails.env }} @@ -144,6 +144,8 @@ spec: value: {{ .Values.api.rails.logLevel | quote }} - name: SIDEKIQ_WEBHOOK value: {{ .Values.webhookWorker.enabled | quote }} + - name: SIDEKIQ_BILLING + value: {{ .Values.billingWorker.enabled | quote }} {{- with .Values.api.extraEnv }} {{- range $key, $value := . }} - name: {{ $key }} diff --git a/templates/billing-worker-deployment.yaml b/templates/billing-worker-deployment.yaml new file mode 100644 index 0000000..790d57f --- /dev/null +++ b/templates/billing-worker-deployment.yaml @@ -0,0 +1,239 @@ +{{- if .Values.billingWorker.enabled -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + io.lago.service: {{ .Release.Name }}-billing-worker + name: {{ .Release.Name }}-billing-worker +spec: + replicas: {{ .Values.billingWorker.replicas }} + selector: + matchLabels: + io.lago.service: {{ .Release.Name }}-billing-worker + strategy: + type: Recreate + template: + metadata: + labels: + io.lago.service: {{ .Release.Name }}-billing-worker + {{- range $key, $value := .Values.billingWorker.podLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + annotations: + {{- range $key, $value := .Values.billingWorker.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + {{- with .Values.billingWorker.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.billingWorker.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.billingWorker.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + initContainers: + {{ if .Values.redis.enabled }} + - name: wait-for-redis + image: "docker.io/bitnami/kubectl:{{ include "kubectlVersion" . }}" + args: + - wait + - pod/{{ .Release.Name }}-redis-master-0 + - --for=condition=ready + - --timeout=180s + {{ end }} + - name: wait-for-migrations + image: "docker.io/bitnami/kubectl:{{ include "kubectlVersion" . }}" + args: + - wait + - job/{{ include "migrateJobName" . }} + - --for=condition=complete + - --timeout=180s + containers: + - args: ["./scripts/start.billing.worker.sh"] + env: + - name: RAILS_ENV + value: {{ .Values.billingWorker.rails.env }} + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: {{ include "secret-path" . }} + key: databaseUrl + - name: REDIS_URL + valueFrom: + secretKeyRef: + name: {{ include "secret-path" . }} + key: redisUrl + - name: LAGO_REDIS_CACHE_URL + valueFrom: + secretKeyRef: + name: {{ include "secret-path" . }} + key: redisUrl + - name: LAGO_PDF_URL + {{- $pdfHost := printf "%s-pdf-svc.%s" .Release.Name .Release.Namespace }} + value: {{ printf "http://%s:%v" $pdfHost .Values.pdf.service.port | quote }} + - name: LAGO_API_URL + value: {{ required "apiUrl value is required" .Values.apiUrl | quote }} + - name: LAGO_FRONT_URL + value: {{ required "frontUrl value is required" .Values.frontUrl | quote }} + - name: RAILS_LOG_TO_STDOUT + value: {{ .Values.billingWorker.rails.logStdout | quote }} + - name: LAGO_RSA_PRIVATE_KEY + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secrets + key: rsaPrivateKey + - name: SECRET_KEY_BASE + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secrets + key: secretKeyBase + - name: ENCRYPTION_DETERMINISTIC_KEY + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secrets + key: encryptionDeterministicKey + - name: ENCRYPTION_KEY_DERIVATION_SALT + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secrets + key: encryptionKeyDerivationSalt + - name: ENCRYPTION_PRIMARY_KEY + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secrets + key: encryptionPrimaryKey + - name: LAGO_DISABLE_SEGMENT + value: {{ not .Values.global.segment.enabled | quote }} + - name: DATABASE_POOL + value: {{ .Values.billingWorker.rails.sidekiqConcurrency | quote }} + - name: SIDEKIQ_CONCURRENCY + value: {{ .Values.billingWorker.rails.sidekiqConcurrency | quote }} + - name: LAGO_LOG_LEVEL + value: {{ .Values.billingWorker.rails.logLevel | quote }} + - name: SIDEKIQ_WEBHOOK + value: {{ .Values.webhookWorker.enabled | quote }} + - name: SIDEKIQ_BILLING + value: {{ .Values.billingWorker.enabled | quote }} + {{- with .Values.billingWorker.extraEnv }} + {{- range $key, $value := . }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{ if .Values.global.license }} + - name: LAGO_LICENSE + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secrets + key: license + {{ end }} + + {{ if or .Values.global.s3.enabled .Values.minio.enabled }} + - name: LAGO_USE_AWS_S3 + value: "true" + {{- if .Values.minio.enabled }} + - name: LAGO_AWS_S3_PATH_STYLE + value: "true" + {{- end }} + {{- if or .Values.global.s3.endpoint .Values.minio.endpoint }} + - name: LAGO_AWS_S3_ENDPOINT + value: {{ if .Values.minio.enabled }} + {{ .Values.minio.endpoint | quote }} + {{ else }} + {{ .Values.global.s3.endpoint | quote }} + {{ end }} + {{- end }} + {{- if or .Values.global.s3.accessKeyId .Values.minio.enabled .Values.global.existingSecret }} + - name: LAGO_AWS_S3_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: {{ if .Values.minio.enabled }} + {{ .Release.Name }}-minio + {{ else }} + {{ include "secret-path" . }} + {{ end }} + key: {{ if .Values.minio.enabled }} + rootUser + {{ else }} + awsS3AccessKeyId + {{ end }} + {{- end }} + {{- if or .Values.global.s3.secretAccessKey .Values.minio.enabled .Values.global.existingSecret }} + - name: LAGO_AWS_S3_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: {{ if .Values.minio.enabled }} + {{ .Release.Name }}-minio + {{ else }} + {{ include "secret-path" . }} + {{ end }} + key: {{ if .Values.minio.enabled }} + rootPassword + {{ else }} + awsS3SecretAccessKey + {{ end }} + {{- end }} + - name: LAGO_AWS_S3_BUCKET + value: {{ if .Values.minio.enabled }} + {{ (index .Values.minio.buckets 0).name | quote }} + {{ else }} + {{ .Values.global.s3.bucket | quote }} + {{ end }} + - name: LAGO_AWS_S3_REGION + value: {{ if .Values.global.s3.enabled }} + {{ .Values.global.s3.region | quote }} + {{ else if .Values.minio.enabled }} + {{ default "us-east-1" .Values.minio.region | quote }} + {{ end }} + {{ end }} + + {{ if .Values.global.smtp.enabled }} + - name: LAGO_FROM_EMAIL + value: {{ .Values.global.smtp.fromEmail }} + - name: LAGO_SMTP_ADDRESS + value: {{ .Values.global.smtp.address }} + - name: LAGO_SMTP_USERNAME + valueFrom: + secretKeyRef: + name: {{ include "secret-path" . }} + key: smtpUsername + - name: LAGO_SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "secret-path" . }} + key: smtpPassword + - name: LAGO_SMTP_PORT + value: "{{ .Values.global.smtp.port }}" + {{ end }} + {{ if .Values.global.newRelic.enabled }} + - name: NEW_RELIC_KEY + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secrets + key: newRelicKey + {{ end }} + image: getlago/api:v{{ .Values.version }} + name: {{ .Release.Name }}-billing-worker + {{- with .Values.billingWorker.resources }} + resources: + {{- toYaml . | nindent 12}} + {{- end }} + {{ if and (not .Values.global.s3.enabled) (not .Values.minio.enabled) }} + volumeMounts: + - mountPath: /app/storage + name: {{ .Release.Name }}-storage-data + {{ end }} + restartPolicy: Always + {{ if and (not .Values.global.s3.enabled) (not .Values.minio.enabled) }} + volumes: + - name: {{ .Release.Name }}-storage-data + persistentVolumeClaim: + claimName: {{ .Release.Name }}-storage-data + {{ end }} + serviceAccountName: {{ .Values.global.serviceAccountName | default (printf "%s-serviceaccount" .Release.Name) }} +{{- end -}} \ No newline at end of file diff --git a/templates/clock-deployment.yaml b/templates/clock-deployment.yaml index d9d9712..3c5e7d5 100644 --- a/templates/clock-deployment.yaml +++ b/templates/clock-deployment.yaml @@ -46,8 +46,7 @@ spec: - --timeout=180s {{ end }} containers: - - args: - - ./scripts/start.clock.sh + - args: ["./scripts/start.clock.sh"] env: - name: RAILS_ENV value: {{ .Values.clock.rails.env }} diff --git a/templates/events-worker-deployment.yaml b/templates/events-worker-deployment.yaml index cd4657d..704a0c1 100644 --- a/templates/events-worker-deployment.yaml +++ b/templates/events-worker-deployment.yaml @@ -53,8 +53,7 @@ spec: - --for=condition=complete - --timeout=180s containers: - - args: - - ./scripts/start.events.worker.sh + - args: ["./scripts/start.events.worker.sh"] env: - name: RAILS_ENV value: {{ .Values.eventsWorker.rails.env }} @@ -108,6 +107,8 @@ spec: value: {{ .Values.eventsWorker.rails.logLevel | quote }} - name: SIDEKIQ_WEBHOOK value: {{ .Values.webhookWorker.enabled | quote }} + - name: SIDEKIQ_BILLING + value: {{ .Values.billingWorker.enabled | quote}} {{- with .Values.eventsWorker.extraEnv }} {{- range $key, $value := . }} - name: {{ $key }} diff --git a/templates/migrate-job.yaml b/templates/migrate-job.yaml index 3b1c425..541f3d3 100644 --- a/templates/migrate-job.yaml +++ b/templates/migrate-job.yaml @@ -44,10 +44,7 @@ spec: - name: lago-migrate image: getlago/api:v{{ .Values.version }} args: - - bundle - - exec - - rake - - db:migrate + - ./scripts/migrate.sh env: - name: RAILS_ENV value: {{ .Values.api.rails.env }} diff --git a/templates/webhook-worker-deployment.yaml b/templates/webhook-worker-deployment.yaml index 609e921..c881eaf 100644 --- a/templates/webhook-worker-deployment.yaml +++ b/templates/webhook-worker-deployment.yaml @@ -54,8 +54,7 @@ spec: - --for=condition=complete - --timeout=180s containers: - - args: - - ./scripts/start.webhook.worker.sh + - args: ["./scripts/start.webhook.worker.sh"] env: - name: RAILS_ENV value: {{ .Values.webhookWorker.rails.env }} @@ -107,6 +106,8 @@ spec: value: {{ .Values.webhookWorker.rails.sidekiqConcurrency | quote }} - name: SIDEKIQ_WEBHOOK value: "true" + - name: SIDEKIQ_BILLING + value: {{ .Values.billingWorker.enabled | quote }} - name: LAGO_LOG_LEVEL value: {{ .Values.webhookWorker.rails.logLevel | quote }} {{- with .Values.webhookWorker.extraEnv }} diff --git a/templates/worker-deployment.yaml b/templates/worker-deployment.yaml index 186b81a..f69c8c5 100644 --- a/templates/worker-deployment.yaml +++ b/templates/worker-deployment.yaml @@ -53,8 +53,7 @@ spec: - --for=condition=complete - --timeout=180s containers: - - args: - - ./scripts/start.worker.sh + - args: ["./scripts/start.worker.sh"] env: - name: RAILS_ENV value: {{ .Values.worker.rails.env }} @@ -117,6 +116,8 @@ spec: value: {{ .Values.worker.rails.logLevel | quote }} - name: SIDEKIQ_WEBHOOK value: {{ .Values.webhookWorker.enabled | quote }} + - name: SIDEKIQ_BILLING + value: {{ .Values.billingWorker.enabled | quote}} {{- with .Values.worker.extraEnv }} {{- range $key, $value := . }} - name: {{ $key }} diff --git a/values.yaml b/values.yaml index e909dba..83d61df 100644 --- a/values.yaml +++ b/values.yaml @@ -81,9 +81,10 @@ global: ingress: enabled: false - #frontHostname: - #apiHostname: - #className: + frontHostname: + apiHostname: + className: + annotations: {} networkPolicy: enabled: false @@ -215,6 +216,30 @@ pdf: nodeSelector: {} affinity: {} +billingWorker: + enabled: true + replicas: 1 + rails: + sidekiqConcurrency: 10 + env: 'production' + logStdout: true + logLevel: info + resources: + requests: + memory: 1Gi + cpu: '1100m' + podAnnotations: {} + podLabels: {} + extraEnv: {} + livenessProbe: + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + tolerations: [] + nodeSelector: {} + affinity: {} + webhookWorker: enabled: true replicas: 1