From 5076005975e4f2d9ce9dae9377a0ae3e9d1f7dec Mon Sep 17 00:00:00 2001 From: Matthias Goerens Date: Thu, 3 Jul 2025 16:46:17 +0200 Subject: [PATCH 01/26] table rase --- .dockerignore | 4 - .github/workflows/container-images.yml | 28 - .github/workflows/tests.yaml | 22 - .gitignore | 20 - Dockerfile | 29 - LICENSE | 201 -- Makefile | 260 -- PROJECT | 38 - README.md | 153 - apis/synapse/v1alpha1/groupversion_info.go | 36 - apis/synapse/v1alpha1/heisenbridge_types.go | 113 - apis/synapse/v1alpha1/mautrixsignal_types.go | 116 - apis/synapse/v1alpha1/synapse_types.go | 184 -- .../synapse/v1alpha1/zz_generated.deepcopy.go | 508 --- bundle.Dockerfile | 20 - ...er-manager-metrics-service_v1_service.yaml | 17 - ...-operator-manager-config_v1_configmap.yaml | 17 - ...c.authorization.k8s.io_v1_clusterrole.yaml | 10 - ...ynapse-operator.clusterserviceversion.yaml | 326 -- .../synapse.opdev.io_heisenbridges.yaml | 111 - .../synapse.opdev.io_mautrixsignals.yaml | 113 - .../manifests/synapse.opdev.io_synapses.yaml | 183 -- bundle/metadata/annotations.yaml | 14 - bundle/tests/scorecard/config.yaml | 70 - .../bases/synapse.opdev.io_heisenbridges.yaml | 105 - .../synapse.opdev.io_mautrixsignals.yaml | 107 - .../crd/bases/synapse.opdev.io_synapses.yaml | 172 - config/crd/kustomization.yaml | 35 - config/crd/kustomizeconfig.yaml | 19 - .../cainjection_in_synapse_heisenbridges.yaml | 7 - ...cainjection_in_synapse_mautrixsignals.yaml | 7 - .../crd/patches/cainjection_in_synapses.yaml | 7 - .../patches/oneofhomeserver_in_synapses.yaml | 5 - .../webhook_in_synapse_heisenbridges.yaml | 16 - .../webhook_in_synapse_mautrixsignals.yaml | 16 - config/crd/patches/webhook_in_synapses.yaml | 16 - config/default/kustomization.yaml | 74 - config/default/manager_auth_proxy_patch.yaml | 27 - config/default/manager_config_patch.yaml | 20 - config/manager/controller_manager_config.yaml | 11 - config/manager/kustomization.yaml | 16 - config/manager/manager.yaml | 56 - ...ynapse-operator.clusterserviceversion.yaml | 75 - config/manifests/kustomization.yaml | 27 - config/prometheus/kustomization.yaml | 2 - config/prometheus/monitor.yaml | 20 - .../rbac/auth_proxy_client_clusterrole.yaml | 9 - config/rbac/auth_proxy_role.yaml | 17 - config/rbac/auth_proxy_role_binding.yaml | 12 - config/rbac/auth_proxy_service.yaml | 15 - config/rbac/kustomization.yaml | 18 - config/rbac/leader_election_role.yaml | 37 - config/rbac/leader_election_role_binding.yaml | 12 - config/rbac/role.yaml | 97 - config/rbac/role_binding.yaml | 12 - config/rbac/service_account.yaml | 5 - config/rbac/synapse_editor_role.yaml | 24 - .../synapse_heisenbridge_editor_role.yaml | 31 - .../synapse_heisenbridge_viewer_role.yaml | 27 - .../synapse_mautrixsignal_editor_role.yaml | 31 - .../synapse_mautrixsignal_viewer_role.yaml | 27 - config/rbac/synapse_viewer_role.yaml | 20 - config/samples/kustomization.yaml | 6 - .../synapse_v1alpha1_heisenbridge.yaml | 13 - .../synapse_v1alpha1_mautrixsignal.yaml | 13 - config/samples/synapse_v1alpha1_synapse.yaml | 10 - config/scorecard/bases/config.yaml | 7 - config/scorecard/kustomization.yaml | 16 - config/scorecard/patches/basic.config.yaml | 10 - config/scorecard/patches/olm.config.yaml | 50 - .../heisenbridge/heisenbridge_configmap.go | 132 - .../heisenbridge/heisenbridge_controller.go | 111 - .../heisenbridge_controller_test.go | 617 ---- .../heisenbridge/heisenbridge_deployment.go | 120 - .../heisenbridge/heisenbridge_service.go | 88 - .../synapse/heisenbridge/heisenbridge_test.go | 5 - .../synapse/heisenbridge/suite_test.go | 34 - .../mautrixsignal/mautrixsignal_configmap.go | 205 -- .../mautrixsignal/mautrixsignal_controller.go | 161 - .../mautrixsignal_controller_test.go | 723 ---- .../mautrixsignal/mautrixsignal_deployment.go | 88 - .../mautrixsignal/mautrixsignal_pvc.go | 72 - .../mautrixsignal/mautrixsignal_service.go | 88 - .../mautrixsignal_serviceaccount.go | 117 - .../mautrixsignal/mautrixsignal_test.go | 5 - .../synapse/mautrixsignal/suite_test.go | 34 - controllers/synapse/synapse/suite_test.go | 34 - .../synapse/synapse/synapse_configmap.go | 502 --- .../synapse/synapse/synapse_controller.go | 364 --- .../synapse/synapse_controller_test.go | 1175 ------- .../synapse/synapse/synapse_deployment.go | 83 - .../synapse/synapse_postgrescluster.go | 237 -- controllers/synapse/synapse/synapse_pvc.go | 72 - .../synapse/synapse/synapse_service.go | 89 - .../synapse/synapse/synapse_serviceaccount.go | 114 - controllers/synapse/synapse/synapse_test.go | 543 ---- .../synapse.yaml | 10 - .../homeserver.yaml | 2895 ----------------- .../02-using-existing-configmap/synapse.yaml | 8 - examples/03-deploying-postgresql/synapse.yaml | 10 - .../A-default-configuration/heisenbridge.yaml | 7 - .../A-default-configuration/synapse.yaml | 9 - .../heisenbridge.yaml | 9 - .../heisenbridge_config.yaml | 12 - .../B-using-existing-configmap/synapse.yaml | 9 - .../mautrixsignal.yaml | 7 - .../A-default-configuration/synapse.yaml | 9 - .../B-using-existing-configmap/config.yaml | 302 -- .../mautrixsignal.yaml | 9 - .../B-using-existing-configmap/synapse.yaml | 9 - examples/README.md | 297 -- go.mod | 79 - go.sum | 192 -- hack/boilerplate.go.txt | 15 - helpers/reconcile/reconcile.go | 108 - helpers/utils/bridge_utils.go | 187 -- helpers/utils/configmap_utils.go | 184 -- helpers/utils/synapse_utils.go | 227 -- helpers/utils/tests_utils.go | 132 - helpers/utils/utils.go | 47 - install/synapse-operator.yaml | 702 ---- .../templates/heisenbridge_configmap.yaml | 20 - .../templates/heisenbridge_deployment.yaml | 37 - .../templates/mautrixsignal_configmap.yaml | 310 -- .../templates/mautrixsignal_deployment.yaml | 52 - internal/templates/pvc.yaml | 12 - internal/templates/rolebinding.yaml | 13 - internal/templates/service.yaml | 16 - internal/templates/serviceaccount.yaml | 5 - internal/templates/synapse_configmap.yaml | 41 - internal/templates/synapse_deployment.yaml | 88 - internal/templates/templates.go | 42 - main.go | 129 - 133 files changed, 16005 deletions(-) delete mode 100644 .dockerignore delete mode 100644 .github/workflows/container-images.yml delete mode 100644 .github/workflows/tests.yaml delete mode 100644 .gitignore delete mode 100644 Dockerfile delete mode 100644 LICENSE delete mode 100644 Makefile delete mode 100644 PROJECT delete mode 100644 README.md delete mode 100644 apis/synapse/v1alpha1/groupversion_info.go delete mode 100644 apis/synapse/v1alpha1/heisenbridge_types.go delete mode 100644 apis/synapse/v1alpha1/mautrixsignal_types.go delete mode 100644 apis/synapse/v1alpha1/synapse_types.go delete mode 100644 apis/synapse/v1alpha1/zz_generated.deepcopy.go delete mode 100644 bundle.Dockerfile delete mode 100644 bundle/manifests/synapse-operator-controller-manager-metrics-service_v1_service.yaml delete mode 100644 bundle/manifests/synapse-operator-manager-config_v1_configmap.yaml delete mode 100644 bundle/manifests/synapse-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml delete mode 100644 bundle/manifests/synapse-operator.clusterserviceversion.yaml delete mode 100644 bundle/manifests/synapse.opdev.io_heisenbridges.yaml delete mode 100644 bundle/manifests/synapse.opdev.io_mautrixsignals.yaml delete mode 100644 bundle/manifests/synapse.opdev.io_synapses.yaml delete mode 100644 bundle/metadata/annotations.yaml delete mode 100644 bundle/tests/scorecard/config.yaml delete mode 100644 config/crd/bases/synapse.opdev.io_heisenbridges.yaml delete mode 100644 config/crd/bases/synapse.opdev.io_mautrixsignals.yaml delete mode 100644 config/crd/bases/synapse.opdev.io_synapses.yaml delete mode 100644 config/crd/kustomization.yaml delete mode 100644 config/crd/kustomizeconfig.yaml delete mode 100644 config/crd/patches/cainjection_in_synapse_heisenbridges.yaml delete mode 100644 config/crd/patches/cainjection_in_synapse_mautrixsignals.yaml delete mode 100644 config/crd/patches/cainjection_in_synapses.yaml delete mode 100644 config/crd/patches/oneofhomeserver_in_synapses.yaml delete mode 100644 config/crd/patches/webhook_in_synapse_heisenbridges.yaml delete mode 100644 config/crd/patches/webhook_in_synapse_mautrixsignals.yaml delete mode 100644 config/crd/patches/webhook_in_synapses.yaml delete mode 100644 config/default/kustomization.yaml delete mode 100644 config/default/manager_auth_proxy_patch.yaml delete mode 100644 config/default/manager_config_patch.yaml delete mode 100644 config/manager/controller_manager_config.yaml delete mode 100644 config/manager/kustomization.yaml delete mode 100644 config/manager/manager.yaml delete mode 100644 config/manifests/bases/synapse-operator.clusterserviceversion.yaml delete mode 100644 config/manifests/kustomization.yaml delete mode 100644 config/prometheus/kustomization.yaml delete mode 100644 config/prometheus/monitor.yaml delete mode 100644 config/rbac/auth_proxy_client_clusterrole.yaml delete mode 100644 config/rbac/auth_proxy_role.yaml delete mode 100644 config/rbac/auth_proxy_role_binding.yaml delete mode 100644 config/rbac/auth_proxy_service.yaml delete mode 100644 config/rbac/kustomization.yaml delete mode 100644 config/rbac/leader_election_role.yaml delete mode 100644 config/rbac/leader_election_role_binding.yaml delete mode 100644 config/rbac/role.yaml delete mode 100644 config/rbac/role_binding.yaml delete mode 100644 config/rbac/service_account.yaml delete mode 100644 config/rbac/synapse_editor_role.yaml delete mode 100644 config/rbac/synapse_heisenbridge_editor_role.yaml delete mode 100644 config/rbac/synapse_heisenbridge_viewer_role.yaml delete mode 100644 config/rbac/synapse_mautrixsignal_editor_role.yaml delete mode 100644 config/rbac/synapse_mautrixsignal_viewer_role.yaml delete mode 100644 config/rbac/synapse_viewer_role.yaml delete mode 100644 config/samples/kustomization.yaml delete mode 100644 config/samples/synapse_v1alpha1_heisenbridge.yaml delete mode 100644 config/samples/synapse_v1alpha1_mautrixsignal.yaml delete mode 100644 config/samples/synapse_v1alpha1_synapse.yaml delete mode 100644 config/scorecard/bases/config.yaml delete mode 100644 config/scorecard/kustomization.yaml delete mode 100644 config/scorecard/patches/basic.config.yaml delete mode 100644 config/scorecard/patches/olm.config.yaml delete mode 100644 controllers/synapse/heisenbridge/heisenbridge_configmap.go delete mode 100644 controllers/synapse/heisenbridge/heisenbridge_controller.go delete mode 100644 controllers/synapse/heisenbridge/heisenbridge_controller_test.go delete mode 100644 controllers/synapse/heisenbridge/heisenbridge_deployment.go delete mode 100644 controllers/synapse/heisenbridge/heisenbridge_service.go delete mode 100644 controllers/synapse/heisenbridge/heisenbridge_test.go delete mode 100644 controllers/synapse/heisenbridge/suite_test.go delete mode 100644 controllers/synapse/mautrixsignal/mautrixsignal_configmap.go delete mode 100644 controllers/synapse/mautrixsignal/mautrixsignal_controller.go delete mode 100644 controllers/synapse/mautrixsignal/mautrixsignal_controller_test.go delete mode 100644 controllers/synapse/mautrixsignal/mautrixsignal_deployment.go delete mode 100644 controllers/synapse/mautrixsignal/mautrixsignal_pvc.go delete mode 100644 controllers/synapse/mautrixsignal/mautrixsignal_service.go delete mode 100644 controllers/synapse/mautrixsignal/mautrixsignal_serviceaccount.go delete mode 100644 controllers/synapse/mautrixsignal/mautrixsignal_test.go delete mode 100644 controllers/synapse/mautrixsignal/suite_test.go delete mode 100644 controllers/synapse/synapse/suite_test.go delete mode 100644 controllers/synapse/synapse/synapse_configmap.go delete mode 100644 controllers/synapse/synapse/synapse_controller.go delete mode 100644 controllers/synapse/synapse/synapse_controller_test.go delete mode 100644 controllers/synapse/synapse/synapse_deployment.go delete mode 100644 controllers/synapse/synapse/synapse_postgrescluster.go delete mode 100644 controllers/synapse/synapse/synapse_pvc.go delete mode 100644 controllers/synapse/synapse/synapse_service.go delete mode 100644 controllers/synapse/synapse/synapse_serviceaccount.go delete mode 100644 controllers/synapse/synapse/synapse_test.go delete mode 100644 examples/01-my-first-synapse-deployment/synapse.yaml delete mode 100644 examples/02-using-existing-configmap/homeserver.yaml delete mode 100644 examples/02-using-existing-configmap/synapse.yaml delete mode 100644 examples/03-deploying-postgresql/synapse.yaml delete mode 100644 examples/04-deploying-heisenbridge/A-default-configuration/heisenbridge.yaml delete mode 100644 examples/04-deploying-heisenbridge/A-default-configuration/synapse.yaml delete mode 100644 examples/04-deploying-heisenbridge/B-using-existing-configmap/heisenbridge.yaml delete mode 100644 examples/04-deploying-heisenbridge/B-using-existing-configmap/heisenbridge_config.yaml delete mode 100644 examples/04-deploying-heisenbridge/B-using-existing-configmap/synapse.yaml delete mode 100644 examples/05-deploying-mautrixsignal/A-default-configuration/mautrixsignal.yaml delete mode 100644 examples/05-deploying-mautrixsignal/A-default-configuration/synapse.yaml delete mode 100644 examples/05-deploying-mautrixsignal/B-using-existing-configmap/config.yaml delete mode 100644 examples/05-deploying-mautrixsignal/B-using-existing-configmap/mautrixsignal.yaml delete mode 100644 examples/05-deploying-mautrixsignal/B-using-existing-configmap/synapse.yaml delete mode 100644 examples/README.md delete mode 100644 go.mod delete mode 100644 go.sum delete mode 100644 hack/boilerplate.go.txt delete mode 100644 helpers/reconcile/reconcile.go delete mode 100644 helpers/utils/bridge_utils.go delete mode 100644 helpers/utils/configmap_utils.go delete mode 100644 helpers/utils/synapse_utils.go delete mode 100644 helpers/utils/tests_utils.go delete mode 100644 helpers/utils/utils.go delete mode 100644 install/synapse-operator.yaml delete mode 100644 internal/templates/heisenbridge_configmap.yaml delete mode 100644 internal/templates/heisenbridge_deployment.yaml delete mode 100644 internal/templates/mautrixsignal_configmap.yaml delete mode 100644 internal/templates/mautrixsignal_deployment.yaml delete mode 100644 internal/templates/pvc.yaml delete mode 100644 internal/templates/rolebinding.yaml delete mode 100644 internal/templates/service.yaml delete mode 100644 internal/templates/serviceaccount.yaml delete mode 100644 internal/templates/synapse_configmap.yaml delete mode 100644 internal/templates/synapse_deployment.yaml delete mode 100644 internal/templates/templates.go delete mode 100644 main.go diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 0f04682..0000000 --- a/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file -# Ignore build and test binaries. -bin/ -testbin/ diff --git a/.github/workflows/container-images.yml b/.github/workflows/container-images.yml deleted file mode 100644 index 2793b8c..0000000 --- a/.github/workflows/container-images.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Build and push container images on Quay.io - -on: - push: - # Publish semver tags as releases. - tags: [ 'v*.*.*' ] - -jobs: - build-and-push: - - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Login to Quay.io - uses: docker/login-action@v2 - with: - registry: quay.io - username: ${{ secrets.QUAY_ROBOT_NAME }} - password: ${{ secrets.QUAY_ROBOT_TOKEN }} - - - name: Build and Push controller image - run: make docker-build && make docker-push - - - name: Build and Push controller image - run: make bundle-build && make bundle-push diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml deleted file mode 100644 index 5a2018d..0000000 --- a/.github/workflows/tests.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Run unit and integration tests - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: 1.23 - - - name: Run test suite - run: make test diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 37e4f1d..0000000 --- a/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -bin/ - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -.vscode/ - diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index fc736d2..0000000 --- a/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -# Build the manager binary -FROM golang:1.23 as builder - -WORKDIR /workspace -# Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum -# cache deps before building and copying source so that we don't need to re-download as much -# and so that source changes don't invalidate our downloaded layer -RUN go mod download - -# Copy the go source -COPY main.go main.go -COPY apis/ apis/ -COPY controllers/ controllers/ -COPY helpers/ helpers/ -COPY internal/ internal/ - -# Build -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go - -# Use distroless as minimal base image to package the manager binary -# Refer to https://github.com/GoogleContainerTools/distroless for more details -FROM gcr.io/distroless/static:nonroot -WORKDIR / -COPY --from=builder /workspace/manager . -USER 65532:65532 - -ENTRYPOINT ["/manager"] diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Makefile b/Makefile deleted file mode 100644 index f8d3333..0000000 --- a/Makefile +++ /dev/null @@ -1,260 +0,0 @@ -# VERSION defines the project version for the bundle. -# Update this value when you upgrade the version of your project. -# To re-generate a bundle for another specific version without changing the standard setup, you can: -# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) -# - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.6.1 - -# CHANNELS define the bundle channels used in the bundle. -# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") -# To re-generate a bundle for other specific channels without changing the standard setup, you can: -# - use the CHANNELS as arg of the bundle target (e.g make bundle CHANNELS=candidate,fast,stable) -# - use environment variables to overwrite this value (e.g export CHANNELS="candidate,fast,stable") -ifneq ($(origin CHANNELS), undefined) -BUNDLE_CHANNELS := --channels=$(CHANNELS) -endif - -# DEFAULT_CHANNEL defines the default channel used in the bundle. -# Add a new line here if you would like to change its default config. (E.g DEFAULT_CHANNEL = "stable") -# To re-generate a bundle for any other default channel without changing the default setup, you can: -# - use the DEFAULT_CHANNEL as arg of the bundle target (e.g make bundle DEFAULT_CHANNEL=stable) -# - use environment variables to overwrite this value (e.g export DEFAULT_CHANNEL="stable") -ifneq ($(origin DEFAULT_CHANNEL), undefined) -BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) -endif -BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) - -# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images. -# This variable is used to construct full image tags for bundle and catalog images. -# -# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both -# quay.io/opdev/synapse-operator-bundle:$VERSION and quay.io/opdev/synapse-operator-catalog:$VERSION. -IMAGE_TAG_BASE ?= quay.io/opdev/synapse-operator - -# BUNDLE_IMG defines the image:tag used for the bundle. -# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:) -BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION) - -# BUNDLE_GEN_FLAGS are the flags passed to the operator-sdk generate bundle command -BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) - -# USE_IMAGE_DIGESTS defines if images are resolved via tags or digests -# You can enable this value if you would like to use SHA Based Digests -# To enable set flag to true -USE_IMAGE_DIGESTS ?= false -ifeq ($(USE_IMAGE_DIGESTS), true) - BUNDLE_GEN_FLAGS += --use-image-digests -endif - -# Image URL to use all building/pushing image targets -IMG ?= $(IMAGE_TAG_BASE):v$(VERSION) -# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.31.0 - -# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) -ifeq (,$(shell go env GOBIN)) -GOBIN=$(shell go env GOPATH)/bin -else -GOBIN=$(shell go env GOBIN) -endif - -# Setting SHELL to bash allows bash commands to be executed by recipes. -# Options are set to exit when a recipe line exits non-zero or a piped command fails. -SHELL = /usr/bin/env bash -o pipefail -.SHELLFLAGS = -ec - -.PHONY: all -all: build - -##@ General - -# The help target prints out all targets with their descriptions organized -# beneath their categories. The categories are represented by '##@' and the -# target descriptions by '##'. The awk commands is responsible for reading the -# entire set of makefiles included in this invocation, looking for lines of the -# file as xyz: ## something, and then pretty-format the target and help. Then, -# if there's a line with ##@ something, that gets pretty-printed as a category. -# More info on the usage of ANSI control characters for terminal formatting: -# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters -# More info on the awk command: -# http://linuxcommand.org/lc3_adv_awk.php - -.PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - -##@ Development - -.PHONY: manifests -manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases - -.PHONY: generate -generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." - -.PHONY: fmt -fmt: ## Run go fmt against code. - go fmt ./... - -.PHONY: vet -vet: ## Run go vet against code. - go vet ./... - -.PHONY: test -test: manifests generate fmt vet envtest ## Run tests. - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out - -##@ Build - -.PHONY: build -build: generate fmt vet ## Build manager binary. - go build -o bin/manager main.go - -.PHONY: run -run: manifests generate fmt vet ## Run a controller from your host. - go run ./main.go - -# If you wish built the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -.PHONY: docker-build -docker-build: test ## Build docker image with the manager. - docker build -t ${IMG} . - -.PHONY: docker-push -docker-push: ## Push docker image with the manager. - docker push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/ -# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=> than the export will fail) -# To properly provided solutions that supports more than one platform you should use this option. -PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: test ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - docker buildx create --name project-v3-builder - docker buildx use project-v3-builder - - docker buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross - - docker buildx rm project-v3-builder - rm Dockerfile.cross - -##@ Deployment - -ifndef ignore-not-found - ignore-not-found = false -endif - -.PHONY: install -install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. - $(KUSTOMIZE) build config/crd | kubectl apply -f - - -.PHONY: uninstall -uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f - - -.PHONY: deploy -deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | kubectl apply -f - - -.PHONY: undeploy -undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f - - -.PHONY: manifest-package -manifest-package: manifests kustomize ## Generate full manifest file for easy controller deployment - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | tee install/synapse-operator.yaml - -##@ Build Dependencies - -## Location to install dependencies to -LOCALBIN ?= $(shell pwd)/bin -$(LOCALBIN): - mkdir -p $(LOCALBIN) - -## Tool Binaries -KUSTOMIZE ?= $(LOCALBIN)/kustomize -CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen -ENVTEST ?= $(LOCALBIN)/setup-envtest - -## Tool Versions -KUSTOMIZE_VERSION ?= v5.4.3 -CONTROLLER_TOOLS_VERSION ?= v0.16.1 - -KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" -.PHONY: kustomize -kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. -$(KUSTOMIZE): $(LOCALBIN) - test -s $(LOCALBIN)/kustomize || { curl -Ss $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); } - -.PHONY: controller-gen -controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. -$(CONTROLLER_GEN): $(LOCALBIN) - test -s $(LOCALBIN)/controller-gen || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION) - -.PHONY: envtest -envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. -$(ENVTEST): $(LOCALBIN) - test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest - -.PHONY: bundle -bundle: manifests kustomize ## Generate bundle manifests and metadata, then validate generated files. - operator-sdk generate kustomize manifests -q - cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) - $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle $(BUNDLE_GEN_FLAGS) - operator-sdk bundle validate ./bundle - -.PHONY: bundle-build -bundle-build: ## Build the bundle image. - docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) . - -.PHONY: bundle-push -bundle-push: ## Push the bundle image. - $(MAKE) docker-push IMG=$(BUNDLE_IMG) - -.PHONY: opm -OPM = ./bin/opm -opm: ## Download opm locally if necessary. -ifeq (,$(wildcard $(OPM))) -ifeq (,$(shell which opm 2>/dev/null)) - @{ \ - set -e ;\ - mkdir -p $(dir $(OPM)) ;\ - OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ - curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.23.0/$${OS}-$${ARCH}-opm ;\ - chmod +x $(OPM) ;\ - } -else -OPM = $(shell which opm) -endif -endif - -# A comma-separated list of bundle images (e.g. make catalog-build BUNDLE_IMGS=example.com/operator-bundle:v0.1.0,example.com/operator-bundle:v0.2.0). -# These images MUST exist in a registry and be pull-able. -BUNDLE_IMGS ?= $(BUNDLE_IMG) - -# The image tag given to the resulting catalog image (e.g. make catalog-build CATALOG_IMG=example.com/operator-catalog:v0.2.0). -CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:v$(VERSION) - -# Set CATALOG_BASE_IMG to an existing catalog image tag to add $BUNDLE_IMGS to that image. -ifneq ($(origin CATALOG_BASE_IMG), undefined) -FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) -endif - -# Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'. -# This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see: -# https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator -.PHONY: catalog-build -catalog-build: opm ## Build a catalog image. - $(OPM) index add --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT) - -# Push the catalog image. -.PHONY: catalog-push -catalog-push: ## Push a catalog image. - $(MAKE) docker-push IMG=$(CATALOG_IMG) diff --git a/PROJECT b/PROJECT deleted file mode 100644 index 50b2f08..0000000 --- a/PROJECT +++ /dev/null @@ -1,38 +0,0 @@ -domain: opdev.io -layout: -- go.kubebuilder.io/v3 -multigroup: true -plugins: - manifests.sdk.operatorframework.io/v2: {} - scorecard.sdk.operatorframework.io/v2: {} -projectName: synapse-operator -repo: github.com/opdev/synapse-operator -resources: -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: opdev.io - group: synapse - kind: Synapse - path: github.com/opdev/synapse-operator/apis/synapse/v1alpha1 - version: v1alpha1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: opdev.io - group: synapse - kind: MautrixSignal - path: github.com/opdev/synapse-operator/apis/synapse/v1alpha1 - version: v1alpha1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: opdev.io - group: synapse - kind: Heisenbridge - path: github.com/opdev/synapse-operator/apis/synapse/v1alpha1 - version: v1alpha1 -version: "3" diff --git a/README.md b/README.md deleted file mode 100644 index d1ed3a9..0000000 --- a/README.md +++ /dev/null @@ -1,153 +0,0 @@ -# A Kubernetes Operator for Synapse - -The Synapse -[operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) -offers a convenient way to deploy and manage a -[Synapse](https://github.com/matrix-org/synapse/) server. It was built with -[operator-sdk](https://sdk.operatorframework.io/). - -## Presentation - -Check out [this video](https://www.youtube.com/watch?v=Vsb18jr_VDc) to have -an introduction to the concept of operators, CRDs, and how the Synapse -Operator is built. - -## Deploying the Synapse Operator - -Each of the following sections present one way to deploy the Synapse operator. - -### Deploy the controller using the existing manifest file - -The easiest way to deploy the Synapse operator is to use the manifest file -present in the `install` directory: - -```shell -$ kubectl apply -f install/synapse-operator.yaml -namespace/synapse-operator-system created -customresourcedefinition.apiextensions.k8s.io/synapses.synapse.opdev.io configured -serviceaccount/synapse-operator-controller-manager created -role.rbac.authorization.k8s.io/synapse-operator-leader-election-role created -clusterrole.rbac.authorization.k8s.io/synapse-operator-manager-role created -clusterrole.rbac.authorization.k8s.io/synapse-operator-metrics-reader created -clusterrole.rbac.authorization.k8s.io/synapse-operator-proxy-role created -rolebinding.rbac.authorization.k8s.io/synapse-operator-leader-election-rolebinding created -clusterrolebinding.rbac.authorization.k8s.io/synapse-operator-manager-rolebinding created -clusterrolebinding.rbac.authorization.k8s.io/synapse-operator-proxy-rolebinding created -configmap/synapse-operator-manager-config created -service/synapse-operator-controller-manager-metrics-service created -deployment.apps/synapse-operator-controller-manager created -``` - -### Run the controller locally with `make run` - -Install the `Synapse` CRD with: - -```shell -$ make install -/home/mgoerens/dev/github.com/opdev/synapse-operator/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases -/home/mgoerens/dev/github.com/opdev/synapse-operator/bin/kustomize build config/crd | kubectl apply -f - -customresourcedefinition.apiextensions.k8s.io/synapses.synapse.opdev.io configured -``` - -Run the controller locally with: - -```shell -$ make run -/home/mgoerens/dev/github.com/opdev/synapse-operator/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases -/home/mgoerens/dev/github.com/opdev/synapse-operator/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..." -go fmt ./... -go vet ./... -go run ./main.go -I0329 13:14:32.483664 26252 request.go:665] Waited for 1.039947837s due to client-side throttling, not priority and fairness, request: GET:https://api.crc.testing:6443/apis/operators.coreos.com/v1?timeout=32s -1.6485524737848275e+09 INFO controller-runtime.metrics Metrics server is starting to listen {"addr": ":8080"} -1.648552473785254e+09 INFO setup starting manager -1.6485524737853944e+09 INFO Starting server {"kind": "health probe", "addr": "[::]:8081"} -1.6485524737853956e+09 INFO Starting server {"path": "/metrics", "kind": "metrics", "addr": "[::]:8080"} -1.6485524737854843e+09 INFO controller.synapse Starting EventSource {"reconciler group": "synapse.opdev.io", "reconciler kind": "Synapse", "source": "kind source: *v1alpha1.Synapse"} -1.648552473785519e+09 INFO controller.synapse Starting EventSource {"reconciler group": "synapse.opdev.io", "reconciler kind": "Synapse", "source": "kind source: *v1.Service"} -1.6485524737855291e+09 INFO controller.synapse Starting EventSource {"reconciler group": "synapse.opdev.io", "reconciler kind": "Synapse", "source": "kind source: *v1.Deployment"} -1.6485524737855399e+09 INFO controller.synapse Starting EventSource {"reconciler group": "synapse.opdev.io", "reconciler kind": "Synapse", "source": "kind source: *v1.PersistentVolumeClaim"} -1.6485524737855482e+09 INFO controller.synapse Starting Controller {"reconciler group": "synapse.opdev.io", "reconciler kind": "Synapse"} -1.6485524738865452e+09 INFO controller.synapse Starting workers {"reconciler group": "synapse.opdev.io", "reconciler kind": "Synapse", "worker count": 1} - -``` - -This runs the controller until you hit `Ctrl` + `C`. - -To uninstall the `Synapse `CRD: - -```shell -$ make uninstall -/home/mgoerens/dev/github.com/opdev/synapse-operator/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases -/home/mgoerens/dev/github.com/opdev/synapse-operator/bin/kustomize build config/crd | kubectl delete -f - -customresourcedefinition.apiextensions.k8s.io "synapses.synapse.opdev.io" deleted -``` - -### Deploy the controller in the Kubernetes cluster with `make deploy` - -Deploy the controller with: - -```shell -$ make deploy -/home/mgoerens/dev/github.com/opdev/synapse-operator/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases -cd config/manager && /home/mgoerens/dev/github.com/opdev/synapse-operator/bin/kustomize edit set image controller=controller:latest -/home/mgoerens/dev/github.com/opdev/synapse-operator/bin/kustomize build config/default | kubectl apply -f - -namespace/synapse-operator-system created -customresourcedefinition.apiextensions.k8s.io/synapses.synapse.opdev.io configured -serviceaccount/synapse-operator-controller-manager created -role.rbac.authorization.k8s.io/synapse-operator-leader-election-role created -clusterrole.rbac.authorization.k8s.io/synapse-operator-manager-role created -clusterrole.rbac.authorization.k8s.io/synapse-operator-metrics-reader created -clusterrole.rbac.authorization.k8s.io/synapse-operator-proxy-role created -rolebinding.rbac.authorization.k8s.io/synapse-operator-leader-election-rolebinding created -clusterrolebinding.rbac.authorization.k8s.io/synapse-operator-manager-rolebinding created -clusterrolebinding.rbac.authorization.k8s.io/synapse-operator-proxy-rolebinding created -configmap/synapse-operator-manager-config created -service/synapse-operator-controller-manager-metrics-service created -deployment.apps/synapse-operator-controller-manager created -``` - -This creates a dedicated namespace `synapse-operator-system` and all required -resources (including the CRD) for the controller to run. - -To cleanup all resources: - -```shell -$ make undeploy -/home/mgoerens/dev/github.com/opdev/synapse-operator/bin/kustomize build config/default | kubectl delete -f - -namespace "synapse-operator-system" deleted -customresourcedefinition.apiextensions.k8s.io "synapses.synapse.opdev.io" deleted -serviceaccount "synapse-operator-controller-manager" deleted -role.rbac.authorization.k8s.io "synapse-operator-leader-election-role" deleted -clusterrole.rbac.authorization.k8s.io "synapse-operator-manager-role" deleted -clusterrole.rbac.authorization.k8s.io "synapse-operator-metrics-reader" deleted -clusterrole.rbac.authorization.k8s.io "synapse-operator-proxy-role" deleted -rolebinding.rbac.authorization.k8s.io "synapse-operator-leader-election-rolebinding" deleted -clusterrolebinding.rbac.authorization.k8s.io "synapse-operator-manager-rolebinding" deleted -clusterrolebinding.rbac.authorization.k8s.io "synapse-operator-proxy-rolebinding" deleted -configmap "synapse-operator-manager-config" deleted -service "synapse-operator-controller-manager-metrics-service" deleted -deployment.apps "synapse-operator-controller-manager" deleted -``` - -## Deploying a Synapse instance - -A set of example how to use the Synapse operator to deploy a Synapse server is -provided under the -[examples](https://github.com/opdev/synapse-operator/tree/main/examples) -directory. - -## Notes and pre-requisites - -- The [postgres-operator](https://github.com/CrunchyData/postgres-operator) - needs to be installed. Specifically the `PostgresCluster` CRD is required. - This is only required if you intend to deploy a PostgreSQL instance alongside - Synapse. -- Tested on OpenShift 4.9.0 - -# Related links - -- [Matrix project homepage](https://matrix.org/) -- [Synape Repository](https://github.com/matrix-org/synapse/) -- [postgres-operator](https://github.com/CrunchyData/postgres-operator) -- [Heisenbridge](https://github.com/hifi/heisenbridge) diff --git a/apis/synapse/v1alpha1/groupversion_info.go b/apis/synapse/v1alpha1/groupversion_info.go deleted file mode 100644 index 21968b9..0000000 --- a/apis/synapse/v1alpha1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package v1alpha1 contains API Schema definitions for the synapse v1alpha1 API group -// +kubebuilder:object:generate=true -// +groupName=synapse.opdev.io -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -var ( - // GroupVersion is group version used to register these objects - GroupVersion = schema.GroupVersion{Group: "synapse.opdev.io", Version: "v1alpha1"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} - - // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme -) diff --git a/apis/synapse/v1alpha1/heisenbridge_types.go b/apis/synapse/v1alpha1/heisenbridge_types.go deleted file mode 100644 index 55fc976..0000000 --- a/apis/synapse/v1alpha1/heisenbridge_types.go +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// HeisenbridgeSpec defines the desired state of Heisenbridge. The user can -// either: -// - enable the bridge, without specifying additional configuration options. -// The bridge will be deployed with a default configuration. -// - enable the bridge and specify an existing ConfigMap by its Name and -// Namespace containing a heisenbridge.yaml. -type HeisenbridgeSpec struct { - // Holds information about the ConfigMap containing the heisenbridge.yaml - // configuration file to be used as input for the configuration of the - // Heisenbridge IRC Bridge. - ConfigMap HeisenbridgeConfigMap `json:"configMap,omitempty"` - - // +kubebuilder:default:=0 - - // Controls the verbosity of the Heisenbrige: - // * 0 corresponds to normal level of logs - // * 1 corresponds to "-v" - // * 2 corresponds to "-vv" - // * 3 corresponds to "-vvv" - VerboseLevel int `json:"verboseLevel,omitempty"` - - // +kubebuilder:validation:Required - - // Name of the Synapse instance, living in the same namespace. - Synapse HeisenbridgeSynapseSpec `json:"synapse"` -} - -type HeisenbridgeSynapseSpec struct { - // +kubebuilder:validation:Required - - // Name of the Synapse instance - Name string `json:"name"` - - // Namespace of the Synapse instance - // TODO: Complete - Namespace string `json:"namespace,omitempty"` -} - -type HeisenbridgeConfigMap struct { - // +kubebuilder:validation:Required - - // Name of the ConfigMap in the given Namespace. - Name string `json:"name"` - - // Namespace in which the ConfigMap is living. If left empty, the - // Heisenbridge namespace is used. - Namespace string `json:"namespace,omitempty"` -} - -// HeisenbridgeStatus defines the observed state of Heisenbridge -type HeisenbridgeStatus struct { - // State of the Heisenbridge instance - State string `json:"state,omitempty"` - - // Reason for the current Heisenbridge State - Reason string `json:"reason,omitempty"` -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status - -// Heisenbridge is the Schema for the heisenbridges API -type Heisenbridge struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // +kubebuilder:validation:Required - Spec HeisenbridgeSpec `json:"spec"` - Status HeisenbridgeStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// HeisenbridgeList contains a list of Heisenbridge -type HeisenbridgeList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Heisenbridge `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Heisenbridge{}, &HeisenbridgeList{}) -} - -func (h *Heisenbridge) GetSynapseName() string { - return h.Spec.Synapse.Name -} - -func (h *Heisenbridge) GetSynapseNamespace() string { - return h.Spec.Synapse.Namespace -} diff --git a/apis/synapse/v1alpha1/mautrixsignal_types.go b/apis/synapse/v1alpha1/mautrixsignal_types.go deleted file mode 100644 index 30e0048..0000000 --- a/apis/synapse/v1alpha1/mautrixsignal_types.go +++ /dev/null @@ -1,116 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// MautrixSignalSpec defines the desired state of MautrixSignal. The user can -// either: -// - enable the bridge, without specifying additional configuration options. -// The bridge will be deployed with a default configuration. -// - enable the bridge and specify an existing ConfigMap by its Name and -// Namespace containing a config.yaml file. -type MautrixSignalSpec struct { - // Holds information about the ConfigMap containing the config.yaml - // configuration file to be used as input for the configuration of the - // mautrix-signal bridge. - ConfigMap MautrixSignalConfigMap `json:"configMap,omitempty"` - - // +kubebuilder:validation:Required - - // Name of the Synapse instance, living in the same namespace. - Synapse MautrixSignalSynapseSpec `json:"synapse"` -} - -type MautrixSignalSynapseSpec struct { - // +kubebuilder:validation:Required - - // Name of the Synapse instance - Name string `json:"name"` - - // Namespace of the Synapse instance - // TODO: Complete - Namespace string `json:"namespace,omitempty"` -} - -type MautrixSignalConfigMap struct { - // +kubebuilder:validation:Required - - // Name of the ConfigMap in the given Namespace. - Name string `json:"name"` - - // Namespace in which the ConfigMap is living. If left empty, the Synapse - // namespace is used. - Namespace string `json:"namespace,omitempty"` -} - -// MautrixSignalStatus defines the observed state of MautrixSignal -type MautrixSignalStatus struct { - // State of the MautrixSignal instance - State string `json:"state,omitempty"` - - // Reason for the current MautrixSignal State - Reason string `json:"reason,omitempty"` - - // Information related to the Synapse instance associated with this bridge - Synapse MautrixSignalStatusSynapse `json:"synapse,omitempty"` - - // +kubebuilder:default:=false - - // Values is set to true if deploying on OpenShift - IsOpenshift bool `json:"isOpenshift,omitempty"` -} - -type MautrixSignalStatusSynapse struct { - ServerName string `json:"serverName,omitempty"` -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status - -// MautrixSignal is the Schema for the mautrixsignals API -type MautrixSignal struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // +kubebuilder:validation:Required - Spec MautrixSignalSpec `json:"spec"` - Status MautrixSignalStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// MautrixSignalList contains a list of MautrixSignal -type MautrixSignalList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []MautrixSignal `json:"items"` -} - -func init() { - SchemeBuilder.Register(&MautrixSignal{}, &MautrixSignalList{}) -} - -func (ms *MautrixSignal) GetSynapseName() string { - return ms.Spec.Synapse.Name -} - -func (ms *MautrixSignal) GetSynapseNamespace() string { - return ms.Spec.Synapse.Namespace -} diff --git a/apis/synapse/v1alpha1/synapse_types.go b/apis/synapse/v1alpha1/synapse_types.go deleted file mode 100644 index 9e4b34e..0000000 --- a/apis/synapse/v1alpha1/synapse_types.go +++ /dev/null @@ -1,184 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// SynapseSpec defines the desired state of Synapse -type SynapseSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // +kubebuilder:validation:Required - - // Holds information related to the homeserver.yaml configuration file. - // The user can either specify an existing ConfigMap by its Name and - // Namespace containing a homeserver.yaml, or provide a set of values for - // the creation of a configuration file from scratch. - Homeserver SynapseHomeserver `json:"homeserver"` - - // +kubebuilder:default:=false - - // Set to true to create a new PostreSQL instance. The homeserver.yaml - // 'database' section will be overwritten. - CreateNewPostgreSQL bool `json:"createNewPostgreSQL,omitempty"` - - // +kubebuilder:default:=false - - // Set to true if deploying on OpenShift - IsOpenshift bool `json:"isOpenshift,omitempty"` -} - -type SynapseHomeserver struct { - // Holds information about the ConfigMap containing the homeserver.yaml - // configuration file to be used as input for the configuration of the - // Synapse server. - ConfigMap *SynapseHomeserverConfigMap `json:"configMap,omitempty"` - - // Holds the required values for the creation of a homeserver.yaml - // configuration file by the Synapse Operator - Values *SynapseHomeserverValues `json:"values,omitempty"` -} - -type SynapseHomeserverConfigMap struct { - // +kubebuilder:validation:Required - - // Name of the ConfigMap in the given Namespace. - Name string `json:"name"` - - // Namespace in which the ConfigMap is living. If left empty, the Synapse - // namespace is used. - Namespace string `json:"namespace,omitempty"` -} - -type SynapseHomeserverValues struct { - // +kubebuilder:validation:Required - - // The public-facing domain of the server - ServerName string `json:"serverName"` - - // +kubebuilder:validation:Required - - // Whether or not to report anonymized homeserver usage statistics - ReportStats bool `json:"reportStats"` -} - -// SynapseStatus defines the observed state of Synapse -type SynapseStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Connection information to the external PostgreSQL Database - DatabaseConnectionInfo SynapseStatusDatabaseConnectionInfo `json:"databaseConnectionInfo,omitempty"` - - // Holds configuration information for Synapse - HomeserverConfiguration SynapseStatusHomeserverConfiguration `json:"homeserverConfiguration,omitempty"` - - // Information on the bridges deployed alongside Synapse - Bridges SynapseStatusBridges `json:"bridges,omitempty"` - - // State of the Synapse instance - State string `json:"state,omitempty"` - - // Reason for the current Synapse State - Reason string `json:"reason,omitempty"` - - // +kubebuilder:default:=false - NeedsReconcile bool `json:"needsReconcile,omitempty"` -} - -type SynapseStatusBridges struct { - // Information on the Heisenbridge (IRC Bridge). - Heisenbridge SynapseStatusBridgesHeisenbridge `json:"heisenbridge,omitempty"` - - // Information on the mautrix-signal bridge. - MautrixSignal SynapseStatusBridgesMautrixSignal `json:"mautrixsignal,omitempty"` -} - -type SynapseStatusBridgesHeisenbridge struct { - // +kubebuilder:default:=false - - // Whether a Heisenbridge has been deployed for this Synapse instance - Enabled bool `json:"enabled,omitempty"` - - // Name of the Heisenbridge object - Name string `json:"name,omitempty"` -} - -type SynapseStatusBridgesMautrixSignal struct { - // Whether a mautrix-signal has been deployed for this Synapse instance - Enabled bool `json:"enabled,omitempty"` - - // Name of the mautrix-signal bridge object - Name string `json:"name,omitempty"` -} - -type SynapseStatusDatabaseConnectionInfo struct { - // Endpoint to connect to the PostgreSQL database - ConnectionURL string `json:"connectionURL,omitempty"` - - // Name of the database to connect to - DatabaseName string `json:"databaseName,omitempty"` - - // User allowed to query the given database - User string `json:"user,omitempty"` - - // Base64 encoded password - Password string `json:"password,omitempty"` - - // State of the PostgreSQL database - State string `json:"State,omitempty"` -} - -type SynapseStatusHomeserverConfiguration struct { - // The public-facing domain of the server - ServerName string `json:"serverName,omitempty"` - - // Whether or not to report anonymized homeserver usage statistics - ReportStats bool `json:"reportStats,omitempty"` -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status - -// Synapse is the Schema for the synapses API -type Synapse struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // +kubebuilder:validation:Required - Spec SynapseSpec `json:"spec"` - Status SynapseStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// SynapseList contains a list of Synapse -type SynapseList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Synapse `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Synapse{}, &SynapseList{}) -} diff --git a/apis/synapse/v1alpha1/zz_generated.deepcopy.go b/apis/synapse/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index b4defae..0000000 --- a/apis/synapse/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,508 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Heisenbridge) DeepCopyInto(out *Heisenbridge) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Heisenbridge. -func (in *Heisenbridge) DeepCopy() *Heisenbridge { - if in == nil { - return nil - } - out := new(Heisenbridge) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Heisenbridge) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HeisenbridgeConfigMap) DeepCopyInto(out *HeisenbridgeConfigMap) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeisenbridgeConfigMap. -func (in *HeisenbridgeConfigMap) DeepCopy() *HeisenbridgeConfigMap { - if in == nil { - return nil - } - out := new(HeisenbridgeConfigMap) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HeisenbridgeList) DeepCopyInto(out *HeisenbridgeList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Heisenbridge, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeisenbridgeList. -func (in *HeisenbridgeList) DeepCopy() *HeisenbridgeList { - if in == nil { - return nil - } - out := new(HeisenbridgeList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HeisenbridgeList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HeisenbridgeSpec) DeepCopyInto(out *HeisenbridgeSpec) { - *out = *in - out.ConfigMap = in.ConfigMap - out.Synapse = in.Synapse -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeisenbridgeSpec. -func (in *HeisenbridgeSpec) DeepCopy() *HeisenbridgeSpec { - if in == nil { - return nil - } - out := new(HeisenbridgeSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HeisenbridgeStatus) DeepCopyInto(out *HeisenbridgeStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeisenbridgeStatus. -func (in *HeisenbridgeStatus) DeepCopy() *HeisenbridgeStatus { - if in == nil { - return nil - } - out := new(HeisenbridgeStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HeisenbridgeSynapseSpec) DeepCopyInto(out *HeisenbridgeSynapseSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeisenbridgeSynapseSpec. -func (in *HeisenbridgeSynapseSpec) DeepCopy() *HeisenbridgeSynapseSpec { - if in == nil { - return nil - } - out := new(HeisenbridgeSynapseSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MautrixSignal) DeepCopyInto(out *MautrixSignal) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MautrixSignal. -func (in *MautrixSignal) DeepCopy() *MautrixSignal { - if in == nil { - return nil - } - out := new(MautrixSignal) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *MautrixSignal) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MautrixSignalConfigMap) DeepCopyInto(out *MautrixSignalConfigMap) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MautrixSignalConfigMap. -func (in *MautrixSignalConfigMap) DeepCopy() *MautrixSignalConfigMap { - if in == nil { - return nil - } - out := new(MautrixSignalConfigMap) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MautrixSignalList) DeepCopyInto(out *MautrixSignalList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]MautrixSignal, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MautrixSignalList. -func (in *MautrixSignalList) DeepCopy() *MautrixSignalList { - if in == nil { - return nil - } - out := new(MautrixSignalList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *MautrixSignalList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MautrixSignalSpec) DeepCopyInto(out *MautrixSignalSpec) { - *out = *in - out.ConfigMap = in.ConfigMap - out.Synapse = in.Synapse -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MautrixSignalSpec. -func (in *MautrixSignalSpec) DeepCopy() *MautrixSignalSpec { - if in == nil { - return nil - } - out := new(MautrixSignalSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MautrixSignalStatus) DeepCopyInto(out *MautrixSignalStatus) { - *out = *in - out.Synapse = in.Synapse -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MautrixSignalStatus. -func (in *MautrixSignalStatus) DeepCopy() *MautrixSignalStatus { - if in == nil { - return nil - } - out := new(MautrixSignalStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MautrixSignalStatusSynapse) DeepCopyInto(out *MautrixSignalStatusSynapse) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MautrixSignalStatusSynapse. -func (in *MautrixSignalStatusSynapse) DeepCopy() *MautrixSignalStatusSynapse { - if in == nil { - return nil - } - out := new(MautrixSignalStatusSynapse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MautrixSignalSynapseSpec) DeepCopyInto(out *MautrixSignalSynapseSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MautrixSignalSynapseSpec. -func (in *MautrixSignalSynapseSpec) DeepCopy() *MautrixSignalSynapseSpec { - if in == nil { - return nil - } - out := new(MautrixSignalSynapseSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Synapse) DeepCopyInto(out *Synapse) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Synapse. -func (in *Synapse) DeepCopy() *Synapse { - if in == nil { - return nil - } - out := new(Synapse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Synapse) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseHomeserver) DeepCopyInto(out *SynapseHomeserver) { - *out = *in - if in.ConfigMap != nil { - in, out := &in.ConfigMap, &out.ConfigMap - *out = new(SynapseHomeserverConfigMap) - **out = **in - } - if in.Values != nil { - in, out := &in.Values, &out.Values - *out = new(SynapseHomeserverValues) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseHomeserver. -func (in *SynapseHomeserver) DeepCopy() *SynapseHomeserver { - if in == nil { - return nil - } - out := new(SynapseHomeserver) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseHomeserverConfigMap) DeepCopyInto(out *SynapseHomeserverConfigMap) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseHomeserverConfigMap. -func (in *SynapseHomeserverConfigMap) DeepCopy() *SynapseHomeserverConfigMap { - if in == nil { - return nil - } - out := new(SynapseHomeserverConfigMap) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseHomeserverValues) DeepCopyInto(out *SynapseHomeserverValues) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseHomeserverValues. -func (in *SynapseHomeserverValues) DeepCopy() *SynapseHomeserverValues { - if in == nil { - return nil - } - out := new(SynapseHomeserverValues) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseList) DeepCopyInto(out *SynapseList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Synapse, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseList. -func (in *SynapseList) DeepCopy() *SynapseList { - if in == nil { - return nil - } - out := new(SynapseList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *SynapseList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseSpec) DeepCopyInto(out *SynapseSpec) { - *out = *in - in.Homeserver.DeepCopyInto(&out.Homeserver) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseSpec. -func (in *SynapseSpec) DeepCopy() *SynapseSpec { - if in == nil { - return nil - } - out := new(SynapseSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseStatus) DeepCopyInto(out *SynapseStatus) { - *out = *in - out.DatabaseConnectionInfo = in.DatabaseConnectionInfo - out.HomeserverConfiguration = in.HomeserverConfiguration - out.Bridges = in.Bridges -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseStatus. -func (in *SynapseStatus) DeepCopy() *SynapseStatus { - if in == nil { - return nil - } - out := new(SynapseStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseStatusBridges) DeepCopyInto(out *SynapseStatusBridges) { - *out = *in - out.Heisenbridge = in.Heisenbridge - out.MautrixSignal = in.MautrixSignal -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseStatusBridges. -func (in *SynapseStatusBridges) DeepCopy() *SynapseStatusBridges { - if in == nil { - return nil - } - out := new(SynapseStatusBridges) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseStatusBridgesHeisenbridge) DeepCopyInto(out *SynapseStatusBridgesHeisenbridge) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseStatusBridgesHeisenbridge. -func (in *SynapseStatusBridgesHeisenbridge) DeepCopy() *SynapseStatusBridgesHeisenbridge { - if in == nil { - return nil - } - out := new(SynapseStatusBridgesHeisenbridge) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseStatusBridgesMautrixSignal) DeepCopyInto(out *SynapseStatusBridgesMautrixSignal) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseStatusBridgesMautrixSignal. -func (in *SynapseStatusBridgesMautrixSignal) DeepCopy() *SynapseStatusBridgesMautrixSignal { - if in == nil { - return nil - } - out := new(SynapseStatusBridgesMautrixSignal) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseStatusDatabaseConnectionInfo) DeepCopyInto(out *SynapseStatusDatabaseConnectionInfo) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseStatusDatabaseConnectionInfo. -func (in *SynapseStatusDatabaseConnectionInfo) DeepCopy() *SynapseStatusDatabaseConnectionInfo { - if in == nil { - return nil - } - out := new(SynapseStatusDatabaseConnectionInfo) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SynapseStatusHomeserverConfiguration) DeepCopyInto(out *SynapseStatusHomeserverConfiguration) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SynapseStatusHomeserverConfiguration. -func (in *SynapseStatusHomeserverConfiguration) DeepCopy() *SynapseStatusHomeserverConfiguration { - if in == nil { - return nil - } - out := new(SynapseStatusHomeserverConfiguration) - in.DeepCopyInto(out) - return out -} diff --git a/bundle.Dockerfile b/bundle.Dockerfile deleted file mode 100644 index 967926e..0000000 --- a/bundle.Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM scratch - -# Core bundle labels. -LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 -LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ -LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ -LABEL operators.operatorframework.io.bundle.package.v1=synapse-operator -LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.29.0 -LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 -LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 - -# Labels for testing. -LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 -LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ - -# Copy files to locations specified by labels. -COPY bundle/manifests /manifests/ -COPY bundle/metadata /metadata/ -COPY bundle/tests/scorecard /tests/scorecard/ diff --git a/bundle/manifests/synapse-operator-controller-manager-metrics-service_v1_service.yaml b/bundle/manifests/synapse-operator-controller-manager-metrics-service_v1_service.yaml deleted file mode 100644 index e3a2abf..0000000 --- a/bundle/manifests/synapse-operator-controller-manager-metrics-service_v1_service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - creationTimestamp: null - labels: - control-plane: controller-manager - name: synapse-operator-controller-manager-metrics-service -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https - selector: - control-plane: controller-manager -status: - loadBalancer: {} diff --git a/bundle/manifests/synapse-operator-manager-config_v1_configmap.yaml b/bundle/manifests/synapse-operator-manager-config_v1_configmap.yaml deleted file mode 100644 index 2a723cb..0000000 --- a/bundle/manifests/synapse-operator-manager-config_v1_configmap.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -data: - controller_manager_config.yaml: | - apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 - kind: ControllerManagerConfig - health: - healthProbeBindAddress: :8081 - metrics: - bindAddress: 127.0.0.1:8080 - webhook: - port: 9443 - leaderElection: - leaderElect: true - resourceName: 8d311e9b.opdev.io -kind: ConfigMap -metadata: - name: synapse-operator-manager-config diff --git a/bundle/manifests/synapse-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/synapse-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml deleted file mode 100644 index 9998eaa..0000000 --- a/bundle/manifests/synapse-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: synapse-operator-metrics-reader -rules: -- nonResourceURLs: - - /metrics - verbs: - - get diff --git a/bundle/manifests/synapse-operator.clusterserviceversion.yaml b/bundle/manifests/synapse-operator.clusterserviceversion.yaml deleted file mode 100644 index 0a70b28..0000000 --- a/bundle/manifests/synapse-operator.clusterserviceversion.yaml +++ /dev/null @@ -1,326 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: ClusterServiceVersion -metadata: - annotations: - alm-examples: |- - [ - { - "apiVersion": "synapse.opdev.io/v1alpha1", - "kind": "Heisenbridge", - "metadata": { - "labels": { - "app.kubernetes.io/created-by": "synapse-operator", - "app.kubernetes.io/instance": "heisenbridge-sample", - "app.kubernetes.io/managed-by": "kustomize", - "app.kubernetes.io/name": "heisenbridge", - "app.kubernetes.io/part-of": "synapse-operator" - }, - "name": "heisenbridge-sample" - }, - "spec": { - "synapse": { - "name": "synapse-sample" - } - } - }, - { - "apiVersion": "synapse.opdev.io/v1alpha1", - "kind": "MautrixSignal", - "metadata": { - "labels": { - "app.kubernetes.io/created-by": "synapse-operator", - "app.kubernetes.io/instance": "mautrixsignal-sample", - "app.kubernetes.io/managed-by": "kustomize", - "app.kubernetes.io/name": "mautrixsignal", - "app.kubernetes.io/part-of": "synapse-operator" - }, - "name": "mautrixsignal-sample" - }, - "spec": { - "synapse": { - "name": "synapse-sample" - } - } - }, - { - "apiVersion": "synapse.opdev.io/v1alpha1", - "kind": "Synapse", - "metadata": { - "name": "synapse-sample" - }, - "spec": { - "createNewPostgreSQL": false, - "homeserver": { - "values": { - "reportStats": true, - "serverName": "my.matrix.host" - } - } - } - } - ] - capabilities: Basic Install - categories: Developer Tools - containerImage: quay.io/opdev/synapse-operator - createdAt: "2025-05-16T15:21:27Z" - description: Deploys and manages the lifecycle of Synapse servers and their associated - components (bridges, databases, ...). Synapse is the reference Matrix homeserver - implementation. - operators.operatorframework.io/builder: operator-sdk-v1.29.0 - operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 - repository: https://github.com/opdev/synapse-operator - name: synapse-operator.v0.6.1 - namespace: placeholder -spec: - apiservicedefinitions: {} - customresourcedefinitions: - owned: - - description: Heisenbridge is the Schema for the heisenbridges API - displayName: Heisenbridge - kind: Heisenbridge - name: heisenbridges.synapse.opdev.io - version: v1alpha1 - - description: MautrixSignal is the Schema for the mautrixsignals API - displayName: Mautrix Signal - kind: MautrixSignal - name: mautrixsignals.synapse.opdev.io - version: v1alpha1 - - description: Synapse is the Schema for the synapses API - displayName: Synapse - kind: Synapse - name: synapses.synapse.opdev.io - version: v1alpha1 - description: Deploys and manages the lifecycle of Synapse servers and their associated - components (bridges, databases, ...). Synapse is the reference Matrix homeserver - implementation. - displayName: Synapse Operator - icon: - - base64data: iVBORw0KGgoAAAANSUhEUgAAAeAAAADMCAMAAACcE4BeAAAAM1BMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjBUbJAAAAEHRSTlMAECAwQFBgcICPn6+/z9/vIxqCigAACNVJREFUeNrt3duCoyoQBVAQRNTy8v9fex7O9HQuFFARiDp7P84kaWUpIKCq/T1eIZeMD2AqAAMYATBybuCVHuNQVNeMe2JcH4Bxzt72fAYwgBEAIwBGAIwAGAEwAmAAIwBGAIwAGAEwAmAEwABGAIwAGAEwAmAEwAiAAQxgACMARgCMABgBMAJgBMAARgCMABjpfCAdgG8TG3hgxm4BDGAAAxjAAAYwgG99CVG/hwvgb6ZB4QMYwAAGMIABDGAAAxjAAAYwgAEMYAADGMDXANY2EA3g2wB/PQAGMIABDGAAAxjAAAYwgAEM4NrA1vmRiGj23napYQDviYho8r43n/05Ywfvp/9f1Dd77501XwPurB+JaPa9vilwN9BzeW2z4/bVjOtL4S5jLzuU/LyEkPaNRte1Bn7aH7oo8PObLYmIaHwo8DlY3HOo0BxDM5ncQyn8xx4Pl8BPmcdND37ree/+fnGM7vnb/lDo7/3ExMrz7Zcf04c/3xUDDrybln7Lji1reiW2y57/4dCOpnT/aL29I9fusvz9IkX2XKl+Zf4vMdmg1/CfZWoyvQU/PaoWwD5aUM/bMMZLdUy0YG7NBlpdA+CO2P9LzSYx27OFSyB8WC+qAbBZUifT7yYnP7uvsXrariKixdQGdtv+MTB3rM/Beiv8WdMA2G7pgv4RzvjsvrG9LT3u0gx1gYMblA2slvRGxyvoQdUHdjll9WefXV7JMg1x+uwPZKoJPO3HgA1ziHeZFTSp+sCZZl7gu2/Bisds+35IuDjwtB8EVsOeB9dLWuuiwCa3tLp836dG+6jvw66VBvb7YWBFWZU0U0H3qjpwl13qgmMhuDkf+/6WaWHgfi8AzBTgSyU9p1qfasCCVrEXdYBfWyG9fuy7r7oGsN5KAHOHCaU/s+r6wPUyZXUyZPVBWeB5LwLM/c6QrKCtujLwyyncH/qttQKw3QsB62QlPWe2YtcCft4groLeJmd+JqfcxFaapjwwlQLmNmuJH9yLujjw+jQ+mTcWqYYtdrR8PNkQ+PC2FwPmBrR87AzfutbAG/ne2sFTlt7ke2t7P0W6TiZ5Ak/vvYxuyR0QkLRqJDs2pcB6iZXA/MEQVnlg+r0k0y51QfM4ZWQpY5DR5F8lMMf7qYG5C8iFr6Bn1RT4ZfRYR7u820u9yh0Pc6IOYxqhPt6cnhKYK1rPXSdvuinw0qn8i5r3YUhmCGNNFDCnsX4DmLyztlPGWufnUQys2EqaPrxCKgkcGFeMDEsEhpldohOrROPsY864SVFgYlYmCYCZAa0lPFY9qpbAwf6cyx+DZAvQRJsotpfR5xVrMeCFPZ0kt48OgiZg0U2Bh/yK8uXiJ9Fu2mhBmYPFWgo40p0V3R8sGKrLXjlaBHgVVJT77gTtpo3+YXUK4C3WGoqAdfZkyqCaAjtJZ5br/U3RyTAvaYKbAm/Rk0l2h3/uaKxgUW4J4I1b2Sq6fBs+HGxVuc1/JeD4hKzwEQ5565G2ri0wOycpql1sQWBqB5zozQqB82ZEJbcHlAB23KcXyd4VBHZ7M+DUhKz0ISw5kyGTagxsRCeSkpzvHwEzlxtVgJ0qC5wxnbPq1sDqVMA9V5nWAF5VaWCVXCAju3uqOTDVBNb9uAoK5jiwLw+cWngmLJICwOsZgDvr/LwKj/zjwF154MSA1qKaA9M3gY31nvJmeioAp0v7kyfdUaErpIsDd33qlK0PPFYBjg1oDerswGMJYDPM8iW0FYBdFeDIgNasTg/sDwPb6bP10RWAbR1gdtZh0/cHdh+vfq8ArCoBcwNao7o7sDtwc0N54K0WsCnVxboYcEf7fiZgqgW8FJhGuiDwgXvPrgXsiw1zXAo4/85TcpcGNkWWclwOOPfO02U0rSb86wDHpwwXfVPgnOUsK/m+ExTrOYFTjyC6KTAlZN3jYxOvDGzlfYk7APeRKvn9wZAXBk6v6Wg+H9wEmNntbewOFOsZgad0SzTfEJg5gWd9qFhPCJy1rrK/H/AsWy9zWeC8ldGNV1W2ABZOnV0WOPPeBrobsBXu5VWBs8dyhpsBD8KWzF8TOP+JY03vTWoALFsKdllgwVzKci9gaenSJYHDq+227dCsw3WBY1u7XRGYmSzrs9fx/zvA/YHpQv814IUb1aAjA1q3BKYDwNO3gD27Covpe03/bBtsj0z4r18CNpFBq+HAgNZ1gfkFUcsRYK7YKgPrJTbsTOzZfRPgSTJQOR5assPdsV8ZeIwSMpU03QbYC3oZ7tiarH3fp/7PWG9nh0bANlEJDx8PaF0DWPAsv2k/DPyYNsDMJPCc6jdu5ibAHTOc8zarEnujms27XP4G8JhsY7mnpN1lNolb5vD0pkPtSLbUhU4C3Gf0kplK2t8EmF+IttHovfeeexFpDHg6BzAzCTxnHY3mHsDdfjz2k9m5FsBz1kUQU0mv+hbAio4Dv3c5u1MA51TQkUp6vAewOQ7sP5mfqw/cZVXQka3tbwGsxsPAY/agZlPg/FEq7gVa+hbAWvRWyiVzO+nrwJJxZuaz8y2ARfcWTjZzGiG5irE2cH4FHTkeh1sAC4Sd0qF/1vmz7M2AF1Gtm/eWw6sCK5N3e/9qmEGqXsmFKwN7Yb8p91W01wROvMrl5yuau7YMX1DEf7QusBE3qiQd0LrYMzqSry+dOv5Q5+byLX0LWFZBRyppfkDrVk/ZWQcdPTfYW126gb4BPH5wYctU0ux94ULgzr6HHw01gU/z/QGb+WkTfODoNg9d6tfiD993fiL6+9NERN730X3JWH2uQ9uhI9tobWK5JPOlQsAnSdc/PKByo9k7o5AbASMARgAMYATACIARACMARgCMABjACIARACMARgCMABgBMIABDGAEwAiAEQAjAEYAjAAYwAiAEQAjAEYAjAAYATCAAQxgBMAIgBEAIwBGAIwAGMAIgBEAIwBGAIwAGAEwgBEAIwBGAIwAGAEwAmAAAxjACIARACPfA17pMQ6Fc824J8b1ATj3NaHIBc7Zl5eoAhjACICRswL/B97uAw3HlRdgAAAAAElFTkSuQmCC - mediatype: image/png - install: - spec: - clusterPermissions: - - rules: - - apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - "" - resources: - - configmaps - - persistentvolumeclaims - - serviceaccounts - - services - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - postgres-operator.crunchydata.com - resources: - - postgresclusters - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - rbac.authorization.k8s.io - resources: - - rolebindings - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - synapse.opdev.io - resources: - - heisenbridges - - mautrixsignals - - synapses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - synapse.opdev.io - resources: - - heisenbridges/finalizers - - mautrixsignals/finalizers - - synapses/finalizers - verbs: - - update - - apiGroups: - - synapse.opdev.io - resources: - - heisenbridges/status - - mautrixsignals/status - - synapses/status - verbs: - - get - - patch - - update - - apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create - - apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create - serviceAccountName: synapse-operator-controller-manager - deployments: - - label: - control-plane: controller-manager - name: synapse-operator-controller-manager - spec: - replicas: 1 - selector: - matchLabels: - control-plane: controller-manager - strategy: {} - template: - metadata: - labels: - control-plane: controller-manager - spec: - containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=10 - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: {} - - args: - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - - --leader-elect - command: - - /manager - image: quay.io/opdev/synapse-operator:v0.6.1 - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 200m - memory: 100Mi - requests: - cpu: 100m - memory: 20Mi - securityContext: - allowPrivilegeEscalation: false - securityContext: - runAsNonRoot: true - serviceAccountName: synapse-operator-controller-manager - terminationGracePeriodSeconds: 10 - permissions: - - rules: - - apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete - - apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch - serviceAccountName: synapse-operator-controller-manager - strategy: deployment - installModes: - - supported: false - type: OwnNamespace - - supported: false - type: SingleNamespace - - supported: false - type: MultiNamespace - - supported: true - type: AllNamespaces - keywords: - - synapse - - matrix - links: - - name: Synapse Operator repository - url: https://github.com/opdev/synapse-operator - - name: Matrix project - url: https://matrix.org - - name: Synapse repository - url: https://github.com/matrix-org/synapse - - name: Heisenbridge repository - url: https://github.com/hifi/heisenbridge - - name: mautrix-signal repository - url: https://github.com/mautrix/signal - maintainers: - - email: mgoerens@redhat.com - name: Matthias Goerens - maturity: alpha - minKubeVersion: 1.24.0 - provider: - name: Community - version: 0.6.1 diff --git a/bundle/manifests/synapse.opdev.io_heisenbridges.yaml b/bundle/manifests/synapse.opdev.io_heisenbridges.yaml deleted file mode 100644 index 20ed8b8..0000000 --- a/bundle/manifests/synapse.opdev.io_heisenbridges.yaml +++ /dev/null @@ -1,111 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.1 - creationTimestamp: null - name: heisenbridges.synapse.opdev.io -spec: - group: synapse.opdev.io - names: - kind: Heisenbridge - listKind: HeisenbridgeList - plural: heisenbridges - singular: heisenbridge - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Heisenbridge is the Schema for the heisenbridges API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: |- - HeisenbridgeSpec defines the desired state of Heisenbridge. The user can - either: - - enable the bridge, without specifying additional configuration options. - The bridge will be deployed with a default configuration. - - enable the bridge and specify an existing ConfigMap by its Name and - Namespace containing a heisenbridge.yaml. - properties: - configMap: - description: |- - Holds information about the ConfigMap containing the heisenbridge.yaml - configuration file to be used as input for the configuration of the - Heisenbridge IRC Bridge. - properties: - name: - description: Name of the ConfigMap in the given Namespace. - type: string - namespace: - description: |- - Namespace in which the ConfigMap is living. If left empty, the - Heisenbridge namespace is used. - type: string - required: - - name - type: object - synapse: - description: Name of the Synapse instance, living in the same namespace. - properties: - name: - description: Name of the Synapse instance - type: string - namespace: - description: Namespace of the Synapse instance - type: string - required: - - name - type: object - verboseLevel: - default: 0 - description: |- - Controls the verbosity of the Heisenbrige: - * 0 corresponds to normal level of logs - * 1 corresponds to "-v" - * 2 corresponds to "-vv" - * 3 corresponds to "-vvv" - type: integer - required: - - synapse - type: object - status: - description: HeisenbridgeStatus defines the observed state of Heisenbridge - properties: - reason: - description: Reason for the current Heisenbridge State - type: string - state: - description: State of the Heisenbridge instance - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/bundle/manifests/synapse.opdev.io_mautrixsignals.yaml b/bundle/manifests/synapse.opdev.io_mautrixsignals.yaml deleted file mode 100644 index b7ad54b..0000000 --- a/bundle/manifests/synapse.opdev.io_mautrixsignals.yaml +++ /dev/null @@ -1,113 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.1 - creationTimestamp: null - name: mautrixsignals.synapse.opdev.io -spec: - group: synapse.opdev.io - names: - kind: MautrixSignal - listKind: MautrixSignalList - plural: mautrixsignals - singular: mautrixsignal - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: MautrixSignal is the Schema for the mautrixsignals API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: |- - MautrixSignalSpec defines the desired state of MautrixSignal. The user can - either: - - enable the bridge, without specifying additional configuration options. - The bridge will be deployed with a default configuration. - - enable the bridge and specify an existing ConfigMap by its Name and - Namespace containing a config.yaml file. - properties: - configMap: - description: |- - Holds information about the ConfigMap containing the config.yaml - configuration file to be used as input for the configuration of the - mautrix-signal bridge. - properties: - name: - description: Name of the ConfigMap in the given Namespace. - type: string - namespace: - description: |- - Namespace in which the ConfigMap is living. If left empty, the Synapse - namespace is used. - type: string - required: - - name - type: object - synapse: - description: Name of the Synapse instance, living in the same namespace. - properties: - name: - description: Name of the Synapse instance - type: string - namespace: - description: Namespace of the Synapse instance - type: string - required: - - name - type: object - required: - - synapse - type: object - status: - description: MautrixSignalStatus defines the observed state of MautrixSignal - properties: - isOpenshift: - default: false - description: Values is set to true if deploying on OpenShift - type: boolean - reason: - description: Reason for the current MautrixSignal State - type: string - state: - description: State of the MautrixSignal instance - type: string - synapse: - description: Information related to the Synapse instance associated - with this bridge - properties: - serverName: - type: string - type: object - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/bundle/manifests/synapse.opdev.io_synapses.yaml b/bundle/manifests/synapse.opdev.io_synapses.yaml deleted file mode 100644 index 76f04e1..0000000 --- a/bundle/manifests/synapse.opdev.io_synapses.yaml +++ /dev/null @@ -1,183 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.1 - creationTimestamp: null - name: synapses.synapse.opdev.io -spec: - group: synapse.opdev.io - names: - kind: Synapse - listKind: SynapseList - plural: synapses - singular: synapse - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Synapse is the Schema for the synapses API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: SynapseSpec defines the desired state of Synapse - properties: - createNewPostgreSQL: - default: false - description: |- - Set to true to create a new PostreSQL instance. The homeserver.yaml - 'database' section will be overwritten. - type: boolean - homeserver: - description: |- - Holds information related to the homeserver.yaml configuration file. - The user can either specify an existing ConfigMap by its Name and - Namespace containing a homeserver.yaml, or provide a set of values for - the creation of a configuration file from scratch. - oneOf: - - required: - - configMap - - required: - - values - properties: - configMap: - description: |- - Holds information about the ConfigMap containing the homeserver.yaml - configuration file to be used as input for the configuration of the - Synapse server. - properties: - name: - description: Name of the ConfigMap in the given Namespace. - type: string - namespace: - description: |- - Namespace in which the ConfigMap is living. If left empty, the Synapse - namespace is used. - type: string - required: - - name - type: object - values: - description: |- - Holds the required values for the creation of a homeserver.yaml - configuration file by the Synapse Operator - properties: - reportStats: - description: Whether or not to report anonymized homeserver - usage statistics - type: boolean - serverName: - description: The public-facing domain of the server - type: string - required: - - reportStats - - serverName - type: object - type: object - isOpenshift: - default: false - description: Set to true if deploying on OpenShift - type: boolean - required: - - homeserver - type: object - status: - description: SynapseStatus defines the observed state of Synapse - properties: - bridges: - description: Information on the bridges deployed alongside Synapse - properties: - heisenbridge: - description: Information on the Heisenbridge (IRC Bridge). - properties: - enabled: - default: false - description: Whether a Heisenbridge has been deployed for - this Synapse instance - type: boolean - name: - description: Name of the Heisenbridge object - type: string - type: object - mautrixsignal: - description: Information on the mautrix-signal bridge. - properties: - enabled: - description: Whether a mautrix-signal has been deployed for - this Synapse instance - type: boolean - name: - description: Name of the mautrix-signal bridge object - type: string - type: object - type: object - databaseConnectionInfo: - description: Connection information to the external PostgreSQL Database - properties: - State: - description: State of the PostgreSQL database - type: string - connectionURL: - description: Endpoint to connect to the PostgreSQL database - type: string - databaseName: - description: Name of the database to connect to - type: string - password: - description: Base64 encoded password - type: string - user: - description: User allowed to query the given database - type: string - type: object - homeserverConfiguration: - description: Holds configuration information for Synapse - properties: - reportStats: - description: Whether or not to report anonymized homeserver usage - statistics - type: boolean - serverName: - description: The public-facing domain of the server - type: string - type: object - needsReconcile: - default: false - type: boolean - reason: - description: Reason for the current Synapse State - type: string - state: - description: State of the Synapse instance - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml deleted file mode 100644 index cac84db..0000000 --- a/bundle/metadata/annotations.yaml +++ /dev/null @@ -1,14 +0,0 @@ -annotations: - # Core bundle annotations. - operators.operatorframework.io.bundle.mediatype.v1: registry+v1 - operators.operatorframework.io.bundle.manifests.v1: manifests/ - operators.operatorframework.io.bundle.metadata.v1: metadata/ - operators.operatorframework.io.bundle.package.v1: synapse-operator - operators.operatorframework.io.bundle.channels.v1: alpha - operators.operatorframework.io.metrics.builder: operator-sdk-v1.29.0 - operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 - operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 - - # Annotations for testing. - operators.operatorframework.io.test.mediatype.v1: scorecard+v1 - operators.operatorframework.io.test.config.v1: tests/scorecard/ diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml deleted file mode 100644 index 89bdfbe..0000000 --- a/bundle/tests/scorecard/config.yaml +++ /dev/null @@ -1,70 +0,0 @@ -apiVersion: scorecard.operatorframework.io/v1alpha3 -kind: Configuration -metadata: - name: config -stages: -- parallel: true - tests: - - entrypoint: - - scorecard-test - - basic-check-spec - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: basic - test: basic-check-spec-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-bundle-validation - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-bundle-validation-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-crds-have-validation - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-crds-have-validation-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-crds-have-resources - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-crds-have-resources-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-spec-descriptors - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-spec-descriptors-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-status-descriptors - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-status-descriptors-test - storage: - spec: - mountPath: {} -storage: - spec: - mountPath: {} diff --git a/config/crd/bases/synapse.opdev.io_heisenbridges.yaml b/config/crd/bases/synapse.opdev.io_heisenbridges.yaml deleted file mode 100644 index 9478ff5..0000000 --- a/config/crd/bases/synapse.opdev.io_heisenbridges.yaml +++ /dev/null @@ -1,105 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.1 - name: heisenbridges.synapse.opdev.io -spec: - group: synapse.opdev.io - names: - kind: Heisenbridge - listKind: HeisenbridgeList - plural: heisenbridges - singular: heisenbridge - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Heisenbridge is the Schema for the heisenbridges API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: |- - HeisenbridgeSpec defines the desired state of Heisenbridge. The user can - either: - - enable the bridge, without specifying additional configuration options. - The bridge will be deployed with a default configuration. - - enable the bridge and specify an existing ConfigMap by its Name and - Namespace containing a heisenbridge.yaml. - properties: - configMap: - description: |- - Holds information about the ConfigMap containing the heisenbridge.yaml - configuration file to be used as input for the configuration of the - Heisenbridge IRC Bridge. - properties: - name: - description: Name of the ConfigMap in the given Namespace. - type: string - namespace: - description: |- - Namespace in which the ConfigMap is living. If left empty, the - Heisenbridge namespace is used. - type: string - required: - - name - type: object - synapse: - description: Name of the Synapse instance, living in the same namespace. - properties: - name: - description: Name of the Synapse instance - type: string - namespace: - description: Namespace of the Synapse instance - type: string - required: - - name - type: object - verboseLevel: - default: 0 - description: |- - Controls the verbosity of the Heisenbrige: - * 0 corresponds to normal level of logs - * 1 corresponds to "-v" - * 2 corresponds to "-vv" - * 3 corresponds to "-vvv" - type: integer - required: - - synapse - type: object - status: - description: HeisenbridgeStatus defines the observed state of Heisenbridge - properties: - reason: - description: Reason for the current Heisenbridge State - type: string - state: - description: State of the Heisenbridge instance - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/config/crd/bases/synapse.opdev.io_mautrixsignals.yaml b/config/crd/bases/synapse.opdev.io_mautrixsignals.yaml deleted file mode 100644 index ba97964..0000000 --- a/config/crd/bases/synapse.opdev.io_mautrixsignals.yaml +++ /dev/null @@ -1,107 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.1 - name: mautrixsignals.synapse.opdev.io -spec: - group: synapse.opdev.io - names: - kind: MautrixSignal - listKind: MautrixSignalList - plural: mautrixsignals - singular: mautrixsignal - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: MautrixSignal is the Schema for the mautrixsignals API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: |- - MautrixSignalSpec defines the desired state of MautrixSignal. The user can - either: - - enable the bridge, without specifying additional configuration options. - The bridge will be deployed with a default configuration. - - enable the bridge and specify an existing ConfigMap by its Name and - Namespace containing a config.yaml file. - properties: - configMap: - description: |- - Holds information about the ConfigMap containing the config.yaml - configuration file to be used as input for the configuration of the - mautrix-signal bridge. - properties: - name: - description: Name of the ConfigMap in the given Namespace. - type: string - namespace: - description: |- - Namespace in which the ConfigMap is living. If left empty, the Synapse - namespace is used. - type: string - required: - - name - type: object - synapse: - description: Name of the Synapse instance, living in the same namespace. - properties: - name: - description: Name of the Synapse instance - type: string - namespace: - description: Namespace of the Synapse instance - type: string - required: - - name - type: object - required: - - synapse - type: object - status: - description: MautrixSignalStatus defines the observed state of MautrixSignal - properties: - isOpenshift: - default: false - description: Values is set to true if deploying on OpenShift - type: boolean - reason: - description: Reason for the current MautrixSignal State - type: string - state: - description: State of the MautrixSignal instance - type: string - synapse: - description: Information related to the Synapse instance associated - with this bridge - properties: - serverName: - type: string - type: object - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/config/crd/bases/synapse.opdev.io_synapses.yaml b/config/crd/bases/synapse.opdev.io_synapses.yaml deleted file mode 100644 index c4240a5..0000000 --- a/config/crd/bases/synapse.opdev.io_synapses.yaml +++ /dev/null @@ -1,172 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.1 - name: synapses.synapse.opdev.io -spec: - group: synapse.opdev.io - names: - kind: Synapse - listKind: SynapseList - plural: synapses - singular: synapse - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Synapse is the Schema for the synapses API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: SynapseSpec defines the desired state of Synapse - properties: - createNewPostgreSQL: - default: false - description: |- - Set to true to create a new PostreSQL instance. The homeserver.yaml - 'database' section will be overwritten. - type: boolean - homeserver: - description: |- - Holds information related to the homeserver.yaml configuration file. - The user can either specify an existing ConfigMap by its Name and - Namespace containing a homeserver.yaml, or provide a set of values for - the creation of a configuration file from scratch. - properties: - configMap: - description: |- - Holds information about the ConfigMap containing the homeserver.yaml - configuration file to be used as input for the configuration of the - Synapse server. - properties: - name: - description: Name of the ConfigMap in the given Namespace. - type: string - namespace: - description: |- - Namespace in which the ConfigMap is living. If left empty, the Synapse - namespace is used. - type: string - required: - - name - type: object - values: - description: |- - Holds the required values for the creation of a homeserver.yaml - configuration file by the Synapse Operator - properties: - reportStats: - description: Whether or not to report anonymized homeserver - usage statistics - type: boolean - serverName: - description: The public-facing domain of the server - type: string - required: - - reportStats - - serverName - type: object - type: object - isOpenshift: - default: false - description: Set to true if deploying on OpenShift - type: boolean - required: - - homeserver - type: object - status: - description: SynapseStatus defines the observed state of Synapse - properties: - bridges: - description: Information on the bridges deployed alongside Synapse - properties: - heisenbridge: - description: Information on the Heisenbridge (IRC Bridge). - properties: - enabled: - default: false - description: Whether a Heisenbridge has been deployed for - this Synapse instance - type: boolean - name: - description: Name of the Heisenbridge object - type: string - type: object - mautrixsignal: - description: Information on the mautrix-signal bridge. - properties: - enabled: - description: Whether a mautrix-signal has been deployed for - this Synapse instance - type: boolean - name: - description: Name of the mautrix-signal bridge object - type: string - type: object - type: object - databaseConnectionInfo: - description: Connection information to the external PostgreSQL Database - properties: - State: - description: State of the PostgreSQL database - type: string - connectionURL: - description: Endpoint to connect to the PostgreSQL database - type: string - databaseName: - description: Name of the database to connect to - type: string - password: - description: Base64 encoded password - type: string - user: - description: User allowed to query the given database - type: string - type: object - homeserverConfiguration: - description: Holds configuration information for Synapse - properties: - reportStats: - description: Whether or not to report anonymized homeserver usage - statistics - type: boolean - serverName: - description: The public-facing domain of the server - type: string - type: object - needsReconcile: - default: false - type: boolean - reason: - description: Reason for the current Synapse State - type: string - state: - description: State of the Synapse instance - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml deleted file mode 100644 index 4438c1a..0000000 --- a/config/crd/kustomization.yaml +++ /dev/null @@ -1,35 +0,0 @@ -# This kustomization.yaml is not intended to be run by itself, -# since it depends on service name and namespace that are out of this kustomize package. -# It should be run by config/default -resources: -- bases/synapse.opdev.io_synapses.yaml -- bases/synapse.opdev.io_mautrixsignals.yaml -- bases/synapse.opdev.io_heisenbridges.yaml -#+kubebuilder:scaffold:crdkustomizeresource - -patches: -- path: patches/oneofhomeserver_in_synapses.yaml - target: - group: apiextensions.k8s.io - version: v1 - kind: CustomResourceDefinition - name: synapses.synapse.opdev.io - -patchesStrategicMerge: -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. -# patches here are for enabling the conversion webhook for each CRD -#- patches/webhook_in_synapses.yaml -#- patches/webhook_in_mautrixsignals.yaml -#- patches/webhook_in_heisenbridges.yaml -#+kubebuilder:scaffold:crdkustomizewebhookpatch - -# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. -# patches here are for enabling the CA injection for each CRD -#- patches/cainjection_in_synapses.yaml -#- patches/cainjection_in_mautrixsignals.yaml -#- patches/cainjection_in_heisenbridges.yaml -#+kubebuilder:scaffold:crdkustomizecainjectionpatch - -# the following config is for teaching kustomize how to do kustomization for CRDs. -configurations: -- kustomizeconfig.yaml diff --git a/config/crd/kustomizeconfig.yaml b/config/crd/kustomizeconfig.yaml deleted file mode 100644 index ec5c150..0000000 --- a/config/crd/kustomizeconfig.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# This file is for teaching kustomize how to substitute name and namespace reference in CRD -nameReference: -- kind: Service - version: v1 - fieldSpecs: - - kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/name - -namespace: -- kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/namespace - create: false - -varReference: -- path: metadata/annotations diff --git a/config/crd/patches/cainjection_in_synapse_heisenbridges.yaml b/config/crd/patches/cainjection_in_synapse_heisenbridges.yaml deleted file mode 100644 index d048b0c..0000000 --- a/config/crd/patches/cainjection_in_synapse_heisenbridges.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: heisenbridges.synapse.opdev.io diff --git a/config/crd/patches/cainjection_in_synapse_mautrixsignals.yaml b/config/crd/patches/cainjection_in_synapse_mautrixsignals.yaml deleted file mode 100644 index 4bff4e0..0000000 --- a/config/crd/patches/cainjection_in_synapse_mautrixsignals.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: mautrixsignals.synapse.opdev.io diff --git a/config/crd/patches/cainjection_in_synapses.yaml b/config/crd/patches/cainjection_in_synapses.yaml deleted file mode 100644 index a24d9a9..0000000 --- a/config/crd/patches/cainjection_in_synapses.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: synapses.synapse.opdev.io diff --git a/config/crd/patches/oneofhomeserver_in_synapses.yaml b/config/crd/patches/oneofhomeserver_in_synapses.yaml deleted file mode 100644 index 9b03553..0000000 --- a/config/crd/patches/oneofhomeserver_in_synapses.yaml +++ /dev/null @@ -1,5 +0,0 @@ -- op: replace - path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/homeserver/oneOf - value: - - required: [configMap] - - required: [values] \ No newline at end of file diff --git a/config/crd/patches/webhook_in_synapse_heisenbridges.yaml b/config/crd/patches/webhook_in_synapse_heisenbridges.yaml deleted file mode 100644 index c889d34..0000000 --- a/config/crd/patches/webhook_in_synapse_heisenbridges.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: heisenbridges.synapse.opdev.io -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/crd/patches/webhook_in_synapse_mautrixsignals.yaml b/config/crd/patches/webhook_in_synapse_mautrixsignals.yaml deleted file mode 100644 index 4f3fadd..0000000 --- a/config/crd/patches/webhook_in_synapse_mautrixsignals.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: mautrixsignals.synapse.opdev.io -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/crd/patches/webhook_in_synapses.yaml b/config/crd/patches/webhook_in_synapses.yaml deleted file mode 100644 index 8989744..0000000 --- a/config/crd/patches/webhook_in_synapses.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: synapses.synapse.opdev.io -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml deleted file mode 100644 index c63ecd3..0000000 --- a/config/default/kustomization.yaml +++ /dev/null @@ -1,74 +0,0 @@ -# Adds namespace to all resources. -namespace: synapse-operator-system - -# Value of this field is prepended to the -# names of all resources, e.g. a deployment named -# "wordpress" becomes "alices-wordpress". -# Note that it should also match with the prefix (text before '-') of the namespace -# field above. -namePrefix: synapse-operator- - -# Labels to add to all resources and selectors. -#commonLabels: -# someName: someValue - -bases: -- ../crd -- ../rbac -- ../manager -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -#- ../webhook -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -#- ../certmanager -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus - -patchesStrategicMerge: -# Protect the /metrics endpoint by putting it behind auth. -# If you want your controller-manager to expose the /metrics -# endpoint w/o any authn/z, please comment the following line. -- manager_auth_proxy_patch.yaml - -# Mount the controller config file for loading manager configurations -# through a ComponentConfig type -#- manager_config_patch.yaml - -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -#- manager_webhook_patch.yaml - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. -# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. -# 'CERTMANAGER' needs to be enabled to use ca injection -#- webhookcainjection_patch.yaml - -# the following config is for teaching kustomize how to do var substitution -vars: -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldref: -# fieldpath: metadata.namespace -#- name: CERTIFICATE_NAME -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -#- name: SERVICE_NAMESPACE # namespace of the service -# objref: -# kind: Service -# version: v1 -# name: webhook-service -# fieldref: -# fieldpath: metadata.namespace -#- name: SERVICE_NAME -# objref: -# kind: Service -# version: v1 -# name: webhook-service diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml deleted file mode 100644 index 4e2232f..0000000 --- a/config/default/manager_auth_proxy_patch.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# This patch inject a sidecar container which is a HTTP proxy for the -# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: kube-rbac-proxy - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=10" - ports: - - containerPort: 8443 - protocol: TCP - name: https - - name: manager - args: - - "--health-probe-bind-address=:8081" - - "--metrics-bind-address=127.0.0.1:8080" - - "--leader-elect" diff --git a/config/default/manager_config_patch.yaml b/config/default/manager_config_patch.yaml deleted file mode 100644 index 6c40015..0000000 --- a/config/default/manager_config_patch.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: manager - args: - - "--config=controller_manager_config.yaml" - volumeMounts: - - name: manager-config - mountPath: /controller_manager_config.yaml - subPath: controller_manager_config.yaml - volumes: - - name: manager-config - configMap: - name: manager-config diff --git a/config/manager/controller_manager_config.yaml b/config/manager/controller_manager_config.yaml deleted file mode 100644 index 19a8075..0000000 --- a/config/manager/controller_manager_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 -kind: ControllerManagerConfig -health: - healthProbeBindAddress: :8081 -metrics: - bindAddress: 127.0.0.1:8080 -webhook: - port: 9443 -leaderElection: - leaderElect: true - resourceName: 8d311e9b.opdev.io diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml deleted file mode 100644 index 710cdd2..0000000 --- a/config/manager/kustomization.yaml +++ /dev/null @@ -1,16 +0,0 @@ -resources: -- manager.yaml - -generatorOptions: - disableNameSuffixHash: true - -configMapGenerator: -- files: - - controller_manager_config.yaml - name: manager-config -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -images: -- name: controller - newName: quay.io/opdev/synapse-operator - newTag: v0.6.1 diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml deleted file mode 100644 index 2026244..0000000 --- a/config/manager/manager.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - name: system ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system - labels: - control-plane: controller-manager -spec: - selector: - matchLabels: - control-plane: controller-manager - replicas: 1 - template: - metadata: - labels: - control-plane: controller-manager - spec: - securityContext: - runAsNonRoot: true - containers: - - command: - - /manager - args: - - --leader-elect - image: controller:latest - name: manager - securityContext: - allowPrivilegeEscalation: false - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 200m - memory: 100Mi - requests: - cpu: 100m - memory: 20Mi - serviceAccountName: controller-manager - terminationGracePeriodSeconds: 10 diff --git a/config/manifests/bases/synapse-operator.clusterserviceversion.yaml b/config/manifests/bases/synapse-operator.clusterserviceversion.yaml deleted file mode 100644 index 13d8e78..0000000 --- a/config/manifests/bases/synapse-operator.clusterserviceversion.yaml +++ /dev/null @@ -1,75 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: ClusterServiceVersion -metadata: - annotations: - alm-examples: '[]' - capabilities: Basic Install - categories: Developer Tools - containerImage: quay.io/opdev/synapse-operator - description: Deploys and manages the lifecycle of Synapse servers and their associated - components (bridges, databases, ...). Synapse is the reference Matrix homeserver - implementation. - repository: https://github.com/opdev/synapse-operator - name: synapse-operator.v0.0.0 - namespace: placeholder -spec: - apiservicedefinitions: {} - customresourcedefinitions: - owned: - - description: Heisenbridge is the Schema for the heisenbridges API - displayName: Heisenbridge - kind: Heisenbridge - name: heisenbridges.synapse.opdev.io - version: v1alpha1 - - description: MautrixSignal is the Schema for the mautrixsignals API - displayName: Mautrix Signal - kind: MautrixSignal - name: mautrixsignals.synapse.opdev.io - version: v1alpha1 - - description: Synapse is the Schema for the synapses API - displayName: Synapse - kind: Synapse - name: synapses.synapse.opdev.io - version: v1alpha1 - description: Deploys and manages the lifecycle of Synapse servers and their associated - components (bridges, databases, ...). Synapse is the reference Matrix homeserver - implementation. - displayName: Synapse Operator - icon: - - base64data: iVBORw0KGgoAAAANSUhEUgAAAeAAAADMCAMAAACcE4BeAAAAM1BMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjBUbJAAAAEHRSTlMAECAwQFBgcICPn6+/z9/vIxqCigAACNVJREFUeNrt3duCoyoQBVAQRNTy8v9fex7O9HQuFFARiDp7P84kaWUpIKCq/T1eIZeMD2AqAAMYATBybuCVHuNQVNeMe2JcH4Bxzt72fAYwgBEAIwBGAIwAGAEwAmAAIwBGAIwAGAEwAmAEwABGAIwAGAEwAmAEwAiAAQxgACMARgCMABgBMAJgBMAARgCMABjpfCAdgG8TG3hgxm4BDGAAAxjAAAYwgG99CVG/hwvgb6ZB4QMYwAAGMIABDGAAAxjAAAYwgAEMYAADGMDXANY2EA3g2wB/PQAGMIABDGAAAxjAAAYwgAEM4NrA1vmRiGj23napYQDviYho8r43n/05Ywfvp/9f1Dd77501XwPurB+JaPa9vilwN9BzeW2z4/bVjOtL4S5jLzuU/LyEkPaNRte1Bn7aH7oo8PObLYmIaHwo8DlY3HOo0BxDM5ncQyn8xx4Pl8BPmcdND37ree/+fnGM7vnb/lDo7/3ExMrz7Zcf04c/3xUDDrybln7Lji1reiW2y57/4dCOpnT/aL29I9fusvz9IkX2XKl+Zf4vMdmg1/CfZWoyvQU/PaoWwD5aUM/bMMZLdUy0YG7NBlpdA+CO2P9LzSYx27OFSyB8WC+qAbBZUifT7yYnP7uvsXrariKixdQGdtv+MTB3rM/Beiv8WdMA2G7pgv4RzvjsvrG9LT3u0gx1gYMblA2slvRGxyvoQdUHdjll9WefXV7JMg1x+uwPZKoJPO3HgA1ziHeZFTSp+sCZZl7gu2/Bisds+35IuDjwtB8EVsOeB9dLWuuiwCa3tLp836dG+6jvw66VBvb7YWBFWZU0U0H3qjpwl13qgmMhuDkf+/6WaWHgfi8AzBTgSyU9p1qfasCCVrEXdYBfWyG9fuy7r7oGsN5KAHOHCaU/s+r6wPUyZXUyZPVBWeB5LwLM/c6QrKCtujLwyyncH/qttQKw3QsB62QlPWe2YtcCft4groLeJmd+JqfcxFaapjwwlQLmNmuJH9yLujjw+jQ+mTcWqYYtdrR8PNkQ+PC2FwPmBrR87AzfutbAG/ne2sFTlt7ke2t7P0W6TiZ5Ak/vvYxuyR0QkLRqJDs2pcB6iZXA/MEQVnlg+r0k0y51QfM4ZWQpY5DR5F8lMMf7qYG5C8iFr6Bn1RT4ZfRYR7u820u9yh0Pc6IOYxqhPt6cnhKYK1rPXSdvuinw0qn8i5r3YUhmCGNNFDCnsX4DmLyztlPGWufnUQys2EqaPrxCKgkcGFeMDEsEhpldohOrROPsY864SVFgYlYmCYCZAa0lPFY9qpbAwf6cyx+DZAvQRJsotpfR5xVrMeCFPZ0kt48OgiZg0U2Bh/yK8uXiJ9Fu2mhBmYPFWgo40p0V3R8sGKrLXjlaBHgVVJT77gTtpo3+YXUK4C3WGoqAdfZkyqCaAjtJZ5br/U3RyTAvaYKbAm/Rk0l2h3/uaKxgUW4J4I1b2Sq6fBs+HGxVuc1/JeD4hKzwEQ5565G2ri0wOycpql1sQWBqB5zozQqB82ZEJbcHlAB23KcXyd4VBHZ7M+DUhKz0ISw5kyGTagxsRCeSkpzvHwEzlxtVgJ0qC5wxnbPq1sDqVMA9V5nWAF5VaWCVXCAju3uqOTDVBNb9uAoK5jiwLw+cWngmLJICwOsZgDvr/LwKj/zjwF154MSA1qKaA9M3gY31nvJmeioAp0v7kyfdUaErpIsDd33qlK0PPFYBjg1oDerswGMJYDPM8iW0FYBdFeDIgNasTg/sDwPb6bP10RWAbR1gdtZh0/cHdh+vfq8ArCoBcwNao7o7sDtwc0N54K0WsCnVxboYcEf7fiZgqgW8FJhGuiDwgXvPrgXsiw1zXAo4/85TcpcGNkWWclwOOPfO02U0rSb86wDHpwwXfVPgnOUsK/m+ExTrOYFTjyC6KTAlZN3jYxOvDGzlfYk7APeRKvn9wZAXBk6v6Wg+H9wEmNntbewOFOsZgad0SzTfEJg5gWd9qFhPCJy1rrK/H/AsWy9zWeC8ldGNV1W2ABZOnV0WOPPeBrobsBXu5VWBs8dyhpsBD8KWzF8TOP+JY03vTWoALFsKdllgwVzKci9gaenSJYHDq+227dCsw3WBY1u7XRGYmSzrs9fx/zvA/YHpQv814IUb1aAjA1q3BKYDwNO3gD27Covpe03/bBtsj0z4r18CNpFBq+HAgNZ1gfkFUcsRYK7YKgPrJTbsTOzZfRPgSTJQOR5assPdsV8ZeIwSMpU03QbYC3oZ7tiarH3fp/7PWG9nh0bANlEJDx8PaF0DWPAsv2k/DPyYNsDMJPCc6jdu5ibAHTOc8zarEnujms27XP4G8JhsY7mnpN1lNolb5vD0pkPtSLbUhU4C3Gf0kplK2t8EmF+IttHovfeeexFpDHg6BzAzCTxnHY3mHsDdfjz2k9m5FsBz1kUQU0mv+hbAio4Dv3c5u1MA51TQkUp6vAewOQ7sP5mfqw/cZVXQka3tbwGsxsPAY/agZlPg/FEq7gVa+hbAWvRWyiVzO+nrwJJxZuaz8y2ARfcWTjZzGiG5irE2cH4FHTkeh1sAC4Sd0qF/1vmz7M2AF1Gtm/eWw6sCK5N3e/9qmEGqXsmFKwN7Yb8p91W01wROvMrl5yuau7YMX1DEf7QusBE3qiQd0LrYMzqSry+dOv5Q5+byLX0LWFZBRyppfkDrVk/ZWQcdPTfYW126gb4BPH5wYctU0ux94ULgzr6HHw01gU/z/QGb+WkTfODoNg9d6tfiD993fiL6+9NERN730X3JWH2uQ9uhI9tobWK5JPOlQsAnSdc/PKByo9k7o5AbASMARgAMYATACIARACMARgCMABjACIARACMARgCMABgBMIABDGAEwAiAEQAjAEYAjAAYwAiAEQAjAEYAjAAYATCAAQxgBMAIgBEAIwBGAIwAGMAIgBEAIwBGAIwAGAEwgBEAIwBGAIwAGAEwAmAAAxjACIARACPfA17pMQ6Fc824J8b1ATj3NaHIBc7Zl5eoAhjACICRswL/B97uAw3HlRdgAAAAAElFTkSuQmCC - mediatype: image/png - install: - spec: - deployments: null - strategy: "" - installModes: - - supported: false - type: OwnNamespace - - supported: false - type: SingleNamespace - - supported: false - type: MultiNamespace - - supported: true - type: AllNamespaces - keywords: - - synapse - - matrix - links: - - name: Synapse Operator repository - url: https://github.com/opdev/synapse-operator - - name: Matrix project - url: https://matrix.org - - name: Synapse repository - url: https://github.com/matrix-org/synapse - - name: Heisenbridge repository - url: https://github.com/hifi/heisenbridge - - name: mautrix-signal repository - url: https://github.com/mautrix/signal - maintainers: - - email: mgoerens@redhat.com - name: Matthias Goerens - maturity: alpha - minKubeVersion: 1.24.0 - provider: - name: Community - version: 0.0.0 diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml deleted file mode 100644 index a33b56f..0000000 --- a/config/manifests/kustomization.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# These resources constitute the fully configured set of manifests -# used to generate the 'manifests/' directory in a bundle. -resources: -- bases/synapse-operator.clusterserviceversion.yaml -- ../default -- ../samples -- ../scorecard - -# [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. -# Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. -# These patches remove the unnecessary "cert" volume and its manager container volumeMount. -#patchesJson6902: -#- target: -# group: apps -# version: v1 -# kind: Deployment -# name: controller-manager -# namespace: system -# patch: |- -# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. -# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. -# - op: remove -# path: /spec/template/spec/containers/1/volumeMounts/0 -# # Remove the "cert" volume, since OLM will create and mount a set of certs. -# # Update the indices in this path if adding or removing volumes in the manager's Deployment. -# - op: remove -# path: /spec/template/spec/volumes/0 diff --git a/config/prometheus/kustomization.yaml b/config/prometheus/kustomization.yaml deleted file mode 100644 index ed13716..0000000 --- a/config/prometheus/kustomization.yaml +++ /dev/null @@ -1,2 +0,0 @@ -resources: -- monitor.yaml diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml deleted file mode 100644 index d19136a..0000000 --- a/config/prometheus/monitor.yaml +++ /dev/null @@ -1,20 +0,0 @@ - -# Prometheus Monitor Service (Metrics) -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - control-plane: controller-manager - name: controller-manager-metrics-monitor - namespace: system -spec: - endpoints: - - path: /metrics - port: https - scheme: https - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - tlsConfig: - insecureSkipVerify: true - selector: - matchLabels: - control-plane: controller-manager diff --git a/config/rbac/auth_proxy_client_clusterrole.yaml b/config/rbac/auth_proxy_client_clusterrole.yaml deleted file mode 100644 index 51a75db..0000000 --- a/config/rbac/auth_proxy_client_clusterrole.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: metrics-reader -rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/auth_proxy_role.yaml deleted file mode 100644 index 80e1857..0000000 --- a/config/rbac/auth_proxy_role.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: proxy-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create diff --git a/config/rbac/auth_proxy_role_binding.yaml b/config/rbac/auth_proxy_role_binding.yaml deleted file mode 100644 index ec7acc0..0000000 --- a/config/rbac/auth_proxy_role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: proxy-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: proxy-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/auth_proxy_service.yaml deleted file mode 100644 index 71f1797..0000000 --- a/config/rbac/auth_proxy_service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - control-plane: controller-manager - name: controller-manager-metrics-service - namespace: system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https - selector: - control-plane: controller-manager diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml deleted file mode 100644 index 731832a..0000000 --- a/config/rbac/kustomization.yaml +++ /dev/null @@ -1,18 +0,0 @@ -resources: -# All RBAC will be applied under this service account in -# the deployment namespace. You may comment out this resource -# if your manager will use a service account that exists at -# runtime. Be sure to update RoleBinding and ClusterRoleBinding -# subjects if changing service account names. -- service_account.yaml -- role.yaml -- role_binding.yaml -- leader_election_role.yaml -- leader_election_role_binding.yaml -# Comment the following 4 lines if you want to disable -# the auth proxy (https://github.com/brancz/kube-rbac-proxy) -# which protects your /metrics endpoint. -- auth_proxy_service.yaml -- auth_proxy_role.yaml -- auth_proxy_role_binding.yaml -- auth_proxy_client_clusterrole.yaml diff --git a/config/rbac/leader_election_role.yaml b/config/rbac/leader_election_role.yaml deleted file mode 100644 index 4190ec8..0000000 --- a/config/rbac/leader_election_role.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: leader-election-role -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch diff --git a/config/rbac/leader_election_role_binding.yaml b/config/rbac/leader_election_role_binding.yaml deleted file mode 100644 index 1d1321e..0000000 --- a/config/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: leader-election-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml deleted file mode 100644 index 9f0c1ac..0000000 --- a/config/rbac/role.yaml +++ /dev/null @@ -1,97 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: manager-role -rules: -- apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - configmaps - - persistentvolumeclaims - - serviceaccounts - - services - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - postgres-operator.crunchydata.com - resources: - - postgresclusters - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - rbac.authorization.k8s.io - resources: - - rolebindings - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - security.openshift.io - resourceNames: - - anyuid - resources: - - securitycontextconstraints - verbs: - - use -- apiGroups: - - synapse.opdev.io - resources: - - heisenbridges - - mautrixsignals - - synapses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - synapse.opdev.io - resources: - - heisenbridges/finalizers - - mautrixsignals/finalizers - - synapses/finalizers - verbs: - - update -- apiGroups: - - synapse.opdev.io - resources: - - heisenbridges/status - - mautrixsignals/status - - synapses/status - verbs: - - get - - patch - - update diff --git a/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml deleted file mode 100644 index 2070ede..0000000 --- a/config/rbac/role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: manager-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/config/rbac/service_account.yaml b/config/rbac/service_account.yaml deleted file mode 100644 index 7cd6025..0000000 --- a/config/rbac/service_account.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: controller-manager - namespace: system diff --git a/config/rbac/synapse_editor_role.yaml b/config/rbac/synapse_editor_role.yaml deleted file mode 100644 index dc72581..0000000 --- a/config/rbac/synapse_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit synapses. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: synapse-editor-role -rules: -- apiGroups: - - synapse.opdev.io - resources: - - synapses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - synapse.opdev.io - resources: - - synapses/status - verbs: - - get diff --git a/config/rbac/synapse_heisenbridge_editor_role.yaml b/config/rbac/synapse_heisenbridge_editor_role.yaml deleted file mode 100644 index 8bd42d4..0000000 --- a/config/rbac/synapse_heisenbridge_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit heisenbridges. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: heisenbridge-editor-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: synapse-operator - app.kubernetes.io/part-of: synapse-operator - app.kubernetes.io/managed-by: kustomize - name: heisenbridge-editor-role -rules: -- apiGroups: - - synapse.opdev.io - resources: - - heisenbridges - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - synapse.opdev.io - resources: - - heisenbridges/status - verbs: - - get diff --git a/config/rbac/synapse_heisenbridge_viewer_role.yaml b/config/rbac/synapse_heisenbridge_viewer_role.yaml deleted file mode 100644 index 223501c..0000000 --- a/config/rbac/synapse_heisenbridge_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view heisenbridges. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: heisenbridge-viewer-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: synapse-operator - app.kubernetes.io/part-of: synapse-operator - app.kubernetes.io/managed-by: kustomize - name: heisenbridge-viewer-role -rules: -- apiGroups: - - synapse.opdev.io - resources: - - heisenbridges - verbs: - - get - - list - - watch -- apiGroups: - - synapse.opdev.io - resources: - - heisenbridges/status - verbs: - - get diff --git a/config/rbac/synapse_mautrixsignal_editor_role.yaml b/config/rbac/synapse_mautrixsignal_editor_role.yaml deleted file mode 100644 index edacdf5..0000000 --- a/config/rbac/synapse_mautrixsignal_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit mautrixsignals. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: mautrixsignal-editor-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: synapse-operator - app.kubernetes.io/part-of: synapse-operator - app.kubernetes.io/managed-by: kustomize - name: mautrixsignal-editor-role -rules: -- apiGroups: - - synapse.opdev.io - resources: - - mautrixsignals - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - synapse.opdev.io - resources: - - mautrixsignals/status - verbs: - - get diff --git a/config/rbac/synapse_mautrixsignal_viewer_role.yaml b/config/rbac/synapse_mautrixsignal_viewer_role.yaml deleted file mode 100644 index d86d935..0000000 --- a/config/rbac/synapse_mautrixsignal_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view mautrixsignals. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: mautrixsignal-viewer-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: synapse-operator - app.kubernetes.io/part-of: synapse-operator - app.kubernetes.io/managed-by: kustomize - name: mautrixsignal-viewer-role -rules: -- apiGroups: - - synapse.opdev.io - resources: - - mautrixsignals - verbs: - - get - - list - - watch -- apiGroups: - - synapse.opdev.io - resources: - - mautrixsignals/status - verbs: - - get diff --git a/config/rbac/synapse_viewer_role.yaml b/config/rbac/synapse_viewer_role.yaml deleted file mode 100644 index b84cd70..0000000 --- a/config/rbac/synapse_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view synapses. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: synapse-viewer-role -rules: -- apiGroups: - - synapse.opdev.io - resources: - - synapses - verbs: - - get - - list - - watch -- apiGroups: - - synapse.opdev.io - resources: - - synapses/status - verbs: - - get diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml deleted file mode 100644 index 00091a4..0000000 --- a/config/samples/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -## Append samples you want in your CSV to this file as resources ## -resources: -- synapse_v1alpha1_synapse.yaml -- synapse_v1alpha1_mautrixsignal.yaml -- synapse_v1alpha1_heisenbridge.yaml -#+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/synapse_v1alpha1_heisenbridge.yaml b/config/samples/synapse_v1alpha1_heisenbridge.yaml deleted file mode 100644 index e30d004..0000000 --- a/config/samples/synapse_v1alpha1_heisenbridge.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: synapse.opdev.io/v1alpha1 -kind: Heisenbridge -metadata: - labels: - app.kubernetes.io/name: heisenbridge - app.kubernetes.io/instance: heisenbridge-sample - app.kubernetes.io/part-of: synapse-operator - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: synapse-operator - name: heisenbridge-sample -spec: - synapse: - name: synapse-sample diff --git a/config/samples/synapse_v1alpha1_mautrixsignal.yaml b/config/samples/synapse_v1alpha1_mautrixsignal.yaml deleted file mode 100644 index 49e45cc..0000000 --- a/config/samples/synapse_v1alpha1_mautrixsignal.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: synapse.opdev.io/v1alpha1 -kind: MautrixSignal -metadata: - labels: - app.kubernetes.io/name: mautrixsignal - app.kubernetes.io/instance: mautrixsignal-sample - app.kubernetes.io/part-of: synapse-operator - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: synapse-operator - name: mautrixsignal-sample -spec: - synapse: - name: synapse-sample diff --git a/config/samples/synapse_v1alpha1_synapse.yaml b/config/samples/synapse_v1alpha1_synapse.yaml deleted file mode 100644 index 1031cae..0000000 --- a/config/samples/synapse_v1alpha1_synapse.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: synapse.opdev.io/v1alpha1 -kind: Synapse -metadata: - name: synapse-sample -spec: - createNewPostgreSQL: false - homeserver: - values: - serverName: my.matrix.host - reportStats: true diff --git a/config/scorecard/bases/config.yaml b/config/scorecard/bases/config.yaml deleted file mode 100644 index c770478..0000000 --- a/config/scorecard/bases/config.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: scorecard.operatorframework.io/v1alpha3 -kind: Configuration -metadata: - name: config -stages: -- parallel: true - tests: [] diff --git a/config/scorecard/kustomization.yaml b/config/scorecard/kustomization.yaml deleted file mode 100644 index 50cd2d0..0000000 --- a/config/scorecard/kustomization.yaml +++ /dev/null @@ -1,16 +0,0 @@ -resources: -- bases/config.yaml -patchesJson6902: -- path: patches/basic.config.yaml - target: - group: scorecard.operatorframework.io - version: v1alpha3 - kind: Configuration - name: config -- path: patches/olm.config.yaml - target: - group: scorecard.operatorframework.io - version: v1alpha3 - kind: Configuration - name: config -#+kubebuilder:scaffold:patchesJson6902 diff --git a/config/scorecard/patches/basic.config.yaml b/config/scorecard/patches/basic.config.yaml deleted file mode 100644 index c04db31..0000000 --- a/config/scorecard/patches/basic.config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - basic-check-spec - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: basic - test: basic-check-spec-test diff --git a/config/scorecard/patches/olm.config.yaml b/config/scorecard/patches/olm.config.yaml deleted file mode 100644 index 122f703..0000000 --- a/config/scorecard/patches/olm.config.yaml +++ /dev/null @@ -1,50 +0,0 @@ -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-bundle-validation - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-bundle-validation-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-crds-have-validation - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-crds-have-validation-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-crds-have-resources - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-crds-have-resources-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-spec-descriptors - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-spec-descriptors-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-status-descriptors - image: quay.io/operator-framework/scorecard-test:v1.12.0 - labels: - suite: olm - test: olm-status-descriptors-test diff --git a/controllers/synapse/heisenbridge/heisenbridge_configmap.go b/controllers/synapse/heisenbridge/heisenbridge_configmap.go deleted file mode 100644 index 43c66c1..0000000 --- a/controllers/synapse/heisenbridge/heisenbridge_configmap.go +++ /dev/null @@ -1,132 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package heisenbridge - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileHeisenbridgeConfigMap is a function of type FnWithRequest, to -// be called in the main reconciliation loop. -// -// It reconciles the heisenbridge ConfigMap to its desired state. It is called -// only if the user hasn't provided its own ConfigMap for heisenbridge -func (r *HeisenbridgeReconciler) reconcileHeisenbridgeConfigMap(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - h := &synapsev1alpha1.Heisenbridge{} - if r, err := utils.GetResource(ctx, r.Client, req, h); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredConfigMap, err := r.configMapForHeisenbridge(h) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredConfigMap, - &corev1.ConfigMap{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// configMapForSynapse returns a synapse ConfigMap object -func (r *HeisenbridgeReconciler) configMapForHeisenbridge(h *synapsev1alpha1.Heisenbridge) (*corev1.ConfigMap, error) { - type configmapExtraValues struct { - synapsev1alpha1.Heisenbridge - HeisenbridgeFQDN string - } - - extraValues := configmapExtraValues{ - Heisenbridge: *h, - HeisenbridgeFQDN: utils.ComputeFQDN(h.Name, h.Namespace), - } - - cm, err := templates.ResourceFromTemplate[configmapExtraValues, corev1.ConfigMap](&extraValues, "heisenbridge_configmap") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set Heisenbridge instance as the owner and controller - if err := ctrl.SetControllerReference(h, cm, r.Scheme); err != nil { - return &corev1.ConfigMap{}, err - } - - return cm, nil -} - -// configureHeisenbridgeConfigMap is a function of type FnWithRequest, to -// be called in the main reconciliation loop. -// -// Following the previous copy of the user-provided ConfigMap, it edits the -// content of the copy to ensure that heisenbridge is correctly configured. -func (r *HeisenbridgeReconciler) configureHeisenbridgeConfigMap(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - h := &synapsev1alpha1.Heisenbridge{} - if r, err := utils.GetResource(ctx, r.Client, req, h); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - keyForConfigMap := types.NamespacedName{ - Name: h.Name, - Namespace: h.Namespace, - } - - // Configure correct URL in Heisenbridge ConfigMap - if err := utils.UpdateConfigMap( - ctx, - r.Client, - keyForConfigMap, - h, - r.updateHeisenbridgeWithURL, - "heisenbridge.yaml", - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// updateHeisenbridgeWithURL is a function of type updateDataFunc function to -// be passed as an argument in a call to updateConfigMap. -// -// It configures the correct Heisenbridge URL, needed for Synapse to reach the -// bridge. -func (r *HeisenbridgeReconciler) updateHeisenbridgeWithURL( - obj client.Object, - heisenbridge map[string]interface{}, -) error { - h := obj.(*synapsev1alpha1.Heisenbridge) - - heisenbridge["url"] = "http://" + utils.ComputeFQDN(h.Name, h.Namespace) + ":9898" - return nil -} diff --git a/controllers/synapse/heisenbridge/heisenbridge_controller.go b/controllers/synapse/heisenbridge/heisenbridge_controller.go deleted file mode 100644 index efe014c..0000000 --- a/controllers/synapse/heisenbridge/heisenbridge_controller.go +++ /dev/null @@ -1,111 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package heisenbridge - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/utils" -) - -// HeisenbridgeReconciler reconciles a Heisenbridge object -type HeisenbridgeReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -//+kubebuilder:rbac:groups=synapse.opdev.io,resources=heisenbridges,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=synapse.opdev.io,resources=heisenbridges/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=synapse.opdev.io,resources=heisenbridges/finalizers,verbs=update - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the Heisenbridge object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.13.0/pkg/reconcile -func (r *HeisenbridgeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - var h synapsev1alpha1.Heisenbridge // The Heisenbridge object being reconciled - if r, err := utils.GetResource(ctx, r.Client, req, &h); subreconciler.ShouldHaltOrRequeue(r, err) { - return subreconciler.Evaluate(r, err) - } - - // The list of subreconcilers for Heisenbridge. - var subreconcilersForHeisenbridge []subreconciler.FnWithRequest - - // We need to trigger a Synapse reconciliation so that it becomes aware of - // the Heisenbridge. - subreconcilersForHeisenbridge = []subreconciler.FnWithRequest{ - utils.HandleDelete(r.Client, &synapsev1alpha1.Heisenbridge{}), - utils.AddFinalizer(r.Client, &synapsev1alpha1.Heisenbridge{}), - utils.TriggerSynapseReconciliation(r.Client, &synapsev1alpha1.Heisenbridge{}), - } - - // The user may specify a ConfigMap, containing the heisenbridge.yaml - // config file, under Spec.Bridges.Heisenbridge.ConfigMap - if h.Spec.ConfigMap.Name != "" { - // If the user provided a custom Heisenbridge configuration via a - // ConfigMap, we need to validate that the ConfigMap exists, and - // create a copy. We also need to edit the heisenbridge - // configuration. - subreconcilersForHeisenbridge = append( - subreconcilersForHeisenbridge, - utils.CopyInputConfigMap(r.Client, r.Scheme, &synapsev1alpha1.Heisenbridge{}), - r.configureHeisenbridgeConfigMap, - ) - } else { - // If the user hasn't provided a ConfigMap with a custom - // heisenbridge.yaml, we create a new ConfigMap with a default - // heisenbridge.yaml. - subreconcilersForHeisenbridge = append( - subreconcilersForHeisenbridge, - r.reconcileHeisenbridgeConfigMap, - ) - } - - // Reconcile Heisenbridge resources: Service and Deployment - subreconcilersForHeisenbridge = append( - subreconcilersForHeisenbridge, - r.reconcileHeisenbridgeService, - r.reconcileHeisenbridgeDeployment, - ) - - // Run all subreconcilers sequentially - for _, f := range subreconcilersForHeisenbridge { - if r, err := f(ctx, req); subreconciler.ShouldHaltOrRequeue(r, err) { - return subreconciler.Evaluate(r, err) - } - } - - return subreconciler.Evaluate(subreconciler.DoNotRequeue()) -} - -// SetupWithManager sets up the controller with the Manager. -func (r *HeisenbridgeReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&synapsev1alpha1.Heisenbridge{}). - Complete(r) -} diff --git a/controllers/synapse/heisenbridge/heisenbridge_controller_test.go b/controllers/synapse/heisenbridge/heisenbridge_controller_test.go deleted file mode 100644 index ce80202..0000000 --- a/controllers/synapse/heisenbridge/heisenbridge_controller_test.go +++ /dev/null @@ -1,617 +0,0 @@ -package heisenbridge - -import ( - "context" - "path/filepath" - "strconv" - - // "strconv" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "gopkg.in/yaml.v2" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/metrics/server" - - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/utils" -) - -var _ = Describe("Integration tests for the Heisenbridge controller", Ordered, Label("integration"), func() { - // Define utility constants for object names and testing timeouts/durations and intervals. - const ( - HeisenbridgeName = "test-heisenbridge" - HeisenbridgeNamespace = "default" - InputConfigMapName = "test-configmap" - - // Name and namespace of the Heisenbridge instance refered by the Heisenbridge Bridge - SynapseName = "test-synapse" - SynapseNamespace = "default" - SynapseServerName = "my.matrix.host" - - timeout = time.Second * 2 - duration = time.Second * 2 - interval = time.Millisecond * 250 - ) - - var k8sClient client.Client - var testEnv *envtest.Environment - var ctx context.Context - var cancel context.CancelFunc - - var deleteResource func(client.Object, types.NamespacedName, bool) - var checkSubresourceAbsence func(types.NamespacedName, ...client.Object) - var checkResourcePresence func(client.Object, types.NamespacedName, metav1.OwnerReference) - var checkStatus func(string, string, types.NamespacedName, client.Object) - - // Common function to start envTest - var startenvTest = func() { - cfg, err := testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - Expect(synapsev1alpha1.AddToScheme(scheme.Scheme)).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Metrics: server.Options{ - BindAddress: "0", - }, - }) - Expect(err).ToNot(HaveOccurred()) - - err = (&HeisenbridgeReconciler{ - Client: k8sManager.GetClient(), - Scheme: k8sManager.GetScheme(), - }).SetupWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - - deleteResource = utils.DeleteResourceFunc(k8sClient, ctx, timeout, interval) - checkSubresourceAbsence = utils.CheckSubresourceAbsenceFunc(k8sClient, ctx, timeout, interval) - checkResourcePresence = utils.CheckResourcePresenceFunc(k8sClient, ctx, timeout, interval) - checkStatus = utils.CheckStatusFunc(k8sClient, ctx, timeout, interval) - - go func() { - defer GinkgoRecover() - Expect(k8sManager.Start(ctx)).ToNot(HaveOccurred(), "failed to run manager") - }() - } - - Context("When a corectly configured Kubernetes cluster is present", func() { - var _ = BeforeAll(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "bundle", "manifests", "synapse.opdev.io_heisenbridges.yaml"), - filepath.Join("..", "..", "..", "bundle", "manifests", "synapse.opdev.io_synapses.yaml"), - }, - ErrorIfCRDPathMissing: true, - } - - startenvTest() - }) - - var _ = AfterAll(func() { - cancel() - By("tearing down the test environment") - Expect(testEnv.Stop()).NotTo(HaveOccurred()) - }) - - Context("Validating Heisenbridge CRD Schema", func() { - var obj map[string]interface{} - - BeforeEach(func() { - obj = map[string]interface{}{ - "apiVersion": "synapse.opdev.io/v1alpha1", - "kind": "Heisenbridge", - "metadata": map[string]interface{}{ - "name": HeisenbridgeName, - "namespace": HeisenbridgeNamespace, - }, - } - }) - - DescribeTable("Creating a misconfigured Heisenbridge instance", - func(heisenbridge map[string]interface{}) { - // Augment base heisenbridge obj with additional fields - for key, value := range heisenbridge { - obj[key] = value - } - // Create Unstructured object from heisenbridge obj - u := unstructured.Unstructured{Object: obj} - Expect(k8sClient.Create(ctx, &u)).ShouldNot(Succeed()) - }, - Entry("when Heisenbridge spec is missing", map[string]interface{}{}), - Entry("when Heisenbridge spec is empty", map[string]interface{}{ - "spec": map[string]interface{}{}, - }), - Entry("when Heisenbridge spec is missing Synapse reference", map[string]interface{}{ - "spec": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": "dummy", - }, - }, - }), - Entry("when Heisenbridge spec Synapse doesn't has a name", map[string]interface{}{ - "spec": map[string]interface{}{ - "synapse": map[string]interface{}{ - "namespase": "dummy", - }, - }, - }), - Entry("when Heisenbridge spec ConfigMap doesn't specify a Name", map[string]interface{}{ - "spec": map[string]interface{}{ - "configMap": map[string]interface{}{ - "namespace": "dummy", - }, - "synapse": map[string]interface{}{ - "name": "dummy", - }, - }, - }), - // This should not work but passes - PEntry("when Heisenbridge spec possesses an invalid field", map[string]interface{}{ - "spec": map[string]interface{}{ - "synapse": map[string]interface{}{ - "name": "dummy", - }, - "invalidSpecFiels": "random", - }, - }), - ) - - DescribeTable("Creating a correct Heisenbridge instance", - func(heisenbridge map[string]interface{}) { - // Augment base heisenbridge obj with additional fields - for key, value := range heisenbridge { - obj[key] = value - } - // Create Unstructured object from heisenbridge obj - u := unstructured.Unstructured{Object: obj} - // Use DryRun option to avoid cleaning up resources - opt := client.CreateOptions{DryRun: []string{"All"}} - Expect(k8sClient.Create(ctx, &u, &opt)).Should(Succeed()) - }, - Entry( - "when the Configuration file is provided via a ConfigMap", - map[string]interface{}{ - "spec": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": "dummy", - "namespace": "dummy", - }, - "synapse": map[string]interface{}{ - "name": "dummy", - "namespace": "dummy", - }, - }, - }, - ), - Entry( - "when optional Synapse Namespace and ConfigMap Namespace are missing", - map[string]interface{}{ - "spec": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": "dummy", - }, - "synapse": map[string]interface{}{ - "name": "dummy", - }, - }, - }, - ), - ) - }) - - Context("When creating a valid Heisenbridge instance", func() { - var heisenbridge *synapsev1alpha1.Heisenbridge - var createdConfigMap *corev1.ConfigMap - var createdDeployment *appsv1.Deployment - var createdService *corev1.Service - - var heisenbridgeLookupKey types.NamespacedName - var expectedOwnerReference metav1.OwnerReference - var heisenbridgeSpec synapsev1alpha1.HeisenbridgeSpec - - var synapse *synapsev1alpha1.Synapse - var synapseLookupKey types.NamespacedName - - var initHeisenbridgeVariables = func() { - // Init variables - heisenbridgeLookupKey = types.NamespacedName{ - Name: HeisenbridgeName, - Namespace: HeisenbridgeNamespace, - } - createdConfigMap = &corev1.ConfigMap{} - createdDeployment = &appsv1.Deployment{} - createdService = &corev1.Service{} - - // The OwnerReference UID must be set after the Heisenbridge instance - // has been created. - expectedOwnerReference = metav1.OwnerReference{ - Kind: "Heisenbridge", - APIVersion: "synapse.opdev.io/v1alpha1", - Name: HeisenbridgeName, - Controller: utils.BoolAddr(true), - BlockOwnerDeletion: utils.BoolAddr(true), - } - - synapseLookupKey = types.NamespacedName{ - Name: SynapseName, - Namespace: SynapseNamespace, - } - } - - var createSynapseInstanceForHeisenbridge = func() { - By("Creating a Synapse instance for Heisenbridge") - synapse = &synapsev1alpha1.Synapse{ - ObjectMeta: metav1.ObjectMeta{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - Spec: synapsev1alpha1.SynapseSpec{ - Homeserver: synapsev1alpha1.SynapseHomeserver{ - Values: &synapsev1alpha1.SynapseHomeserverValues{ - ServerName: SynapseServerName, - ReportStats: false, - }, - }, - }, - } - Expect(k8sClient.Create(ctx, synapse)).Should(Succeed()) - k8sClient.Get(ctx, synapseLookupKey, synapse) - - By("Verifying that the Synapse object was created") - Eventually(func() bool { - err := k8sClient.Get(ctx, synapseLookupKey, synapse) - return err == nil - }, timeout, interval).Should(BeTrue()) - } - - var cleanupSynapseCR = func() { - By("Cleaning up Synapse CR") - Expect(k8sClient.Delete(ctx, synapse)).Should(Succeed()) - } - - var createHeisenbridgeInstance = func() { - By("Creating the Heisenbridge instance") - heisenbridge = &synapsev1alpha1.Heisenbridge{ - ObjectMeta: metav1.ObjectMeta{ - Name: HeisenbridgeName, - Namespace: HeisenbridgeNamespace, - }, - Spec: heisenbridgeSpec, - } - Expect(k8sClient.Create(ctx, heisenbridge)).Should(Succeed()) - - By("Verifying that the Heisenbridge object was created") - Eventually(func() bool { - err := k8sClient.Get(ctx, heisenbridgeLookupKey, heisenbridge) - return err == nil - }, timeout, interval).Should(BeTrue()) - - expectedOwnerReference.UID = heisenbridge.GetUID() - } - - var cleanupHeisenbridgeChildResources = func() { - // Child resources must be manually deleted as the controllers responsible of - // their lifecycle are not running. - By("Cleaning up Heisenbridge ConfigMap") - deleteResource(createdConfigMap, heisenbridgeLookupKey, false) - - By("Cleaning up Heisenbridge Deployment") - deleteResource(createdDeployment, heisenbridgeLookupKey, false) - - By("Cleaning up Heisenbridge Service") - deleteResource(createdService, heisenbridgeLookupKey, false) - } - - var cleanupHeisenbridgeResources = func() { - By("Cleaning up Heisenbridge CR") - Expect(k8sClient.Delete(ctx, heisenbridge)).Should(Succeed()) - - cleanupHeisenbridgeChildResources() - } - - When("No Heisenbridge ConfigMap is provided", func() { - BeforeAll(func() { - initHeisenbridgeVariables() - - heisenbridgeSpec = synapsev1alpha1.HeisenbridgeSpec{ - Synapse: synapsev1alpha1.HeisenbridgeSynapseSpec{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - } - - createSynapseInstanceForHeisenbridge() - createHeisenbridgeInstance() - }) - - AfterAll(func() { - cleanupHeisenbridgeResources() - cleanupSynapseCR() - }) - - It("Should should update the Heisenbridge Status", func() { - expectedStatus := synapsev1alpha1.HeisenbridgeStatus{ - State: "", - Reason: "", - } - - // Status may need some time to be updated - Eventually(func() synapsev1alpha1.HeisenbridgeStatus { - _ = k8sClient.Get(ctx, heisenbridgeLookupKey, heisenbridge) - return heisenbridge.Status - }, timeout, interval).Should(Equal(expectedStatus)) - }) - - It("Should create a Heisenbridge ConfigMap", func() { - checkResourcePresence(createdConfigMap, heisenbridgeLookupKey, expectedOwnerReference) - }) - - It("Should create a Heisenbridge Deployment", func() { - checkResourcePresence(createdDeployment, heisenbridgeLookupKey, expectedOwnerReference) - }) - - It("Should create a Heisenbridge Service", func() { - checkResourcePresence(createdService, heisenbridgeLookupKey, expectedOwnerReference) - }) - }) - - When("Specifying the Heisenbridge configuration via a ConfigMap", func() { - var inputConfigMap *corev1.ConfigMap - var heisenbridgeYaml string = "" - - const heisenbridgeFQDN = HeisenbridgeName + "." + HeisenbridgeNamespace + ".svc.cluster.local" - const synapseFQDN = SynapseName + "." + SynapseNamespace + ".svc.cluster.local" - const heisenbridgePort = 9898 - - var createHeisenbridgeConfigMap = func() { - By("Creating a ConfigMap containing a basic heisenbridge.yaml") - // Incomplete heisenbridge.yaml, containing only the required data for our - // tests. We test that those values are correctly updated. - heisenbridgeYaml = "url: http://10.217.5.134:" + strconv.Itoa(heisenbridgePort) - - inputConfigmapData := map[string]string{ - "heisenbridge.yaml": heisenbridgeYaml, - } - - // Populate the ConfigMap with the minimum data needed - inputConfigMap = &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: InputConfigMapName, - Namespace: HeisenbridgeNamespace, - }, - Data: inputConfigmapData, - } - Expect(k8sClient.Create(ctx, inputConfigMap)).Should(Succeed()) - } - - var cleanupHeisenbridgeConfigMap = func() { - By("Cleaning up ConfigMap") - Expect(k8sClient.Delete(ctx, inputConfigMap)).Should(Succeed()) - } - - BeforeAll(func() { - initHeisenbridgeVariables() - - heisenbridgeSpec = synapsev1alpha1.HeisenbridgeSpec{ - ConfigMap: synapsev1alpha1.HeisenbridgeConfigMap{ - Name: InputConfigMapName, - Namespace: HeisenbridgeNamespace, - }, - Synapse: synapsev1alpha1.HeisenbridgeSynapseSpec{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - } - - createSynapseInstanceForHeisenbridge() - createHeisenbridgeConfigMap() - createHeisenbridgeInstance() - }) - - AfterAll(func() { - cleanupHeisenbridgeResources() - cleanupHeisenbridgeConfigMap() - cleanupSynapseCR() - }) - - It("Should should update the Heisenbridge Status", func() { - expectedStatus := synapsev1alpha1.HeisenbridgeStatus{ - State: "", - Reason: "", - } - // Status may need some time to be updated - Eventually(func() synapsev1alpha1.HeisenbridgeStatus { - _ = k8sClient.Get(ctx, heisenbridgeLookupKey, heisenbridge) - return heisenbridge.Status - }, timeout, interval).Should(Equal(expectedStatus)) - }) - - It("Should create a Heisenbridge ConfigMap", func() { - checkResourcePresence(createdConfigMap, heisenbridgeLookupKey, expectedOwnerReference) - }) - - It("Should create a Heisenbridge Deployment", func() { - checkResourcePresence(createdDeployment, heisenbridgeLookupKey, expectedOwnerReference) - }) - - It("Should create a Heisenbridge Service", func() { - checkResourcePresence(createdService, heisenbridgeLookupKey, expectedOwnerReference) - }) - - It("Should overwrite necessary values in the created heisenbridge ConfigMap", func() { - Eventually(func(g Gomega) { - By("Verifying that the heisenbridge ConfigMap exists") - g.Expect(k8sClient.Get(ctx, heisenbridgeLookupKey, createdConfigMap)).Should(Succeed()) - - configMapdata, ok := createdConfigMap.Data["heisenbridge.yaml"] - g.Expect(ok).Should(BeTrue()) - - heisenbridge := make(map[string]interface{}) - g.Expect(yaml.Unmarshal([]byte(configMapdata), heisenbridge)).Should(Succeed()) - - _, ok = heisenbridge["url"] - g.Expect(ok).Should(BeTrue()) - - g.Expect(heisenbridge["url"]).To(Equal("http://" + heisenbridgeFQDN + ":" + strconv.Itoa(heisenbridgePort))) - }, timeout, interval).Should(Succeed()) - }) - - It("Should not modify the input ConfigMap", func() { - Eventually(func(g Gomega) { - By("Fetching the inputConfigMap data") - inputConfigMapLookupKey := types.NamespacedName{ - Name: InputConfigMapName, - Namespace: HeisenbridgeNamespace, - } - g.Expect(k8sClient.Get(ctx, inputConfigMapLookupKey, inputConfigMap)).Should(Succeed()) - - configMapdata, ok := inputConfigMap.Data["heisenbridge.yaml"] - g.Expect(ok).Should(BeTrue()) - - By("Verifying the heisenbridge.yaml hasn't changed") - g.Expect(configMapdata).To(Equal(heisenbridgeYaml)) - }, timeout, interval).Should(Succeed()) - }) - }) - - When("Heisenbridge references a non existing Synapse", func() { - BeforeAll(func() { - initHeisenbridgeVariables() - - heisenbridgeSpec = synapsev1alpha1.HeisenbridgeSpec{ - Synapse: synapsev1alpha1.HeisenbridgeSynapseSpec{ - Name: "not-exist", - Namespace: SynapseNamespace, - }, - } - - createHeisenbridgeInstance() - }) - - AfterAll(func() { - By("Cleaning up heisenbridge CR") - Expect(k8sClient.Delete(ctx, heisenbridge)).Should(Succeed()) - }) - - It("Should not create any Heisenbridge resources", func() { - checkStatus("", "", heisenbridgeLookupKey, heisenbridge) - checkSubresourceAbsence( - heisenbridgeLookupKey, - createdConfigMap, - createdDeployment, - createdService, - ) - }) - }) - - When("Creating and deleting Heisenbridge resources", func() { - const bridgeFinalizer = "synapse.opdev.io/finalizer" - - BeforeAll(func() { - initHeisenbridgeVariables() - - heisenbridgeSpec = synapsev1alpha1.HeisenbridgeSpec{ - Synapse: synapsev1alpha1.HeisenbridgeSynapseSpec{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - } - - createSynapseInstanceForHeisenbridge() - }) - - AfterAll(func() { - cleanupHeisenbridgeChildResources() - cleanupSynapseCR() - }) - - When("Creating Heisenbridge", func() { - BeforeAll(func() { - createHeisenbridgeInstance() - }) - - It("Should add a Finalizer", func() { - Eventually(func() []string { - _ = k8sClient.Get(ctx, heisenbridgeLookupKey, heisenbridge) - return heisenbridge.Finalizers - }, timeout, interval).Should(ContainElement(bridgeFinalizer)) - }) - - It("Should trigger the reconciliation of Synapse", func() { - Eventually(func() bool { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status.NeedsReconcile - }, timeout, interval).Should(BeTrue()) - - // Set needsReconcile back to False, as the Synapse Controller - // would do if it would be running - synapse.Status.NeedsReconcile = false - Expect(k8sClient.Status().Update(ctx, synapse)).Should(Succeed()) - - time.Sleep(time.Second) - }) - }) - - When("Deleting Heisenbridge", func() { - BeforeAll(func() { - By("Sending delete request") - Expect(k8sClient.Delete(ctx, heisenbridge)).Should(Succeed()) - }) - - // Heisenbridge controller is too fast and complete cleanup - // tasks (trigger Synapse reconciliation) and effectively - // deletes the Heisenbridge instance before we have time to - // check that the finalizer was removed. - // Instead, we check that the Heisenbridge instance is - // indeed absent. - PIt("Should remove the Finalizer", func() { - Eventually(func() []string { - _ = k8sClient.Get(ctx, heisenbridgeLookupKey, heisenbridge) - return heisenbridge.Finalizers - }, timeout, interval).ShouldNot(ContainElement(bridgeFinalizer)) - }) - - It("Should effectively remove the Heisenbridge instance", func() { - Eventually(func() bool { - err := k8sClient.Get(ctx, heisenbridgeLookupKey, heisenbridge) - return err == nil - }, timeout, interval).Should(BeFalse()) - }) - - It("Should trigger the reconciliation of Synapse", func() { - Eventually(func() bool { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status.NeedsReconcile - }, timeout, interval).Should(BeTrue()) - }) - }) - }) - }) - }) -}) diff --git a/controllers/synapse/heisenbridge/heisenbridge_deployment.go b/controllers/synapse/heisenbridge/heisenbridge_deployment.go deleted file mode 100644 index 45584d0..0000000 --- a/controllers/synapse/heisenbridge/heisenbridge_deployment.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package heisenbridge - -import ( - "context" - "fmt" - - appsv1 "k8s.io/api/apps/v1" - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// labelsForSynapse returns the labels for selecting the resources -// belonging to the given synapse CR name. -func labelsForHeisenbridge(name string) map[string]string { - return map[string]string{"app": "heisenbridge", "heisenbridge_cr": name} -} - -// reconcileHeisenbridgeDeployment is a function of type FnWithRequest, to -// be called in the main reconciliation loop. -// -// It reconciles the Deployment for Heisenbridge to its desired state. -func (r *HeisenbridgeReconciler) reconcileHeisenbridgeDeployment(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - h := &synapsev1alpha1.Heisenbridge{} - if r, err := utils.GetResource(ctx, r.Client, req, h); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredDeployment, err := r.deploymentForHeisenbridge(h) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredDeployment, - &appsv1.Deployment{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// deploymentForHeisenbridge returns a Heisenbridge Deployment object -func (r *HeisenbridgeReconciler) deploymentForHeisenbridge(h *synapsev1alpha1.Heisenbridge) (*appsv1.Deployment, error) { - type deploymentExtraValues struct { - synapsev1alpha1.Heisenbridge - Labels map[string]string - Command []string - } - - extraValues := deploymentExtraValues{ - Heisenbridge: *h, - Labels: labelsForHeisenbridge(h.Name), - Command: r.craftHeisenbridgeCommad(*h), - } - - dep, err := templates.ResourceFromTemplate[deploymentExtraValues, appsv1.Deployment](&extraValues, "heisenbridge_deployment") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set Heisenbridge instance as the owner and controller - if err := ctrl.SetControllerReference(h, dep, r.Scheme); err != nil { - return &appsv1.Deployment{}, err - } - return dep, nil -} - -func (r *HeisenbridgeReconciler) craftHeisenbridgeCommad(h synapsev1alpha1.Heisenbridge) []string { - command := []string{ - "python", - "-m", - "heisenbridge", - } - - if h.Spec.VerboseLevel > 0 { - verbosity := "-" - for i := 1; i <= h.Spec.VerboseLevel; i++ { - verbosity = verbosity + "v" - } - command = append(command, verbosity) - } - - SynapseName := h.Spec.Synapse.Name - SynapseNamespace := utils.ComputeNamespace(h.Namespace, h.Spec.Synapse.Namespace) - - command = append( - command, - "-c", - "/data-heisenbridge/heisenbridge.yaml", - "-l", - "0.0.0.0", - "http://"+utils.ComputeFQDN(SynapseName, SynapseNamespace)+":8008", - ) - - return command -} diff --git a/controllers/synapse/heisenbridge/heisenbridge_service.go b/controllers/synapse/heisenbridge/heisenbridge_service.go deleted file mode 100644 index 1352385..0000000 --- a/controllers/synapse/heisenbridge/heisenbridge_service.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package heisenbridge - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileHeisenbridgeService is a function of type FnWithRequest, to be -// called in the main reconciliation loop. -// -// It reconciles the Service for Heisenbridge to its desired state. -func (r *HeisenbridgeReconciler) reconcileHeisenbridgeService(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - h := &synapsev1alpha1.Heisenbridge{} - if r, err := utils.GetResource(ctx, r.Client, req, h); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredService, err := r.serviceForHeisenbridge(h) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredService, - &corev1.Service{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// serviceForSynapse returns a Heisenbridge Service object -func (r *HeisenbridgeReconciler) serviceForHeisenbridge(h *synapsev1alpha1.Heisenbridge) (*corev1.Service, error) { - type serviceExtraValues struct { - synapsev1alpha1.Heisenbridge - Labels map[string]string - PortName string - Port int - TargetPort int - } - - extraValues := serviceExtraValues{ - Heisenbridge: *h, - Labels: labelsForHeisenbridge(h.Name), - PortName: "heisenbridge", - Port: 9898, - TargetPort: 9898, - } - - service, err := templates.ResourceFromTemplate[serviceExtraValues, corev1.Service](&extraValues, "service") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set Heisenbridge instance as the owner and controller - if err := ctrl.SetControllerReference(h, service, r.Scheme); err != nil { - return &corev1.Service{}, err - } - return service, nil -} diff --git a/controllers/synapse/heisenbridge/heisenbridge_test.go b/controllers/synapse/heisenbridge/heisenbridge_test.go deleted file mode 100644 index ee7785d..0000000 --- a/controllers/synapse/heisenbridge/heisenbridge_test.go +++ /dev/null @@ -1,5 +0,0 @@ -// -//This file contains unit tests for the heisenbridge package -// - -package heisenbridge diff --git a/controllers/synapse/heisenbridge/suite_test.go b/controllers/synapse/heisenbridge/suite_test.go deleted file mode 100644 index fdee86a..0000000 --- a/controllers/synapse/heisenbridge/suite_test.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package heisenbridge - -import ( - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - //+kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Heisenbridge Controller Suite") -} diff --git a/controllers/synapse/mautrixsignal/mautrixsignal_configmap.go b/controllers/synapse/mautrixsignal/mautrixsignal_configmap.go deleted file mode 100644 index 4974158..0000000 --- a/controllers/synapse/mautrixsignal/mautrixsignal_configmap.go +++ /dev/null @@ -1,205 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package mautrixsignal - -import ( - "context" - "errors" - "fmt" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileMautrixSignalConfigMap is a function of type FnWithRequest, to -// be called in the main reconciliation loop. -// -// It reconciles the mautrix-signal ConfigMap to its desired state. It is -// called only if the user hasn't provided its own ConfigMap for -// mautrix-signal. -func (r *MautrixSignalReconciler) reconcileMautrixSignalConfigMap(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - ms := &synapsev1alpha1.MautrixSignal{} - if r, err := utils.GetResource(ctx, r.Client, req, ms); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredConfigMap, err := r.configMapForMautrixSignal(ms) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredConfigMap, - &corev1.ConfigMap{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// configMapForSynapse returns a synapse ConfigMap object -func (r *MautrixSignalReconciler) configMapForMautrixSignal(ms *synapsev1alpha1.MautrixSignal) (*corev1.ConfigMap, error) { - synapseName := ms.Spec.Synapse.Name - synapseNamespace := utils.ComputeNamespace(ms.Namespace, ms.Spec.Synapse.Namespace) - - type configmapExtraValues struct { - synapsev1alpha1.MautrixSignal - SynapseFQDN string - MautrixsignalFQDN string - } - - extraValues := configmapExtraValues{ - MautrixSignal: *ms, - SynapseFQDN: utils.ComputeFQDN(synapseName, synapseNamespace), - MautrixsignalFQDN: utils.ComputeFQDN(ms.Name, ms.Namespace), - } - - cm, err := templates.ResourceFromTemplate[configmapExtraValues, corev1.ConfigMap](&extraValues, "mautrixsignal_configmap") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set MautrixSignal instance as the owner and controller - if err := ctrl.SetControllerReference(ms, cm, r.Scheme); err != nil { - return &corev1.ConfigMap{}, err - } - - return cm, nil -} - -// configureMautrixSignalConfigMap is a function of type FnWithRequest, to -// be called in the main reconciliation loop. -// -// Following the previous copy of the user-provided ConfigMap, it edits the -// content of the copy to ensure that mautrix-signal is correctly configured. -func (r *MautrixSignalReconciler) configureMautrixSignalConfigMap(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - ms := &synapsev1alpha1.MautrixSignal{} - if r, err := utils.GetResource(ctx, r.Client, req, ms); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - keyForConfigMap := types.NamespacedName{ - Name: ms.Name, - Namespace: ms.Namespace, - } - - // Correct data in mautrix-signal ConfigMap - if err := utils.UpdateConfigMap( - ctx, - r.Client, - keyForConfigMap, - ms, - r.updateMautrixSignalData, - "config.yaml", - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// updateMautrixSignalData is a function of type updateDataFunc function to -// be passed as an argument in a call to updateConfigMap. -// -// It configures the user-provided config.yaml with the correct values. Among -// other things, it ensures that the bridge can reach the Synapse homeserver -// and knows the correct path to the signald socket. -func (r *MautrixSignalReconciler) updateMautrixSignalData( - obj client.Object, - config map[string]interface{}, -) error { - ms := obj.(*synapsev1alpha1.MautrixSignal) - - synapseName := ms.Spec.Synapse.Name - synapseNamespace := utils.ComputeNamespace(ms.Namespace, ms.Spec.Synapse.Namespace) - synapseServerName := ms.Status.Synapse.ServerName - - // Update the homeserver section so that the bridge can reach Synapse - configHomeserver, ok := config["homeserver"].(map[interface{}]interface{}) - if !ok { - err := errors.New("cannot parse mautrix-signal config.yaml: error parsing 'homeserver' section") - return err - } - configHomeserver["address"] = "http://" + utils.ComputeFQDN(synapseName, synapseNamespace) + ":8008" - configHomeserver["domain"] = synapseServerName - config["homeserver"] = configHomeserver - - // Update the appservice section so that Synapse can reach the bridge - configAppservice, ok := config["appservice"].(map[interface{}]interface{}) - if !ok { - err := errors.New("cannot parse mautrix-signal config.yaml: error parsing 'appservice' section") - return err - } - configAppservice["address"] = "http://" + utils.ComputeFQDN(ms.Name, ms.Namespace) + ":29328" - config["appservice"] = configAppservice - - // Update the path to the signal socket path - configSignal, ok := config["signal"].(map[interface{}]interface{}) - if !ok { - err := errors.New("cannot parse mautrix-signal config.yaml: error parsing 'signal' section") - return err - } - configSignal["socket_path"] = "/signald/signald.sock" - config["signal"] = configSignal - - // Update persmissions to use the correct domain name - configBridge, ok := config["bridge"].(map[interface{}]interface{}) - if !ok { - err := errors.New("cannot parse mautrix-signal config.yaml: error parsing 'bridge' section") - return err - } - configBridge["permissions"] = map[string]string{ - "*": "relay", - synapseServerName: "user", - "@admin:" + synapseServerName: "admin", - } - config["bridge"] = configBridge - - // Update the path to the log file - configLogging, ok := config["logging"].(map[interface{}]interface{}) - if !ok { - err := errors.New("cannot parse mautrix-signal config.yaml: error parsing 'logging' section") - return err - } - configLoggingHandlers, ok := configLogging["handlers"].(map[interface{}]interface{}) - if !ok { - err := errors.New("cannot parse mautrix-signal config.yaml: error parsing 'logging/handlers' section") - return err - } - configLoggingHandlersFile, ok := configLoggingHandlers["file"].(map[interface{}]interface{}) - if !ok { - err := errors.New("cannot parse mautrix-signal config.yaml: error parsing 'logging/handlers/file' section") - return err - } - configLoggingHandlersFile["filename"] = "/data/mautrix-signal.log" - configLoggingHandlers["file"] = configLoggingHandlersFile - configLogging["handlers"] = configLoggingHandlers - config["logging"] = configLogging - - return nil -} diff --git a/controllers/synapse/mautrixsignal/mautrixsignal_controller.go b/controllers/synapse/mautrixsignal/mautrixsignal_controller.go deleted file mode 100644 index 8a08ebe..0000000 --- a/controllers/synapse/mautrixsignal/mautrixsignal_controller.go +++ /dev/null @@ -1,161 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package mautrixsignal - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - ctrllog "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/utils" -) - -// MautrixSignalReconciler reconciles a MautrixSignal object -type MautrixSignalReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -//+kubebuilder:rbac:groups=synapse.opdev.io,resources=mautrixsignals,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=synapse.opdev.io,resources=mautrixsignals/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=synapse.opdev.io,resources=mautrixsignals/finalizers,verbs=update - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the MautrixSignal object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.13.0/pkg/reconcile -func (r *MautrixSignalReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - var ms synapsev1alpha1.MautrixSignal // The mautrix-signal object being reconciled - if r, err := utils.GetResource(ctx, r.Client, req, &ms); subreconciler.ShouldHaltOrRequeue(r, err) { - return subreconciler.Evaluate(r, err) - } - - // The list of subreconcilers for mautrix-signal. - var subreconcilersForMautrixSignal []subreconciler.FnWithRequest - - // We need to trigger a Synapse reconciliation so that it becomes aware of - // the MautrixSignal. We also need to complete the MautrixSignal Status. - subreconcilersForMautrixSignal = []subreconciler.FnWithRequest{ - utils.HandleDelete(r.Client, &synapsev1alpha1.MautrixSignal{}), - utils.AddFinalizer(r.Client, &synapsev1alpha1.MautrixSignal{}), - utils.TriggerSynapseReconciliation(r.Client, &synapsev1alpha1.MautrixSignal{}), - r.buildMautrixSignalStatus, - } - - // The user may specify a ConfigMap, containing the config.yaml config - // file, under Spec.Bridges.MautrixSignal.ConfigMap - if ms.Spec.ConfigMap.Name != "" { - // If the user provided a custom mautrix-signal configuration via a - // ConfigMap, we need to validate that the ConfigMap exists, and - // create a copy. We also need to edit the mautrix-signal - // configuration. - subreconcilersForMautrixSignal = append( - subreconcilersForMautrixSignal, - utils.CopyInputConfigMap(r.Client, r.Scheme, &synapsev1alpha1.MautrixSignal{}), - r.configureMautrixSignalConfigMap, - ) - } else { - // If the user hasn't provided a ConfigMap with a custom - // config.yaml, we create a new ConfigMap with a default - // config.yaml. - subreconcilersForMautrixSignal = append( - subreconcilersForMautrixSignal, - r.reconcileMautrixSignalConfigMap, - ) - } - - // SA and RB are only necessary if we're running on OpenShift - if ms.Status.IsOpenshift { - subreconcilersForMautrixSignal = append( - subreconcilersForMautrixSignal, - r.reconcileMautrixSignalServiceAccount, - r.reconcileMautrixSignalRoleBinding, - ) - } - - // Reconcile mautrix-signal resources: Service, PVC and Deployment - subreconcilersForMautrixSignal = append( - subreconcilersForMautrixSignal, - r.reconcileMautrixSignalService, - r.reconcileMautrixSignalPVC, - r.reconcileMautrixSignalDeployment, - ) - - // Run all subreconcilers sequentially - for _, f := range subreconcilersForMautrixSignal { - if r, err := f(ctx, req); subreconciler.ShouldHaltOrRequeue(r, err) { - return subreconciler.Evaluate(r, err) - } - } - - return subreconciler.Evaluate(subreconciler.DoNotRequeue()) -} - -func (r *MautrixSignalReconciler) buildMautrixSignalStatus(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - log := ctrllog.FromContext(ctx) - - ms := &synapsev1alpha1.MautrixSignal{} - if r, err := utils.GetResource(ctx, r.Client, req, ms); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - s := synapsev1alpha1.Synapse{} - if err := utils.FetchSynapseInstance(ctx, r.Client, ms, &s); err != nil { - log.Error(err, "Error fetching Synapse instance") - return subreconciler.RequeueWithError(err) - } - - // Get Synapse ServerName - serverName, err := utils.GetSynapseServerName(s) - if err != nil { - log.Error( - err, - "Error getting Synapse ServerName", - "Synapse Name", ms.Spec.Synapse.Name, - "Synapse Namespace", utils.ComputeNamespace(ms.Namespace, ms.Spec.Synapse.Namespace), - ) - return subreconciler.RequeueWithError(err) - } - ms.Status.Synapse.ServerName = serverName - - ms.Status.IsOpenshift = s.Spec.IsOpenshift - - err = utils.UpdateResourceStatus(ctx, r.Client, ms, &synapsev1alpha1.MautrixSignal{}) - if err != nil { - log.Error(err, "Error updating mautrix-signal Status") - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// SetupWithManager sets up the controller with the Manager. -func (r *MautrixSignalReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&synapsev1alpha1.MautrixSignal{}). - Complete(r) -} diff --git a/controllers/synapse/mautrixsignal/mautrixsignal_controller_test.go b/controllers/synapse/mautrixsignal/mautrixsignal_controller_test.go deleted file mode 100644 index 15c7da4..0000000 --- a/controllers/synapse/mautrixsignal/mautrixsignal_controller_test.go +++ /dev/null @@ -1,723 +0,0 @@ -package mautrixsignal - -import ( - "context" - "path/filepath" - "strconv" - - // "strconv" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "gopkg.in/yaml.v2" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/metrics/server" - - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/utils" -) - -var _ = Describe("Integration tests for the MautrixSignal controller", Ordered, Label("integration"), func() { - // Define utility constants for object names and testing timeouts/durations and intervals. - const ( - MautrixSignalName = "test-mautrixsignal" - MautrixSignalNamespace = "default" - InputConfigMapName = "test-configmap" - - // Name and namespace of the MautrixSignal instance refered by the MautrixSignal Bridge - SynapseName = "test-synapse" - SynapseNamespace = "default" - SynapseServerName = "my.matrix.host" - - timeout = time.Second * 2 - duration = time.Second * 2 - interval = time.Millisecond * 250 - ) - - var k8sClient client.Client - var testEnv *envtest.Environment - var ctx context.Context - var cancel context.CancelFunc - - var deleteResource func(client.Object, types.NamespacedName, bool) - var checkSubresourceAbsence func(types.NamespacedName, ...client.Object) - var checkResourcePresence func(client.Object, types.NamespacedName, metav1.OwnerReference) - var checkStatus func(string, string, types.NamespacedName, client.Object) - - // Common function to start envTest - var startenvTest = func() { - cfg, err := testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - Expect(synapsev1alpha1.AddToScheme(scheme.Scheme)).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Metrics: server.Options{ - BindAddress: "0", - }, - }) - Expect(err).ToNot(HaveOccurred()) - - err = (&MautrixSignalReconciler{ - Client: k8sManager.GetClient(), - Scheme: k8sManager.GetScheme(), - }).SetupWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - - deleteResource = utils.DeleteResourceFunc(k8sClient, ctx, timeout, interval) - checkSubresourceAbsence = utils.CheckSubresourceAbsenceFunc(k8sClient, ctx, timeout, interval) - checkResourcePresence = utils.CheckResourcePresenceFunc(k8sClient, ctx, timeout, interval) - checkStatus = utils.CheckStatusFunc(k8sClient, ctx, timeout, interval) - - go func() { - defer GinkgoRecover() - Expect(k8sManager.Start(ctx)).ToNot(HaveOccurred(), "failed to run manager") - }() - } - - Context("When a corectly configured Kubernetes cluster is present", func() { - var _ = BeforeAll(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "bundle", "manifests", "synapse.opdev.io_mautrixsignals.yaml"), - filepath.Join("..", "..", "..", "bundle", "manifests", "synapse.opdev.io_synapses.yaml"), - }, - ErrorIfCRDPathMissing: true, - } - - startenvTest() - }) - - var _ = AfterAll(func() { - cancel() - By("tearing down the test environment") - Expect(testEnv.Stop()).NotTo(HaveOccurred()) - }) - - Context("Validating MautrixSignal CRD Schema", func() { - var obj map[string]interface{} - - BeforeEach(func() { - obj = map[string]interface{}{ - "apiVersion": "synapse.opdev.io/v1alpha1", - "kind": "MautrixSignal", - "metadata": map[string]interface{}{ - "name": MautrixSignalName, - "namespace": MautrixSignalNamespace, - }, - } - }) - - DescribeTable("Creating a misconfigured MautrixSignal instance", - func(mautrixsignal map[string]interface{}) { - // Augment base mautrixsignal obj with additional fields - for key, value := range mautrixsignal { - obj[key] = value - } - // Create Unstructured object from mautrixsignal obj - u := unstructured.Unstructured{Object: obj} - Expect(k8sClient.Create(ctx, &u)).ShouldNot(Succeed()) - }, - Entry("when MautrixSignal spec is missing", map[string]interface{}{}), - Entry("when MautrixSignal spec is empty", map[string]interface{}{ - "spec": map[string]interface{}{}, - }), - Entry("when MautrixSignal spec is missing Synapse reference", map[string]interface{}{ - "spec": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": "dummy", - }, - }, - }), - Entry("when MautrixSignal spec Synapse doesn't has a name", map[string]interface{}{ - "spec": map[string]interface{}{ - "synapse": map[string]interface{}{ - "namespase": "dummy", - }, - }, - }), - Entry("when MautrixSignal spec ConfigMap doesn't specify a Name", map[string]interface{}{ - "spec": map[string]interface{}{ - "configMap": map[string]interface{}{ - "namespace": "dummy", - }, - "synapse": map[string]interface{}{ - "name": "dummy", - }, - }, - }), - // This should not work but passes - PEntry("when MautrixSignal spec possesses an invalid field", map[string]interface{}{ - "spec": map[string]interface{}{ - "synapse": map[string]interface{}{ - "name": "dummy", - }, - "invalidSpecFiels": "random", - }, - }), - ) - - DescribeTable("Creating a correct MautrixSignal instance", - func(mautrixsignal map[string]interface{}) { - // Augment base mautrixsignal obj with additional fields - for key, value := range mautrixsignal { - obj[key] = value - } - // Create Unstructured object from mautrixsignal obj - u := unstructured.Unstructured{Object: obj} - // Use DryRun option to avoid cleaning up resources - opt := client.CreateOptions{DryRun: []string{"All"}} - Expect(k8sClient.Create(ctx, &u, &opt)).Should(Succeed()) - }, - Entry( - "when the Configuration file is provided via a ConfigMap", - map[string]interface{}{ - "spec": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": "dummy", - "namespace": "dummy", - }, - "synapse": map[string]interface{}{ - "name": "dummy", - "namespace": "dummy", - }, - }, - }, - ), - Entry( - "when optional Synapse Namespace and ConfigMap Namespace are missing", - map[string]interface{}{ - "spec": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": "dummy", - }, - "synapse": map[string]interface{}{ - "name": "dummy", - }, - }, - }, - ), - ) - }) - - Context("When creating a valid MautrixSignal instance", func() { - var mautrixsignal *synapsev1alpha1.MautrixSignal - var createdConfigMap *corev1.ConfigMap - var createdPVC *corev1.PersistentVolumeClaim - var createdDeployment *appsv1.Deployment - var createdService *corev1.Service - var createdServiceAccount *corev1.ServiceAccount - var createdRoleBinding *rbacv1.RoleBinding - - var mautrixsignalLookupKey types.NamespacedName - var expectedOwnerReference metav1.OwnerReference - var mautrixsignalSpec synapsev1alpha1.MautrixSignalSpec - - var synapse *synapsev1alpha1.Synapse - var synapseLookupKey types.NamespacedName - - var initMautrixSignalVariables = func() { - // Init variables - mautrixsignalLookupKey = types.NamespacedName{ - Name: MautrixSignalName, - Namespace: MautrixSignalNamespace, - } - createdConfigMap = &corev1.ConfigMap{} - createdPVC = &corev1.PersistentVolumeClaim{} - createdDeployment = &appsv1.Deployment{} - createdService = &corev1.Service{} - createdServiceAccount = &corev1.ServiceAccount{} - createdRoleBinding = &rbacv1.RoleBinding{} - - // The OwnerReference UID must be set after the MautrixSignal instance - // has been created. - expectedOwnerReference = metav1.OwnerReference{ - Kind: "MautrixSignal", - APIVersion: "synapse.opdev.io/v1alpha1", - Name: MautrixSignalName, - Controller: utils.BoolAddr(true), - BlockOwnerDeletion: utils.BoolAddr(true), - } - - synapseLookupKey = types.NamespacedName{ - Name: SynapseName, - Namespace: SynapseNamespace, - } - } - - var createSynapseInstanceForMautrixSignal = func() { - By("Creating a Synapse instance for MautrixSignal") - synapse = &synapsev1alpha1.Synapse{ - ObjectMeta: metav1.ObjectMeta{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - Spec: synapsev1alpha1.SynapseSpec{ - Homeserver: synapsev1alpha1.SynapseHomeserver{ - Values: &synapsev1alpha1.SynapseHomeserverValues{ - ServerName: SynapseServerName, - ReportStats: false, - }, - }, - IsOpenshift: true, - }, - } - Expect(k8sClient.Create(ctx, synapse)).Should(Succeed()) - k8sClient.Get(ctx, synapseLookupKey, synapse) - // Manually populating the status as the Synapse controller is not running - synapse.Status = synapsev1alpha1.SynapseStatus{ - HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{ - ServerName: SynapseServerName, - ReportStats: false, - }, - } - Expect(k8sClient.Status().Update(ctx, synapse)).Should(Succeed()) - - By("Verifying that the Synapse object was created") - Eventually(func() bool { - err := k8sClient.Get(ctx, synapseLookupKey, synapse) - return err == nil - }, timeout, interval).Should(BeTrue()) - } - - var cleanupSynapseCR = func() { - By("Cleaning up Synapse CR") - Expect(k8sClient.Delete(ctx, synapse)).Should(Succeed()) - } - - var createMautrixSignalInstance = func() { - By("Creating the MautrixSignal instance") - mautrixsignal = &synapsev1alpha1.MautrixSignal{ - ObjectMeta: metav1.ObjectMeta{ - Name: MautrixSignalName, - Namespace: MautrixSignalNamespace, - }, - Spec: mautrixsignalSpec, - } - Expect(k8sClient.Create(ctx, mautrixsignal)).Should(Succeed()) - - By("Verifying that the MautrixSignal object was created") - Eventually(func() bool { - err := k8sClient.Get(ctx, mautrixsignalLookupKey, mautrixsignal) - return err == nil - }, timeout, interval).Should(BeTrue()) - - expectedOwnerReference.UID = mautrixsignal.GetUID() - } - - var cleanupMautrixSignalChildResources = func() { - // Child resources must be manually deleted as the controllers responsible of - // their lifecycle are not running. - By("Cleaning up MautrixSignal ConfigMap") - deleteResource(createdConfigMap, mautrixsignalLookupKey, false) - - By("Cleaning up MautrixSignal PVC") - deleteResource(createdPVC, mautrixsignalLookupKey, true) - - By("Cleaning up MautrixSignal Deployment") - deleteResource(createdDeployment, mautrixsignalLookupKey, false) - - By("Cleaning up MautrixSignal Service") - deleteResource(createdService, mautrixsignalLookupKey, false) - - By("Cleaning up MautrixSignal RoleBinding") - deleteResource(createdRoleBinding, mautrixsignalLookupKey, false) - - By("Cleaning up MautrixSignal ServiceAccount") - deleteResource(createdServiceAccount, mautrixsignalLookupKey, false) - } - - var cleanupMautrixSignalResources = func() { - By("Cleaning up MautrixSignal CR") - Expect(k8sClient.Delete(ctx, mautrixsignal)).Should(Succeed()) - - cleanupMautrixSignalChildResources() - } - - When("No MautrixSignal ConfigMap is provided", func() { - BeforeAll(func() { - initMautrixSignalVariables() - - mautrixsignalSpec = synapsev1alpha1.MautrixSignalSpec{ - Synapse: synapsev1alpha1.MautrixSignalSynapseSpec{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - } - - createSynapseInstanceForMautrixSignal() - createMautrixSignalInstance() - }) - - AfterAll(func() { - cleanupMautrixSignalResources() - cleanupSynapseCR() - }) - - It("Should should update the MautrixSignal Status", func() { - expectedStatus := synapsev1alpha1.MautrixSignalStatus{ - State: "", - Reason: "", - Synapse: synapsev1alpha1.MautrixSignalStatusSynapse{ - ServerName: SynapseServerName, - }, - IsOpenshift: true, - } - - // Status may need some time to be updated - Eventually(func() synapsev1alpha1.MautrixSignalStatus { - _ = k8sClient.Get(ctx, mautrixsignalLookupKey, mautrixsignal) - - return mautrixsignal.Status - }, timeout, interval).Should(Equal(expectedStatus)) - }) - - It("Should create a MautrixSignal ConfigMap", func() { - checkResourcePresence(createdConfigMap, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal PVC", func() { - checkResourcePresence(createdPVC, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal Deployment", func() { - checkResourcePresence(createdDeployment, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal Service", func() { - checkResourcePresence(createdService, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal ServiceAccount", func() { - checkResourcePresence(createdServiceAccount, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal RoleBinding", func() { - checkResourcePresence(createdRoleBinding, mautrixsignalLookupKey, expectedOwnerReference) - }) - }) - - When("Specifying the MautrixSignal configuration via a ConfigMap", func() { - var inputConfigMap *corev1.ConfigMap - var configYaml string = "" - - const mautrixsignalFQDN = MautrixSignalName + "." + MautrixSignalNamespace + ".svc.cluster.local" - const synapseFQDN = SynapseName + "." + SynapseNamespace + ".svc.cluster.local" - const mautrixsignalPort = 29328 - - var createMautrixSignalConfigMap = func() { - By("Creating a ConfigMap containing a basic config.yaml") - // Incomplete config.yaml, containing only the required data for our - // tests. We test that those values are correctly updated. - configYaml = ` -homeserver: - address: http://localhost:8008 - domain: mydomain.com -appservice: - address: http://localhost:29328 -signal: - socket_path: /var/run/signald/signald.sock -bridge: - permissions: - "*": "relay" - "mydomain.com": "user" - "@admin:mydomain.com": "admin" -logging: - handlers: - file: - filename: ./mautrix-signal.log` - - inputConfigmapData := map[string]string{ - "config.yaml": configYaml, - } - - // Populate the ConfigMap with the minimum data needed - inputConfigMap = &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: InputConfigMapName, - Namespace: MautrixSignalNamespace, - }, - Data: inputConfigmapData, - } - Expect(k8sClient.Create(ctx, inputConfigMap)).Should(Succeed()) - } - - var cleanupMautrixSignalConfigMap = func() { - By("Cleaning up ConfigMap") - Expect(k8sClient.Delete(ctx, inputConfigMap)).Should(Succeed()) - } - - BeforeAll(func() { - initMautrixSignalVariables() - - mautrixsignalSpec = synapsev1alpha1.MautrixSignalSpec{ - ConfigMap: synapsev1alpha1.MautrixSignalConfigMap{ - Name: InputConfigMapName, - Namespace: MautrixSignalNamespace, - }, - Synapse: synapsev1alpha1.MautrixSignalSynapseSpec{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - } - - createSynapseInstanceForMautrixSignal() - createMautrixSignalConfigMap() - createMautrixSignalInstance() - }) - - AfterAll(func() { - cleanupMautrixSignalResources() - cleanupMautrixSignalConfigMap() - cleanupSynapseCR() - }) - - It("Should should update the MautrixSignal Status", func() { - expectedStatus := synapsev1alpha1.MautrixSignalStatus{ - State: "", - Reason: "", - Synapse: synapsev1alpha1.MautrixSignalStatusSynapse{ - ServerName: SynapseServerName, - }, - IsOpenshift: true, - } - // Status may need some time to be updated - Eventually(func() synapsev1alpha1.MautrixSignalStatus { - _ = k8sClient.Get(ctx, mautrixsignalLookupKey, mautrixsignal) - return mautrixsignal.Status - }, timeout, interval).Should(Equal(expectedStatus)) - }) - - It("Should create a MautrixSignal ConfigMap", func() { - checkResourcePresence(createdConfigMap, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal PVC", func() { - checkResourcePresence(createdPVC, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal Deployment", func() { - checkResourcePresence(createdDeployment, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal Service", func() { - checkResourcePresence(createdService, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal ServiceAccount", func() { - checkResourcePresence(createdServiceAccount, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should create a MautrixSignal RoleBinding", func() { - checkResourcePresence(createdRoleBinding, mautrixsignalLookupKey, expectedOwnerReference) - }) - - It("Should overwrite necessary values in the created mautrix-signal ConfigMap", func() { - Eventually(func(g Gomega) { - By("Verifying that the mautrixsignal ConfigMap exists") - g.Expect(k8sClient.Get(ctx, mautrixsignalLookupKey, createdConfigMap)).Should(Succeed()) - - ConfigMapdata, ok := createdConfigMap.Data["config.yaml"] - g.Expect(ok).Should(BeTrue()) - - config := make(map[string]interface{}) - g.Expect(yaml.Unmarshal([]byte(ConfigMapdata), config)).Should(Succeed()) - - By("Verifying that the homeserver configuration has been updated") - configHomeserver, ok := config["homeserver"].(map[interface{}]interface{}) - g.Expect(ok).Should(BeTrue()) - g.Expect(configHomeserver["address"]).To(Equal("http://" + synapseFQDN + ":8008")) - g.Expect(configHomeserver["domain"]).To(Equal(SynapseServerName)) - - By("Verifying that the appservice configuration has been updated") - configAppservice, ok := config["appservice"].(map[interface{}]interface{}) - g.Expect(ok).Should(BeTrue()) - g.Expect(configAppservice["address"]).To(Equal("http://" + mautrixsignalFQDN + ":" + strconv.Itoa(mautrixsignalPort))) - - By("Verifying that the signal configuration has been updated") - configSignal, ok := config["signal"].(map[interface{}]interface{}) - g.Expect(ok).Should(BeTrue()) - g.Expect(configSignal["socket_path"]).To(Equal("/signald/signald.sock")) - - By("Verifying that the permissions have been updated") - configBridge, ok := config["bridge"].(map[interface{}]interface{}) - g.Expect(ok).Should(BeTrue()) - configBridgePermissions, ok := configBridge["permissions"].(map[interface{}]interface{}) - g.Expect(ok).Should(BeTrue()) - g.Expect(configBridgePermissions).Should(HaveKeyWithValue("*", "relay")) - g.Expect(configBridgePermissions).Should(HaveKeyWithValue(SynapseServerName, "user")) - g.Expect(configBridgePermissions).Should(HaveKeyWithValue("@admin:"+SynapseServerName, "admin")) - - By("Verifying that the log configuration file path have been updated") - configLogging, ok := config["logging"].(map[interface{}]interface{}) - g.Expect(ok).Should(BeTrue()) - configLoggingHandlers, ok := configLogging["handlers"].(map[interface{}]interface{}) - g.Expect(ok).Should(BeTrue()) - configLoggingHandlersFile, ok := configLoggingHandlers["file"].(map[interface{}]interface{}) - g.Expect(ok).Should(BeTrue()) - g.Expect(configLoggingHandlersFile["filename"]).To(Equal("/data/mautrix-signal.log")) - }, timeout, interval).Should(Succeed()) - }) - - It("Should not modify the input ConfigMap", func() { - Eventually(func(g Gomega) { - By("Fetching the inputConfigMap data") - inputConfigMapLookupKey := types.NamespacedName{ - Name: InputConfigMapName, - Namespace: MautrixSignalNamespace, - } - g.Expect(k8sClient.Get(ctx, inputConfigMapLookupKey, inputConfigMap)).Should(Succeed()) - - ConfigMapdata, ok := inputConfigMap.Data["config.yaml"] - g.Expect(ok).Should(BeTrue()) - - By("Verifying the config.yaml hasn't changed") - g.Expect(ConfigMapdata).To(Equal(configYaml)) - }, timeout, interval).Should(Succeed()) - }) - }) - - When("MautrixSignal references a non existing Synapse", func() { - BeforeAll(func() { - initMautrixSignalVariables() - - mautrixsignalSpec = synapsev1alpha1.MautrixSignalSpec{ - Synapse: synapsev1alpha1.MautrixSignalSynapseSpec{ - Name: "not-exist", - Namespace: SynapseNamespace, - }, - } - - createMautrixSignalInstance() - }) - - AfterAll(func() { - By("Cleaning up mautrixsignal CR") - Expect(k8sClient.Delete(ctx, mautrixsignal)).Should(Succeed()) - }) - - It("Should not create any MautrixSignal resources", func() { - checkStatus("", "", mautrixsignalLookupKey, mautrixsignal) - checkSubresourceAbsence( - mautrixsignalLookupKey, - createdConfigMap, - createdPVC, - createdDeployment, - createdService, - createdServiceAccount, - createdRoleBinding, - ) - }) - }) - - When("Creating and deleting MautrixSignal resources", func() { - const bridgeFinalizer = "synapse.opdev.io/finalizer" - - BeforeAll(func() { - initMautrixSignalVariables() - - mautrixsignalSpec = synapsev1alpha1.MautrixSignalSpec{ - Synapse: synapsev1alpha1.MautrixSignalSynapseSpec{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - } - - createSynapseInstanceForMautrixSignal() - }) - - AfterAll(func() { - cleanupMautrixSignalChildResources() - cleanupSynapseCR() - }) - - When("Creating MautrixSignal", func() { - BeforeAll(func() { - createMautrixSignalInstance() - }) - - It("Should add a Finalizer", func() { - Eventually(func() []string { - _ = k8sClient.Get(ctx, mautrixsignalLookupKey, mautrixsignal) - return mautrixsignal.Finalizers - }, timeout, interval).Should(ContainElement(bridgeFinalizer)) - }) - - It("Should trigger the reconciliation of Synapse", func() { - Eventually(func() bool { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status.NeedsReconcile - }, timeout, interval).Should(BeTrue()) - - // Set needsReconcile back to False, as the Synapse Controller - // would do if it would be running - synapse.Status.NeedsReconcile = false - Expect(k8sClient.Status().Update(ctx, synapse)).Should(Succeed()) - - time.Sleep(time.Second) - }) - }) - - When("Deleting MautrixSignal", func() { - BeforeAll(func() { - By("Sending delete request") - Expect(k8sClient.Delete(ctx, mautrixsignal)).Should(Succeed()) - }) - - // MautrixSignal controller is too fast and complete cleanup - // tasks (trigger Synapse reconciliation) and effectively - // deletes the MautrixSignal instance before we have time to - // check that the finalizer was removed. - // Instead, we check that the MautrixSignal instance is - // indeed absent. - PIt("Should remove the Finalizer", func() { - Eventually(func() []string { - _ = k8sClient.Get(ctx, mautrixsignalLookupKey, mautrixsignal) - return mautrixsignal.Finalizers - }, timeout, interval).ShouldNot(ContainElement(bridgeFinalizer)) - }) - - It("Should effectively remove the MautrixSignal instance", func() { - Eventually(func() bool { - err := k8sClient.Get(ctx, mautrixsignalLookupKey, mautrixsignal) - return err == nil - }, timeout, interval).Should(BeFalse()) - }) - - It("Should trigger the reconciliation of Synapse", func() { - Eventually(func() bool { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status.NeedsReconcile - }, timeout, interval).Should(BeTrue()) - }) - }) - }) - }) - }) -}) diff --git a/controllers/synapse/mautrixsignal/mautrixsignal_deployment.go b/controllers/synapse/mautrixsignal/mautrixsignal_deployment.go deleted file mode 100644 index 1108ddd..0000000 --- a/controllers/synapse/mautrixsignal/mautrixsignal_deployment.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package mautrixsignal - -import ( - "context" - "fmt" - - appsv1 "k8s.io/api/apps/v1" - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// labelsForMautrixSignal returns the labels for selecting the resources -// belonging to the given synapse CR name. -func labelsForMautrixSignal(name string) map[string]string { - return map[string]string{"app": "mautrix-signal", "mautrixsignal_cr": name} -} - -// reconcileMautrixSignalDeployment is a function of type FnWithRequest, -// to be called in the main reconciliation loop. -// -// It reconciles the Deployment for mautrix-signal to its desired state. -func (r *MautrixSignalReconciler) reconcileMautrixSignalDeployment(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - ms := &synapsev1alpha1.MautrixSignal{} - if r, err := utils.GetResource(ctx, r.Client, req, ms); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredDeployment, err := r.deploymentForMautrixSignal(ms) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredDeployment, - &appsv1.Deployment{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// deploymentForMautrixSignal returns a Deployment object for the mautrix-signal bridge -func (r *MautrixSignalReconciler) deploymentForMautrixSignal(ms *synapsev1alpha1.MautrixSignal) (*appsv1.Deployment, error) { - type deploymentExtraValues struct { - synapsev1alpha1.MautrixSignal - Labels map[string]string - } - - extraValues := deploymentExtraValues{ - MautrixSignal: *ms, - Labels: labelsForMautrixSignal(ms.Name), - } - - dep, err := templates.ResourceFromTemplate[deploymentExtraValues, appsv1.Deployment](&extraValues, "mautrixsignal_deployment") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set MautrixSignal instance as the owner and controller - if err := ctrl.SetControllerReference(ms, dep, r.Scheme); err != nil { - return &appsv1.Deployment{}, err - } - return dep, nil -} diff --git a/controllers/synapse/mautrixsignal/mautrixsignal_pvc.go b/controllers/synapse/mautrixsignal/mautrixsignal_pvc.go deleted file mode 100644 index c731c9c..0000000 --- a/controllers/synapse/mautrixsignal/mautrixsignal_pvc.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package mautrixsignal - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileMautrixSignalPVC is a function of type FnWithRequest, to be -// called in the main reconciliation loop. -// -// It reconciles the PVC for mautrix-signal to its desired state. -func (r *MautrixSignalReconciler) reconcileMautrixSignalPVC(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - ms := &synapsev1alpha1.MautrixSignal{} - if r, err := utils.GetResource(ctx, r.Client, req, ms); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredPVC, err := r.persistentVolumeClaimForMautrixSignal(ms) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredPVC, - &corev1.PersistentVolumeClaim{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// persistentVolumeClaimForMautrixSignal returns a mautrix-signal PVC object -func (r *MautrixSignalReconciler) persistentVolumeClaimForMautrixSignal(ms *synapsev1alpha1.MautrixSignal) (*corev1.PersistentVolumeClaim, error) { - pvc, err := templates.ResourceFromTemplate[synapsev1alpha1.MautrixSignal, corev1.PersistentVolumeClaim](ms, "pvc") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set MautrixSignal instance as the owner and controller - if err := ctrl.SetControllerReference(ms, pvc, r.Scheme); err != nil { - return &corev1.PersistentVolumeClaim{}, err - } - return pvc, nil -} diff --git a/controllers/synapse/mautrixsignal/mautrixsignal_service.go b/controllers/synapse/mautrixsignal/mautrixsignal_service.go deleted file mode 100644 index 801606a..0000000 --- a/controllers/synapse/mautrixsignal/mautrixsignal_service.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package mautrixsignal - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileMautrixSignalService is a function of type FnWithRequest, to -// be called in the main reconciliation loop. -// -// It reconciles the Service for mautrix-signal to its desired state. -func (r *MautrixSignalReconciler) reconcileMautrixSignalService(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - ms := &synapsev1alpha1.MautrixSignal{} - if r, err := utils.GetResource(ctx, r.Client, req, ms); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredService, err := r.serviceForMautrixSignal(ms) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredService, - &corev1.Service{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// serviceForMautrixSignal returns a mautrix-signal Service object -func (r *MautrixSignalReconciler) serviceForMautrixSignal(ms *synapsev1alpha1.MautrixSignal) (*corev1.Service, error) { - type serviceExtraValues struct { - synapsev1alpha1.MautrixSignal - Labels map[string]string - PortName string - Port int - TargetPort int - } - - extraValues := serviceExtraValues{ - MautrixSignal: *ms, - Labels: labelsForMautrixSignal(ms.Name), - PortName: "mautrix-signal", - Port: 29328, - TargetPort: 29328, - } - - service, err := templates.ResourceFromTemplate[serviceExtraValues, corev1.Service](&extraValues, "service") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set MautrixSignal instance as the owner and controller - if err := ctrl.SetControllerReference(ms, service, r.Scheme); err != nil { - return &corev1.Service{}, err - } - return service, nil -} diff --git a/controllers/synapse/mautrixsignal/mautrixsignal_serviceaccount.go b/controllers/synapse/mautrixsignal/mautrixsignal_serviceaccount.go deleted file mode 100644 index dad2c6f..0000000 --- a/controllers/synapse/mautrixsignal/mautrixsignal_serviceaccount.go +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package mautrixsignal - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileMautrixSignalServiceAccount is a function of type -// FnWithRequest, to be called in the main reconciliation loop. -// -// It reconciles the ServiceAccount for mautrix-signal to its desired state. -func (r *MautrixSignalReconciler) reconcileMautrixSignalServiceAccount(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - ms := &synapsev1alpha1.MautrixSignal{} - if r, err := utils.GetResource(ctx, r.Client, req, ms); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredServiceAccount, err := r.serviceAccountForMautrixSignal(ms) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredServiceAccount, - &corev1.ServiceAccount{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// serviceAccountForMautrixSignal returns a ServiceAccount object for running the mautrix-signal bridge -func (r *MautrixSignalReconciler) serviceAccountForMautrixSignal(ms *synapsev1alpha1.MautrixSignal) (client.Object, error) { - // TODO: https://github.com/opdev/synapse-operator/issues/19 - sa, err := templates.ResourceFromTemplate[synapsev1alpha1.MautrixSignal, corev1.ServiceAccount](ms, "serviceaccount") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set MautrixSignal instance as the owner and controller - if err := ctrl.SetControllerReference(ms, sa, r.Scheme); err != nil { - return &corev1.ServiceAccount{}, err - } - return sa, nil -} - -// reconcileMautrixSignalRoleBinding is a function of type FnWithRequest, -// to be called in the main reconciliation loop. -// -// It reconciles the RoleBinding for mautrix-signal to its desired state. -func (r *MautrixSignalReconciler) reconcileMautrixSignalRoleBinding(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - ms := &synapsev1alpha1.MautrixSignal{} - if r, err := utils.GetResource(ctx, r.Client, req, ms); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredRoleBinding, err := r.roleBindingForMautrixSignal(ms) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredRoleBinding, - &rbacv1.RoleBinding{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// roleBindingForMautrixSignal returns a RoleBinding object for the mautrix-signal bridge -func (r *MautrixSignalReconciler) roleBindingForMautrixSignal(ms *synapsev1alpha1.MautrixSignal) (*rbacv1.RoleBinding, error) { - // TODO: https://github.com/opdev/synapse-operator/issues/19 - rb, err := templates.ResourceFromTemplate[synapsev1alpha1.MautrixSignal, rbacv1.RoleBinding](ms, "rolebinding") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set MautrixSignal instance as the owner and controller - if err := ctrl.SetControllerReference(ms, rb, r.Scheme); err != nil { - return &rbacv1.RoleBinding{}, err - } - return rb, nil -} diff --git a/controllers/synapse/mautrixsignal/mautrixsignal_test.go b/controllers/synapse/mautrixsignal/mautrixsignal_test.go deleted file mode 100644 index 1f56e37..0000000 --- a/controllers/synapse/mautrixsignal/mautrixsignal_test.go +++ /dev/null @@ -1,5 +0,0 @@ -// -//This file contains unit tests for the mautrixsignal package -// - -package mautrixsignal diff --git a/controllers/synapse/mautrixsignal/suite_test.go b/controllers/synapse/mautrixsignal/suite_test.go deleted file mode 100644 index 6006435..0000000 --- a/controllers/synapse/mautrixsignal/suite_test.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package mautrixsignal - -import ( - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - //+kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "MautrixSignal Controller Suite") -} diff --git a/controllers/synapse/synapse/suite_test.go b/controllers/synapse/synapse/suite_test.go deleted file mode 100644 index 0669eaf..0000000 --- a/controllers/synapse/synapse/suite_test.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package synapse - -import ( - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - //+kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Synapse Controller Suite") -} diff --git a/controllers/synapse/synapse/synapse_configmap.go b/controllers/synapse/synapse/synapse_configmap.go deleted file mode 100644 index c7caca1..0000000 --- a/controllers/synapse/synapse/synapse_configmap.go +++ /dev/null @@ -1,502 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package synapse - -import ( - "context" - "crypto/rand" - "errors" - "fmt" - "io" - "math/big" - "strconv" - "strings" - "time" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - ctrllog "sigs.k8s.io/controller-runtime/pkg/log" - - subreconciler "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileSynapseConfigMap is a function of type FnWithRequest, to be -// called in the main reconciliation loop. -// -// It reconciles the synapse ConfigMap to its desired state. It is called only -// if the user hasn't provided its own ConfigMap for synapse -func (r *SynapseReconciler) reconcileSynapseConfigMap(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredConfigMap, err := r.configMapForSynapse(s) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredConfigMap, - &corev1.ConfigMap{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// configMapForSynapse returns a synapse ConfigMap object -func (r *SynapseReconciler) configMapForSynapse(s *synapsev1alpha1.Synapse) (*corev1.ConfigMap, error) { - type configmapExtraValues struct { - synapsev1alpha1.Synapse - RegistrationSharedSecret string - MacaroonSecretKey string - FormSecret string - } - - registrationSharedSecret, err := generateASCIIPassword(defaultGeneratedPasswordLength) - if err != nil { - return nil, err - } - macaroonSecretKey, err := generateASCIIPassword(defaultGeneratedPasswordLength) - if err != nil { - return nil, err - } - formSecret, err := generateASCIIPassword(defaultGeneratedPasswordLength) - if err != nil { - return nil, err - } - - extraValues := configmapExtraValues{ - Synapse: *s, - RegistrationSharedSecret: registrationSharedSecret, - MacaroonSecretKey: macaroonSecretKey, - FormSecret: formSecret, - } - - cm, err := templates.ResourceFromTemplate[configmapExtraValues, corev1.ConfigMap](&extraValues, "synapse_configmap") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set Synapse instance as the owner and controller - if err := ctrl.SetControllerReference(s, cm, r.Scheme); err != nil { - return &corev1.ConfigMap{}, err - } - - return cm, nil -} - -// parseInputSynapseConfigMap is a function of type FnWithRequest, to be -// called in the main reconciliation loop. -// -// It checks that the ConfigMap referenced by -// synapse.Spec.Homeserver.ConfigMap.Name exists and extrats the server_name -// and report_stats values. -func (r *SynapseReconciler) parseInputSynapseConfigMap(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - log := ctrllog.FromContext(ctx) - - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - var inputConfigMap corev1.ConfigMap // the user-provided ConfigMap. It should contain a valid homeserver.yaml - ConfigMapName := s.Spec.Homeserver.ConfigMap.Name - ConfigMapNamespace := utils.ComputeNamespace(s.Namespace, s.Spec.Homeserver.ConfigMap.Namespace) - keyForInputConfigMap := types.NamespacedName{ - Name: ConfigMapName, - Namespace: ConfigMapNamespace, - } - - // Get and validate the inputConfigMap - if err := r.Get(ctx, keyForInputConfigMap, &inputConfigMap); err != nil { - reason := "ConfigMap " + ConfigMapName + " does not exist in namespace " + ConfigMapNamespace - utils.SetFailedState(ctx, r.Client, s, reason) - - log.Error( - err, - "Failed to get ConfigMap", - "ConfigMap.Namespace", - ConfigMapNamespace, - "ConfigMap.Name", - ConfigMapName, - ) - return subreconciler.RequeueWithDelayAndError(time.Duration(30), err) - } - - if err := r.ParseHomeserverConfigMap(ctx, s, inputConfigMap); err != nil { - return subreconciler.RequeueWithDelayAndError(time.Duration(30), err) - } - - err := utils.UpdateResourceStatus(ctx, r.Client, s, &synapsev1alpha1.Synapse{}) - if err != nil { - log.Error(err, "Error updating Synapse Status") - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// ParseHomeserverConfigMap loads the ConfigMap, which name is determined by -// Spec.Homeserver.ConfigMap.Name, run validation checks and fetch necesarry -// value needed to configure the Synapse Deployment. -func (r *SynapseReconciler) ParseHomeserverConfigMap(ctx context.Context, synapse *synapsev1alpha1.Synapse, cm corev1.ConfigMap) error { - log := ctrllog.FromContext(ctx) - - // TODO: - // - Ensure that key path is and log config file path are in /data - // - Otherwise, edit homeserver.yaml with new paths - - // Load and validate homeserver.yaml - homeserver, err := utils.LoadYAMLFileFromConfigMapData(cm, "homeserver.yaml") - if err != nil { - return err - } - - // Fetch server_name and report_stats - if _, ok := homeserver["server_name"]; !ok { - err := errors.New("missing server_name key in homeserver.yaml") - log.Error(err, "Missing server_name key in homeserver.yaml") - return err - } - server_name, ok := homeserver["server_name"].(string) - if !ok { - err := errors.New("error converting server_name to string") - log.Error(err, "Error converting server_name to string") - return err - } - - if _, ok := homeserver["report_stats"]; !ok { - err := errors.New("missing report_stats key in homeserver.yaml") - log.Error(err, "Missing report_stats key in homeserver.yaml") - return err - } - report_stats, ok := homeserver["report_stats"].(bool) - if !ok { - err := errors.New("error converting report_stats to bool") - log.Error(err, "Error converting report_stats to bool") - return err - } - - // Populate the Status.HomeserverConfiguration with values defined in homeserver.yaml - synapse.Status.HomeserverConfiguration.ServerName = server_name - synapse.Status.HomeserverConfiguration.ReportStats = report_stats - - log.Info( - "Loaded homeserver.yaml from ConfigMap successfully", - "server_name:", synapse.Status.HomeserverConfiguration.ServerName, - "report_stats:", synapse.Status.HomeserverConfiguration.ReportStats, - ) - - return nil -} - -// updateSynapseConfigMapForPostgresCluster is a function of type -// FnWithRequest, to be called in the main reconciliation loop. -// -// It configures the 'database' section of homeserver.yaml to allow Synapse to -// connect to the newly created PostgresCluster instance. -func (r *SynapseReconciler) updateSynapseConfigMapForPostgresCluster(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - keyForSynapse := types.NamespacedName{ - Name: s.Name, - Namespace: s.Namespace, - } - - if err := utils.UpdateConfigMap( - ctx, - r.Client, - keyForSynapse, - s, - r.updateHomeserverWithPostgreSQLInfos, - "homeserver.yaml", - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -func (r *SynapseReconciler) updateHomeserverWithPostgreSQLInfos( - obj client.Object, - homeserver map[string]interface{}, -) error { - s := obj.(*synapsev1alpha1.Synapse) - - databaseData, err := r.fetchDatabaseDataFromSynapseStatus(*s) - if err != nil { - return err - } - - // Save new database section of homeserver.yaml - homeserver["database"] = databaseData - return nil -} - -func (r *SynapseReconciler) fetchDatabaseDataFromSynapseStatus(s synapsev1alpha1.Synapse) (map[string]interface{}, error) { - databaseData := HomeserverPgsqlDatabase{} - - // Check if s.Status.DatabaseConnectionInfo contains necessary information - if s.Status.DatabaseConnectionInfo == (synapsev1alpha1.SynapseStatusDatabaseConnectionInfo{}) { - err := errors.New("missing DatabaseConnectionInfo in Synapse status") - return map[string]interface{}{}, err - } - - if s.Status.DatabaseConnectionInfo.User == "" { - err := errors.New("missing User in DatabaseConnectionInfo") - return map[string]interface{}{}, err - } - - if s.Status.DatabaseConnectionInfo.Password == "" { - err := errors.New("missing Password in DatabaseConnectionInfo") - return map[string]interface{}{}, err - } - decodedPassword := base64decode([]byte(s.Status.DatabaseConnectionInfo.Password)) - - if s.Status.DatabaseConnectionInfo.DatabaseName == "" { - err := errors.New("missing DatabaseName in DatabaseConnectionInfo") - return map[string]interface{}{}, err - } - - if s.Status.DatabaseConnectionInfo.ConnectionURL == "" { - err := errors.New("missing ConnectionURL in DatabaseConnectionInfo") - return map[string]interface{}{}, err - } - connectionURL := strings.Split(s.Status.DatabaseConnectionInfo.ConnectionURL, ":") - if len(connectionURL) < 2 { - err := errors.New("error parsing the Connection URL with value: " + s.Status.DatabaseConnectionInfo.ConnectionURL) - return map[string]interface{}{}, err - } - port, err := strconv.ParseInt(connectionURL[1], 10, 64) - if err != nil { - return map[string]interface{}{}, err - } - - // Populate databaseData - databaseData.Name = "psycopg2" - databaseData.Args.User = s.Status.DatabaseConnectionInfo.User - databaseData.Args.Password = decodedPassword - databaseData.Args.Database = s.Status.DatabaseConnectionInfo.DatabaseName - databaseData.Args.Host = connectionURL[0] - databaseData.Args.Port = port - databaseData.Args.CpMin = 5 - databaseData.Args.CpMax = 10 - - // Convert databaseData into a map[string]interface{} - databaseDataMap, err := utils.ConvertStructToMap(databaseData) - if err != nil { - return map[string]interface{}{}, err - } - - return databaseDataMap, nil -} - -func (r *SynapseReconciler) updateSynapseConfigMapForBridges(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - if s.Status.Bridges.Heisenbridge.Enabled { - if r, err := r.updateSynapseConfigMapForHeisenbridge(ctx, req); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - } - - if s.Status.Bridges.MautrixSignal.Enabled { - if r, err := r.updateSynapseConfigMapForMautrixSignal(ctx, req); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - } - - return subreconciler.ContinueReconciling() -} - -// updateSynapseConfigMapForHeisenbridge is a function of type -// FnWithRequest, to be called in the main reconciliation loop. -// -// It registers the heisenbridge as an application service in the -// homeserver.yaml config file. -func (r *SynapseReconciler) updateSynapseConfigMapForHeisenbridge(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - keyForSynapse := types.NamespacedName{ - Name: s.Name, - Namespace: s.Namespace, - } - - // Update the Synapse ConfigMap to enable heisenbridge - if err := utils.UpdateConfigMap( - ctx, - r.Client, - keyForSynapse, - s, - r.updateHomeserverWithHeisenbridgeInfos, - "homeserver.yaml", - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// updateHomeserverWithHeisenbridgeInfos is a function of type updateDataFunc -// function to be passed as an argument in a call to utils.UpdateConfigMap. -// -// It enables the Heisenbridge as an AppService in Synapse. -func (r *SynapseReconciler) updateHomeserverWithHeisenbridgeInfos( - _ client.Object, - homeserver map[string]interface{}, -) error { - // Add heisenbridge configuration file to the list of application services - r.addAppServiceToHomeserver(homeserver, "/data-heisenbridge/heisenbridge.yaml") - return nil -} - -// updateSynapseConfigMapForMautrixSignal is a function of type -// FnWithRequest, to be called in the main reconciliation loop. -// -// It registers the mautrix-signal bridge as an application service in the -// homeserver.yaml config file. -func (r *SynapseReconciler) updateSynapseConfigMapForMautrixSignal(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - keyForSynapse := types.NamespacedName{ - Name: s.Name, - Namespace: s.Namespace, - } - - // Update the Synapse ConfigMap to enable mautrix-signal - if err := utils.UpdateConfigMap( - ctx, - r.Client, - keyForSynapse, - s, - r.updateHomeserverWithMautrixSignalInfos, - "homeserver.yaml", - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// updateHomeserverWithMautrixSignalInfos is a function of type updateDataFunc -// function to be passed as an argument in a call to utils.UpdateConfigMap. -// -// It enables the mautrix-signal bridge as an AppService in Synapse. -func (r *SynapseReconciler) updateHomeserverWithMautrixSignalInfos( - _ client.Object, - homeserver map[string]interface{}, -) error { - // Add mautrix-signal configuration file to the list of application services - r.addAppServiceToHomeserver(homeserver, "/data-mautrixsignal/registration.yaml") - return nil -} - -func (r *SynapseReconciler) addAppServiceToHomeserver( - homeserver map[string]interface{}, - configFilePath string, -) { - homeserverAppService, ok := homeserver["app_service_config_files"].([]string) - if !ok { - // "app_service_config_files" key not present, or malformed. Overwrite with - // the given app_service config file. - homeserver["app_service_config_files"] = []string{configFilePath} - } else { - // There are already app services registered. Adding to the list. - homeserver["app_service_config_files"] = append(homeserverAppService, configFilePath) - } -} - -// The following constant is used as a part of password generation. -const ( - // DefaultGeneratedPasswordLength is the default length of what a generated - // password should be if it's not set elsewhere - defaultGeneratedPasswordLength = 24 -) - -// accumulate gathers n bytes from f and returns them as a string. It returns -// an empty string when f returns an error. -func accumulate(n int, f func() (byte, error)) (string, error) { - result := make([]byte, n) - - for i := range result { - if b, err := f(); err == nil { - result[i] = b - } else { - return "", err - } - } - - return string(result), nil -} - -// randomCharacter builds a function that returns random bytes from class. -func randomCharacter(random io.Reader, class string) func() (byte, error) { - if random == nil { - panic("requires a random source") - } - if len(class) == 0 { - panic("class cannot be empty") - } - - size := big.NewInt(int64(len(class))) - - return func() (byte, error) { - if i, err := rand.Int(random, size); err == nil { - return class[int(i.Int64())], nil - } else { - return 0, err - } - } -} - -// policyASCII is the list of acceptable characters from which to generate an -// ASCII password. -const policyASCII = `` + - `()*+,-./` + `:;<=>?@` + `[]^_` + `{|}` + - `ABCDEFGHIJKLMNOPQRSTUVWXYZ` + - `abcdefghijklmnopqrstuvwxyz` + - `0123456789` - -var randomASCII = randomCharacter(rand.Reader, policyASCII) - -// GenerateASCIIPassword returns a random string of printable ASCII characters. -func generateASCIIPassword(length int) (string, error) { - return accumulate(length, randomASCII) -} diff --git a/controllers/synapse/synapse/synapse_controller.go b/controllers/synapse/synapse/synapse_controller.go deleted file mode 100644 index 80fe4f1..0000000 --- a/controllers/synapse/synapse/synapse_controller.go +++ /dev/null @@ -1,364 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package synapse - -import ( - "context" - "errors" - "strings" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - ctrllog "sigs.k8s.io/controller-runtime/pkg/log" - - pgov1beta1 "github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1" - subreconciler "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/utils" -) - -// SynapseReconciler reconciles a Synapse object -type SynapseReconciler struct { - client.Client - Scheme *runtime.Scheme -} - -type HomeserverPgsqlDatabase struct { - Name string `yaml:"name"` - TxnLimit int64 `yaml:"txn_limit"` - Args struct { - User string `yaml:"user"` - Password string `yaml:"password"` - Database string `yaml:"database"` - Host string `yaml:"host"` - Port int64 `yaml:"port"` - CpMin int64 `yaml:"cp_min"` - CpMax int64 `yaml:"cp_max"` - } -} - -//+kubebuilder:rbac:groups=synapse.opdev.io,resources=synapses,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=synapse.opdev.io,resources=synapses/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=synapse.opdev.io,resources=synapses/finalizers,verbs=update -//+kubebuilder:rbac:groups=core,resources=services;persistentvolumeclaims;configmaps;serviceaccounts,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=rolebindings,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=postgres-operator.crunchydata.com,resources=postgresclusters,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=security.openshift.io,resourceNames=anyuid,resources=securitycontextconstraints,verbs=use - -func GetPostgresClusterResourceName(synapse synapsev1alpha1.Synapse) string { - return strings.Join([]string{synapse.Name, "pgsql"}, "-") -} - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.9.2/pkg/reconcile -func (r *SynapseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - log := ctrllog.FromContext(ctx) - - var synapse synapsev1alpha1.Synapse // The Synapse object being reconciled - if r, err := utils.GetResource(ctx, r.Client, req, &synapse); subreconciler.ShouldHaltOrRequeue(r, err) { - return subreconciler.Evaluate(r, err) - } - - // The list of subreconcilers for Synapse. - var subreconcilersForSynapse []subreconciler.FnWithRequest - - // Synapse should either have a Spec.Homeserver.ConfigMap or Spec.Homeserver.Values - if synapse.Spec.Homeserver.ConfigMap != nil { - // If the user provided a ConfigMap for the Homeserver config file: - // * We ensure that it exists and is a valid yaml file - // * We populate the Status.HomeserverConfiguration with the values defined in the input ConfigMap - // * We create a copy of the user-provided ConfigMap. - subreconcilersForSynapse = []subreconciler.FnWithRequest{ - r.parseInputSynapseConfigMap, - utils.CopyInputConfigMap(r.Client, r.Scheme, &synapsev1alpha1.Synapse{}), - } - } else { - // If the user hasn't provided a ConfigMap with a custom - // homeserver.yaml, we create a new ConfigMap. The default - // homeserver.yaml is configured with values defined in - // Spec.Homeserver.Values - subreconcilersForSynapse = []subreconciler.FnWithRequest{ - r.setStatusHomeserverConfiguration, - r.reconcileSynapseConfigMap, - } - } - - // Determine the existence of Bridges referencing this Synapse instance - subreconcilersForSynapse = append( - subreconcilersForSynapse, - r.updateSynapseStatusBridges, - r.updateSynapseConfigMapForBridges, - ) - - if synapse.Spec.CreateNewPostgreSQL { - if !r.isPostgresOperatorInstalled(ctx) { - reason := "Cannot create PostgreSQL instance for synapse. Postgres-operator is not installed." - utils.SetFailedState(ctx, r.Client, &synapse, reason) - - err := errors.New("cannot create PostgreSQL instance for synapse. Potsgres-operator is not installed") - log.Error(err, "Cannot create PostgreSQL instance for synapse. Potsgres-operator is not installed.") - return subreconciler.Evaluate(subreconciler.DoNotRequeue()) - } - - // Reconcile the PostgresCluster CR and ConfigMap. - // Also update the Synapse Status and ConfigMap with database - // connection information. - subreconcilersForSynapse = append( - subreconcilersForSynapse, - r.reconcilePostgresClusterConfigMap, - r.reconcilePostgresClusterCR, - r.updateSynapseStatusWithPostgreSQLInfos, - r.updateSynapseConfigMapForPostgresCluster, - ) - } - - // SA and RB are only necessary if we're running on OpenShift - if synapse.Spec.IsOpenshift { - subreconcilersForSynapse = append( - subreconcilersForSynapse, - r.reconcileSynapseServiceAccount, - r.reconcileSynapseRoleBinding, - ) - } - - // Reconcile Synapse resources: Service, PVC, Deployment - subreconcilersForSynapse = append( - subreconcilersForSynapse, - r.reconcileSynapseService, - r.reconcileSynapsePVC, - r.reconcileSynapseDeployment, - r.setSynapseStatusAsRunning, - ) - - // Run all subreconcilers sequentially - for _, f := range subreconcilersForSynapse { - if r, err := f(ctx, req); subreconciler.ShouldHaltOrRequeue(r, err) { - return subreconciler.Evaluate(r, err) - } - } - - return subreconciler.Evaluate(subreconciler.DoNotRequeue()) -} - -// labelsForSynapse returns the labels for selecting the resources -// belonging to the given synapse CR name. -func labelsForSynapse(name string) map[string]string { - return map[string]string{"app": "synapse", "synapse_cr": name} -} - -func (r *SynapseReconciler) setStatusHomeserverConfiguration(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - log := ctrllog.FromContext(ctx) - - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - s.Status.HomeserverConfiguration.ServerName = s.Spec.Homeserver.Values.ServerName - s.Status.HomeserverConfiguration.ReportStats = s.Spec.Homeserver.Values.ReportStats - - err := utils.UpdateResourceStatus(ctx, r.Client, s, &synapsev1alpha1.Synapse{}) - if err != nil { - log.Error(err, "Error updating Synapse Status") - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -func (r *SynapseReconciler) isPostgresOperatorInstalled(ctx context.Context) bool { - err := r.Client.List(ctx, &pgov1beta1.PostgresClusterList{}) - return err == nil -} - -// updateSynapseStatusWithPostgreSQLInfos is a function of type -// FnWithRequest, to be called in the main reconciliation loop. -// -// It parses the PostgresCluster Secret and updates the Synapse status with the -// database connection information. -func (r *SynapseReconciler) updateSynapseStatusWithPostgreSQLInfos(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - log := ctrllog.FromContext(ctx) - - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - var postgresSecret corev1.Secret - - keyForPostgresClusterSecret := types.NamespacedName{ - Name: GetPostgresClusterResourceName(*s) + "-pguser-synapse", - Namespace: s.Namespace, - } - - // Get PostgresCluster Secret containing information for the synapse user - if err := r.Get(ctx, keyForPostgresClusterSecret, &postgresSecret); err != nil { - return subreconciler.RequeueWithError(err) - } - - // Locally updates the Synapse Status - if err := r.updateSynapseStatusDatabase(s, postgresSecret); err != nil { - return subreconciler.RequeueWithError(err) - } - - // Actually sends an API request to update the Status - err := utils.UpdateResourceStatus(ctx, r.Client, s, &synapsev1alpha1.Synapse{}) - if err != nil { - log.Error(err, "Error updating Synapse Status") - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -func (r *SynapseReconciler) updateSynapseStatusDatabase( - s *synapsev1alpha1.Synapse, - postgresSecret corev1.Secret, -) error { - var postgresSecretData map[string][]byte = postgresSecret.Data - - host, ok := postgresSecretData["host"] - if !ok { - err := errors.New("missing host in PostgreSQL Secret") - // log.Error(err, "Missing host in PostgreSQL Secret") - return err - } - - port, ok := postgresSecretData["port"] - if !ok { - err := errors.New("missing port in PostgreSQL Secret") - // log.Error(err, "Missing port in PostgreSQL Secret") - return err - } - - // See https://github.com/opdev/synapse-operator/issues/12 - // databaseName, ok := postgresSecretData["dbname"] - _, ok = postgresSecretData["dbname"] - if !ok { - err := errors.New("missing dbname in PostgreSQL Secret") - // log.Error(err, "Missing dbname in PostgreSQL Secret") - return err - } - - user, ok := postgresSecretData["user"] - if !ok { - err := errors.New("missing user in PostgreSQL Secret") - // log.Error(err, "Missing user in PostgreSQL Secret") - return err - } - - password, ok := postgresSecretData["password"] - if !ok { - err := errors.New("missing password in PostgreSQL Secret") - // log.Error(err, "Missing password in PostgreSQL Secret") - return err - } - - s.Status.DatabaseConnectionInfo.ConnectionURL = string(host) + ":" + string(port) - // s.Status.DatabaseConnectionInfo.DatabaseName = string(databaseName) // See https://github.com/opdev/synapse-operator/issues/12 - s.Status.DatabaseConnectionInfo.DatabaseName = "synapse" - s.Status.DatabaseConnectionInfo.User = string(user) - s.Status.DatabaseConnectionInfo.Password = string(base64encode(string(password))) - s.Status.DatabaseConnectionInfo.State = "READY" - - return nil -} - -// setSynapseStatusAsRunning is a function of type FnWithRequest, to be -// called in the main reconciliation loop. -// -// It set the Synapse Status 'State' field to 'RUNNING'. -func (r *SynapseReconciler) setSynapseStatusAsRunning(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - log := ctrllog.FromContext(ctx) - - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - s.Status.NeedsReconcile = false - s.Status.State = "RUNNING" - s.Status.Reason = "" - - err := utils.UpdateResourceStatus(ctx, r.Client, s, &synapsev1alpha1.Synapse{}) - if err != nil { - log.Error(err, "Error updating Synapse Status") - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -func (r *SynapseReconciler) updateSynapseStatusBridges(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - log := ctrllog.FromContext(ctx) - - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - // Set to default - s.Status.Bridges.Heisenbridge = synapsev1alpha1.SynapseStatusBridgesHeisenbridge{} - s.Status.Bridges.MautrixSignal = synapsev1alpha1.SynapseStatusBridgesMautrixSignal{} - - hList := &synapsev1alpha1.HeisenbridgeList{} - r.Client.List(ctx, hList) - for _, h := range hList.Items { - if h.Spec.Synapse.Name == s.Name && h.GetDeletionTimestamp() == nil { - s.Status.Bridges.Heisenbridge.Enabled = true - s.Status.Bridges.Heisenbridge.Name = h.Name - break - } - } - - msList := &synapsev1alpha1.MautrixSignalList{} - r.Client.List(ctx, msList) - for _, ms := range msList.Items { - if ms.Spec.Synapse.Name == s.Name && ms.GetDeletionTimestamp() == nil { - s.Status.Bridges.MautrixSignal.Enabled = true - s.Status.Bridges.MautrixSignal.Name = ms.Name - break - } - } - - err := utils.UpdateResourceStatus(ctx, r.Client, s, &synapsev1alpha1.Synapse{}) - if err != nil { - log.Error(err, "Error updating Synapse Status") - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// SetupWithManager sets up the controller with the Manager. -func (r *SynapseReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&synapsev1alpha1.Synapse{}). - Owns(&corev1.Service{}). - Owns(&appsv1.Deployment{}). - Owns(&corev1.PersistentVolumeClaim{}). - Complete(r) -} diff --git a/controllers/synapse/synapse/synapse_controller_test.go b/controllers/synapse/synapse/synapse_controller_test.go deleted file mode 100644 index 7d46e9a..0000000 --- a/controllers/synapse/synapse/synapse_controller_test.go +++ /dev/null @@ -1,1175 +0,0 @@ -package synapse - -import ( - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "path/filepath" - "runtime" - "strconv" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "gopkg.in/yaml.v2" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/config" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/metrics/server" - - pgov1beta1 "github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/utils" -) - -var _ = Describe("Integration tests for the Synapse controller", Ordered, Label("integration"), func() { - // Define utility constants for object names and testing timeouts/durations and intervals. - const ( - SynapseName = "test-synapse" - SynapseNamespace = "default" - InputConfigMapName = "test-configmap" - ServerName = "example.com" - ReportStats = false - - timeout = time.Second * 2 - duration = time.Second * 2 - interval = time.Millisecond * 250 - ) - - var k8sClient client.Client - var k8sManager manager.Manager - var testEnv *envtest.Environment - var ctx context.Context - var cancel context.CancelFunc - - var deleteResource func(client.Object, types.NamespacedName, bool) - var checkSubresourceAbsence func(types.NamespacedName, ...client.Object) - var checkResourcePresence func(client.Object, types.NamespacedName, metav1.OwnerReference) - var checkStatus func(string, string, types.NamespacedName, client.Object) - - // Common function to start envTest - var startenvTest = func() { - cfg, err := testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - Expect(synapsev1alpha1.AddToScheme(scheme.Scheme)).NotTo(HaveOccurred()) - Expect(pgov1beta1.AddToScheme(scheme.Scheme)).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - k8sManager, err = ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Metrics: server.Options{ - BindAddress: "0", - }, - Controller: config.Controller{ - SkipNameValidation: utils.BoolAddr(true), - }, - }) - Expect(err).ToNot(HaveOccurred()) - - err = (&SynapseReconciler{ - Client: k8sManager.GetClient(), - Scheme: k8sManager.GetScheme(), - }).SetupWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - - deleteResource = utils.DeleteResourceFunc(k8sClient, ctx, timeout, interval) - checkSubresourceAbsence = utils.CheckSubresourceAbsenceFunc(k8sClient, ctx, timeout, interval) - checkResourcePresence = utils.CheckResourcePresenceFunc(k8sClient, ctx, timeout, interval) - checkStatus = utils.CheckStatusFunc(k8sClient, ctx, timeout, interval) - - go func() { - defer GinkgoRecover() - Expect(k8sManager.Start(ctx)).ToNot(HaveOccurred(), "failed to run manager") - }() - } - - Context("When a corectly configured Kubernetes cluster is present", func() { - var _ = BeforeAll(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("Getting latest version of the PostgresCluster CRD") - postgresOperatorVersion := "5.2.0" - postgresClusterURL := "https://raw.githubusercontent.com/redhat-openshift-ecosystem/community-operators-prod/main/operators/postgresql/" + - postgresOperatorVersion + - "/manifests/postgresclusters.postgres-operator.crunchydata.com.crd.yaml" - - resp, err := http.Get(postgresClusterURL) - Expect(err).ShouldNot(HaveOccurred()) - - // The CRD is downloaded as a YAML document. The CustomResourceDefinition - // struct defined in the v1 package only possess json tags. In order to - // successfully Unmarshal the CRD Document into a - // CustomResourceDefinition object, it is necessary to first transform the - // YAML document into a intermediate JSON document. - defer resp.Body.Close() - yamlBody, err := io.ReadAll(resp.Body) - Expect(err).ShouldNot(HaveOccurred()) - - // Unmarshal the YAML document into an intermediate map - var mapBody interface{} - Expect(yaml.Unmarshal(yamlBody, &mapBody)).ShouldNot(HaveOccurred()) - - // The map has to be converted. See https://stackoverflow.com/a/40737676/6133648 - mapBody = utils.Convert(mapBody) - - // Marshal the map into an intermediate JSON document - jsonBody, err := json.Marshal(mapBody) - Expect(err).ShouldNot(HaveOccurred()) - - // Unmarshall the JSON document into the final CustomResourceDefinition object. - var PostgresClusterCRD v1.CustomResourceDefinition - Expect(json.Unmarshal(jsonBody, &PostgresClusterCRD)).ShouldNot(HaveOccurred()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "bundle", "manifests", "synapse.opdev.io_synapses.yaml"), - filepath.Join("..", "..", "..", "bundle", "manifests", "synapse.opdev.io_heisenbridges.yaml"), - filepath.Join("..", "..", "..", "bundle", "manifests", "synapse.opdev.io_mautrixsignals.yaml"), - }, - CRDs: []*v1.CustomResourceDefinition{&PostgresClusterCRD}, - ErrorIfCRDPathMissing: true, - BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - AttachControlPlaneOutput: true, - } - - startenvTest() - }) - - var _ = AfterAll(func() { - cancel() - By("tearing down the test environment") - Expect(testEnv.Stop()).NotTo(HaveOccurred()) - }) - - Context("Validating Synapse CRD Schema", func() { - var obj map[string]interface{} - - BeforeEach(func() { - obj = map[string]interface{}{ - "apiVersion": "synapse.opdev.io/v1alpha1", - "kind": "Synapse", - "metadata": map[string]interface{}{ - "name": SynapseName, - "namespace": SynapseNamespace, - }, - } - }) - - DescribeTable("Creating a misconfigured Synapse instance", - func(synapse_data map[string]interface{}) { - // Augment base synapse obj with additional fields - for key, value := range synapse_data { - obj[key] = value - } - // Create Unstructured object from synapse obj - u := unstructured.Unstructured{Object: obj} - Expect(k8sClient.Create(ctx, &u)).ShouldNot(Succeed()) - }, - Entry("when Synapse spec is missing", map[string]interface{}{}), - Entry("when Synapse spec is empty", map[string]interface{}{ - "spec": map[string]interface{}{}, - }), - Entry("when Synapse spec is missing Homeserver", map[string]interface{}{ - "spec": map[string]interface{}{"createNewPostgreSQL": true}, - }), - Entry("when Synapse spec Homeserver is empty", map[string]interface{}{ - "spec": map[string]interface{}{ - "homeserver": map[string]interface{}{}, - }, - }), - Entry("when Synapse spec Homeserver possess both Values and ConfigMap", map[string]interface{}{ - "spec": map[string]interface{}{ - "homeserver": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": InputConfigMapName, - "namespace": SynapseNamespace, - }, - "values": map[string]interface{}{ - "serverName": ServerName, - "reportStats": ReportStats, - }, - }}, - }), - Entry("when Synapse spec Homeserver ConfigMap doesn't specify a Name", map[string]interface{}{ - "spec": map[string]interface{}{ - "homeserver": map[string]interface{}{ - "configMap": map[string]interface{}{ - "namespace": SynapseNamespace, - }, - }}, - }), - Entry("when Synapse spec Homeserver Values is missing ServerName", map[string]interface{}{ - "spec": map[string]interface{}{ - "homeserver": map[string]interface{}{ - "values": map[string]interface{}{ - "reportStats": ReportStats, - }, - }}, - }), - Entry("when Synapse spec Homeserver Values is missing ReportStats", map[string]interface{}{ - "spec": map[string]interface{}{ - "homeserver": map[string]interface{}{ - "values": map[string]interface{}{ - "serverName": ServerName, - }, - }}, - }), - // This should not work but passes - PEntry("when Synapse spec possesses an invalid field", map[string]interface{}{ - "spec": map[string]interface{}{ - "homeserver": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": InputConfigMapName, - "namespace": SynapseNamespace, - }, - }, - "invalidSpecFiels": "random", - }, - }), - ) - - DescribeTable("Creating a correct Synapse instance", - func(synapse_data map[string]interface{}) { - // Augment base synapse obj with additional fields - for key, value := range synapse_data { - obj[key] = value - } - // Create Unstructured object from synapse obj - u := unstructured.Unstructured{Object: obj} - // Use DryRun option to avoid cleaning up resources - opt := client.CreateOptions{DryRun: []string{"All"}} - Expect(k8sClient.Create(ctx, &u, &opt)).Should(Succeed()) - }, - Entry( - "when the Homeserver Configuration file is provided via a ConfigMap", - map[string]interface{}{ - "spec": map[string]interface{}{ - "homeserver": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": InputConfigMapName, - "namespace": SynapseNamespace, - }, - }, - "createNewPostreSQL": true, - }, - }, - ), - Entry( - "when the Homeserver Configuration values are provided", - map[string]interface{}{ - "spec": map[string]interface{}{ - "homeserver": map[string]interface{}{ - "values": map[string]interface{}{ - "serverName": ServerName, - "reportStats": ReportStats, - }, - }, - "createNewPostreSQL": true, - }, - }, - ), - Entry( - "when optional CreateNewPostgreSQL and ConfigMap Namespace are missing", - map[string]interface{}{ - "spec": map[string]interface{}{ - "homeserver": map[string]interface{}{ - "configMap": map[string]interface{}{ - "name": InputConfigMapName, - }, - }, - }, - }, - ), - ) - }) - - Context("When creating a valid Synapse instance", func() { - var synapse *synapsev1alpha1.Synapse - var createdConfigMap *corev1.ConfigMap - var createdPVC *corev1.PersistentVolumeClaim - var createdDeployment *appsv1.Deployment - var createdService *corev1.Service - var createdServiceAccount *corev1.ServiceAccount - var createdRoleBinding *rbacv1.RoleBinding - var synapseLookupKey types.NamespacedName - var expectedOwnerReference metav1.OwnerReference - var synapseSpec synapsev1alpha1.SynapseSpec - - var initSynapseVariables = func() { - // Init variables - synapseLookupKey = types.NamespacedName{Name: SynapseName, Namespace: SynapseNamespace} - createdConfigMap = &corev1.ConfigMap{} - createdPVC = &corev1.PersistentVolumeClaim{} - createdDeployment = &appsv1.Deployment{} - createdService = &corev1.Service{} - createdServiceAccount = &corev1.ServiceAccount{} - createdRoleBinding = &rbacv1.RoleBinding{} - // The OwnerReference UID must be set after the Synapse instance has been - // created. - expectedOwnerReference = metav1.OwnerReference{ - Kind: "Synapse", - APIVersion: "synapse.opdev.io/v1alpha1", - Name: SynapseName, - Controller: utils.BoolAddr(true), - BlockOwnerDeletion: utils.BoolAddr(true), - } - } - - var createSynapseInstance = func() { - By("Creating the Synapse instance") - synapse = &synapsev1alpha1.Synapse{ - ObjectMeta: metav1.ObjectMeta{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - Spec: synapseSpec, - } - Expect(k8sClient.Create(ctx, synapse)).Should(Succeed()) - - By("Verifying that the Synapse object was created") - Eventually(func() bool { - err := k8sClient.Get(ctx, synapseLookupKey, synapse) - return err == nil - }, timeout, interval).Should(BeTrue()) - - expectedOwnerReference.UID = synapse.GetUID() - } - - var cleanupSynapseResources = func() { - By("Cleaning up Synapse CR") - Expect(k8sClient.Delete(ctx, synapse)).Should(Succeed()) - - // Child resources must be manually deleted as the controllers responsible of - // their lifecycle are not running. - By("Cleaning up Synapse ConfigMap") - deleteResource(createdConfigMap, synapseLookupKey, false) - - By("Cleaning up Synapse PVC") - deleteResource(createdPVC, synapseLookupKey, true) - - By("Cleaning up Synapse Deployment") - deleteResource(createdDeployment, synapseLookupKey, false) - - By("Cleaning up Synapse Service") - deleteResource(createdService, synapseLookupKey, false) - - By("Cleaning up Synapse RoleBinding") - deleteResource(createdRoleBinding, synapseLookupKey, false) - - By("Cleaning up Synapse ServiceAccount") - deleteResource(createdServiceAccount, synapseLookupKey, false) - } - - When("Specifying the Synapse configuration via Values", func() { - BeforeAll(func() { - initSynapseVariables() - - synapseSpec = synapsev1alpha1.SynapseSpec{ - Homeserver: synapsev1alpha1.SynapseHomeserver{ - Values: &synapsev1alpha1.SynapseHomeserverValues{ - ServerName: ServerName, - ReportStats: ReportStats, - }, - }, - IsOpenshift: true, - } - - createSynapseInstance() - }) - - AfterAll(func() { - cleanupSynapseResources() - }) - - It("Should should update the Synapse Status", func() { - expectedStatus := synapsev1alpha1.SynapseStatus{ - State: "RUNNING", - Reason: "", - HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{ - ServerName: ServerName, - ReportStats: ReportStats, - }, - } - // Status may need some time to be updated - Eventually(func() synapsev1alpha1.SynapseStatus { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status - }, timeout, interval).Should(Equal(expectedStatus)) - }) - - It("Should create a Synapse ConfigMap", func() { - checkResourcePresence(createdConfigMap, synapseLookupKey, expectedOwnerReference) - }) - - It("Should create a Synapse PVC", func() { - checkResourcePresence(createdPVC, synapseLookupKey, expectedOwnerReference) - }) - - It("Should create a Synapse Deployment", func() { - By("Checking that a Synapse Deployment exists and is correctly configured") - checkResourcePresence(createdDeployment, synapseLookupKey, expectedOwnerReference) - - By("Checking that initContainers contains the required environment variables") - envVars := []corev1.EnvVar{{ - Name: "SYNAPSE_SERVER_NAME", - Value: ServerName, - }, { - Name: "SYNAPSE_REPORT_STATS", - Value: utils.BoolToYesNo(ReportStats), - }} - Expect(createdDeployment.Spec.Template.Spec.InitContainers[0].Env).Should(ContainElements(envVars)) - }) - - It("Should create a Synapse Service", func() { - checkResourcePresence(createdService, synapseLookupKey, expectedOwnerReference) - }) - - It("Should create a Synapse ServiceAccount", func() { - checkResourcePresence(createdServiceAccount, synapseLookupKey, expectedOwnerReference) - }) - - It("Should create a Synapse RoleBinding", func() { - checkResourcePresence(createdRoleBinding, synapseLookupKey, expectedOwnerReference) - }) - }) - - When("Specifying the Synapse configuration via a ConfigMap", func() { - var inputConfigMap *corev1.ConfigMap - var inputConfigmapData map[string]string - - var createSynapseConfigMap = func() { - By("Creating a ConfigMap containing a basic homeserver.yaml") - // Populate the ConfigMap with the minimum data needed - inputConfigMap = &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: InputConfigMapName, - Namespace: SynapseNamespace, - }, - Data: inputConfigmapData, - } - Expect(k8sClient.Create(ctx, inputConfigMap)).Should(Succeed()) - } - - var cleanupSynapseConfigMap = func() { - By("Cleaning up ConfigMap") - Expect(k8sClient.Delete(ctx, inputConfigMap)).Should(Succeed()) - } - - When("Creating a simple Synapse instance", func() { - BeforeAll(func() { - initSynapseVariables() - - inputConfigmapData = map[string]string{ - "homeserver.yaml": "server_name: " + ServerName + "\n" + - "report_stats: " + strconv.FormatBool(ReportStats), - } - - synapseSpec = synapsev1alpha1.SynapseSpec{ - Homeserver: synapsev1alpha1.SynapseHomeserver{ - ConfigMap: &synapsev1alpha1.SynapseHomeserverConfigMap{ - Name: InputConfigMapName, - }, - }, - IsOpenshift: true, - } - - createSynapseConfigMap() - createSynapseInstance() - }) - - AfterAll(func() { - cleanupSynapseResources() - cleanupSynapseConfigMap() - }) - - It("Should should update the Synapse Status", func() { - expectedStatus := synapsev1alpha1.SynapseStatus{ - State: "RUNNING", - Reason: "", - HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{ - ServerName: ServerName, - ReportStats: ReportStats, - }, - } - // Status may need some time to be updated - Eventually(func() synapsev1alpha1.SynapseStatus { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status - }, timeout, interval).Should(Equal(expectedStatus)) - }) - - It("Should create a Synapse ConfigMap", func() { - checkResourcePresence(createdConfigMap, synapseLookupKey, expectedOwnerReference) - }) - - It("Should create a Synapse PVC", func() { - checkResourcePresence(createdPVC, synapseLookupKey, expectedOwnerReference) - }) - - It("Should create a Synapse Deployment", func() { - By("Checking that a Synapse Deployment exists and is correctly configured") - checkResourcePresence(createdDeployment, synapseLookupKey, expectedOwnerReference) - - By("Checking that initContainers contains the required environment variables") - envVars := []corev1.EnvVar{{ - Name: "SYNAPSE_SERVER_NAME", - Value: ServerName, - }, { - Name: "SYNAPSE_REPORT_STATS", - Value: utils.BoolToYesNo(ReportStats), - }} - Expect(createdDeployment.Spec.Template.Spec.InitContainers[0].Env).Should(ContainElements(envVars)) - }) - - It("Should create a Synapse Service", func() { - checkResourcePresence(createdService, synapseLookupKey, expectedOwnerReference) - }) - - It("Should create a Synapse ServiceAccount", func() { - checkResourcePresence(createdServiceAccount, synapseLookupKey, expectedOwnerReference) - }) - - It("Should create a Synapse RoleBinding", func() { - checkResourcePresence(createdRoleBinding, synapseLookupKey, expectedOwnerReference) - }) - }) - - When("Requesting a new PostgreSQL instance to be created for Synapse", func() { - var createdPostgresCluster *pgov1beta1.PostgresCluster - var postgresSecret corev1.Secret - var postgresLookupKeys types.NamespacedName - - BeforeAll(func() { - initSynapseVariables() - - postgresLookupKeys = types.NamespacedName{ - Name: synapseLookupKey.Name + "-pgsql", - Namespace: synapseLookupKey.Namespace, - } - - // Init variable - createdPostgresCluster = &pgov1beta1.PostgresCluster{} - - inputConfigmapData = map[string]string{ - "homeserver.yaml": "server_name: " + ServerName + "\n" + - "report_stats: " + strconv.FormatBool(ReportStats), - } - - synapseSpec = synapsev1alpha1.SynapseSpec{ - Homeserver: synapsev1alpha1.SynapseHomeserver{ - ConfigMap: &synapsev1alpha1.SynapseHomeserverConfigMap{ - Name: InputConfigMapName, - }, - }, - CreateNewPostgreSQL: true, - IsOpenshift: true, - } - - createSynapseConfigMap() - createSynapseInstance() - }) - - doPostgresControllerJob := func() { - // The postgres-operator is responsible for creating a Secret holding - // information on how to connect to the synapse Database with the synapse - // user. As this controller is not running during our integration tests, - // we have to manually create this secret here. - postgresSecret = corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: SynapseName + "-pgsql-pguser-synapse", - Namespace: SynapseNamespace, - }, - Data: map[string][]byte{ - "host": []byte("hostname.postgresql.url"), - "port": []byte("5432"), - "dbname": []byte("synapse"), - "user": []byte("synapse"), - "password": []byte("VerySecureSyn@psePassword!"), - }, - } - Expect(k8sClient.Create(ctx, &postgresSecret)).Should(Succeed()) - - // The portgres-operator is responsible for updating the PostgresCluster - // status, with the number of Pods being ready. This is used a part of - // the 'isPostgresClusterReady' method in the Synapse controller. - createdPostgresCluster.Status.InstanceSets = []pgov1beta1.PostgresInstanceSetStatus{{ - Name: "instance1", - Replicas: 1, - ReadyReplicas: 1, - UpdatedReplicas: 1, - }} - Expect(k8sClient.Status().Update(ctx, createdPostgresCluster)).Should(Succeed()) - } - - AfterAll(func() { - By("Cleaning up the Synapse PostgresCluster") - deleteResource(createdPostgresCluster, postgresLookupKeys, false) - - cleanupSynapseResources() - cleanupSynapseConfigMap() - }) - - It("Should create a PostgresCluster for Synapse", func() { - By("Checking that a Synapse PostgresCluster exists") - checkResourcePresence(createdPostgresCluster, postgresLookupKeys, expectedOwnerReference) - }) - - It("Should update the Synapse status", func() { - By("Checking that the controller detects the Database as not ready") - Expect(k8sClient.Get(ctx, synapseLookupKey, synapse)).Should(Succeed()) - Expect(synapse.Status.DatabaseConnectionInfo.State).Should(Equal("NOT READY")) - - // Once the PostgresCluster has been created, we simulate the - // postgres-operator reconciliation. - By("Simulating the postgres-operator controller job") - doPostgresControllerJob() - - By("Checking that the Synapse Status is correctly updated") - Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, synapseLookupKey, synapse)).Should(Succeed()) - - g.Expect(synapse.Status.DatabaseConnectionInfo.ConnectionURL).Should(Equal("hostname.postgresql.url:5432")) - g.Expect(synapse.Status.DatabaseConnectionInfo.DatabaseName).Should(Equal("synapse")) - g.Expect(synapse.Status.DatabaseConnectionInfo.User).Should(Equal("synapse")) - g.Expect(synapse.Status.DatabaseConnectionInfo.Password).Should(Equal(string(base64encode("VerySecureSyn@psePassword!")))) - g.Expect(synapse.Status.DatabaseConnectionInfo.State).Should(Equal("READY")) - }, timeout, interval).Should(Succeed()) - }) - - It("Should update the ConfigMap Data", func() { - Eventually(func(g Gomega) { - // Fetching database section of the homeserver.yaml configuration file - g.Expect(k8sClient.Get(ctx, - types.NamespacedName{Name: SynapseName, Namespace: SynapseNamespace}, - createdConfigMap, - )).Should(Succeed()) - - ConfigMapData, ok := createdConfigMap.Data["homeserver.yaml"] - g.Expect(ok).Should(BeTrue()) - - homeserver := make(map[string]interface{}) - g.Expect(yaml.Unmarshal([]byte(ConfigMapData), homeserver)).Should(Succeed()) - - _, ok = homeserver["database"] - g.Expect(ok).Should(BeTrue()) - - marshalled_homeserver_database, err := yaml.Marshal(homeserver["database"]) - g.Expect(err).ShouldNot(HaveOccurred()) - - var hs_database HomeserverPgsqlDatabase - g.Expect(yaml.Unmarshal(marshalled_homeserver_database, &hs_database)).Should(Succeed()) - - // hs_database, ok := homeserver["database"].(HomeserverPgsqlDatabase) - // g.Expect(ok).Should(BeTrue()) - - // Testing that the database section is correctly configured for using - // the PostgreSQL DB - g.Expect(hs_database.Name).Should(Equal("psycopg2")) - g.Expect(hs_database.Args.Host).Should(Equal("hostname.postgresql.url")) - - g.Expect(hs_database.Args.Port).Should(Equal(int64(5432))) - g.Expect(hs_database.Args.Database).Should(Equal("synapse")) - g.Expect(hs_database.Args.User).Should(Equal("synapse")) - g.Expect(hs_database.Args.Password).Should(Equal("VerySecureSyn@psePassword!")) - - g.Expect(hs_database.Args.CpMin).Should(Equal(int64(5))) - g.Expect(hs_database.Args.CpMax).Should(Equal(int64(10))) - }, timeout, interval).Should(Succeed()) - }) - }) - - When("Enabling the Heisenbridge", func() { - const ( - heisenbridgeName = "test-heisenbridge" - heisenbridgeNamespace = "default" - ) - var heisenbridge *synapsev1alpha1.Heisenbridge - - BeforeAll(func() { - initSynapseVariables() - - inputConfigmapData = map[string]string{ - "homeserver.yaml": "server_name: " + ServerName + "\n" + - "report_stats: " + strconv.FormatBool(ReportStats), - } - - synapseSpec = synapsev1alpha1.SynapseSpec{ - Homeserver: synapsev1alpha1.SynapseHomeserver{ - ConfigMap: &synapsev1alpha1.SynapseHomeserverConfigMap{ - Name: InputConfigMapName, - }, - }, - IsOpenshift: true, - } - - createSynapseConfigMap() - createSynapseInstance() - }) - - AfterAll(func() { - cleanupSynapseResources() - cleanupSynapseConfigMap() - }) - - It("Should update the Synapse Status", func() { - expectedStatus := synapsev1alpha1.SynapseStatus{ - State: "RUNNING", - Reason: "", - HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{ - ServerName: ServerName, - ReportStats: ReportStats, - }, - } - // Status may need some time to be updated - Eventually(func() synapsev1alpha1.SynapseStatus { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status - }, timeout, interval).Should(Equal(expectedStatus)) - }) - - It("Should register the presence of the bridge in the Synapse status", func() { - By("Creating the Heisenbridge object") - heisenbridge = &synapsev1alpha1.Heisenbridge{ - ObjectMeta: metav1.ObjectMeta{ - Name: heisenbridgeName, - Namespace: heisenbridgeNamespace, - }, - Spec: synapsev1alpha1.HeisenbridgeSpec{ - Synapse: synapsev1alpha1.HeisenbridgeSynapseSpec{ - Name: SynapseName, - }, - }, - } - Expect(k8sClient.Create(ctx, heisenbridge)).Should(Succeed()) - - By("Triggering the Synapse reconciliation") - synapse.Status.NeedsReconcile = true - Expect(k8sClient.Status().Update(ctx, synapse)).Should(Succeed()) - - By("Checking the Synapse Status") - expectedStatusBridgesHeisenbridge := synapsev1alpha1.SynapseStatusBridgesHeisenbridge{ - Enabled: true, - Name: heisenbridgeName, - } - Eventually(func(g Gomega) synapsev1alpha1.SynapseStatusBridgesHeisenbridge { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status.Bridges.Heisenbridge - }, timeout, interval).Should(Equal(expectedStatusBridgesHeisenbridge)) - }) - - It("Should update the Synapse homeserver.yaml", func() { - Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, - types.NamespacedName{Name: SynapseName, Namespace: SynapseNamespace}, - createdConfigMap, - )).Should(Succeed()) - - ConfigMapData, ok := createdConfigMap.Data["homeserver.yaml"] - g.Expect(ok).Should(BeTrue()) - - homeserver := make(map[string]interface{}) - g.Expect(yaml.Unmarshal([]byte(ConfigMapData), homeserver)).Should(Succeed()) - - _, ok = homeserver["app_service_config_files"] - g.Expect(ok).Should(BeTrue()) - - g.Expect(homeserver["app_service_config_files"]).Should(ContainElement("/data-heisenbridge/heisenbridge.yaml")) - }, timeout, interval).Should(Succeed()) - }) - - It("Should mount the Heisenbridge ConfigMap in the Synapse Deployment", func() { - By("Checking that a Synapse Deployment exists and is correctly configured") - checkResourcePresence(createdDeployment, synapseLookupKey, expectedOwnerReference) - - By("Checking that the VolumeMount for the Heisenbridge Volume is present") - heisenbridgeVolumeMount := corev1.VolumeMount{ - Name: "data-heisenbridge", - MountPath: "/data-heisenbridge", - } - Expect(createdDeployment.Spec.Template.Spec.Containers[0].VolumeMounts). - Should(ContainElement(heisenbridgeVolumeMount)) - - By("Checking that the Volume for the Heisenbridge ConfigMap is present") - var defaultMode int32 = 420 - heisenbridgeVolume := corev1.Volume{ - Name: "data-heisenbridge", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: heisenbridgeName, - }, - DefaultMode: &defaultMode, - }, - }, - } - Expect(createdDeployment.Spec.Template.Spec.Volumes). - Should(ContainElement(heisenbridgeVolume)) - }) - - It("Should unregister Heisenbridge when deleted", func() { - By("Deleting the Heisenbridge object") - Expect(k8sClient.Delete(ctx, heisenbridge)).Should(Succeed()) - - By("Triggering the Synapse reconciliation") - synapse.Status.NeedsReconcile = true - Expect(k8sClient.Status().Update(ctx, synapse)).Should(Succeed()) - - By("Checking the Synapse Status") - expectedStatusBridgesHeisenbridge := synapsev1alpha1.SynapseStatusBridgesHeisenbridge{ - Enabled: false, - } - Eventually(func(g Gomega) synapsev1alpha1.SynapseStatusBridgesHeisenbridge { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status.Bridges.Heisenbridge - }, timeout, interval).Should(Equal(expectedStatusBridgesHeisenbridge)) - }) - }) - - When("A Mautrix-Signal bridge refers this Synapse instance", func() { - const ( - mautrixSignalName = "test-mautrixsignal" - mautrixSignalNamespace = "default" - ) - - var mautrixsignal *synapsev1alpha1.MautrixSignal - - BeforeAll(func() { - initSynapseVariables() - - inputConfigmapData = map[string]string{ - "homeserver.yaml": "server_name: " + ServerName + "\n" + - "report_stats: " + strconv.FormatBool(ReportStats), - } - - synapseSpec = synapsev1alpha1.SynapseSpec{ - Homeserver: synapsev1alpha1.SynapseHomeserver{ - ConfigMap: &synapsev1alpha1.SynapseHomeserverConfigMap{ - Name: InputConfigMapName, - }, - }, - IsOpenshift: true, - } - - createSynapseConfigMap() - createSynapseInstance() - }) - - AfterAll(func() { - cleanupSynapseResources() - cleanupSynapseConfigMap() - }) - - It("Should update the Synapse Status", func() { - expectedStatus := synapsev1alpha1.SynapseStatus{ - State: "RUNNING", - Reason: "", - HomeserverConfiguration: synapsev1alpha1.SynapseStatusHomeserverConfiguration{ - ServerName: ServerName, - ReportStats: ReportStats, - }, - } - // Status may need some time to be updated - Eventually(func() synapsev1alpha1.SynapseStatus { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status - }, timeout, interval).Should(Equal(expectedStatus)) - }) - - It("Should register the presence of the bridge in the Synapse status", func() { - By("Creating the MautrixSignal object") - mautrixsignal = &synapsev1alpha1.MautrixSignal{ - ObjectMeta: metav1.ObjectMeta{ - Name: mautrixSignalName, - Namespace: mautrixSignalNamespace, - }, - Spec: synapsev1alpha1.MautrixSignalSpec{ - Synapse: synapsev1alpha1.MautrixSignalSynapseSpec{ - Name: SynapseName, - }, - }, - } - Expect(k8sClient.Create(ctx, mautrixsignal)).Should(Succeed()) - - By("Triggering the Synapse reconciliation") - synapse.Status.NeedsReconcile = true - Expect(k8sClient.Status().Update(ctx, synapse)).Should(Succeed()) - - expectedStatusBridgesMautrixSignal := synapsev1alpha1.SynapseStatusBridgesMautrixSignal{ - Enabled: true, - Name: mautrixSignalName, - } - Eventually(func(g Gomega) synapsev1alpha1.SynapseStatusBridgesMautrixSignal { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status.Bridges.MautrixSignal - }, timeout, interval).Should(Equal(expectedStatusBridgesMautrixSignal)) - }) - - It("Should update the Synapse homeserver.yaml", func() { - Eventually(func(g Gomega) { - g.Expect(k8sClient.Get( - ctx, - types.NamespacedName{Name: SynapseName, Namespace: SynapseNamespace}, - createdConfigMap, - )).Should(Succeed()) - - ConfigMapData, ok := createdConfigMap.Data["homeserver.yaml"] - g.Expect(ok).Should(BeTrue()) - - homeserver := make(map[string]interface{}) - g.Expect(yaml.Unmarshal([]byte(ConfigMapData), homeserver)).Should(Succeed()) - - _, ok = homeserver["app_service_config_files"] - g.Expect(ok).Should(BeTrue()) - - g.Expect(homeserver["app_service_config_files"]).Should(ContainElement("/data-mautrixsignal/registration.yaml")) - }, timeout, interval).Should(Succeed()) - }) - - It("Should mount the MautrixSignal PVC in the Synapse Deployment", func() { - By("Checking that a Synapse Deployment exists and is correctly configured") - checkResourcePresence(createdDeployment, synapseLookupKey, expectedOwnerReference) - - By("Checking that the VolumeMount for the Mautrix-Signal Volume is present") - mautrixsignalVolumeMount := corev1.VolumeMount{ - Name: "data-mautrixsignal", - MountPath: "/data-mautrixsignal", - } - Expect(createdDeployment.Spec.Template.Spec.Containers[0].VolumeMounts). - Should(ContainElement(mautrixsignalVolumeMount)) - - By("Checking that the Volume for the Mautrix-Signal PVC is present") - mautrixsignalVolume := corev1.Volume{ - Name: "data-mautrixsignal", - VolumeSource: corev1.VolumeSource{ - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: mautrixSignalName, - }, - }, - } - Expect(createdDeployment.Spec.Template.Spec.Volumes). - Should(ContainElement(mautrixsignalVolume)) - }) - - It("Should unregister MautrixSignal when deleted", func() { - By("Deleting the MautrixSignal object") - Expect(k8sClient.Delete(ctx, mautrixsignal)).Should(Succeed()) - - By("Triggering the Synapse reconciliation") - synapse.Status.NeedsReconcile = true - Expect(k8sClient.Status().Update(ctx, synapse)).Should(Succeed()) - - By("Checking the Synapse Status") - expectedStatusBridgesMautrixSignal := synapsev1alpha1.SynapseStatusBridgesMautrixSignal{ - Enabled: false, - } - Eventually(func(g Gomega) synapsev1alpha1.SynapseStatusBridgesMautrixSignal { - _ = k8sClient.Get(ctx, synapseLookupKey, synapse) - return synapse.Status.Bridges.MautrixSignal - }, timeout, interval).Should(Equal(expectedStatusBridgesMautrixSignal)) - }) - }) - }) - }) - - Context("When creating an incorrect Synapse instance", func() { - var synapse *synapsev1alpha1.Synapse - var createdPVC *corev1.PersistentVolumeClaim - var createdDeployment *appsv1.Deployment - var createdService *corev1.Service - var createdServiceAccount *corev1.ServiceAccount - var createdRoleBinding *rbacv1.RoleBinding - var synapseLookupKey types.NamespacedName - - var initSynapseVariables = func() { - // Init variables - synapseLookupKey = types.NamespacedName{Name: SynapseName, Namespace: SynapseNamespace} - createdPVC = &corev1.PersistentVolumeClaim{} - createdDeployment = &appsv1.Deployment{} - createdService = &corev1.Service{} - createdServiceAccount = &corev1.ServiceAccount{} - createdRoleBinding = &rbacv1.RoleBinding{} - } - - BeforeEach(func() { - initSynapseVariables() - - By("Creating a Synapse instance which refers an absent ConfigMap") - synapse = &synapsev1alpha1.Synapse{ - ObjectMeta: metav1.ObjectMeta{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - Spec: synapsev1alpha1.SynapseSpec{ - Homeserver: synapsev1alpha1.SynapseHomeserver{ - ConfigMap: &synapsev1alpha1.SynapseHomeserverConfigMap{ - Name: InputConfigMapName, - }, - }, - }, - } - Expect(k8sClient.Create(ctx, synapse)).Should(Succeed()) - }) - - AfterEach(func() { - By("Cleaning up Synapse CR") - Expect(k8sClient.Delete(ctx, synapse)).Should(Succeed()) - }) - - It("Should get in a failed state and not create child objects", func() { - reason := "ConfigMap " + InputConfigMapName + " does not exist in namespace " + SynapseNamespace - checkStatus("FAILED", reason, synapseLookupKey, synapse) - checkSubresourceAbsence( - synapseLookupKey, - createdPVC, - createdDeployment, - createdService, - createdServiceAccount, - createdRoleBinding, - ) - }) - }) - }) - - Context("When the Kubernetes cluster is missing the postgres-operator", func() { - BeforeAll(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "bundle", "manifests", "synapse.opdev.io_synapses.yaml"), - }, - ErrorIfCRDPathMissing: true, - BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", - fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - AttachControlPlaneOutput: true, - } - - startenvTest() - }) - - AfterAll(func() { - cancel() - By("tearing down the test environment") - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) - }) - - When("Requesting a new PostgreSQL instance to be created for Synapse", func() { - var synapse *synapsev1alpha1.Synapse - var configMap *corev1.ConfigMap - - var createdPVC *corev1.PersistentVolumeClaim - var createdDeployment *appsv1.Deployment - var createdService *corev1.Service - var createdServiceAccount *corev1.ServiceAccount - var createdRoleBinding *rbacv1.RoleBinding - var synapseLookupKey types.NamespacedName - - var createdPostgresCluster *pgov1beta1.PostgresCluster - var postgresLookupKeys types.NamespacedName - - var initSynapseVariables = func() { - // Init variables - synapseLookupKey = types.NamespacedName{Name: SynapseName, Namespace: SynapseNamespace} - createdPVC = &corev1.PersistentVolumeClaim{} - createdDeployment = &appsv1.Deployment{} - createdService = &corev1.Service{} - createdServiceAccount = &corev1.ServiceAccount{} - createdRoleBinding = &rbacv1.RoleBinding{} - } - - BeforeAll(func() { - initSynapseVariables() - - postgresLookupKeys = types.NamespacedName{ - Name: synapseLookupKey.Name + "-pgsql", - Namespace: synapseLookupKey.Namespace, - } - - createdPostgresCluster = &pgov1beta1.PostgresCluster{} - - configMap = &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: InputConfigMapName, - Namespace: SynapseNamespace, - }, - Data: map[string]string{ - "homeserver.yaml": "server_name: " + ServerName + "\n" + - "report_stats: " + strconv.FormatBool(ReportStats), - }, - } - Expect(k8sClient.Create(ctx, configMap)).Should(Succeed()) - - By("Creating the Synapse instance") - synapse = &synapsev1alpha1.Synapse{ - ObjectMeta: metav1.ObjectMeta{ - Name: SynapseName, - Namespace: SynapseNamespace, - }, - Spec: synapsev1alpha1.SynapseSpec{ - Homeserver: synapsev1alpha1.SynapseHomeserver{ - ConfigMap: &synapsev1alpha1.SynapseHomeserverConfigMap{ - Name: InputConfigMapName, - }, - }, - CreateNewPostgreSQL: true, - }, - } - Expect(k8sClient.Create(ctx, synapse)).Should(Succeed()) - }) - - AfterAll(func() { - By("Cleaning up ConfigMap") - Expect(k8sClient.Delete(ctx, configMap)).Should(Succeed()) - - By("Cleaning up Synapse CR") - Expect(k8sClient.Delete(ctx, synapse)).Should(Succeed()) - }) - - It("Should not create Synapse sub-resources", func() { - reason := "Cannot create PostgreSQL instance for synapse. Postgres-operator is not installed." - checkStatus("FAILED", reason, synapseLookupKey, synapse) - checkSubresourceAbsence( - synapseLookupKey, - createdPVC, - createdDeployment, - createdService, - createdServiceAccount, - createdRoleBinding, - ) - checkSubresourceAbsence( - postgresLookupKeys, - createdPostgresCluster, - ) - }) - }) - }) -}) diff --git a/controllers/synapse/synapse/synapse_deployment.go b/controllers/synapse/synapse/synapse_deployment.go deleted file mode 100644 index 6828430..0000000 --- a/controllers/synapse/synapse/synapse_deployment.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package synapse - -import ( - "context" - "fmt" - - appsv1 "k8s.io/api/apps/v1" - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileSynapseDeployment is a function of type FnWithRequest, to be -// called in the main reconciliation loop. -// -// It reconciles the Deployment for Synapse to its desired state. -func (r *SynapseReconciler) reconcileSynapseDeployment(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - depl, err := r.deploymentForSynapse(s) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - depl, - &appsv1.Deployment{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// deploymentForSynapse returns a synapse Deployment object -func (r *SynapseReconciler) deploymentForSynapse(s *synapsev1alpha1.Synapse) (*appsv1.Deployment, error) { - type deploymentExtraValues struct { - synapsev1alpha1.Synapse - Labels map[string]string - } - - extraValues := deploymentExtraValues{ - Synapse: *s, - Labels: labelsForSynapse(s.Name), - } - - dep, err := templates.ResourceFromTemplate[deploymentExtraValues, appsv1.Deployment](&extraValues, "synapse_deployment") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set Synapse instance as the owner and controller - if err := ctrl.SetControllerReference(s, dep, r.Scheme); err != nil { - return &appsv1.Deployment{}, err - } - - return dep, nil -} diff --git a/controllers/synapse/synapse/synapse_postgrescluster.go b/controllers/synapse/synapse/synapse_postgrescluster.go deleted file mode 100644 index 71910dd..0000000 --- a/controllers/synapse/synapse/synapse_postgrescluster.go +++ /dev/null @@ -1,237 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package synapse - -import ( - "context" - b64 "encoding/base64" - "errors" - "time" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - ctrllog "sigs.k8s.io/controller-runtime/pkg/log" - - pgov1beta1 "github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1" - subreconciler "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" -) - -// reconcilePostgresClusterCR is a function of type FnWithRequest, to be -// called in the main reconciliation loop. -// -// It reconciles the PostgresCluster CR to its desired state, and requeues -// until the PostgreSQL cluster is up. -func (r *SynapseReconciler) reconcilePostgresClusterCR(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - log := ctrllog.FromContext(ctx) - - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - createdPostgresCluster := pgov1beta1.PostgresCluster{} - postgresClusterObjectMeta := reconcile.SetObjectMeta( - GetPostgresClusterResourceName(*s), - s.Namespace, - map[string]string{}, - ) - keyForPostgresCluster := types.NamespacedName{ - Name: GetPostgresClusterResourceName(*s), - Namespace: s.Namespace, - } - - desiredPostgresCluster, err := r.postgresClusterForSynapse(s, postgresClusterObjectMeta) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - // Create PostgresCluster for Synapse - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredPostgresCluster, - &createdPostgresCluster, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - // Wait for PostgresCluster to be up - // TODO: can be removed ? - if err := r.Get(ctx, keyForPostgresCluster, &createdPostgresCluster); err != nil { - return subreconciler.RequeueWithError(err) - } - if !r.isPostgresClusterReady(createdPostgresCluster) { - s.Status.DatabaseConnectionInfo.State = "NOT READY" - err = utils.UpdateResourceStatus(ctx, r.Client, s, &synapsev1alpha1.Synapse{}) - if err != nil { - log.Error(err, "Error updating Synapse State") - } - - err = errors.New("postgreSQL Database not ready yet") - return subreconciler.RequeueWithDelayAndError(time.Duration(5), err) - } - - return subreconciler.ContinueReconciling() -} - -// postgresClusterForSynapse returns a PostgresCluster object -func (r *SynapseReconciler) postgresClusterForSynapse(s *synapsev1alpha1.Synapse, objectMeta metav1.ObjectMeta) (*pgov1beta1.PostgresCluster, error) { - postgresCluster := &pgov1beta1.PostgresCluster{ - ObjectMeta: objectMeta, - Spec: pgov1beta1.PostgresClusterSpec{ - Image: "registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.5-1", - PostgresVersion: 14, - InstanceSets: []pgov1beta1.PostgresInstanceSetSpec{{ - Name: "instance1", - DataVolumeClaimSpec: corev1.PersistentVolumeClaimSpec{ - AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, - Resources: corev1.VolumeResourceRequirements{ - Requests: corev1.ResourceList{ - "storage": *resource.NewQuantity(1*1024*1024*1024, resource.BinarySI), - }, - }, - }, - }}, - Backups: pgov1beta1.Backups{ - PGBackRest: pgov1beta1.PGBackRestArchive{ - Image: "registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.40-1", - Repos: []pgov1beta1.PGBackRestRepo{{ - Name: "repo1", - Volume: &pgov1beta1.RepoPVC{ - VolumeClaimSpec: corev1.PersistentVolumeClaimSpec{ - AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, - Resources: corev1.VolumeResourceRequirements{ - Requests: corev1.ResourceList{ - "storage": *resource.NewQuantity(1*1024*1024*1024, resource.BinarySI), - }, - }, - }, - }, - }}, - }, - }, - Users: []pgov1beta1.PostgresUserSpec{{ - Name: "synapse", - Databases: []pgov1beta1.PostgresIdentifier{"dummy"}, - }}, - // See https://github.com/opdev/synapse-operator/issues/12 - DatabaseInitSQL: &pgov1beta1.DatabaseInitSQL{ - Name: objectMeta.Name, - Key: "createdb.sql", - }, - }, - } - - // Set Synapse instance as the owner and controller - if err := ctrl.SetControllerReference(s, postgresCluster, r.Scheme); err != nil { - return &pgov1beta1.PostgresCluster{}, err - } - return postgresCluster, nil -} - -func (r *SynapseReconciler) isPostgresClusterReady(p pgov1beta1.PostgresCluster) bool { - var status_found bool - - // Going through instance Specs - for _, instance_spec := range p.Spec.InstanceSets { - status_found = false - for _, instance_status := range p.Status.InstanceSets { - if instance_status.Name == instance_spec.Name { - desired_replicas := *instance_spec.Replicas - if instance_status.Replicas != desired_replicas || - instance_status.ReadyReplicas != desired_replicas || - instance_status.UpdatedReplicas != desired_replicas { - return false - } - // Found instance in Status, breaking out of for loop - status_found = true - break - } - } - - // Instance found in spec, but not in status - if !status_found { - return false - } - } - - // All instances have the correct number of replicas - return true -} - -// reconcilePostgresClusterConfigMap is a function of type FnWithRequest, -// to be called in the main reconciliation loop. -// -// It reconciles the PostgresCluster ConfigMap to its desired state. -func (r *SynapseReconciler) reconcilePostgresClusterConfigMap(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - postgresClusterObjectMeta := reconcile.SetObjectMeta( - GetPostgresClusterResourceName(*s), - s.Namespace, - map[string]string{}, - ) - - desiredConfigMap, err := r.configMapForPostgresCluster(s, postgresClusterObjectMeta) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - // Create ConfigMap for PostgresCluster - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredConfigMap, - &corev1.ConfigMap{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// configMapForPostgresCluster returns a ConfigMap object -func (r *SynapseReconciler) configMapForPostgresCluster(s *synapsev1alpha1.Synapse, objectMeta metav1.ObjectMeta) (*corev1.ConfigMap, error) { - configMap := &corev1.ConfigMap{ - ObjectMeta: objectMeta, - Data: map[string]string{"createdb.sql": "CREATE DATABASE synapse LOCALE 'C' ENCODING 'UTF-8' TEMPLATE template0;"}, - } - - if err := ctrl.SetControllerReference(s, configMap, r.Scheme); err != nil { - return &corev1.ConfigMap{}, err - } - - return configMap, nil -} - -func base64encode(to_encode string) []byte { - return []byte(b64.StdEncoding.EncodeToString([]byte(to_encode))) -} - -func base64decode(to_decode []byte) string { - decoded_bytes, _ := b64.StdEncoding.DecodeString(string(to_decode)) - return string(decoded_bytes) -} diff --git a/controllers/synapse/synapse/synapse_pvc.go b/controllers/synapse/synapse/synapse_pvc.go deleted file mode 100644 index 27ca360..0000000 --- a/controllers/synapse/synapse/synapse_pvc.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package synapse - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - ctrl "sigs.k8s.io/controller-runtime" - - subreconciler "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileSynapsePVC is a function of type FnWithRequest, to be called -// in the main reconciliation loop. -// -// It reconciles the PVC for synapse to its desired state. -func (r *SynapseReconciler) reconcileSynapsePVC(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredPVC, err := r.persistentVolumeClaimForSynapse(s) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredPVC, - &corev1.PersistentVolumeClaim{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - - return subreconciler.ContinueReconciling() -} - -// persistentVolumeClaimForSynapse returns a synapse PVC object -func (r *SynapseReconciler) persistentVolumeClaimForSynapse(s *synapsev1alpha1.Synapse) (*corev1.PersistentVolumeClaim, error) { - pvc, err := templates.ResourceFromTemplate[synapsev1alpha1.Synapse, corev1.PersistentVolumeClaim](s, "pvc") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set Synapse instance as the owner and controller - if err := ctrl.SetControllerReference(s, pvc, r.Scheme); err != nil { - return &corev1.PersistentVolumeClaim{}, err - } - return pvc, nil -} diff --git a/controllers/synapse/synapse/synapse_service.go b/controllers/synapse/synapse/synapse_service.go deleted file mode 100644 index 082c2af..0000000 --- a/controllers/synapse/synapse/synapse_service.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package synapse - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - ctrl "sigs.k8s.io/controller-runtime" - - subreconciler "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileSynapseService is a function of type FnWithRequest, to be -// called in the main reconciliation loop. -// -// It reconciles the Service for synapse to its desired state. -func (r *SynapseReconciler) reconcileSynapseService(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - // objectMetaForSynapse := reconcile.SetObjectMeta(s.Name, s.Namespace, map[string]string{}) - - desiredService, err := r.serviceForSynapse(s) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredService, - &corev1.Service{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - return subreconciler.ContinueReconciling() -} - -// serviceForSynapse returns a synapse Service object -func (r *SynapseReconciler) serviceForSynapse(s *synapsev1alpha1.Synapse) (*corev1.Service, error) { - type serviceExtraValues struct { - synapsev1alpha1.Synapse - Labels map[string]string - PortName string - Port int - TargetPort int - } - - extraValues := serviceExtraValues{ - Synapse: *s, - Labels: labelsForSynapse(s.Name), - PortName: "synapse-unsecure", - Port: 8008, - TargetPort: 8008, - } - - service, err := templates.ResourceFromTemplate[serviceExtraValues, corev1.Service](&extraValues, "service") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set Synapse instance as the owner and controller - if err := ctrl.SetControllerReference(s, service, r.Scheme); err != nil { - return &corev1.Service{}, err - } - return service, nil -} diff --git a/controllers/synapse/synapse/synapse_serviceaccount.go b/controllers/synapse/synapse/synapse_serviceaccount.go deleted file mode 100644 index 7eba991..0000000 --- a/controllers/synapse/synapse/synapse_serviceaccount.go +++ /dev/null @@ -1,114 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package synapse - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - ctrl "sigs.k8s.io/controller-runtime" - - subreconciler "github.com/opdev/subreconciler" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/reconcile" - "github.com/opdev/synapse-operator/helpers/utils" - "github.com/opdev/synapse-operator/internal/templates" -) - -// reconcileSynapseServiceAccount is a function of type FnWithRequest, to -// be called in the main reconciliation loop. -// -// It reconciles the ServiceAccount for synapse to its desired state. -func (r *SynapseReconciler) reconcileSynapseServiceAccount(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredServiceAccount, err := r.serviceAccountForSynapse(s) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredServiceAccount, - &corev1.ServiceAccount{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - return subreconciler.ContinueReconciling() -} - -// serviceAccountForSynapse returns a synapse ServiceAccount object -func (r *SynapseReconciler) serviceAccountForSynapse(s *synapsev1alpha1.Synapse) (*corev1.ServiceAccount, error) { - // TODO: https://github.com/opdev/synapse-operator/issues/19 - sa, err := templates.ResourceFromTemplate[synapsev1alpha1.Synapse, corev1.ServiceAccount](s, "serviceaccount") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set Synapse instance as the owner and controller - if err := ctrl.SetControllerReference(s, sa, r.Scheme); err != nil { - return &corev1.ServiceAccount{}, err - } - return sa, nil -} - -// reconcileSynapseRoleBinding is a function of type FnWithRequest, to be -// called in the main reconciliation loop. -// -// It reconciles the RoleBinding for synapse to its desired state. -func (r *SynapseReconciler) reconcileSynapseRoleBinding(ctx context.Context, req ctrl.Request) (*ctrl.Result, error) { - s := &synapsev1alpha1.Synapse{} - if r, err := utils.GetResource(ctx, r.Client, req, s); subreconciler.ShouldHaltOrRequeue(r, err) { - return r, err - } - - desiredRoleBinding, err := r.roleBindingForSynapse(s) - if err != nil { - return subreconciler.RequeueWithError(err) - } - - if err := reconcile.ReconcileResource( - ctx, - r.Client, - desiredRoleBinding, - &rbacv1.RoleBinding{}, - ); err != nil { - return subreconciler.RequeueWithError(err) - } - return subreconciler.ContinueReconciling() -} - -// roleBindingForSynapse returns a synapse RoleBinding object -func (r *SynapseReconciler) roleBindingForSynapse(s *synapsev1alpha1.Synapse) (*rbacv1.RoleBinding, error) { - // TODO: https://github.com/opdev/synapse-operator/issues/19 - rb, err := templates.ResourceFromTemplate[synapsev1alpha1.Synapse, rbacv1.RoleBinding](s, "rolebinding") - if err != nil { - return nil, fmt.Errorf("could not get template: %v", err) - } - - // Set Synapse instance as the owner and controller - if err := ctrl.SetControllerReference(s, rb, r.Scheme); err != nil { - return &rbacv1.RoleBinding{}, err - } - return rb, nil -} diff --git a/controllers/synapse/synapse/synapse_test.go b/controllers/synapse/synapse/synapse_test.go deleted file mode 100644 index f5472ea..0000000 --- a/controllers/synapse/synapse/synapse_test.go +++ /dev/null @@ -1,543 +0,0 @@ -// -//This file contains unit tests for the Synapse package -// - -package synapse - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "gopkg.in/yaml.v2" - - pgov1beta1 "github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1" - synapsev1alpha1 "github.com/opdev/synapse-operator/apis/synapse/v1alpha1" - "github.com/opdev/synapse-operator/helpers/utils" - corev1 "k8s.io/api/core/v1" -) - -var _ = Describe("Unit tests for Synapse package", Label("unit"), func() { - // Testing ParseHomeserverConfigMap - Context("When parsing the homeserver ConfigMap", func() { - var r SynapseReconciler - var ctx context.Context - var s synapsev1alpha1.Synapse - var cm corev1.ConfigMap - var data map[string]string - - BeforeEach(func() { - // Init variables needed for each test - r = SynapseReconciler{} - ctx = context.Background() - s = synapsev1alpha1.Synapse{} - }) - - Context("Extracting the server name and report stats value from ConfigMap", func() { - JustBeforeEach(func() { - cm = corev1.ConfigMap{ - Data: data, - } - }) - - When("when server name is valid and report stat set to true", func() { - BeforeEach(func() { - data = map[string]string{ - "homeserver.yaml": "server_name: my-server-name\nreport_stats: true", - } - }) - - It("should accordingly update the Synapse Status", func() { - Expect(r.ParseHomeserverConfigMap(ctx, &s, cm)).Should(Succeed()) - Expect(s.Status.HomeserverConfiguration.ServerName).Should(Equal("my-server-name")) - Expect(s.Status.HomeserverConfiguration.ReportStats).Should(BeTrue()) - }) - }) - - When("when server name is valid and report stat set to false", func() { - BeforeEach(func() { - data = map[string]string{ - "homeserver.yaml": "server_name: my-server-name\nreport_stats: false", - } - }) - - It("should accordingly update the Synapse Status", func() { - Expect(r.ParseHomeserverConfigMap(ctx, &s, cm)).Should(Succeed()) - Expect(s.Status.HomeserverConfiguration.ServerName).Should(Equal("my-server-name")) - Expect(s.Status.HomeserverConfiguration.ReportStats).Should(BeFalse()) - }) - }) - - When("when 'homeserver.yaml' is not present in the ConfigMap data", func() { - BeforeEach(func() { - data = map[string]string{ - "not-homeserver.yaml": "server_name: my-server-name\nreport_stats: true", - } - }) - - It("should fail to parse the ConfigMap data", func() { - Expect(r.ParseHomeserverConfigMap(ctx, &s, cm)).ShouldNot(Succeed()) - }) - }) - - When("when 'server_name' is not present in the 'homeserver.yaml'", func() { - BeforeEach(func() { - data = map[string]string{ - "homeserver.yaml": "not_server_name: my-server-name\nreport_stats: true", - } - }) - - It("should fail to parse the ConfigMap data", func() { - Expect(r.ParseHomeserverConfigMap(ctx, &s, cm)).ShouldNot(Succeed()) - }) - }) - - When("when 'server_name' is not a valid string", func() { - BeforeEach(func() { - data = map[string]string{ - "homeserver.yaml": "server_name: 1234567890\nreport_stats: true", - } - }) - - It("should fail to parse the ConfigMap data", func() { - Expect(r.ParseHomeserverConfigMap(ctx, &s, cm)).ShouldNot(Succeed()) - }) - }) - - When("when 'report_stats' is not present in the 'homeserver.yaml'", func() { - BeforeEach(func() { - data = map[string]string{ - "homeserver.yaml": "server_name: my-server-name\nnot_report_stats: true", - } - }) - - It("should fail to parse the ConfigMap data", func() { - Expect(r.ParseHomeserverConfigMap(ctx, &s, cm)).ShouldNot(Succeed()) - }) - }) - - When("when 'report_stats' is not a valid bool", func() { - BeforeEach(func() { - data = map[string]string{ - "homeserver.yaml": "server_name: my-server-name\nreport_stats: not-a-bool", - } - }) - - It("should fail to parse the ConfigMap data", func() { - Expect(r.ParseHomeserverConfigMap(ctx, &s, cm)).ShouldNot(Succeed()) - }) - }) - - When("when 'homeserver.yaml' is not valid YAML", func() { - BeforeEach(func() { - data = map[string]string{ - "homeserver.yaml": "not valid YAML!", - } - }) - - It("should fail to parse the ConfigMap data", func() { - Expect(r.ParseHomeserverConfigMap(ctx, &s, cm)).ShouldNot(Succeed()) - }) - }) - }) - }) - - Context("When checking if the PostreSQL Cluster is ready", func() { - var postgresCluster pgov1beta1.PostgresCluster - var postgresInstanceSetSpec []pgov1beta1.PostgresInstanceSetSpec - var postgresInstanceSetStatus []pgov1beta1.PostgresInstanceSetStatus - var r SynapseReconciler - var repl int32 - - BeforeEach(func() { - r = SynapseReconciler{} - - // Default PostgresCluster state, to be overwritten in BeforeEach - repl = int32(1) - postgresInstanceSetSpec = []pgov1beta1.PostgresInstanceSetSpec{{ - Name: "instance1", - Replicas: &repl, - }} - postgresInstanceSetStatus = []pgov1beta1.PostgresInstanceSetStatus{{ - Name: "instance1", - ReadyReplicas: 1, - Replicas: 1, - UpdatedReplicas: 1, - }} - }) - - JustBeforeEach(func() { - postgresCluster.Spec.InstanceSets = postgresInstanceSetSpec - postgresCluster.Status.InstanceSets = postgresInstanceSetStatus - }) - - When("when all replicas are ready and have the desired specification", func() { - // No BeforeEach, use default PostgresCluster state - It("Should consider the PostgreSQL cluster as ready", func() { - Expect(r.isPostgresClusterReady(postgresCluster)).Should(BeTrue()) - }) - }) - - When("when some replicas are not ready", func() { - BeforeEach(func() { - postgresInstanceSetStatus = []pgov1beta1.PostgresInstanceSetStatus{{ - Name: "instance1", - ReadyReplicas: 0, - Replicas: 1, - UpdatedReplicas: 1, - }} - }) - - It("Should not consider the PostgreSQL cluster as ready", func() { - Expect(r.isPostgresClusterReady(postgresCluster)).Should(BeFalse()) - }) - }) - - When("when some replicas are not updated", func() { - BeforeEach(func() { - postgresInstanceSetStatus = []pgov1beta1.PostgresInstanceSetStatus{{ - Name: "instance1", - ReadyReplicas: 1, - Replicas: 1, - UpdatedReplicas: 0, - }} - }) - - It("Should not consider the PostgreSQL cluster as ready", func() { - Expect(r.isPostgresClusterReady(postgresCluster)).Should(BeFalse()) - }) - }) - - When("when no replicas exist", func() { - BeforeEach(func() { - postgresInstanceSetStatus = []pgov1beta1.PostgresInstanceSetStatus{{ - Name: "instance1", - ReadyReplicas: 0, - Replicas: 0, - UpdatedReplicas: 0, - }} - }) - - It("Should not consider the PostgreSQL cluster as ready", func() { - Expect(r.isPostgresClusterReady(postgresCluster)).Should(BeFalse()) - }) - }) - - When("when no enough replicas exist", func() { - BeforeEach(func() { - repl = int32(2) - postgresInstanceSetSpec = []pgov1beta1.PostgresInstanceSetSpec{{ - Name: "instance1", - Replicas: &repl, - }} - }) - - It("Should not consider the PostgreSQL cluster as ready", func() { - Expect(r.isPostgresClusterReady(postgresCluster)).Should(BeFalse()) - }) - }) - - When("when an instance is present in spec but not in status", func() { - BeforeEach(func() { - repl = int32(1) - postgresInstanceSetSpec = []pgov1beta1.PostgresInstanceSetSpec{{ - Name: "instance1", - Replicas: &repl, - }, { - Name: "instance2", - Replicas: &repl, - }} - }) - - It("Should not consider the PostgreSQL cluster as ready", func() { - Expect(r.isPostgresClusterReady(postgresCluster)).Should(BeFalse()) - }) - }) - - }) - - Context("When updating the Synapse Status with PostgreSQL database information", func() { - var r SynapseReconciler - var s synapsev1alpha1.Synapse - var synapseDatabaseInfo synapsev1alpha1.SynapseStatusDatabaseConnectionInfo - var postgresSecret corev1.Secret - var postgresSecretData map[string][]byte - - // Re-usable test for checking different happy paths - check_happy_path := func() { - By("Updating the Synapse Status") - Expect(r.updateSynapseStatusDatabase(&s, postgresSecret)).Should(Succeed()) - - By("Checking that the Database information in the Synapse Status are correct") - Expect(s.Status.DatabaseConnectionInfo.ConnectionURL).Should(Equal("unittestdb-primary.unittest-postgres.svc:5432")) - Expect(s.Status.DatabaseConnectionInfo.DatabaseName).Should(Equal("synapse")) - Expect(s.Status.DatabaseConnectionInfo.User).Should(Equal("synapse")) - Expect(s.Status.DatabaseConnectionInfo.Password).Should(Equal(string(base64encode("iOycqrF;EbyqUo7Z2oma}.