First try at Noggin deployment

Signed-off-by: Aurélien Bompard <aurelien@bompard.org>
This commit is contained in:
Aurélien Bompard 2020-08-19 12:43:06 +02:00
parent 9d9680cc73
commit 6e1873ce1b
No known key found for this signature in database
GPG key ID: 31584CFEB9BF64AD
16 changed files with 555 additions and 5 deletions

View file

@ -0,0 +1,95 @@
- name: make the app be real
hosts: os_masters[0]:os_masters_stg[0]
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:
pre_tasks:
- name: Get the IPA CA cert
slurp:
src: /etc/ipa/ca.crt
delegate_to: "{{ ipa_server }}"
register: ipa_ca_cert
roles:
- role: rabbit/user
username: "noggin{{ env_suffix }}"
- role: openshift/project
app: noggin
description: noggin
appowners:
- abompard
- pingou
tags:
- apply-appowners
when: env == "production"
- role: openshift/project
app: noggin
description: noggin
appowners:
- abompard
- pingou
- nils
- ryanlerch
tags:
- apply-appowners
when: env == "staging"
- role: openshift/secret-file
app: noggin
secret_name: fedora-messaging-ca
key: cacert.pem
privatefile: "rabbitmq/{{env}}/pki/ca.crt"
- role: openshift/secret-file
app: noggin
secret_name: fedora-messaging-crt
key: noggin-cert.pem
privatefile: "rabbitmq/{{env}}/pki/issued/noggin{{env_suffix}}.crt"
- role: openshift/secret-file
app: noggin
secret_name: fedora-messaging-key
key: noggin-key.pem
privatefile: "rabbitmq/{{env}}/pki/private/noggin{{env_suffix}}.key"
- role: openshift/imagestream
app: noggin
imagename: noggin
- role: openshift/object
app: noggin
template: buildconfig.yml
objectname: buildconfig.yml
- role: openshift/object
app: noggin
template: configmap.yml
objectname: configmap.yml
- role: openshift/object
app: noggin
file: service.yml
objectname: service.yml
- role: openshift/object
app: noggin
template: route.yml
objectname: route.yml
- role: openshift/object
app: noggin
file: secrets.yml
objectname: secrets.yml
- role: openshift/object
app: noggin
file: secret-webhook.yml
objectname: secret-webhook.yml
- role: openshift/object
app: noggin
file: deploymentconfig.yml
objectname: deploymentconfig.yml
- role: openshift/start-build
app: noggin
buildname: noggin

View file

@ -7,6 +7,7 @@
- haveged
- ipa-server
- ipa-server-dns
- ipa-fas
tags:
- ipa/server
- packages
@ -180,6 +181,16 @@
- krb5
when: ipa_initial
- name: Configure password policy
command: ipa pwpolicy-mod global_policy --maxlife=0 --minlife=0 --history=0 --minclasses=0 --minlength=0 --maxfail=0
tags:
- ipa/server
- config
when: ipa_initial
register: pwpolicy_output
changed_when: "'no modifications to be performed' not in pwpolicy_output.stderr"
failed_when: "'no modifications to be performed' not in pwpolicy_output.stderr and pwpolicy_output.rc != 0"
- name: Create fas_sync user
command: ipa user-add fas_sync --first=FAS --last=Sync
tags:
@ -200,15 +211,80 @@
changed_when: "'already a member' not in promote_output.stdout"
failed_when: "'already a member' not in promote_output.stdout and promote_output.rc != 0"
- name: Configure password policy
command: ipa pwpolicy-mod global_policy --maxlife=0 --minlife=0 --history=0 --minclasses=0 --minlength=0 --maxfail=0
# Noggin user setup
- name: Register the proper noggin admin password
set_fact:
noggin_password: "{{ (env == 'production')|ternary(noggin_admin_password, noggin_stg_admin_password) }}"
- name: Create noggin user
# Expiration date will be a Friday 13th in 30 years. I'm sure we'll remember that.
# (if unset, IPA will assume the password is expired because it hasn't been set by the user themselves)
shell: echo -e "{{ noggin_password }}\n{{ noggin_password }}" | ipa user-add noggin --first=Noggin --last=User --password --password-expiration 20500513000000Z
tags:
- ipa/server
- config
when: ipa_initial
register: pwpolicy_output
changed_when: "'no modifications to be performed' not in pwpolicy_output.stderr"
failed_when: "'no modifications to be performed' not in pwpolicy_output.stderr and pwpolicy_output.rc != 0"
register: create_output
changed_when: "'already exists' not in create_output.stderr"
failed_when: "'already exists' not in create_output.stderr and create_output.rc != 0"
- name: Create the noggin privilege
command: ipa privilege-add "Self-service Portal Administrators"
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'already exists' not in output.stdout"
failed_when: "'already exists' not in output.stdout and output.rc != 0"
- name: Setup the noggin privilege
command: ipa privilege-add-permission
"Self-service Portal Administrators"
--permissions="System: Modify Users"
--permissions="System: Change User password"
--permissions="System: Add Stage User"
--permissions="System: Read Stage Users"
--permissions="System: Modify Stage User"
--permissions="System: Modify User RDN"
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'Number of permissions added 0' not in output.stdout"
failed_when: "'Number of permissions added 0' not in output.stdout and output.rc != 0"
- name: Create the noggin role
command: ipa role-add "Self-service Portal Administrator"
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'already exists' not in output.stdout"
failed_when: "'already exists' not in output.stdout and output.rc != 0"
- name: Setup the noggin role
command: ipa role-add-privilege "Self-service Portal Administrator" --privileges="Self-service Portal Administrators"
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'Number of privileges added 0' not in output.stdout"
failed_when: "'Number of privileges added 0' not in output.stdout and output.rc != 0"
- name: Give noggin the appropriate role
command: ipa role-add-member "Self-service Portal Administrator" --user=noggin
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'Number of members added 0' not in output.stdout"
failed_when: "'Number of members added 0' not in output.stdout and output.rc != 0"
- name: Destroy admin ticket
command: kdestroy -A
@ -219,6 +295,7 @@
- krb5
when: ipa_initial
- name: Create LDIF directory
file: path=/root/ldif state=directory owner=root group=root mode=0750
tags:

View file

@ -0,0 +1,7 @@
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: noggin
namespace: aaa
labels:
app: noggin

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: noggin-web
namespace: aaa
labels:
app: noggin
spec:
ports:
- name: noggin-web
port: 8080
targetPort: 8080
selector:
app: noggin
deploymentconfig: noggin

View file

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

View file

@ -0,0 +1,70 @@
{% macro load_file(filename) %}{% include filename %}{%- endmacro -%}
---
apiVersion: v1
kind: List
metadata: {}
items:
- apiVersion: v1
kind: ConfigMap
metadata:
name: noggin-config
namespace: aaa
labels:
app: noggin
data:
noggin.cfg: |-
{{ load_file('noggin.cfg.py') | indent(6) }}
gunicorn.conf.py: |-
{{ load_file('gunicorn.conf.py') | indent(6) }}
- apiVersion: v1
kind: ConfigMap
metadata:
name: wsgi-script
namespace: aaa
labels:
app: noggin
data:
wsgi.py: |-
{{ load_file('wsgi.py') | indent(6) }}
__init__.py: ""
- apiVersion: v1
kind: ConfigMap
metadata:
name: fedora-messaging-config
namespace: aaa
labels:
app: noggin
data:
config.toml: |-
{{ load_file('fedora-messaging.toml') | indent(6) }}
- apiVersion: v1
kind: ConfigMap
metadata:
name: fedora-messaging-tls
namespace: aaa
labels:
app: noggin
data:
cacert.pem: |-
{{ load_file('fedora-messaging-ca.pem') | indent(6) }}
noggin-cert.pem: |-
{{ load_file('fedora-messaging-cert.pem') | indent(6) }}
noggin-key.pem: |-
{{ load_file('fedora-messaging-key.pem') | indent(6) }}
- apiVersion: v1
kind: ConfigMap
metadata:
name: ipa-config
namespace: aaa
data:
ldap.conf: |-
{{ load_file('ipa-ldap.conf') | indent(6) }}
default.conf: |-
{{ load_file('ipa-default.conf') | indent(6) }}
ca.crt: |-
{{ ipa_ca_cert | indent(6) }}

View file

@ -0,0 +1,122 @@
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: noggin
namespace: aaa
labels:
app: noggin
spec:
replicas: 1
selector:
app: noggin
deploymentconfig: noggin
strategy:
type: Rolling
activeDeadlineSeconds: 21600
rollingParams:
intervalSeconds: 1
maxSurge: 25%
maxUnavailable: 25%
timeoutSeconds: 600
updatePeriodSeconds: 1
template:
metadata:
creationTimestamp: null
labels:
app: noggin
deploymentconfig: noggin
spec:
containers:
- name: noggin
imagePullPolicy: Always
ports:
- containerPort: 8080
#protocol: TCP
#resources: {}
#terminationMessagePath: /dev/termination-log
#terminationMessagePolicy: File
volumeMounts:
- name: noggin-config-volume
mountPath: "/etc/noggin"
readOnly: true
- name: noggin-secrets-volume
mountPath: "/etc/noggin-secrets"
readOnly: true
- name: wsgi-script-volume
mountPath: "/opt/app-root/src/deploy"
readOnly: true
- name: fedora-messaging-config-volume
mountPath: "/etc/fedora-messaging"
readOnly: true
- name: fedora-messaging-ca-volume
mountPath: /etc/pki/fedora-messaging/cacert.pem
subPath: cacert.pem
readOnly: true
- name: fedora-messaging-crt-volume
mountPath: /etc/pki/fedora-messaging/noggin-cert.pem
subPath: noggin-cert.pem
readOnly: true
- name: fedora-messaging-key-volume
mountPath: /etc/pki/fedora-messaging/noggin-key.pem
subPath: noggin-key.pem
readOnly: true
- name: ipa-config-volume
mountPath: "/etc/ipa"
readOnly: true
env:
- name: NOGGIN_CONFIG_PATH
value: "/etc/noggin/noggin.cfg"
- name: APP_MODULE
value: "deploy.wsgi"
- name: APP_CONFIG
value: "/etc/noggin/gunicorn.conf.py"
readinessProbe:
timeoutSeconds: 10
initialDelaySeconds: 5
periodSeconds: 60
httpGet:
path: /healthz/ready
port: 8080
livenessProbe:
timeoutSeconds: 10
initialDelaySeconds: 10
periodSeconds: 60
httpGet:
path: /healthz/live
port: 8080
volumes:
- name: noggin-config-volume
configMap:
name: noggin-config
- name: noggin-secrets-volume
secret:
secretName: noggin-secrets
- name: wsgi-script-volume
configMap:
name: wsgi-script
- name: fedora-messaging-config-volume
configMap:
name: fedora-messaging-config
- name: fedora-messaging-ca-volume
secret:
secretName: fedora-messaging-ca
- name: fedora-messaging-crt-volume
secret:
secretName: fedora-messaging-crt
- name: fedora-messaging-key-volume
secret:
secretName: fedora-messaging-key
- name: ipa-config-volume
configMap:
name: ipa-config
triggers:
- imageChangeParams:
automatic: true
containerNames:
- noggin
from:
kind: ImageStreamTag
name: noggin:latest
namespace: aaa
type: ImageChange
- type: ConfigChange

View file

@ -0,0 +1,29 @@
amqp_url = "amqps://noggin:@rabbitmq{{ env_suffix }}.fedoraproject.org/%2Fpubsub"
passive_declares = true
publish_exchange = "amq.topic"
topic_prefix = ""
[tls]
ca_cert = "/etc/pki/fedora-messaging/cacert.pem"
keyfile = "/etc/pki/fedora-messaging/noggin-key.pem"
certfile = "/etc/pki/fedora-messaging/noggin-cert.pem"
[client_properties]
app = "Noggin"
[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"]
[log_config.root]
level = "WARNING"
handlers = ["console"]

View file

@ -0,0 +1 @@
timeout = 60

View file

@ -0,0 +1,8 @@
[global]
basedn = dc=freeipa-dev,dc=fedoraproject,dc=org
realm = {{ ipa_realm }}
domain = {{ ipa_realm | lower }}
server = {{ ipa_server }}
host = {{ inventory_hostname }}
xmlrpc_uri = https://{{ ipa_server }}/ipa/xml
enable_ra = True

View file

@ -0,0 +1,9 @@
SASL_NOCANON on
URI ldaps://{{ ipa_server }}
{% if env == "staging" %}
BASE dc=stg,dc=fedoraproject,dc=org
{% else %}
BASE dc=fedoraproject,dc=org
{% endif %}
TLS_CACERT /etc/ipa/ca.crt
SASL_MECH GSSAPI

View file

@ -0,0 +1,37 @@
#
# This is the config file for Noggin as intended to be used in OpenShift
#
def from_file(path):
return open(path, 'r').read().strip()
# IPA settings
FREEIPA_SERVERS = ['{{ ipa_server }}']
FREEIPA_CACERT = '/etc/ipa/ca.crt'
# Cookies
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = True
# FreeIPA
FREEIPA_ADMIN_USER = "noggin"
# How many minutes before a password reset request expires
PASSWORD_RESET_EXPIRATION = 10
# Email
MAIL_FROM = "Fedora Account System <fas@fedoraproject.org>"
MAIL_DEFAULT_SENDER = "Fedora Account System <fas@fedoraproject.org>"
MAIL_SERVER = "smtp.sendgrid.net"
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USERNAME = "apikey"
# Theme
THEME = "fas"
# Those file should be mounted from OpenShift secrets
FREEIPA_ADMIN_PASSWORD = from_file('/etc/noggin-secrets/ipa-admin')
FERNET_SECRET = from_file('/etc/noggin-secrets/fernet').encode('utf-8')
SECRET_KEY = from_file('/etc/noggin-secrets/session').encode('utf-8')
MAIL_PASSWORD = from_file('/etc/noggin-secrets/smtp')

View file

@ -0,0 +1,17 @@
apiVersion: v1
kind: Route
metadata:
name: noggin-web
namespace: aaa
labels:
app: noggin
spec:
host: account{{ env_suffix }}.fedoraproject.org
port:
targetPort: web
to:
kind: Service
name: noggin-web
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: noggin-github-webhook-secret
namespace: aaa
data:
WebHookSecretKey: "{{ (env == 'production')|ternary(noggin_github_secret, noggin_stg_github_secret) }}"
type: Opaque

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: noggin-secrets
namespace: aaa
stringData:
freeipa-admin-password: "{{ (env == 'production')|ternary(noggin_admin_password, noggin_stg_admin_password) }}"
fernet-secret: "{{ (env == 'production')|ternary(noggin_fernet_secret, noggin_stg_fernet_secret) }}"
session-secret: "{{ (env == 'production')|ternary(noggin_session_secret, noggin_stg_session_secret) }}"

View file

@ -0,0 +1,4 @@
from werkzeug.middleware.proxy_fix import ProxyFix
from noggin.app import app as application
# application.wsgi_app.add_files('/etc/noggin/well-known-files', prefix='.well-known/')
application.wsgi_app = ProxyFix(application.wsgi_app, x_proto=1, x_host=1)