diff --git a/playbooks/openshift-apps/fmn.yml b/playbooks/openshift-apps/fmn.yml new file mode 100644 index 0000000000..914b4d9e68 --- /dev/null +++ b/playbooks/openshift-apps/fmn.yml @@ -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 diff --git a/roles/openshift-apps/fmn/files/imagestream.yml b/roles/openshift-apps/fmn/files/imagestream.yml new file mode 100644 index 0000000000..4f650faca8 --- /dev/null +++ b/roles/openshift-apps/fmn/files/imagestream.yml @@ -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 diff --git a/roles/openshift-apps/fmn/files/service.yml b/roles/openshift-apps/fmn/files/service.yml new file mode 100644 index 0000000000..5270eda15a --- /dev/null +++ b/roles/openshift-apps/fmn/files/service.yml @@ -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 diff --git a/roles/openshift-apps/fmn/templates/buildconfig.yml b/roles/openshift-apps/fmn/templates/buildconfig.yml new file mode 100644 index 0000000000..3589b75441 --- /dev/null +++ b/roles/openshift-apps/fmn/templates/buildconfig.yml @@ -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 %} diff --git a/roles/openshift-apps/fmn/templates/configmap.yml b/roles/openshift-apps/fmn/templates/configmap.yml new file mode 100644 index 0000000000..fe26120d6c --- /dev/null +++ b/roles/openshift-apps/fmn/templates/configmap.yml @@ -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) }} diff --git a/roles/openshift-apps/fmn/templates/consumer.toml b/roles/openshift-apps/fmn/templates/consumer.toml new file mode 100644 index 0000000000..7b78ac0243 --- /dev/null +++ b/roles/openshift-apps/fmn/templates/consumer.toml @@ -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"] diff --git a/roles/openshift-apps/fmn/templates/deploymentconfig.yml b/roles/openshift-apps/fmn/templates/deploymentconfig.yml new file mode 100644 index 0000000000..61de80964b --- /dev/null +++ b/roles/openshift-apps/fmn/templates/deploymentconfig.yml @@ -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 diff --git a/roles/openshift-apps/fmn/templates/fmn.cfg b/roles/openshift-apps/fmn/templates/fmn.cfg new file mode 100644 index 0000000000..52fde1c545 --- /dev/null +++ b/roles/openshift-apps/fmn/templates/fmn.cfg @@ -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 diff --git a/roles/openshift-apps/fmn/templates/secret-webhook.yml b/roles/openshift-apps/fmn/templates/secret-webhook.yml new file mode 100644 index 0000000000..67d396f327 --- /dev/null +++ b/roles/openshift-apps/fmn/templates/secret-webhook.yml @@ -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 diff --git a/roles/openshift-apps/fmn/templates/secret.yml b/roles/openshift-apps/fmn/templates/secret.yml new file mode 100644 index 0000000000..09492116d5 --- /dev/null +++ b/roles/openshift-apps/fmn/templates/secret.yml @@ -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 %} diff --git a/roles/openshift-apps/fmn/templates/sender.toml b/roles/openshift-apps/fmn/templates/sender.toml new file mode 100644 index 0000000000..e99236df8b --- /dev/null +++ b/roles/openshift-apps/fmn/templates/sender.toml @@ -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 " +# 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"]