Skip to content

swh/production: Add web-webhooks deployment

Guillaume Samson requested to merge web_webhooks_production into production

Related to swh/infra/sysadm-environment#5374 (closed)

These modifications will delete the current ingress web-archive-ingress-webhooks pointing to the web-archive service and will create a deployment web-webhooks and an ingress web-webhooks-ingress-webhooks to be used by Svix-server as a endpoint.

Helm-diff
[swh] Comparing changes between branches production and web_webhooks_production (per environment)...
Your branch is up to date with 'origin/production'.
[swh] Generate config in production branch for environment staging, namespace swh...
[swh] Generate config in production branch for environment staging, namespace swh-cassandra...
[swh] Generate config in production branch for environment staging, namespace swh-cassandra-next-version...
Your branch is up to date with 'origin/web_webhooks_production'.
[swh] Generate config in web_webhooks_production branch for environment staging...
[swh] Generate config in web_webhooks_production branch for environment staging...
[swh] Generate config in web_webhooks_production branch for environment staging...
Your branch is up to date with 'origin/production'.
[swh] Generate config in production branch for environment production, namespace swh...
[swh] Generate config in production branch for environment production, namespace swh-cassandra...
[swh] Generate config in production branch for environment production, namespace swh-cassandra-next-version...
Your branch is up to date with 'origin/web_webhooks_production'.
[swh] Generate config in web_webhooks_production branch for environment production...
[swh] Generate config in web_webhooks_production branch for environment production...
[swh] Generate config in web_webhooks_production branch for environment production...


------------- diff for environment staging namespace swh -------------

No differences


------------- diff for environment staging namespace swh-cassandra -------------

No differences


------------- diff for environment staging namespace swh-cassandra-next-version -------------

No differences


------------- diff for environment production namespace swh -------------

--- /tmp/swh-chart.swh.3yn1YBE1/production-swh.before	2024-08-09 15:45:10.864877729 +0200
+++ /tmp/swh-chart.swh.3yn1YBE1/production-swh.after	2024-08-09 15:45:11.484892375 +0200
@@ -8515,20 +8515,168 @@
     - swh.web.banners
     - swh.web.deposit
     - swh.web.inbound_email
     - swh.web.jslicenses
     - swh.web.mailmap
     - swh.web.metrics
     - swh.web.save_code_now
     - swh.web.save_origin_webhooks
     - swh.web.vault
 ---
+# Source: swh/templates/web/configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  namespace: swh
+  name: web-webhooks-configuration-template
+data:
+  config.yml.template: |
+    instance_name: archive.softwareheritage.org
+    allowed_hosts:
+      - archive.softwareheritage.org
+      - archive.internal.softwareheritage.org
+      - ${POD_IP}
+    production_server_names:
+      - archive.softwareheritage.org
+      - archive.internal.softwareheritage.org
+      - ${POD_IP}
+    storage:
+      cls: remote
+      url: http://storage-azure-read-only-rpc-ingress
+    search:
+      cls: remote
+      url: http://search-rpc-ingress
+    scheduler:
+      cls: remote
+      url: http://scheduler.internal.softwareheritage.org
+    vault:
+      cls: remote
+      url: http://vault-rpc-ingress
+    indexer_storage:
+      cls: remote
+      url: http://indexer-storage-read-only-rpc-ingress
+    counters_backend: swh-counters
+    counters:
+      cls: remote
+      url: http://counters-rpc-ingress
+    deposit:
+      private_api_url: https://deposit.softwareheritage.org/1/private/
+      private_api_user: ${DEPOSIT_USERNAME}
+      private_api_password: ${DEPOSIT_PASSWORD}
+    add_forge_now:
+      email_address: add-forge-now@archive.softwareheritage.org
+      gitlab_pipeline:
+        token: ${GITLAB_AFN_TOKEN}
+        trigger_url: https://gitlab.softwareheritage.org/api/v4/projects/474/trigger/pipeline
+
+    secret_key: "${DJANGO_SECRET_KEY}"
+    secret_key_fallbacks:
+      - "${DJANGO_SECRET_KEY_FALLBACK_1}"
+      - "${DJANGO_SECRET_KEY_FALLBACK_2}"
+    production_db:
+    
+      host: postgresql-web-rw.internal.softwareheritage.org
+      port: 5432
+      name: swh-web
+      user: swh-web
+      password: ${POSTGRESQL_PASSWORD}
+    client_config:
+      sentry_dsn: ${SWH_SENTRY_DSN}
+    throttling:
+      cache_uri: memcached:11211
+      scopes:
+        swh_api:
+          exempted_networks:
+          - 10.42.0.0/16
+          - 10.43.0.0/16
+          - 127.0.0.0/8
+          - 128.93.166.14
+          - 131.107.174.0/24
+          - 192.168.100.0/24
+          - 192.168.200.0/22
+          - 213.135.60.145
+          - 213.135.60.146
+          - 37.187.137.47
+          - 37.187.96.121
+          limiter_rate:
+            default: 120/h
+        swh_save_origin:
+          exempted_networks:
+          - 10.42.0.0/16
+          - 10.43.0.0/16
+          - 127.0.0.0/8
+          - 128.93.166.14
+          - 131.107.174.0/24
+          - 192.168.100.0/24
+          - 192.168.200.0/22
+          - 213.135.60.145
+          - 213.135.60.146
+          - 37.187.96.121
+          limiter_rate:
+            POST: 10/h
+            default: 120/h
+        swh_vault_cooking:
+          exempted_networks:
+          - 10.42.0.0/16
+          - 10.43.0.0/16
+          - 127.0.0.0/8
+          - 128.93.166.14
+          - 131.107.174.0/24
+          - 192.168.100.0/24
+          - 192.168.200.0/22
+          - 213.135.60.145
+          - 213.135.60.146
+          - 37.187.96.121
+          limiter_rate:
+            GET: 60/m
+            default: 120/h
+        swh_api_origin_search:
+          limiter_rate:
+            default: 10/m
+        swh_api_origin_visit_latest:
+          limiter_rate:
+            default: 700/m
+        swh_raw_object:
+          limiter_rate:
+            default: 120/h
+    keycloak:
+      realm_name: SoftwareHeritage
+      server_url: https://auth.softwareheritage.org/auth/
+    
+    content_display_max_size: 5242880
+    es_workers_index_url: http://esnode1.internal.softwareheritage.org:9200/swh_workers-*
+    give:
+      public_key: ${GIVE_PUBLIC_KEY}
+      token: ${GIVE_PRIVATE_TOKEN}
+    history_counters_url: http://counters-rpc-ingress/counters_history/history.json#
+    inbound_email:
+      shared_key: ${INBOUND_EMAIL_SHARED_KEY}
+    matomo:
+      site_id: 59
+      url: https://piwik.inria.fr/
+    save_code_now_webhook_secret: ${WEBHOOKS_SECRET}
+    search_config:
+      metadata_backend: swh-search
+    swh_extra_django_apps:
+    - swh.web.add_forge_now
+    - swh.web.archive_coverage
+    - swh.web.badges
+    - swh.web.banners
+    - swh.web.deposit
+    - swh.web.inbound_email
+    - swh.web.jslicenses
+    - swh.web.mailmap
+    - swh.web.metrics
+    - swh.web.save_code_now
+    - swh.web.save_origin_webhooks
+    - swh.web.vault
+---
 # Source: swh/templates/alter/deployment.yaml
 apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
   name: alter-recovery-bundles-pvc
   namespace: swh
 spec:
   storageClassName: cephfs
   accessModes:
     - ReadWriteMany
@@ -8996,20 +9144,41 @@
     app: web-archive
   ports:
     - port: 5004
       targetPort: 5004
       name: rpc
     
     - port: 80
       targetPort: 80
       name: webstatic
 ---
+# Source: swh/templates/web/service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: web-webhooks
+  namespace: swh
+  labels:
+    app: web-webhooks
+spec:
+  type: ClusterIP
+  selector:
+    app: web-webhooks
+  ports:
+    - port: 5004
+      targetPort: 5004
+      name: rpc
+    
+    - port: 80
+      targetPort: 80
+      name: webstatic
+---
 # Source: swh/templates/alter/deployment.yaml
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
     app: alter
   name: alter
   namespace: swh
 spec:
   replicas: 1
@@ -25459,20 +25628,281 @@
          items:
          - key: "config.yml.template"
            path: "config.yml.template"
       - name: static
         emptyDir: {}
       - name: config-utils
         configMap:
           name: config-utils
           defaultMode: 0555
 ---
+# Source: swh/templates/web/deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  namespace: swh
+  name: web-webhooks
+  labels:
+    app: web-webhooks
+spec:
+  revisionHistoryLimit: 2
+  selector:
+    matchLabels:
+      app: web-webhooks
+  strategy:
+    type: RollingUpdate
+    rollingUpdate:
+      maxSurge: 1
+  template:
+    metadata:
+      labels:
+        app: web-webhooks
+      annotations:
+        checksum/config: 18507c7556a59eba244275998dc690153d18aa2f5cab2cb21bb5f30adcee7abe
+        checksum/config-utils: d75ca13b805bce6a8ab59c8e24c938f2283108f6a79134f6e71db86308651dc6
+    spec:
+      affinity:
+        nodeAffinity:
+          requiredDuringSchedulingIgnoredDuringExecution:
+            nodeSelectorTerms:
+            - matchExpressions:
+              - key: swh/web
+                operator: In
+                values:
+                - "true"
+      priorityClassName: swh-frontend-rpc
+      
+      initContainers:
+        - name: prepare-configuration
+          image: container-registry.softwareheritage.org/swh/infra/swh-apps/utils:20231211.1
+          imagePullPolicy: IfNotPresent
+          command:
+          - /entrypoints/prepare-configuration.sh
+          env:
+            - name: SWH_SENTRY_DSN
+              valueFrom:
+                secretKeyRef:
+                  name: common-secrets
+                  key: web-sentry-dsn
+                  # 'name' secret should exist & include key
+                  # if the setting doesn't exist, sentry pushes will be disabled
+                  optional: false
+            - name: DEPOSIT_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  key: password
+                  name: deposit-secrets
+                  optional: false
+            - name: DEPOSIT_USERNAME
+              valueFrom:
+                secretKeyRef:
+                  key: username
+                  name: deposit-secrets
+                  optional: false
+            - name: DJANGO_SECRET_KEY
+              valueFrom:
+                secretKeyRef:
+                  key: webapp-django-secret-key
+                  name: swh-webapp-django-secret
+                  optional: false
+            - name: DJANGO_SECRET_KEY_FALLBACK_1
+              valueFrom:
+                secretKeyRef:
+                  key: webapp-django-secret-key-fallback-1
+                  name: swh-webapp-django-secret
+                  optional: false
+            - name: DJANGO_SECRET_KEY_FALLBACK_2
+              valueFrom:
+                secretKeyRef:
+                  key: webapp-django-secret-key-fallback-2
+                  name: swh-webapp-django-secret
+                  optional: false
+            - name: GITLAB_AFN_TOKEN
+              valueFrom:
+                secretKeyRef:
+                  key: gitlab_afn_token
+                  name: common-secrets
+                  optional: false
+            - name: GIVE_PRIVATE_TOKEN
+              valueFrom:
+                secretKeyRef:
+                  key: private-token
+                  name: web-give-secrets
+                  optional: false
+            - name: GIVE_PUBLIC_KEY
+              valueFrom:
+                secretKeyRef:
+                  key: public-key
+                  name: web-give-secrets
+                  optional: false
+            - name: INBOUND_EMAIL_SHARED_KEY
+              valueFrom:
+                secretKeyRef:
+                  key: web-inbound-email-shared-key
+                  name: common-secrets
+                  optional: false
+            - name: POSTGRESQL_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  key: postgres-swh-web-password
+                  name: swh-postgresql-web-secrets
+                  optional: false
+            - name: WEBHOOKS_SECRET
+              valueFrom:
+                secretKeyRef:
+                  key: webhooks-secret
+                  name: common-secrets
+                  optional: false
+          volumeMounts:
+            - name: configuration
+              mountPath: /etc/swh
+            - name: configuration-template
+              mountPath: /etc/swh/configuration-template
+            - name: config-utils
+              mountPath: /entrypoints
+              readOnly: true
+        - name: do-migration
+          image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20240806.1
+          imagePullPolicy: IfNotPresent
+          env:
+            - name: SWH_CONFIG_FILENAME
+              value: /etc/swh/config.yml
+          command:
+            - django-admin
+          args:
+            - migrate
+            - --settings=swh.web.settings.production
+          volumeMounts:
+            - name: configuration
+              mountPath: /etc/swh
+        
+        - name: prepare-static
+          image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20240806.1
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+          args:
+            - -c
+            - cp -r $PWD/.local/share/swh/web/static/ /usr/share/swh/web/static/
+          volumeMounts:
+          - name: static
+            mountPath: /usr/share/swh/web/static
+      containers:
+        - name: web-webhooks
+          resources:
+            requests:
+              memory: 6Gi
+              cpu: 500m
+          image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20240806.1
+          imagePullPolicy: IfNotPresent
+          ports:
+            - containerPort: 5004
+              name: webapp
+          readinessProbe:
+            httpGet:
+              path: /
+              port: webapp
+              httpHeaders:
+                - name: Host
+                  value: archive.softwareheritage.org
+            initialDelaySeconds: 5
+            failureThreshold: 30
+            periodSeconds: 10
+            timeoutSeconds: 30
+          livenessProbe:
+            tcpSocket:
+              port: webapp
+            initialDelaySeconds: 3
+            periodSeconds: 10
+            timeoutSeconds: 30
+          command:
+            - /bin/bash
+          args:
+            - -c
+            - /opt/swh/entrypoint.sh
+          env:
+            - name: WORKERS
+              value: "4"
+            - name: THREADS
+              value: "2"
+            - name: TIMEOUT
+              value: "3600"
+            - name: STATSD_HOST
+              value: prometheus-statsd-exporter
+            - name: STATSD_PORT
+              value: "9125"
+            - name: STATSD_TAGS
+              value: deployment:web-webhooks
+            - name: SWH_LOG_LEVEL
+              value: "INFO"
+            - name: SWH_CONFIG_FILENAME
+              value: /etc/swh/config.yml
+            - name: SWH_SENTRY_ENVIRONMENT
+              value: production
+            - name: SWH_MAIN_PACKAGE
+              value: swh.web
+            - name: SWH_SENTRY_DSN
+              valueFrom:
+                secretKeyRef:
+                  name: common-secrets
+                  key: web-sentry-dsn
+                  # 'name' secret should exist & include key
+                  # if the setting doesn't exist, sentry pushes will be disabled
+                  optional: true
+            - name: SWH_SENTRY_DISABLE_LOGGING_EVENTS
+              value: "true"
+          volumeMounts:
+          - name: configuration
+            mountPath: /etc/swh
+            readOnly: true
+        - name: nginx
+          resources:
+            requests:
+              memory: 50Mi
+              cpu: 10m
+          image: nginx:bullseye
+          imagePullPolicy: IfNotPresent
+          ports:
+            - containerPort: 80
+              name: webstatic
+          readinessProbe:
+            httpGet:
+              path: static/robots.txt
+              port: webstatic
+            initialDelaySeconds: 5
+            failureThreshold: 30
+            periodSeconds: 10
+          livenessProbe:
+            httpGet:
+              path: static/robots.txt
+              port: webstatic
+            initialDelaySeconds: 3
+            periodSeconds: 10
+          volumeMounts:
+            - name: static
+              mountPath: /usr/share/nginx/html
+      volumes:
+      - name: configuration
+        emptyDir: {}
+      - name: configuration-template
+        configMap:
+         name: web-webhooks-configuration-template
+         items:
+         - key: "config.yml.template"
+           path: "config.yml.template"
+      - name: static
+        emptyDir: {}
+      - name: config-utils
+        configMap:
+          name: config-utils
+          defaultMode: 0555
+---
 # Source: swh/templates/indexer-storage/autoscaling.yaml
 apiVersion: autoscaling/v2
 kind: HorizontalPodAutoscaler
 metadata:
   namespace: swh
   name: indexer-storage-read-only
   labels:
     app: indexer-storage-read-only
 spec:
   scaleTargetRef:
@@ -25574,20 +26004,43 @@
   minReplicas: 8
   maxReplicas: 10
   metrics:
   - type: Resource
     resource:
       name: cpu
       target:
         type: Utilization
         averageUtilization: 100
 ---
+# Source: swh/templates/web/autoscaling.yaml
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+  namespace: swh
+  name: web-webhooks
+  labels:
+    app: web-webhooks
+spec:
+  scaleTargetRef:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: web-webhooks
+  minReplicas: 4
+  maxReplicas: 8
+  metrics:
+  - type: Resource
+    resource:
+      name: cpu
+      target:
+        type: Utilization
+        averageUtilization: 100
+---
 # Source: swh/templates/counters/refresh-counters-cache-cronjob.yaml
 apiVersion: batch/v1
 kind: CronJob
 metadata:
   name: counters-refresh-counters-cache-cronjob
 spec:
   # By default, every 4h
   schedule: "0 */1 * * *"
   concurrencyPolicy: Forbid
   jobTemplate:
@@ -27727,84 +28180,60 @@
           service:
             name: web-archive
             port:
               number: 80
 ---
 # Source: swh/templates/web/ingress.yaml
 apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   namespace: swh
-  name: web-archive-ingress-webhooks
+  name: web-webhooks-ingress-webhooks
   labels:
-    app: web-archive
+    app: web-webhooks
     endpoint-definition: webhooks
   annotations: 
     cert-manager.io/cluster-issuer: letsencrypt-production-gandi
     kubernetes.io/ingress.class: nginx
     kubernetes.io/tls-acme: "true"
     nginx.ingress.kubernetes.io/limit-connections: "10"
     nginx.ingress.kubernetes.io/service-upstream: "true"
     nginx.ingress.kubernetes.io/ssl-redirect: "true"
     nginx.ingress.kubernetes.io/whitelist-source-range: 128.93.166.2/32,192.168.100.0/24
 spec:
   rules:
   - host: archive.softwareheritage.org
     http:
       paths:
       - path: /save/origin/visit/webhook
         pathType: Prefix
         backend:
           service:
-            name: web-archive
-            port:
-              number: 5004
-      
-  - host: base.softwareheritage.org
-    http:
-      paths:
-      - path: /save/origin/visit/webhook
-        pathType: Prefix
-        backend:
-          service:
-            name: web-archive
+            name: web-webhooks
             port:
               number: 5004
       
   - host: archive.internal.softwareheritage.org
     http:
       paths:
       - path: /save/origin/visit/webhook
         pathType: Prefix
         backend:
           service:
-            name: web-archive
-            port:
-              number: 5004
-      
-  - host: archive-dynamic.internal.softwareheritage.org
-    http:
-      paths:
-      - path: /save/origin/visit/webhook
-        pathType: Prefix
-        backend:
-          service:
-            name: web-archive
+            name: web-webhooks
             port:
               number: 5004
       
   tls:
   - hosts:
     - archive.softwareheritage.org
-    - base.softwareheritage.org
     - archive.internal.softwareheritage.org
-    - archive-dynamic.internal.softwareheritage.org
     secretName: swh-web-archive-crt
 ---
 # Source: swh/templates/cookers/deployment.yaml
 # Set useJsonLogger to false to let the logs be plain text
 ---
 # Source: swh/templates/listers/deployment.yaml
 # Set useJsonLogger to false to let the logs be plain text
 ---
 # Source: swh/templates/loaders/deployment.yaml
 # if defined at the "typed" loader level
@@ -30791,20 +31220,39 @@
     port: rpc
     interval: 300s
     scrapeTimeout: 60s
   selector:
     matchLabels:
       app: web-archive
   namespaceSelector:
     matchNames:
       - swh
 ---
+# Source: swh/templates/web/monitoring.yaml
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+  name: web-webhooks-metrics
+  namespace: swh
+spec:
+  endpoints:
+  - path: /metrics/prometheus/
+    port: rpc
+    interval: 300s
+    scrapeTimeout: 60s
+  selector:
+    matchLabels:
+      app: web-webhooks
+  namespaceSelector:
+    matchNames:
+      - swh
+---
 # Source: swh/templates/checker-deposit/keda-autoscaling.yaml
 apiVersion: keda.sh/v1alpha1
 kind: TriggerAuthentication
 metadata:
   name: amqp-authentication-checker-deposit
   namespace: swh
 spec:
   secretTargetRef:
   - parameter: host            # "host" is required by the scalerObject trigger metadata
     name: common-secrets


------------- diff for environment production namespace swh-cassandra -------------

No differences

I've removed unnecessary host names from the new ingress.

Merge request reports