diff --git a/apps/rabbitmq/templates/statefulset.yaml b/apps/rabbitmq/templates/statefulset.yaml index 04183cdc..599e6da8 100644 --- a/apps/rabbitmq/templates/statefulset.yaml +++ b/apps/rabbitmq/templates/statefulset.yaml @@ -17,7 +17,7 @@ spec: app: rabbitmq spec: containers: - - image: rabbitmq:3.13.7-management-alpine + - image: rabbitmq:4.2.1-management-alpine imagePullPolicy: Always name: rabbitmq ports: diff --git a/infra/clusterroles/Chart.yaml b/infra/clusterroles/Chart.yaml new file mode 100644 index 00000000..7dda8cfd --- /dev/null +++ b/infra/clusterroles/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: clusterroles +version: 1.0.0 + +description: "Special cluster roles" \ No newline at end of file diff --git a/infra/clusterroles/templates/clusterrole-read-cm-secrets.yaml b/infra/clusterroles/templates/clusterrole-read-cm-secrets.yaml new file mode 100644 index 00000000..f1f4efed --- /dev/null +++ b/infra/clusterroles/templates/clusterrole-read-cm-secrets.yaml @@ -0,0 +1,10 @@ +# Roles to access configMaps and secrets in all namespaces. +# This is a very dangerous role, only use it with care! +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: read-cm-secrets +rules: + - apiGroups: [""] + resources: ["configmaps", "secrets"] + verbs: ["get", "list"] \ No newline at end of file diff --git a/infra/mariadb/templates/init-database-with-user.yaml b/infra/mariadb/templates/init-database-with-user.yaml new file mode 100644 index 00000000..8d01e276 --- /dev/null +++ b/infra/mariadb/templates/init-database-with-user.yaml @@ -0,0 +1,107 @@ +# ======================================= +# Jesus, what the fuck is happening here? +# ======================================= +# +# 1. Create a service account +# 2. Permit it to read configmaps and secrets in the faf-apps namespace +# 3. Iterate over the databasesAndUsers list and create a job for each database +# a) initContainer: Load the configmap and secret into environment variables. This must happen via k8s api, as we can't directly reference cm/secrets cross-namespace. +# b) actual container: Load the env from file and create the database and user + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: init-apps + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: allow-init-apps-read-app-config + namespace: faf-apps +subjects: + - kind: ServiceAccount + name: init-apps + namespace: faf-infra +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: read-cm-secrets + +--- + +{{- $wave := 1 }} +{{- range .Values.databasesAndUsers }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: mariadb-sync-db-user-{{ $wave }} + labels: + app: mariadb-sync-db-user + argocd.argoproj.io/instance: mariadb + annotations: + argocd.argoproj.io/hook: PostSync + argocd.argoproj.io/hook-delete-policy: HookSucceeded + argocd.argoproj.io/sync-wave: '{{ $wave }}' +spec: + backoffLimit: 1 + template: + spec: + serviceAccountName: init-apps + volumes: + - name: config # We will store the apps config for database, username and password here + emptyDir: {} + initContainers: + - name: load-config + image: alpine/kubectl + command: ["/bin/sh", "-c"] + args: + - | + mkdir -p /config + + echo -n "SYNC_DATABASE=" > /config/env + kubectl get cm {{ .configMapRef }} \ + -n faf-apps \ + -o jsonpath='{.data.{{ .databaseKey }}}' >> /config/env + echo >> /config/env + + echo -n "SYNC_USERNAME=" >> /config/env + kubectl get cm {{ .configMapRef }} \ + -n faf-apps \ + -o jsonpath='{.data.{{ .usernameKey }}}' >> /config/env + echo >> /config/env + + echo -n "SYNC_PASSWORD=" >> /config/env + kubectl get secret {{ .secretRef }} \ + -n faf-apps \ + -o jsonpath='{.data.{{ .passwordKey }}}' \ + | base64 -d >> /config/env + echo >> /config/env + volumeMounts: + - name: config + mountPath: /config + containers: + - name: mariadb-sync-db-user + image: {{ $.Values.image.repository }}:{{ $.Values.image.tag }} + imagePullPolicy: Always + envFrom: + - secretRef: + name: mariadb + command: ["/bin/sh", "-c"] + args: + - | + set -a + . /config/env + set +a + + mariadb --host=mariadb --user=root --password="${MARIADB_ROOT_PASSWORD}" -e "CREATE DATABASE IF NOT EXISTS \`${SYNC_DATABASE}\`;" 2>&1 + mariadb --host=mariadb --user=root --password="${MARIADB_ROOT_PASSWORD}" -e "CREATE USER IF NOT EXISTS '${SYNC_USERNAME}'@'%' IDENTIFIED BY '${SYNC_PASSWORD}';" 2>&1 + mariadb --host=mariadb --user=root --password="${MARIADB_ROOT_PASSWORD}" -e "GRANT ALL PRIVILEGES ON \`${SYNC_DATABASE}\`.* TO '${SYNC_USERNAME}'@'%';" 2>&1 + volumeMounts: + - name: config + mountPath: /config + restartPolicy: Never +{{- $wave = add $wave 1 }} +{{- end }} diff --git a/infra/mariadb/templates/statefulset.yaml b/infra/mariadb/templates/statefulset.yaml index 6551d457..90a20fe3 100644 --- a/infra/mariadb/templates/statefulset.yaml +++ b/infra/mariadb/templates/statefulset.yaml @@ -17,7 +17,7 @@ spec: app: mariadb spec: containers: - - image: mariadb:12.1 + - image: {{ $.Values.image.repository }}:{{ $.Values.image.tag }} imagePullPolicy: Always name: mariadb ports: diff --git a/infra/mariadb/values.yaml b/infra/mariadb/values.yaml index 40430462..0845f456 100644 --- a/infra/mariadb/values.yaml +++ b/infra/mariadb/values.yaml @@ -1,2 +1,64 @@ +image: + repository: "mariadb" + tag: "12.1" + infisical-secret: name: mariadb + +databasesAndUsers: + # Main FAF database + - configMapRef: faf-api + secretRef: faf-api + databaseKey: DATABASE_NAME + usernameKey: DATABASE_USERNAME + passwordKey: DATABASE_PASSWORD + + - configMapRef: faf-user-service + secretRef: faf-user-service + databaseKey: DB_DATABASE + usernameKey: DB_USERNAME + passwordKey: DB_PASSWORD + + - configMapRef: faf-lobby-server + secretRef: faf-lobby-server + databaseKey: DB_NAME + usernameKey: DB_LOGIN + passwordKey: DB_PASSWORD + + - configMapRef: faf-replay-server + secretRef: faf-replay-server + databaseKey: RS_DB_DATABASE + usernameKey: RS_DB_USERNAME + passwordKey: RS_DB_PASSWORD + + - configMapRef: faf-policy-server + secretRef: faf-policy-server + databaseKey: DATABASE_NAME + usernameKey: DATABASE_USER + passwordKey: DATABASE_PASSWORD + + # League service database + - configMapRef: faf-api + secretRef: faf-api + databaseKey: LEAGUE_DATABASE_NAME + usernameKey: LEAGUE_DATABASE_USERNAME + passwordKey: LEAGUE_DATABASE_PASSWORD + + - configMapRef: faf-league-service + secretRef: faf-league-service + databaseKey: DB_NAME + usernameKey: DB_LOGIN + passwordKey: DB_PASSWORD + + # Others + - configMapRef: wordpress + secretRef: wordpress + databaseKey: WORDPRESS_DB_NAME + usernameKey: WORDPRESS_DB_USER + passwordKey: WORDPRESS_DB_PASSWORD + + - configMapRef: ergochat + secretRef: ergochat + databaseKey: ERGO__DATASTORE__MYSQL__HISTORY_DATABASE + usernameKey: ERGO__DATASTORE__MYSQL__USER + passwordKey: ERGO__DATASTORE__MYSQL__PASSWORD