Initial deployment of Badges in Openshift

Signed-off-by: Aurélien Bompard <aurelien@bompard.org>
This commit is contained in:
Aurélien Bompard 2024-03-21 17:37:44 +01:00
parent 48bcbc6ec8
commit 06dbfa9654
No known key found for this signature in database
GPG key ID: 31584CFEB9BF64AD
9 changed files with 644 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 }}"

View file

@ -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) }}

View file

@ -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

View file

@ -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"]

View file

@ -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"]

View file

@ -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 %}