swh: Support dynamic webapp configuration
This inlines the webapp configuration as we do for other templates. So we can reuse most of the existing "configurationRef".
This also adds the cronjob to update the save-code-now statuses (currently implemented as a timer in the static infra).
New secrets have been added in the k8s-private-data for {production,staging}-cassandra.yaml & minikube. So this can be merged. There will be redeployment as the order in the configmap is surely different than what's currently deployed (so hash is different so it will be rolling upgraded). But the resulting deployment will be equivalent nonetheless.
Tests are happy:
make minikube
-
make swh-helm-diff
[1] make swh-test
[1]
make swh-helm-diff
[swh] Comparing changes between branches production and webapp...
Switched to branch 'production'
Your branch is up to date with 'origin/production'.
[swh] Generate config in production branch for swh/values/default.yaml...
[swh] Generate config in production branch for swh/values/minikube.yaml...
[swh] Generate config in production branch for swh/values/production-cassandra.yaml...
[swh] Generate config in production branch for swh/values/production.yaml...
[swh] Generate config in production branch for swh/values/staging-cassandra.yaml...
[swh] Generate config in production branch for swh/values/staging.yaml...
Switched to branch 'webapp'
Your branch is ahead of 'origin/webapp' by 1 commit.
(use "git push" to publish your local commits)
[swh] Generate config in webapp branch for swh/values/default.yaml...
[swh] Generate config in webapp branch for swh/values/minikube.yaml...
[swh] Generate config in webapp branch for swh/values/production-cassandra.yaml...
[swh] Generate config in webapp branch for swh/values/production.yaml...
[swh] Generate config in webapp branch for swh/values/staging-cassandra.yaml...
[swh] Generate config in webapp branch for swh/values/staging.yaml...
------------- diff for swh/values/default.yaml -------------
No differences
------------- diff for swh/values/minikube.yaml -------------
No differences
------------- diff for swh/values/production-cassandra.yaml -------------
--- /tmp/swh-chart.swh.G891rP93/production-cassandra.yaml.before 2023-10-05 12:19:21.384028588 +0200
+++ /tmp/swh-chart.swh.G891rP93/production-cassandra.yaml.after 2023-10-05 12:19:22.548029743 +0200
@@ -893,20 +893,138 @@
if [ -e "${DB_VERSION}" ]; then
echo "Unable to find the code version"
exit 1
fi
if [ "$DB_VERSION" -ne "$CODE_VERSION" ]; then
echo "code and DB versions are different. Blocking the deployment"
exit 1
fi
---
+# Source: swh/templates/web/configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ namespace: swh-cassandra
+ name: web-configuration-template
+data:
+ config.yml.template: |
+ storage:
+ cls: remote
+ url: http://storage:5002
+ search:
+ cls: remote
+ url: http://moma.internal.softwareheritage.org:5010
+ scheduler:
+ cls: remote
+ url: http://scheduler.internal.softwareheritage.org:80
+ vault:
+ cls: remote
+ url: http://vangogh.euwest.azure.internal.softwareheritage.org:5005/
+ indexer_storage:
+ cls: remote
+ url: http://saam.internal.softwareheritage.org:5007/
+ counters_backend: swh-counters
+ counters:
+ cls: remote
+ url: http://counters1.internal.softwareheritage.org:5011/
+
+ secret_key: ${DJANGO_SECRET_KEY}
+ 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
+ add_forge_now:
+ email_address: add-forge-now@archive.softwareheritage.org
+ allowed_hosts:
+ - webapp-cassandra.internal.softwareheritage.org
+ 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://counters1.internal.softwareheritage.org:5011/counters_history/history.json#
+ instance_name: webapp-cassandra.internal.softwareheritage.org
+ keycloak:
+ realm_name: SoftwareHeritage
+ server_url: https://auth.softwareheritage.org/auth/
+ 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/charts/keda/templates/crds/crd-clustertriggerauthentications.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.0
labels:
app.kubernetes.io/name: keda-operator
helm.sh/chart: keda-2.11.0
app.kubernetes.io/component: operator
@@ -12539,64 +12657,101 @@
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
template:
metadata:
labels:
app: web
+ annotations:
+ checksum/config: a2002452e950674e079d529d30d26ca9647cecfe1d5407c97dfca676baff6bd9
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: swh/web
operator: In
values:
- "true"
priorityClassName: swh-cassandra-frontend-rpc
initContainers:
- # - name: prepare-configuration
- # image: debian:bullseye
- # imagePullPolicy: IfNotPresent
- # command:
- # - /bin/bash
- # args:
- # - -c
- # - eval echo "\"$(</etc/softwareheritage/configuration-template/config.yml.template)\"" > /etc/softwareheritage/config.yml
- # volumeMounts:
- # - name: configuration
- # mountPath: /etc/softwareheritage
- # - name: configuration-template
- # mountPath: /etc/softwareheritage/configuration-template
+ - name: prepare-configuration
+ image: debian:bullseye
+ imagePullPolicy: IfNotPresent
+ command:
+ - /bin/bash
+ args:
+ - -c
+ - eval echo "\"$(</etc/swh/configuration-template/config.yml.template)\"" > /etc/swh/config.yml
+ env:
+
+ - name: DJANGO_SECRET_KEY
+ valueFrom:
+ secretKeyRef:
+ name:
+ key: webapp-django-secret-key
+ # 'name' secret must exist & include that ^ key
+ optional: false
+
+
+ - name: GIVE_PRIVATE_TOKEN
+ valueFrom:
+ secretKeyRef:
+ name: web-give-secrets
+ key: private-token
+ # 'name' secret must exist & include that ^ key
+ optional: false
+ - name: GIVE_PUBLIC_KEY
+ valueFrom:
+ secretKeyRef:
+ name: web-give-secrets
+ key: public-key
+ # 'name' secret must exist & include that ^ key
+ optional: false
+
+ - 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
+
+ volumeMounts:
+ - name: configuration
+ mountPath: /etc/swh
+ - name: configuration-template
+ mountPath: /etc/swh/configuration-template
- name: prepare-static
- image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20231003.1
+ image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20231004.3
imagePullPolicy: IfNotPresent
command:
- - /bin/bash
+ - /bin/bash
args:
- - -c
- - cp -r $PWD/.local/share/swh/web/static/ /usr/share/swh/web/static/
+ - -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
resources:
requests:
memory: 500Mi
cpu: 500m
- image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20231003.1
+ image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20231004.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5004
name: webapp
readinessProbe:
httpGet:
path: /
port: webapp
httpHeaders:
- name: Host
@@ -12609,48 +12764,59 @@
httpGet:
path: /
port: webapp
httpHeaders:
- name: Host
value: webapp-cassandra.internal.softwareheritage.org
initialDelaySeconds: 3
periodSeconds: 10
timeoutSeconds: 30
command:
- - /bin/bash
+ - /bin/bash
args:
- - -c
- - /srv/swh/entrypoint.sh
+ - -c
+ - /opt/swh/entrypoint.sh
env:
- name: STATSD_HOST
value: prometheus-statsd-exporter
- name: STATSD_PORT
value: "9125"
- name: 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"
+
+ - name: DJANGO_SECRET_KEY
+ valueFrom:
+ secretKeyRef:
+ name:
+ key: webapp-django-secret-key
+ # 'name' secret must exist & include that ^ key
+ optional: false
+
volumeMounts:
- name: configuration
- mountPath: /etc/softwareheritage
+ mountPath: /etc/swh
readOnly: true
- name: nginx
resources:
requests:
memory: 500Mi
cpu: 500m
image: nginx:bullseye
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
@@ -12661,40 +12827,32 @@
port: webstatic
initialDelaySeconds: 5
failureThreshold: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: static/robots.txt
port: webstatic
initialDelaySeconds: 3
periodSeconds: 10
- # command:
- # - /bin/bash
- # args:
- # - -c
- # - /srv/swh/entrypoint.sh
volumeMounts:
- - name: static
- mountPath: /usr/share/nginx/html
+ - name: static
+ mountPath: /usr/share/nginx/html
volumes:
- name: configuration
- secret:
- secretName: swh-cassandra-webapp-config
- #- name: configuration
- # emptyDir: {}
- #- name: configuration-template
- # configMap:
- # name: web-configuration-template
- # items:
- # - key: "config.yml.template"
- # path: "config.yml.template"
+ emptyDir: {}
+ - name: configuration-template
+ configMap:
+ name: web-configuration-template
+ items:
+ - key: "config.yml.template"
+ path: "config.yml.template"
- name: static
emptyDir: {}
---
# Source: swh/templates/graphql/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: swh-cassandra
name: graphql-ingress
annotations:
------------- diff for swh/values/production.yaml -------------
No differences
------------- diff for swh/values/staging-cassandra.yaml -------------
--- /tmp/swh-chart.swh.G891rP93/staging-cassandra.yaml.before 2023-10-05 12:19:21.876029077 +0200
+++ /tmp/swh-chart.swh.G891rP93/staging-cassandra.yaml.after 2023-10-05 12:19:23.028030220 +0200
@@ -3425,20 +3425,81 @@
if [ -e "${DB_VERSION}" ]; then
echo "Unable to find the code version"
exit 1
fi
if [ "$DB_VERSION" -ne "$CODE_VERSION" ]; then
echo "code and DB versions are different. Blocking the deployment"
exit 1
fi
---
+# Source: swh/templates/web/configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ namespace: swh-cassandra
+ name: web-configuration-template
+data:
+ config.yml.template: |
+ storage:
+ cls: remote
+ url: http://storage:5002
+ search:
+ cls: remote
+ url: http://search0.internal.staging.swh.network:5010
+ scheduler:
+ cls: remote
+ url: http://scheduler.internal.staging.swh.network:80
+ vault:
+ cls: remote
+ url: http://vault.internal.staging.swh.network:5005/
+ indexer_storage:
+ cls: remote
+ url: http://storage1.internal.staging.swh.network:5007/
+ counters_backend: swh-counters
+ counters:
+ cls: remote
+ url: http://counters0.internal.staging.swh.network:5011/
+
+ secret_key: ${DJANGO_SECRET_KEY}
+ client_config:
+ sentry_dsn: ${SWH_SENTRY_DSN}
+ add_forge_now:
+ email_address: add-forge-now@webapp.staging.swh.network
+ allowed_hosts:
+ - webapp-cassandra.internal.staging.swh.network
+ content_display_max_size: 5242880
+ give:
+ public_key: ${GIVE_PUBLIC_KEY}
+ token: ${GIVE_PRIVATE_TOKEN}
+ history_counters_url: http://counters0.internal.staging.swh.network:5011/counters_history/history.json
+ instance_name: webapp-cassandra.internal.staging.swh.network
+ keycloak:
+ realm_name: SoftwareHeritageStaging
+ server_url: https://auth.softwareheritage.org/auth/
+ matomo: {}
+ 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/charts/keda/templates/crds/crd-clustertriggerauthentications.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.0
labels:
app.kubernetes.io/name: keda-operator
helm.sh/chart: keda-2.11.0
app.kubernetes.io/component: operator
@@ -19371,64 +19432,101 @@
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
template:
metadata:
labels:
app: web
+ annotations:
+ checksum/config: 5d5e556085b982849f17c80c17f7e3cb894b17886ce4e33c4d1918bf9a04beac
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: swh/web
operator: In
values:
- "true"
priorityClassName: swh-cassandra-frontend-rpc
initContainers:
- # - name: prepare-configuration
- # image: debian:bullseye
- # imagePullPolicy: IfNotPresent
- # command:
- # - /bin/bash
- # args:
- # - -c
- # - eval echo "\"$(</etc/softwareheritage/configuration-template/config.yml.template)\"" > /etc/softwareheritage/config.yml
- # volumeMounts:
- # - name: configuration
- # mountPath: /etc/softwareheritage
- # - name: configuration-template
- # mountPath: /etc/softwareheritage/configuration-template
+ - name: prepare-configuration
+ image: debian:bullseye
+ imagePullPolicy: IfNotPresent
+ command:
+ - /bin/bash
+ args:
+ - -c
+ - eval echo "\"$(</etc/swh/configuration-template/config.yml.template)\"" > /etc/swh/config.yml
+ env:
+
+ - name: DJANGO_SECRET_KEY
+ valueFrom:
+ secretKeyRef:
+ name:
+ key: webapp-django-secret-key
+ # 'name' secret must exist & include that ^ key
+ optional: false
+
+
+ - name: GIVE_PRIVATE_TOKEN
+ valueFrom:
+ secretKeyRef:
+ name: web-give-secrets
+ key: private-token
+ # 'name' secret must exist & include that ^ key
+ optional: false
+ - name: GIVE_PUBLIC_KEY
+ valueFrom:
+ secretKeyRef:
+ name: web-give-secrets
+ key: public-key
+ # 'name' secret must exist & include that ^ key
+ optional: false
+
+ - 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
+
+ volumeMounts:
+ - name: configuration
+ mountPath: /etc/swh
+ - name: configuration-template
+ mountPath: /etc/swh/configuration-template
- name: prepare-static
- image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20231003.1
+ image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20231004.3
imagePullPolicy: IfNotPresent
command:
- - /bin/bash
+ - /bin/bash
args:
- - -c
- - cp -r $PWD/.local/share/swh/web/static/ /usr/share/swh/web/static/
+ - -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
resources:
requests:
memory: 500Mi
cpu: 500m
- image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20231003.1
+ image: container-registry.softwareheritage.org/swh/infra/swh-apps/web:20231004.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5004
name: webapp
readinessProbe:
httpGet:
path: /
port: webapp
httpHeaders:
- name: Host
@@ -19441,48 +19539,59 @@
httpGet:
path: /
port: webapp
httpHeaders:
- name: Host
value: webapp-cassandra.internal.staging.swh.network
initialDelaySeconds: 3
periodSeconds: 10
timeoutSeconds: 30
command:
- - /bin/bash
+ - /bin/bash
args:
- - -c
- - /srv/swh/entrypoint.sh
+ - -c
+ - /opt/swh/entrypoint.sh
env:
- name: STATSD_HOST
value: prometheus-statsd-exporter
- name: STATSD_PORT
value: "9125"
- name: LOG_LEVEL
value: "INFO"
+ - name: SWH_CONFIG_FILENAME
+ value: /etc/swh/config.yml
- name: SWH_SENTRY_ENVIRONMENT
value: staging
- 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"
+
+ - name: DJANGO_SECRET_KEY
+ valueFrom:
+ secretKeyRef:
+ name:
+ key: webapp-django-secret-key
+ # 'name' secret must exist & include that ^ key
+ optional: false
+
volumeMounts:
- name: configuration
- mountPath: /etc/softwareheritage
+ mountPath: /etc/swh
readOnly: true
- name: nginx
resources:
requests:
memory: 500Mi
cpu: 500m
image: nginx:bullseye
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
@@ -19493,40 +19602,32 @@
port: webstatic
initialDelaySeconds: 5
failureThreshold: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: static/robots.txt
port: webstatic
initialDelaySeconds: 3
periodSeconds: 10
- # command:
- # - /bin/bash
- # args:
- # - -c
- # - /srv/swh/entrypoint.sh
volumeMounts:
- - name: static
- mountPath: /usr/share/nginx/html
+ - name: static
+ mountPath: /usr/share/nginx/html
volumes:
- name: configuration
- secret:
- secretName: swh-cassandra-webapp-config
- #- name: configuration
- # emptyDir: {}
- #- name: configuration-template
- # configMap:
- # name: web-configuration-template
- # items:
- # - key: "config.yml.template"
- # path: "config.yml.template"
+ emptyDir: {}
+ - name: configuration-template
+ configMap:
+ name: web-configuration-template
+ items:
+ - key: "config.yml.template"
+ path: "config.yml.template"
- name: static
emptyDir: {}
---
# Source: swh/templates/storage/autoscaling.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
namespace: swh-cassandra
name: storage
labels:
------------- diff for swh/values/staging.yaml -------------
No differences
Note: Diff with a cheat (with an local extra commit not present in the MR to keep the old :80 port on the remote scheduler url to reduce the noise)