First attempt at a FMN deployment in staging

Signed-off-by: Aurélien Bompard <aurelien@bompard.org>
This commit is contained in:
Aurélien Bompard 2022-11-18 11:13:33 +01:00
parent 11aa396050
commit b03a8c6a93
No known key found for this signature in database
GPG key ID: 31584CFEB9BF64AD
11 changed files with 742 additions and 0 deletions

View file

@ -0,0 +1,125 @@
- 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
tasks:
- name: FMN DB user
postgresql_user:
name: fmn
password: "{{ (env == 'production')|ternary(fmn_prod_db_password, fmn_stg_db_password) }}"
- name: FMN database creation
postgresql_db:
name: fmn
owner: fmn
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
vars:
roles:
- role: openshift/project
app: fmn
description: "Fedora Messaging Notifications"
appowners:
- abompard
- ryanlerch
- nphilipp
tags:
- apply-appowners
- role: openshift/object
app: fmn
file: imagestream.yml
objectname: imagestream.yml
- role: openshift/object
app: fmn
template: buildconfig.yml
objectname: buildconfig.yml
- role: openshift/object
app: fmn
template: configmap.yml
objectname: configmap.yml
- role: openshift/object
app: fmn
file: service.yml
objectname: service.yml
- role: openshift/route
app: fmn
routename: frontend
host: "fmn.apps.ocp{{ env_suffix }}.fedoraproject.org"
servicename: frontend
serviceport: web
annotations:
haproxy.router.openshift.io/timeout: 5m
- role: openshift/route
app: fmn
routename: api
host: "fmn-api.apps.ocp{{ env_suffix }}.fedoraproject.org"
servicename: api
serviceport: web
annotations:
haproxy.router.openshift.io/timeout: 5m
- role: openshift/route
app: fmn
routename: sendria
host: "fmn-email.apps.ocp{{ env_suffix }}.fedoraproject.org"
servicename: sendria
serviceport: web
annotations:
haproxy.router.openshift.io/timeout: 5m
- role: openshift/object
app: fmn
template: secrets.yml
objectname: secrets.yml
- role: openshift/object
app: fmn
template: secret-webhook.yml
objectname: secret-webhook.yml
# Fedora Messaging
- role: openshift/secret-file
app: fmn
secret_name: fedora-messaging-ca
key: cacert.pem
privatefile: "rabbitmq/{{env}}/pki/ca.crt"
- role: openshift/secret-file
app: fmn
secret_name: fedora-messaging-crt
key: fmn-cert.pem
privatefile: "rabbitmq/{{env}}/pki/issued/fmn{{env_suffix}}.crt"
- role: openshift/secret-file
app: fmn
secret_name: fedora-messaging-key
key: fmn-key.pem
privatefile: "rabbitmq/{{env}}/pki/private/fmn{{env_suffix}}.key"
# Deployment config
- role: openshift/object
app: fmn
template: deploymentconfig.yml
objectname: deploymentconfig.yml

View file

@ -0,0 +1,33 @@
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: ImageStream
metadata:
name: fmn
- apiVersion: v1
kind: ImageStream
metadata:
name: ubi8-python-310
spec:
lookupPolicy:
local: false
tags:
- name: latest
from:
kind: DockerImage
name: registry.access.redhat.com/ubi8/python-310:latest
importPolicy:
scheduled: true
referencePolicy:
type: Source
- apiVersion: v1
kind: ImageStream
metadata:
name: sendria
spec:
tags:
- name: latest
from:
kind: DockerImage
name: hub.docker.com/msztolcman/sendria:v2.2.2.0

View file

@ -0,0 +1,45 @@
---
apiVersion: v1
kind: Service
metadata:
name: frontend
labels:
app: fmn
spec:
ports:
- name: web
port: 8080
targetPort: 8080
selector:
app: fmn
deploymentconfig: frontend
---
apiVersion: v1
kind: Service
metadata:
name: api
labels:
app: fmn
spec:
ports:
- name: web
port: 8081
targetPort: 8081
selector:
app: fmn
deploymentconfig: api
---
apiVersion: v1
kind: Service
metadata:
name: sendria
labels:
app: fmn
spec:
ports:
- name: web
port: 1080
targetPort: 1080
selector:
app: fmn
deploymentconfig: sendria

View file

@ -0,0 +1,41 @@
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
name: fmn
labels:
app: fmn
build: fmn
spec:
runPolicy: Serial
source:
type: Git
git:
uri: https://github.com/fedora-infra/fmn.git
{% if env == "staging" %}
ref: fmn-next
{% else %}
ref: stable
{% endif %}
contextDir: /
strategy:
type: Source
sourceStrategy:
from:
kind: ImageStreamTag
name: python:3.10-ubi8
namespace: openshift
output:
to:
kind: ImageStreamTag
name: fmn:latest
triggers:
- type: ConfigChange
- type: ImageChange
- type: GitHub
{% if fmn_stg_github_secret is defined and env == 'staging' %}
github:
secret: "{{ fmn_stg_github_secret }}"
{% elif fmn_github_secret is defined and env == 'production' %}
github:
secret: "{{ fmn_github_secret }}"
{% endif %}

View file

@ -0,0 +1,19 @@
{% macro load_file(filename) %}{% include filename %}{%- endmacro -%}
---
apiVersion: v1
kind: List
metadata: {}
items:
- apiVersion: v1
kind: ConfigMap
metadata:
name: fmn
labels:
app: fmn
data:
fmn.cfg: |-
{{ load_file('fmn.cfg') | indent(6) }}
consumer.toml: |-
{{ load_file('consumer.toml') | indent(6) }}
sender.toml: |-
{{ load_file('sender.toml') | indent(6) }}

View file

@ -0,0 +1,76 @@
amqp_url = "amqps://fmn{{ env_suffix }}:@rabbitmq{{ env_suffix }}.fedoraproject.org/%2Fpubsub"
callback = "fmn.consumer:Consumer"
passive_declares = true
[tls]
ca_cert = "/etc/pki/rabbitmq/ca/rabbitmq-ca.crt"
keyfile = "/etc/pki/rabbitmq/key/rabbitmq-fmn.key"
certfile = "/etc/pki/rabbitmq/crt/rabbitmq-fmn.crt"
[client_properties]
app = "FMN consumer"
# 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.fmn]
durable = true
auto_delete = false
exclusive = false
arguments = {}
[[bindings]]
queue = "fmn"
exchange = "amq.topic"
routing_keys = ["#"]
[consumer_config]
settings_file = "/etc/fmn/fmn.cfg"
[consumer_config.send_queue]
url = "amqps://fmn{{ env_suffix }}:@rabbitmq{{ env_suffix }}.fedoraproject.org/%2Ffmn"
[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,328 @@
---
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: frontend
labels:
app: fmn
spec:
replicas: 1
selector:
app: fmn
deploymentconfig: frontend
strategy:
type: Rolling
activeDeadlineSeconds: 21600
rollingParams:
intervalSeconds: 1
maxSurge: 25%
maxUnavailable: 25%
timeoutSeconds: 600
updatePeriodSeconds: 1
template:
metadata:
creationTimestamp: null
labels:
app: fmn
deploymentconfig: frontend
spec:
containers:
- name: frontend
imagePullPolicy: Always
ports:
- containerPort: 8080
volumeMounts:
- name: httpdir-volume
mountPath: /httpdir
env:
- name: APP_SCRIPT
value: ".s2i/run-frontend.sh"
volumes:
- name: httpdir-volume
emptyDir: {}
triggers:
- type: ImageChange
imageChangeParams:
automatic: true
containerNames:
- frontend
from:
kind: ImageStreamTag
name: fmn:latest
- type: ConfigChange
---
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: api
labels:
app: fmn
spec:
replicas: 1
selector:
app: fmn
deploymentconfig: api
strategy:
type: Rolling
activeDeadlineSeconds: 21600
rollingParams:
intervalSeconds: 1
maxSurge: 25%
maxUnavailable: 25%
timeoutSeconds: 600
updatePeriodSeconds: 1
template:
metadata:
creationTimestamp: null
labels:
app: fmn
deploymentconfig: api
spec:
containers:
- name: api
imagePullPolicy: Always
ports:
- containerPort: 8081
volumeMounts:
- name: etc-fmn
mountPath: "/etc/fmn"
readOnly: true
env:
- name: APP_SCRIPT
value: ".s2i/run-api.sh"
- name: OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: fmn
key: oidc-client-secret
volumes:
- name: etc-fmn
configMap:
name: fmn-config
- name: rabbitmq-ca-volume
mountPath: /etc/pki/rabbitmq/ca
readOnly: true
- name: rabbitmq-key-volume
mountPath: /etc/pki/rabbitmq/key
readOnly: true
- name: rabbitmq-crt-volume
mountPath: /etc/pki/rabbitmq/crt
readOnly:
- name: rabbitmq-ca-volume
secret:
secretName: rabbitmq-ca
- name: rabbitmq-key-volume
secret:
secretName: rabbitmq-key
- name: rabbitmq-crt-volume
secret:
secretName: rabbitmq-cert
triggers:
- type: ImageChange
imageChangeParams:
automatic: true
containerNames:
- api
from:
kind: ImageStreamTag
name: fmn:latest
- type: ConfigChange
---
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: consumer
labels:
app: fmn
spec:
# There can be as many as necessary
replicas: 1
selector:
app: fmn
deploymentconfig: consumer
strategy:
# TODO: not rolling
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
app: fmn
deploymentconfig: consumer
spec:
containers:
- name: consumer
imagePullPolicy: Always
volumeMounts:
- name: etc-fmn
mountPath: "/etc/fmn"
readOnly: true
- name: rabbitmq-ca-volume
mountPath: /etc/pki/rabbitmq/ca
readOnly: true
- name: rabbitmq-key-volume
mountPath: /etc/pki/rabbitmq/key
readOnly: true
- name: rabbitmq-crt-volume
mountPath: /etc/pki/rabbitmq/crt
readOnly: true
env:
- name: APP_SCRIPT
value: ".s2i/run-consumer.sh"
volumes:
- name: etc-fmn
configMap:
name: fmn-config
- name: rabbitmq-ca-volume
mountPath: /etc/pki/rabbitmq/ca
readOnly: true
- name: rabbitmq-key-volume
mountPath: /etc/pki/rabbitmq/key
readOnly: true
- name: rabbitmq-crt-volume
mountPath: /etc/pki/rabbitmq/crt
readOnly:
- name: rabbitmq-ca-volume
secret:
secretName: rabbitmq-ca
- name: rabbitmq-key-volume
secret:
secretName: rabbitmq-key
- name: rabbitmq-crt-volume
secret:
secretName: rabbitmq-cert
triggers:
- type: ImageChange
imageChangeParams:
automatic: true
containerNames:
- consumer
from:
kind: ImageStreamTag
name: fmn:latest
- type: ConfigChange
---
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: sender-email
labels:
app: fmn
spec:
# For IRC there can be only one. For email there can be many.
replicas: 1
selector:
app: fmn
deploymentconfig: sender-email
strategy:
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
app: fmn
deploymentconfig: sender-email
spec:
containers:
- name: sender-email
imagePullPolicy: Always
volumeMounts:
- name: etc-fmn
mountPath: "/etc/fmn"
readOnly: true
- name: rabbitmq-ca-volume
mountPath: /etc/pki/rabbitmq/ca
readOnly: true
- name: rabbitmq-key-volume
mountPath: /etc/pki/rabbitmq/key
readOnly: true
- name: rabbitmq-crt-volume
mountPath: /etc/pki/rabbitmq/crt
readOnly: true
env:
- name: APP_SCRIPT
value: ".s2i/run-sender-email.sh"
volumes:
- name: etc-fmn
configMap:
name: fmn-config
- name: rabbitmq-ca-volume
mountPath: /etc/pki/rabbitmq/ca
readOnly: true
- name: rabbitmq-key-volume
mountPath: /etc/pki/rabbitmq/key
readOnly: true
- name: rabbitmq-crt-volume
mountPath: /etc/pki/rabbitmq/crt
readOnly:
- name: rabbitmq-ca-volume
secret:
secretName: rabbitmq-ca
- name: rabbitmq-key-volume
secret:
secretName: rabbitmq-key
- name: rabbitmq-crt-volume
secret:
secretName: rabbitmq-cert
triggers:
- type: ImageChange
imageChangeParams:
automatic: true
containerNames:
- sender-email
from:
kind: ImageStreamTag
name: fmn:latest
- type: ConfigChange
---
apiVersion: v1
kind: DeploymentConfig
metadata:
labels:
app: fmn
service: sendria
name: sendria
spec:
replicas: 1
selector:
app: fmn
deploymentconfig: sendria
strategy:
type: Recreate
template:
metadata:
labels:
app: fmn
deploymentconfig: sendria
spec:
containers:
- name: sendria
image: sendria:latest
ports:
- containerPort: 1025
- containerPort: 1080
resources: {}
readinessProbe:
timeoutSeconds: 1
initialDelaySeconds: 30
httpGet:
path: /
port: 1080
livenessProbe:
timeoutSeconds: 1
initialDelaySeconds: 40
httpGet:
path: /
port: 1080
triggers:
- type: ConfigChange
- type: ImageChange
imageChangeParams:
automatic: true
containerNames:
- sendria
from:
kind: ImageStreamTag
name: sendria:latest

View file

@ -0,0 +1,9 @@
DATABASE__SQLALCHEMY__URL="postgresql://fmn:{{ (env == 'production')|ternary(fmn_prod_db_password, fmn_stg_db_password) }}@db-datanommer01{{ env_suffix }}.iad2.fedoraproject.org/fmn2"
CORS_ORIGINS="https://fmn.apps.ocp{{ env_suffix }}.fedoraproject.org"
OIDC_PROVIDER_URL="https://id{{ env_suffix }}.fedoraproject.org/openidc"
OIDC_CONF_ENDPOINT="/.well-known/openid-configuration"
OIDC_TOKEN_INFO_ENDPOINT="/TokenInfo"
OIDC_CLIENT_ID="fmn"
# OIDC_CLIENT_SECRET is set in the environement by the deploymentconfig
SERVICES__FASJSON_URL=https://fasjson{{ env_suffix }}.fedoraproject.org
SERVICES__DISTGIT_URL=https://src{{ env_suffix }}.fedoraproject.org

View file

@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: fmn-github-webhook-secret
data:
WebHookSecretKey: "{{ (env == 'production')|ternary(fmn_prod_github_secret, fmn_stg_github_secret) }}"
type: Opaque

View file

@ -0,0 +1,13 @@
---
kind: Secret
apiVersion: v1
metadata:
name: fmn
stringData:
{% if env == 'staging' %}
oidc-client-secret: {{ fmn_stg_oidc_client_secret }}
redis-password: {{ fmn_stg_redis_password }}
{% else %}
oidc-client-secret: {{ fmn_prod_oidc_client_secret }}
redis-password: {{ fmn_prod_redis_password }}
{% endif %}

View file

@ -0,0 +1,46 @@
# A sample configuration for the FMN sender. This file is in the TOML format.
amqp_url = "amqps://fmn{{ env_suffix }}:@rabbitmq{{ env_suffix }}.fedoraproject.org/%2Ffmn"
queue = "email"
[handler]
class = "fmn.sender.email:EmailHandler"
# class = "fmn.sender.irc:IRCHandler"
from = "FMN <fmn{{ env_suffix }}@fedoraproject.org>"
# smtp_host = "bastion{{ env_suffix }}.iad2.fedoraproject.org"
smtp_host = "sendria.fmn.svc.cluster.local"
smtp_port = 1025
# irc_url = "ircs://fedora-notif:fmnpassword@irc.libera.chat:6697"
[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.fmn]
level = "DEBUG"
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.loggers.irc]
level = "DEBUG"
propagate = false
handlers = ["console"]
[log_config.root]
level = "ERROR"
handlers = ["console"]