From 06dbfa965448a7a684d5bd183d53b563efbb54e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Bompard?= Date: Thu, 21 Mar 2024 17:37:44 +0100 Subject: [PATCH] Initial deployment of Badges in Openshift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Aurélien Bompard --- playbooks/openshift-apps/badges.yml | 134 ++++++++++++ .../badges/files/imagestream.yml | 29 +++ roles/openshift-apps/badges/files/service.yml | 15 ++ .../badges/templates/buildconfig.yml | 73 +++++++ .../badges/templates/configmap.yml | 17 ++ .../badges/templates/deploymentconfig.yml | 200 ++++++++++++++++++ .../badges/templates/fm-fedbadges.toml | 95 +++++++++ .../badges/templates/fm-tahrir.toml | 70 ++++++ .../badges/templates/secrets.yml | 11 + 9 files changed, 644 insertions(+) create mode 100644 playbooks/openshift-apps/badges.yml create mode 100644 roles/openshift-apps/badges/files/imagestream.yml create mode 100644 roles/openshift-apps/badges/files/service.yml create mode 100644 roles/openshift-apps/badges/templates/buildconfig.yml create mode 100644 roles/openshift-apps/badges/templates/configmap.yml create mode 100644 roles/openshift-apps/badges/templates/deploymentconfig.yml create mode 100644 roles/openshift-apps/badges/templates/fm-fedbadges.toml create mode 100644 roles/openshift-apps/badges/templates/fm-tahrir.toml create mode 100644 roles/openshift-apps/badges/templates/secrets.yml diff --git a/playbooks/openshift-apps/badges.yml b/playbooks/openshift-apps/badges.yml new file mode 100644 index 0000000000..473c78538d --- /dev/null +++ b/playbooks/openshift-apps/badges.yml @@ -0,0 +1,134 @@ +# +# Badges (fedbadges & Tahrir) +# + +--- +- name: setup the database + hosts: db01.iad2.fedoraproject.org:db01.stg.iad2.fedoraproject.org + gather_facts: no + become: yes + become_user: postgres + vars_files: + - /srv/web/infra/ansible/vars/global.yml + - /srv/private/ansible/vars.yml + - /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml + # - /srv/web/infra/ansible/vars/apps/badges.yml + + tasks: + - name: DB user + postgresql_user: + name: "{{ tahrirDBUser }}" + password: "{{ (env == 'production')|ternary(tahrirDBPassword, tahrirstgDBPassword) }}" + - name: Database creation + postgresql_db: + name: "tahrir" + owner: "{{ tahrirDBUser }}" + encoding: UTF-8 + +- name: make the app be real + # Only staging for now + # hosts: os_control_stg:os_control + hosts: os_control_stg + user: root + gather_facts: false + + vars_files: + - /srv/web/infra/ansible/vars/global.yml + - /srv/private/ansible/vars.yml + - /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml + # - /srv/web/infra/ansible/vars/apps/badges.yml + + roles: + - role: rabbit/user + username: "tahrir{{ env_suffix }}" + sent_topics: ^org\.fedoraproject\.{{ env_short }}\.badges\..* + tags: + - config + - fedora-messaging + - rabbitmq_cluster + - role: rabbit/queue + username: "fedbadges{{ env_suffix }}" + queue_name: "fedbadges{{ env_suffix }}" + routing_keys: + # The FMN queue is subscribed to everything + - "#" + thresholds: + warning: 20000 + critical: 25000 + # Fedbadges does not send messages + sent_topics: "^$" + tags: + - config + - fedora-messaging + - rabbitmq_cluster + + - role: openshift/project + app: badges + description: "Badges" + appowners: + - abompard + - nphilipp + - rlerch + tags: + - apply-appowners + + - role: openshift/object + app: badges + file: imagestream.yml + objectname: imagestream.yml + + - role: openshift/object + app: badges + template: buildconfig.yml + objectname: buildconfig.yml + + # - role: openshift/object + # app: badges + # template: secrets.yml + # objectname: secrets.yml + + - role: openshift/object + app: badges + template: configmap.yml + objectname: configmap.yml + + - role: openshift/object + app: badges + file: service.yml + objectname: service.yml + + # Routes + - role: openshift/route + app: badges + routename: frontend + host: "badges.apps.ocp{{ env_suffix }}.fedoraproject.org" + servicename: frontend + serviceport: web + annotations: + haproxy.router.openshift.io/timeout: 5m + + # Deployment config + - role: openshift/object + app: badges + file: deploymentconfig.yml + objectname: deploymentconfig.yml + + - role: openshift/start-build + app: badges + buildname: "{{ item }}" + loop: + - fedbadges + - tahrir + tags: + - never + - build + + - role: openshift/rollout + app: badges + dcname: "{{ item }}" + loop: + - fedbadges + - tahrir + tags: + - never + - rollout diff --git a/roles/openshift-apps/badges/files/imagestream.yml b/roles/openshift-apps/badges/files/imagestream.yml new file mode 100644 index 0000000000..2da36b52f6 --- /dev/null +++ b/roles/openshift-apps/badges/files/imagestream.yml @@ -0,0 +1,29 @@ +apiVersion: image.openshift.io/v1 +kind: List +items: + # The main images + - apiVersion: image.openshift.io/v1 + kind: ImageStream + metadata: + name: fedbadges + - apiVersion: image.openshift.io/v1 + kind: ImageStream + metadata: + name: tahrir + # The Python 3.10 builder image + - apiVersion: image.openshift.io/v1 + kind: ImageStream + metadata: + name: python-310 + spec: + lookupPolicy: + local: false + tags: + - name: latest + from: + kind: DockerImage + name: quay.io/fedora/python-310:latest + importPolicy: + scheduled: true + referencePolicy: + type: Source diff --git a/roles/openshift-apps/badges/files/service.yml b/roles/openshift-apps/badges/files/service.yml new file mode 100644 index 0000000000..39e63487b7 --- /dev/null +++ b/roles/openshift-apps/badges/files/service.yml @@ -0,0 +1,15 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: frontend + labels: + app: badges +spec: + ports: + - name: web + port: 8080 + targetPort: 8080 + selector: + app: badges + deploymentconfig: frontend diff --git a/roles/openshift-apps/badges/templates/buildconfig.yml b/roles/openshift-apps/badges/templates/buildconfig.yml new file mode 100644 index 0000000000..ded06e2ff5 --- /dev/null +++ b/roles/openshift-apps/badges/templates/buildconfig.yml @@ -0,0 +1,73 @@ +{% macro load_file(filename) %}{% include filename %}{%- endmacro -%} +--- +apiVersion: build.openshift.io/v1 +kind: BuildConfig +metadata: + name: fedbadges + labels: + app: badges + build: fedbadges +spec: + runPolicy: Serial + source: + type: Git + git: + uri: https://github.com/fedora-infra/fedbadges.git + # ref: {{ (env == 'production')|ternary('stable', 'staging') }} + ref: fedora-messaging + contextDir: / + strategy: + type: Source + sourceStrategy: + from: + kind: ImageStreamTag + name: python-310:latest + output: + to: + kind: ImageStreamTag + name: fedbadges:latest + triggers: + - type: ConfigChange + - type: ImageChange + # - type: GitHub + # github: + # # Not sure why secretReference does not work, but it doesn't. + # # secretReference: + # # name: github-webook + # secret: "{{ badges_stg_github_secret }}" +--- +apiVersion: build.openshift.io/v1 +kind: BuildConfig +metadata: + name: tahrir + labels: + app: badges + build: tahrir +spec: + runPolicy: Serial + source: + type: Git + git: + uri: https://github.com/fedora-infra/tahrir.git + # ref: {{ (env == 'production')|ternary('stable', 'staging') }} + ref: develop + contextDir: / + strategy: + type: Source + sourceStrategy: + from: + kind: ImageStreamTag + name: python-310:latest + output: + to: + kind: ImageStreamTag + name: tahrir:latest + triggers: + - type: ConfigChange + - type: ImageChange + # - type: GitHub + # github: + # # Not sure why secretReference does not work, but it doesn't. + # # secretReference: + # # name: github-webook + # secret: "{{ badges_stg_github_secret }}" diff --git a/roles/openshift-apps/badges/templates/configmap.yml b/roles/openshift-apps/badges/templates/configmap.yml new file mode 100644 index 0000000000..ba36fca5c0 --- /dev/null +++ b/roles/openshift-apps/badges/templates/configmap.yml @@ -0,0 +1,17 @@ +{% macro load_file(filename) %}{% include filename %}{%- endmacro -%} +--- +apiVersion: v1 +kind: List +metadata: {} +items: +- apiVersion: v1 + kind: ConfigMap + metadata: + name: badges + labels: + app: badges + data: + fm-tahrir.toml: |- + {{ load_file('fm-tahrir.toml') | indent(6) }} + fm-fedbadges.toml: |- + {{ load_file('fm-fedbadges.toml') | indent(6) }} diff --git a/roles/openshift-apps/badges/templates/deploymentconfig.yml b/roles/openshift-apps/badges/templates/deploymentconfig.yml new file mode 100644 index 0000000000..28c0be8b4e --- /dev/null +++ b/roles/openshift-apps/badges/templates/deploymentconfig.yml @@ -0,0 +1,200 @@ +--- +# Frontend component (Python/Pyramid served by gunicorn) +apiVersion: apps.openshift.io/v1 +kind: DeploymentConfig +metadata: + name: frontend + labels: + app: badges +spec: + replicas: 1 + selector: + app: badges + deploymentconfig: frontend + strategy: + type: Rolling + activeDeadlineSeconds: 21600 + rollingParams: + intervalSeconds: 1 + maxSurge: 25% + maxUnavailable: 25% + timeoutSeconds: 600 + updatePeriodSeconds: 1 + template: + metadata: + creationTimestamp: null + labels: + app: badges + deploymentconfig: frontend + spec: + containers: + - name: frontend + imagePullPolicy: Always + ports: + - containerPort: 8080 + volumeMounts: + - name: etc-badges + mountPath: "/etc/badges" + readOnly: true + - name: ipa-config-volume + mountPath: /etc/ipa + readOnly: true + - name: keytab-volume + mountPath: /etc/keytabs + readOnly: true + - name: fedora-messaging-ca-volume + mountPath: /etc/pki/fedora-messaging/ca + readOnly: true + - name: fedora-messaging-key-volume + mountPath: /etc/pki/fedora-messaging/key + readOnly: true + - name: fedora-messaging-crt-volume + mountPath: /etc/pki/fedora-messaging/crt + readOnly: true + + env: + - name: APP_MODULE + value: "deploy.wsgi" + - name: APP_CONFIG + value: "/etc/noggin/gunicorn.conf.py" + - name: OIDC_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: badges + key: oidc-client-secret + - name: KRB5_CONFIG + value: /etc/ipa/krb5.conf + - name: KRB5_CLIENT_KTNAME + value: /etc/keytabs/service.keytab + - name: FEDORA_MESSAGING_CONF + value: /etc/badges/fm-tahrir.toml + + # readinessProbe: + # timeoutSeconds: 1 + # initialDelaySeconds: 5 + # httpGet: + # path: /api/v1/healthz/ready + # port: 8080 + # livenessProbe: + # timeoutSeconds: 1 + # initialDelaySeconds: 20 + # httpGet: + # path: /api/v1/healthz/live + # port: 8080 + + volumes: + - name: etc-badges + configMap: + name: badges + - name: ipa-config-volume + configMap: + name: ipa-client-config + - name: keytab-volume + secret: + secretName: keytab + - name: fedora-messaging-ca-volume + secret: + secretName: fedora-messaging-ca + - name: fedora-messaging-key-volume + secret: + secretName: fedora-messaging-key + - name: fedora-messaging-crt-volume + secret: + secretName: fedora-messaging-crt + triggers: + - type: ConfigChange + - type: ImageChange + imageChangeParams: + automatic: true + containerNames: + - frontend + from: + kind: ImageStreamTag + name: badges:latest +--- +# Consumer component (Fedora Messaging consume command) +apiVersion: apps.openshift.io/v1 +kind: DeploymentConfig +metadata: + name: consumer + labels: + app: badges +spec: + # There can be as many as necessary + replicas: 1 + selector: + app: badges + deploymentconfig: consumer + strategy: + type: Recreate + # recreateParams: + # mid: + # execNewPod: + # command: [/opt/app-root/bin/fmn, database, sync] + # containerName: consumer + # volumes: + # - etc-badges + # failurePolicy: Abort + template: + metadata: + creationTimestamp: null + labels: + app: badges + deploymentconfig: consumer + spec: + containers: + - name: consumer + imagePullPolicy: Always + volumeMounts: + - name: etc-badges + mountPath: "/etc/badges" + readOnly: true + - name: ipa-config-volume + mountPath: /etc/ipa + readOnly: true + - name: keytab-volume + mountPath: /etc/keytabs + readOnly: true + - name: fedora-messaging-ca-volume + mountPath: /etc/pki/fedora-messaging/ca + readOnly: true + - name: fedora-messaging-key-volume + mountPath: /etc/pki/fedora-messaging/key + readOnly: true + - name: fedora-messaging-crt-volume + mountPath: /etc/pki/fedora-messaging/crt + readOnly: true + env: + - name: KRB5_CONFIG + value: /etc/ipa/krb5.conf + - name: KRB5_CLIENT_KTNAME + value: /etc/keytabs/service.keytab + volumes: + - name: etc-badges + configMap: + name: badges + - name: ipa-config-volume + configMap: + name: ipa-client-config + - name: keytab-volume + secret: + secretName: keytab + - name: fedora-messaging-ca-volume + secret: + secretName: fedora-messaging-ca + - name: fedora-messaging-key-volume + secret: + secretName: fedora-messaging-key + - name: fedora-messaging-crt-volume + secret: + secretName: fedora-messaging-crt + triggers: + - type: ConfigChange + - type: ImageChange + imageChangeParams: + automatic: true + containerNames: + - consumer + from: + kind: ImageStreamTag + name: badges:latest diff --git a/roles/openshift-apps/badges/templates/fm-fedbadges.toml b/roles/openshift-apps/badges/templates/fm-fedbadges.toml new file mode 100644 index 0000000000..131bf6e310 --- /dev/null +++ b/roles/openshift-apps/badges/templates/fm-fedbadges.toml @@ -0,0 +1,95 @@ +# +# Fedora Messaging configuration for the consumer component +# + +amqp_url = "amqps://fedbadges{{ env_suffix }}:@rabbitmq{{ env_suffix }}.fedoraproject.org/%2Fpubsub" +callback = "fedbadges.consumer:FedoraBadgesConsumer" +passive_declares = true + +[tls] +ca_cert = "/etc/pki/fedora-messaging/ca/cacert.pem" +certfile = "/etc/pki/fedora-messaging/crt/fedbadges-cert.pem" +keyfile = "/etc/pki/fedora-messaging/key/fedbadges-key.pem" + + +[client_properties] +app = "Fedbadges" + +# If the exchange or queue name has a "." in it, use quotes as seen here. +[exchanges."amq.topic"] +type = "topic" +durable = true +auto_delete = false +arguments = {} + +[queues."fedbadges{{ env_suffix }}"] +durable = true +auto_delete = false +exclusive = false +arguments = {} + +[[bindings]] +queue = "fedbadges{{ env_suffix }}" +exchange = "amq.topic" +routing_keys = ["#"] + + +[consumer_config] + +# This tells the consumer where to look for its BadgeRule definitions. It +# may be a relative or an absolute path on the file system. +badges_directory = "/var/lib/badges/badges" + +# Number of seconds to delay before consuming a message for our event loop. +# This is here to help us mitigate distributed race conditions between +# fedbadges and datanommer. +consume_delay = 1 + +# This is a sqlalchemy URI that points to the Badges DB. In +# production, this will be a postgres URI. +database_uri = "postgresql://{{ tahrirDBUser }}:{{ (env == 'production')|ternary(tahrirDBPassword, tahrirstgDBPassword) }}@db01{{ env_suffix }}.iad2.fedoraprject.org/tahrir" + +# Datanommer database URI +datanommer_db_uri = "postgresql://{{ datanommerDBUser }}:{{ (env == 'production')|ternary(datanommerDBPassword, datanommer_stg_db_password) }}@db-datanommer{{ (env == 'production')|ternary('02', '01') }}{{ env_suffix }}.iad2.fedoraproject.org/datanommer2" +datagrepper_url = "https://apps{{ env_suffix }}.fedoraproject.org/datagrepper" +distgit_hostname = "src{{ env_suffix }}.fedoraproject.org" +id_provider_hostname = "id{{ env_suffix }}.fedoraproject.org" +fasjson_base_url = "https://fasjson{{ env_suffix }}.fedoraproject.org" + + +[qos] +prefetch_size = 0 +prefetch_count = 25 + +[log_config] +version = 1 +disable_existing_loggers = true + +[log_config.formatters.simple] +format = "[%(asctime)s] [%(levelname)s %(name)s] %(message)s" + +[log_config.handlers.console] +class = "logging.StreamHandler" +formatter = "simple" +stream = "ext://sys.stdout" + +[log_config.loggers.fedbadges] +level = "DEBUG" +propagate = false +handlers = ["console"] + +[log_config.loggers.fedora_messaging] +level = "INFO" +propagate = false +handlers = ["console"] + +# Twisted is the asynchronous framework that manages the TCP/TLS connection, as well +# as the consumer event loop. When debugging you may want to lower this log level. +[log_config.loggers.twisted] +level = "INFO" +propagate = false +handlers = ["console"] + +[log_config.root] +level = "ERROR" +handlers = ["console"] diff --git a/roles/openshift-apps/badges/templates/fm-tahrir.toml b/roles/openshift-apps/badges/templates/fm-tahrir.toml new file mode 100644 index 0000000000..af468c2a38 --- /dev/null +++ b/roles/openshift-apps/badges/templates/fm-tahrir.toml @@ -0,0 +1,70 @@ +# +# Fedora Messaging configuration for the frontend +# + +amqp_url = "amqps://tahrir{{ env_suffix }}:@rabbitmq{{ env_suffix }}.fedoraproject.org/%2Fpubsub" +passive_declares = true + +# The topic_prefix configuration value will add a prefix to the topics of every sent message. +# This is used for migrating from fedmsg, and should not be used afterwards. +{% if env == "staging" %} +topic_prefix = "org.fedoraproject.stg" +{% else %} +topic_prefix = "org.fedoraproject.prod" +{% endif %} + +[tls] +ca_cert = "/etc/pki/fedora-messaging/ca/cacert.pem" +certfile = "/etc/pki/fedora-messaging/crt/tahrir-cert.pem" +keyfile = "/etc/pki/fedora-messaging/key/tahrir-key.pem" + + +[client_properties] +app = "Tahrir" + +# If the exchange or queue name has a "." in it, use quotes as seen here. +[exchanges."amq.topic"] +type = "topic" +durable = true +auto_delete = false +arguments = {} + + +[qos] +prefetch_size = 0 +prefetch_count = 25 + +[log_config] +version = 1 +disable_existing_loggers = true + +[log_config.formatters.simple] +format = "[%(levelname)s %(name)s] %(message)s" + +[log_config.handlers.console] +class = "logging.StreamHandler" +formatter = "simple" +stream = "ext://sys.stdout" + +[log_config.loggers.fedora_messaging] +level = "INFO" +propagate = false +handlers = ["console"] + +# Twisted is the asynchronous framework that manages the TCP/TLS connection, as well +# as the consumer event loop. When debugging you may want to lower this log level. +[log_config.loggers.twisted] +level = "INFO" +propagate = false +handlers = ["console"] + +# Pika is the underlying AMQP client library. When debugging you may want to +# lower this log level. +[log_config.loggers.pika] +level = "WARNING" +propagate = false +handlers = ["console"] + +[log_config.root] +level = "ERROR" +handlers = ["console"] diff --git a/roles/openshift-apps/badges/templates/secrets.yml b/roles/openshift-apps/badges/templates/secrets.yml new file mode 100644 index 0000000000..0981c7fe14 --- /dev/null +++ b/roles/openshift-apps/badges/templates/secrets.yml @@ -0,0 +1,11 @@ +--- +kind: Secret +apiVersion: v1 +metadata: + name: badges +stringData: +{% if env == 'staging' %} + oidc-client-secret: {{ badges_stg_oidc_client_secret }} +{% else %} + oidc-client-secret: {{ badges_prod_oidc_client_secret }} +{% endif %}