├── .github └── workflows │ ├── release-catalog.yaml │ ├── release.yaml │ └── test.yaml ├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile ├── OWNERS ├── OWNERS_ALIASES ├── PROJECT ├── README.md ├── bundle.Dockerfile ├── bundle ├── manifests │ ├── monitoring.3scale.net_prometheusexporters.yaml │ ├── prometheus-exporter-operator-controller-manager-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml │ ├── prometheus-exporter-operator-controller-manager-metrics-service_v1_service.yaml │ └── prometheus-exporter-operator.clusterserviceversion.yaml ├── metadata │ └── annotations.yaml └── tests │ └── scorecard │ └── config.yaml ├── catalog ├── Dockerfile └── prometheus-exporter-operator │ ├── alpha-channel.yaml │ ├── objects │ ├── prometheus-exporter-operator.v0.4.0.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.4.1.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.5.0.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.6.0.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.6.1.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.6.2.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.7.0.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.8.0.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.8.1.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.9.0-alpha.1.clusterserviceversion.yaml │ ├── prometheus-exporter-operator.v0.9.0.clusterserviceversion.yaml │ └── prometheus-exporter-operator.v0.9.1.clusterserviceversion.yaml │ ├── operator.yaml │ └── stable-channel.yaml ├── config ├── crd │ ├── bases │ │ └── monitoring.3scale.net_prometheusexporters.yaml │ └── kustomization.yaml ├── default │ ├── kustomization.yaml │ ├── manager_auth_proxy_patch.yaml │ ├── manager_config_patch.yaml │ └── manager_metrics_patch.yaml ├── manager │ ├── controller_manager_config.yaml │ ├── kustomization.yaml │ └── manager.yaml ├── manifests │ ├── bases │ │ └── prometheus-exporter-operator.clusterserviceversion.yaml │ └── kustomization.yaml ├── manual │ ├── kustomization.yaml │ └── manager_metrics_patch.yaml ├── prometheus │ ├── kustomization.yaml │ └── monitor.yaml ├── rbac │ ├── auth_proxy_client_clusterrole.yaml │ ├── auth_proxy_role.yaml │ ├── auth_proxy_role_binding.yaml │ ├── auth_proxy_service.yaml │ ├── kustomization.yaml │ ├── leader_election_role.yaml │ ├── leader_election_role_binding.yaml │ ├── metrics_service.yaml │ ├── prometheusexporter_editor_role.yaml │ ├── prometheusexporter_viewer_role.yaml │ ├── role.yaml │ ├── role_binding.yaml │ └── service_account.yaml ├── samples │ ├── kustomization.yaml │ └── monitoring_v1alpha1_prometheusexporter.yaml ├── scorecard │ ├── bases │ │ └── config.yaml │ ├── kustomization.yaml │ └── patches │ │ ├── basic.config.yaml │ │ └── olm.config.yaml └── testing │ ├── debug_logs_patch.yaml │ ├── external-apis │ ├── grafanadashboards.grafana.integreatly.org.yaml │ ├── grafanadashboards.integreatly.org.yaml │ └── servicemonitors.monitoring.coreos.com.yaml │ ├── kustomization.yaml │ └── pull_policy │ ├── Always.yaml │ ├── IfNotPresent.yaml │ └── Never.yaml ├── docs ├── development.md ├── install.md ├── prometheus-exporter-crd-reference.md └── release.md ├── examples ├── Makefile ├── README.md ├── cloudwatch │ ├── cloudwatch-configmap.yaml │ ├── cloudwatch-cr.yaml │ └── cloudwatch-secret.yaml ├── elasticsearch │ └── es-cr.yaml ├── manticore │ └── manticore-cr.yaml ├── memcached │ ├── memcached-cr.yaml │ └── memcached-db-service.yaml ├── mysql │ ├── mysql-cr.yaml │ ├── mysql-db-service.yaml │ └── mysql-secret.yaml ├── postgresql │ ├── postgresql-cr.yaml │ ├── postgresql-db-service.yaml │ └── postgresql-secret.yaml ├── probe │ ├── probe-configmap.yaml │ ├── probe-cr.yaml │ ├── probe-secret.yaml │ └── probe-target-probe.yaml ├── redis │ ├── redis-cr-2.yaml │ ├── redis-cr.yaml │ └── redis-db-service.yaml ├── sendgrid │ ├── sendgrid-cr.yaml │ └── sendgrid-secret.yaml └── sphinx │ └── sphinx-cr.yaml ├── hack └── new-release.sh ├── img ├── example-cloudwatch-dashboard.png ├── example-es-dashboard.png ├── example-manticore-dashboard.png ├── example-memcached-dashboard.png ├── example-mysql-dashboard.png ├── example-postgresql-dashboard.png ├── example-probe-dashboard.png ├── example-redis-dashboard.png ├── example-sendgrid-dashboard.png ├── example-sphinx-dashboard.png └── prometheus-exporter-operator-logo.svg ├── kuttl-test.yaml ├── molecule ├── default │ ├── converge.yml │ ├── create.yml │ ├── destroy.yml │ ├── kustomize.yml │ ├── molecule.yml │ ├── prepare.yml │ ├── tasks │ │ └── prometheusexporter_test.yml │ └── verify.yml └── kind │ ├── converge.yml │ ├── create.yml │ ├── destroy.yml │ └── molecule.yml ├── playbooks └── .placeholder ├── prometheus-rules ├── cloudwatch-prometheusrule.yaml ├── es-prometheusrule.yaml ├── general-prometheusrule.yaml ├── manticore-prometheusrule.yaml ├── memcached-prometheusrule.yaml ├── mysql-prometheusrule.yaml ├── postgresql-prometheusrule.yaml ├── probe-prometheusrule.yaml ├── redis-prometheusrule.yaml ├── sendgrid-prometheusrule.yaml └── sphinx-prometheusrule.yaml ├── requirements.yml ├── roles └── prometheusexporter │ ├── defaults │ └── main.yml │ ├── exporters │ ├── cloudwatch │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ ├── vars.yml │ │ └── volumes.yml.j2 │ ├── es │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ └── vars.yml │ ├── manticore │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ └── vars.yml │ ├── memcached │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ └── vars.yml │ ├── mysql │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ └── vars.yml │ ├── postgresql │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ └── vars.yml │ ├── probe │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ ├── vars.yml │ │ └── volumes.yml.j2 │ ├── redis │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ └── vars.yml │ ├── sendgrid │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ └── vars.yml │ └── sphinx │ │ ├── container.yml.j2 │ │ ├── grafanadashboard.json.j2 │ │ └── vars.yml │ ├── meta │ └── main.yml │ ├── tasks │ └── main.yml │ └── templates │ ├── deployment.yml.j2 │ ├── grafanadashboard.yml.j2 │ ├── service.yml.j2 │ └── servicemonitor.yml.j2 ├── test └── e2e │ ├── operator │ └── 00-assert.yaml │ ├── prometheusexporter-grafanadashboard-apiversion │ ├── 01-assert.yaml │ └── 01-prometheusexporter.yaml │ └── prometheusexporter │ ├── 01-assert.yaml │ └── 01-prometheusexporter.yaml └── watches.yaml /.github/workflows/release-catalog.yaml: -------------------------------------------------------------------------------- 1 | name: release-catalog 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - catalog/**/stable-channel.yaml 9 | workflow_dispatch: 10 | 11 | jobs: 12 | catalog: 13 | name: Build and push the catalog release image 14 | runs-on: ubuntu-latest 15 | env: 16 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | 21 | - uses: actions/cache@v4 22 | with: 23 | key: ${{ runner.os }}-bin 24 | path: ./bin 25 | 26 | - name: Set up QEMU 27 | uses: docker/setup-qemu-action@v3 28 | 29 | - name: Set up Docker Buildx 30 | uses: docker/setup-buildx-action@v3 31 | 32 | - name: Login to quay.io 33 | uses: docker/login-action@v3 34 | with: 35 | password: ${{ secrets.REGISTRY_PASSWORD }} 36 | registry: quay.io 37 | username: ${{ secrets.REGISTRY_USER }} 38 | 39 | - name: Build and push the catalog container image 40 | run: make catalog-push 41 | 42 | - name: Build and push the current catalog container image as latest 43 | run: make catalog-push-latest 44 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - bundle/manifests/** 9 | workflow_dispatch: 10 | 11 | jobs: 12 | check: 13 | name: Check if it's a stable release 14 | runs-on: ubuntu-latest 15 | outputs: 16 | stable-release: ${{ env.NEW_RELEASE }} 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | 21 | - uses: actions/cache@v4 22 | with: 23 | key: ${{ runner.os }}-bin 24 | path: ./bin 25 | 26 | - id: new-release 27 | name: Check if it's a stable release 28 | run: | 29 | echo "NEW_RELEASE=$(make get-new-release)" >> $GITHUB_ENV 30 | 31 | build: 32 | if: needs.check.outputs.stable-release != '' 33 | name: Build and push the stable release images for the operator and the bundle 34 | needs: check 35 | runs-on: ubuntu-latest 36 | env: 37 | RELEASE: ${{ needs.check.outputs.stable-release }} 38 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 39 | steps: 40 | - name: Checkout 41 | uses: actions/checkout@v4 42 | 43 | - uses: actions/cache@v4 44 | with: 45 | key: ${{ runner.os }}-bin 46 | path: ./bin 47 | 48 | - name: Set up QEMU 49 | uses: docker/setup-qemu-action@v3 50 | 51 | - name: Set up Docker Buildx 52 | uses: docker/setup-buildx-action@v3 53 | 54 | - name: Login to quay.io 55 | uses: docker/login-action@v3 56 | with: 57 | password: ${{ secrets.REGISTRY_PASSWORD }} 58 | registry: quay.io 59 | username: ${{ secrets.REGISTRY_USER }} 60 | 61 | - name: Build and push operator container image 62 | run: make container-push 63 | 64 | - name: Build and push bundle container image 65 | run: make bundle-push 66 | 67 | - id: bundle-image 68 | name: Retrieves the bundle image name 69 | run: echo "BUNDLE_IMAGE=$(make -s bundle-image)" >> $GITHUB_OUTPUT 70 | 71 | - name: Update catalog files with the new bundle 72 | run: make catalog 73 | 74 | - name: Create a new draft-release in github 75 | run: gh release create "${{ env.RELEASE }}" --draft --title "${{ env.RELEASE }}" --generate-notes 76 | 77 | - env: 78 | CI_COMMIT_AUTHOR_EMAIL: 3scale-robot@users.noreply.github.com 79 | CI_COMMIT_AUTHOR_NAME: 3scale-robot 80 | CATALOG_RELEASE_BRANCH: catalog/${{ needs.check.outputs.stable-release }} 81 | CATALOG_RELEASE_PR_TITLE: "release: catalog for bundle ${{ needs.check.outputs.stable-release }}" 82 | CATALOG_RELEASE_PR_BODY: | 83 | This PR updates the catalog inventory files with the new bundle [${{ needs.check.outputs.stable-release }}](https://github.com/${GITHUB_REPOSITORY}/releases/tag/${{ needs.check.outputs.stable-release }}). 84 | 85 | [${{ steps.bundle-image.outputs.BUNDLE_IMAGE }}](https://${{ steps.bundle-image.outputs.BUNDLE_IMAGE }}) 86 | 87 | Please review and merge this PR to build and release the new catalog. 88 | 89 | /kind release 90 | /priority important-soon 91 | name: GIT commit and push catalog 92 | run: | 93 | git config --global user.name "${{ env.CI_COMMIT_AUTHOR_NAME }}" 94 | git config --global user.email "${{ env.CI_COMMIT_AUTHOR_EMAIL }}" 95 | git ls-remote --exit-code --heads origin refs/heads/${{ env.CATALOG_RELEASE_BRANCH }} && git push origin -d ${{ env.CATALOG_RELEASE_BRANCH }} 96 | git checkout -b ${{ env.CATALOG_RELEASE_BRANCH }} 97 | git add catalog 98 | git commit -m "${{ env.CATALOG_RELEASE_PR_TITLE }}" 99 | git push --set-upstream origin ${{ env.CATALOG_RELEASE_BRANCH }} 100 | gh pr create -B main -H ${{ env.CATALOG_RELEASE_BRANCH }} --title "${{ env.CATALOG_RELEASE_PR_TITLE }}" --body "${{ env.CATALOG_RELEASE_PR_BODY }}" 101 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - uses: actions/cache@v4 16 | with: 17 | path: ./bin 18 | key: ${{ runner.os }}-bin 19 | 20 | - name: Run test-e2e 21 | run: make test-e2e 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | bin 8 | 9 | # editor and IDE paraphernalia 10 | .idea 11 | *.swp 12 | *.swo 13 | *~ 14 | kubeconfig 15 | 16 | # tmp folder 17 | tmp 18 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/operator-framework/ansible-operator:v1.24.0 2 | 3 | COPY requirements.yml ${HOME}/requirements.yml 4 | RUN ansible-galaxy collection install -r ${HOME}/requirements.yml \ 5 | && chmod -R ug+rwx ${HOME}/.ansible 6 | 7 | COPY watches.yaml ${HOME}/watches.yaml 8 | COPY roles/ ${HOME}/roles/ 9 | COPY playbooks/ ${HOME}/playbooks/ 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | "approvers": 2 | - "team-sre-approvers" 3 | "labels": 4 | - "wg/sre" 5 | "reviewers": 6 | - "team-sre-reviewers" 7 | -------------------------------------------------------------------------------- /OWNERS_ALIASES: -------------------------------------------------------------------------------- 1 | "aliases": 2 | "team-sre-approvers": 3 | - "raelga" 4 | - "roivaz" 5 | - "slopezz" 6 | "team-sre-reviewers": 7 | - "raelga" 8 | - "roivaz" 9 | - "slopezz" 10 | -------------------------------------------------------------------------------- /PROJECT: -------------------------------------------------------------------------------- 1 | domain: 3scale.net 2 | layout: 3 | - ansible.sdk.operatorframework.io/v1 4 | plugins: 5 | manifests.sdk.operatorframework.io/v2: {} 6 | scorecard.sdk.operatorframework.io/v2: {} 7 | projectName: prometheus-exporter-operator 8 | resources: 9 | - api: 10 | crdVersion: v1 11 | namespaced: true 12 | domain: 3scale.net 13 | group: monitoring 14 | kind: PrometheusExporter 15 | version: v1alpha1 16 | version: "3" 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Prometheus Exporter Operator 2 | 3 | Prometheus Exporter Operator 4 | 5 | [![test](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/test.yaml/badge.svg)](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/test.yaml) 6 | [![build](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/release.yaml/badge.svg)](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/release.yaml) 7 | [![catalog](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/release-catalog.yaml/badge.svg)](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/release-catalog.yaml) 8 | [![release](https://badgen.net/github/release/3scale-sre/prometheus-exporter-operator)](https://github.com/3scale-sre/prometheus-exporter-operator/releases) 9 | [![license](https://badgen.net/github/license/3scale-sre/prometheus-exporter-operator)](https://github.com/3scale-sre/prometheus-exporter-operator/blob/main/LICENSE) 10 | 11 | A Kubernetes Operator based on the Operator SDK to centralize the setup of 3rd party prometheus exporters on **Kubernetes/OpenShift**, with a collection of grafana dashboards. 12 | 13 | By just providing a few parameters like _dbHost_ or _dbPort_ (operator manage the container image, port, argument, command, volumes... and also prometheus `ServiceMonitor` and `GrafanaDashboard` k8s objects), you can setup different prometheus exporters to monitor: 14 | 15 | - The **internals from different databases** 16 | - **HTTP/TCP endpoints** (availability, latency, SSL/TLS certificate expiration...) 17 | - Any available **cloudwatch metric from any AWS Service** 18 | - Sendgrid email statistics (delivered, bounces, errors. spam...) 19 | 20 | Current prometheus exporters `types` supported, managed by same prometheus-exporter-operator: 21 | 22 | - memcached 23 | - redis 24 | - mysql 25 | - postgresql 26 | - sphinx 27 | - manticore 28 | - es (elasticsearch) 29 | - cloudwatch 30 | - probe (blackbox) 31 | - sendgrid 32 | 33 | The operator manages the lifecycle of the following objects: 34 | 35 | - Deployment (one per CR) 36 | - Service (one per CR) 37 | - ServiceMonitor (optional, one per CR) 38 | - GrafanaDashboard (optional, one per Namespace) 39 | 40 | > **NOTE** >
Some exporters need some **extra objects to be previously manually created** in order to work (**manual objects names need to be specified on required CR fields**). This extra needed objects includes **Secrets (credentials) or Configmaps (configuration files) on specific formats**. Examples to help you create these extra objects are provided on [examples](examples/) directory for all exporter types. 41 | >
>
**If you modify the content of these extra needed objects (_Secrets_/_Configmaps_), exporters won't load them automatically, so you need to force a new pod creation by for example deleting the running pod.** 42 | 43 | ## Current status 44 | 45 | Operator is available at [OperatorHub.io](https://operatorhub.io/operator/prometheus-exporter-operator) (on both Kubernetes/OpenShift OLM catalogs) 46 | 47 | ## Requirements 48 | 49 | - [prometheus-operator](https://github.com/coreos/prometheus-operator) v0.17.0+ 50 | - [grafana-operator](https://github.com/integr8ly/grafana-operator) v3.0.0+ 51 | 52 | ## Documentation 53 | 54 | - [PrometheusExporter Custom Resource Reference](docs/prometheus-exporter-crd-reference.md) 55 | - [Install](docs/install.md) 56 | - [Development](docs/development.md) 57 | - [Examples](examples/) 58 | - [Release](docs/release.md) 59 | 60 | ## GrafanaDashboards 61 | 62 | `GrafanaDashboards` management is included in the operator: 63 | 64 | - For each CR, a `GrafanaDashboard` (optional, enabled by default `grafanaDashboard.enabled: true`) is created, but actually operator manages a single dashboard type per Namespace (not per CR) 65 | - If you deploy for example different redis CRs, and you want to have the redis dashboard created, you need to enabled it on every redis CR with the same grafana-operator label selector (but actually, operator will just manage a single dashboard per Namespace shared accross all CRs from the same type) 66 | - You can deploy the prometheus-exporter-operator with different operator versions on different Namespaces, so operator will create separate dashboards per Namespace (they won't collision, that's why dashboard name includes the Namespace) 67 | - All grafana dashboards are preconfigured to use `CR_NAME` as the filter of all possible dashboards of every type (for example `staging-system-memcached`) 68 | - _In the future it is possible that `GrafanaDashboard` management get its own CRD separate from `PrometheusExporter` CRD (so you could have N PrometheusExporter CRs, and also an additonal single Dashboard CR per exporter type_ 69 | 70 | ### Memcached example dashboard 71 | 72 | Example Memcached Dashboard 73 | 74 | ### Redis example dashboard 75 | 76 | Example Redis Dashboard 77 | 78 | ### MySQL example dashboard 79 | 80 | Example MySQL Dashboard 81 | 82 | ### PostgreSQL example dashboard 83 | 84 | Example PostgreSQL Dashboard 85 | 86 | ### Sphinx example dashboard 87 | 88 | Example Sphinx Dashboard 89 | 90 | ### Manticore example dashboard 91 | 92 | Example Manticore Dashboard 93 | 94 | ### Elasticsearch example dashboard 95 | 96 | Example Elasticsearch Dashboard 97 | 98 | ### AWS CloudWatch example dashboard 99 | 100 | Example AWS Cloudwatch Dashboard 101 | 102 | ### Blackbox probe example dashboard 103 | 104 | Example Blackbox Probe Dashboard 105 | 106 | ### Sendgrid example dashboard 107 | 108 | Example Sendgrid Dashboard 109 | 110 | ## PrometheusRules 111 | 112 | `PrometheusRules` management is NOT included in the operator (at least by the moment), because it depends on: 113 | 114 | - What you need to monitor (maybe ones just need basic cpu/mem alerts, while others may be interested on specific alerts checking internals of a database) 115 | - Why you want to be paged (severity warning/critical, minutes duration before firing an alert...) 116 | - Customizable thresholds definition (it is something that depends on infrastructure dimensions...) 117 | 118 | However, some examples of prometheus rules can be found at [prometheus-rules](prometheus-rules/) directory. 119 | 120 | ## Contributing 121 | 122 | You can contribute by: 123 | 124 | - Raising any issues you find using Prometheus Exporter Operator 125 | - Fixing issues by opening [Pull Requests](https://github.com/3scale-sre/prometheus-exporter-operator/pulls) 126 | - Submitting a patch or opening a PR 127 | - Improving documentation 128 | - Talking about Prometheus Exporter Operator 129 | 130 | All bugs, tasks or enhancements are tracked as [GitHub issues](https://github.com/3scale-sre/prometheus-exporter-operator/issues). 131 | 132 | ## License 133 | 134 | Prometheus Exporter Operator is under Apache 2.0 license. See the [LICENSE](LICENSE) file for details. 135 | -------------------------------------------------------------------------------- /bundle.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | 3 | # Core bundle labels. 4 | LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 5 | LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ 6 | LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ 7 | LABEL operators.operatorframework.io.bundle.package.v1=prometheus-exporter-operator 8 | LABEL operators.operatorframework.io.bundle.channels.v1=alpha,stable 9 | LABEL operators.operatorframework.io.bundle.channel.default.v1=alpha 10 | LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.24.0 11 | LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 12 | LABEL operators.operatorframework.io.metrics.project_layout=ansible.sdk.operatorframework.io/v1 13 | 14 | # Labels for testing. 15 | LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 16 | LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ 17 | 18 | # Copy files to locations specified by labels. 19 | COPY bundle/manifests /manifests/ 20 | COPY bundle/metadata /metadata/ 21 | COPY bundle/tests/scorecard /tests/scorecard/ 22 | -------------------------------------------------------------------------------- /bundle/manifests/monitoring.3scale.net_prometheusexporters.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | creationTimestamp: null 5 | name: prometheusexporters.monitoring.3scale.net 6 | spec: 7 | group: monitoring.3scale.net 8 | names: 9 | kind: PrometheusExporter 10 | listKind: PrometheusExporterList 11 | plural: prometheusexporters 12 | singular: prometheusexporter 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | description: PrometheusExporter is the Schema for the prometheusexporters 19 | API 20 | properties: 21 | apiVersion: 22 | description: 'APIVersion defines the versioned schema of this representation 23 | of an object. Servers should convert recognized schemas to the latest 24 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 25 | type: string 26 | kind: 27 | description: 'Kind is a string value representing the REST resource this 28 | object represents. Servers may infer this from the endpoint the client 29 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 30 | type: string 31 | metadata: 32 | type: object 33 | spec: 34 | description: Spec defines the desired state of PrometheusExporter 35 | properties: 36 | awsCredentialsSecretName: 37 | description: For cloudwatch exporter, the Secret name containing AWS 38 | IAM credentials (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY) 39 | type: string 40 | configurationConfigmapName: 41 | description: For cloudwatch exporter, the ConfigMap name containing 42 | Cloudwatch config.yml (Services, Dimensions, Tags used for autodiscovery...). 43 | For probe exporter, ConfigMap name containing blackbox modules configuration. 44 | type: string 45 | configurationSecretName: 46 | description: For probe exporter, optional Secret name containing blackbox 47 | modules configuration. Replaces usage of configurationConfigmapName 48 | (in case config includes sensitive data and so you prefer to use 49 | a Secret) 50 | type: string 51 | dbCheckKeys: 52 | description: For redis exporter, the optional redis keys to monitor 53 | type: string 54 | dbConnectionStringSecretName: 55 | description: For mysql and postgresql exporters, the Secret name containing 56 | connection string definition (DSN) 57 | type: string 58 | dbHost: 59 | description: For redis, memcached, sphinx, manticore and es exporters, 60 | the db host to monitor 61 | type: string 62 | dbPort: 63 | description: For redis, memcached, sphinx, manticore and es exporters, 64 | the db port to monitor 65 | type: integer 66 | extraLabel: 67 | properties: 68 | key: 69 | description: Add extra label key to all created resources 70 | type: string 71 | value: 72 | description: Add extra label value to all created resources 73 | type: string 74 | type: object 75 | grafanaDashboard: 76 | properties: 77 | apiVersion: 78 | description: GrafanaDashboard custom resource apiVersion 79 | enum: 80 | - v1alpha1 81 | - v1beta1 82 | type: string 83 | enabled: 84 | description: Create (true) or not (false) GrafanaDashboard object 85 | type: boolean 86 | label: 87 | properties: 88 | key: 89 | description: Label key used by grafana-operator for dashboard 90 | discovery 91 | type: string 92 | value: 93 | description: Label value used by grafana-operator for dashboard 94 | discovery 95 | type: string 96 | type: object 97 | type: object 98 | image: 99 | properties: 100 | name: 101 | description: Prometheus exporter image name 102 | type: string 103 | version: 104 | description: Prometheus exporter image tag version 105 | type: string 106 | type: object 107 | livenessProbe: 108 | description: Readiness probe 109 | properties: 110 | failureThreshold: 111 | description: Minimum consecutive failures for the probe to be 112 | considered failed after having succeeded 113 | format: int32 114 | type: integer 115 | periodSeconds: 116 | description: How often (in seconds) to perform the probe 117 | format: int32 118 | type: integer 119 | successThreshold: 120 | description: Minimum consecutive successes for the probe to be 121 | considered successful after having failed 122 | format: int32 123 | type: integer 124 | timeoutSeconds: 125 | description: Number of seconds after which the probe times out 126 | format: int32 127 | type: integer 128 | type: object 129 | logLevel: 130 | description: For probe exporter, log level of the exporter 131 | enum: 132 | - info 133 | - debug 134 | type: string 135 | nodeSelector: 136 | additionalProperties: 137 | type: string 138 | description: Map of nodeSelector key-value pairs 139 | type: object 140 | port: 141 | description: Prometheus exporter port where metrics are available 142 | type: integer 143 | probeTargetLabel: 144 | description: For probe exporter, specifies the Prometheus label used 145 | to distinguish among monitored targets on grafana dashboard 146 | type: string 147 | readinessProbe: 148 | description: Readiness probe 149 | properties: 150 | failureThreshold: 151 | description: Minimum consecutive failures for the probe to be 152 | considered failed after having succeeded 153 | format: int32 154 | type: integer 155 | periodSeconds: 156 | description: How often (in seconds) to perform the probe 157 | format: int32 158 | type: integer 159 | successThreshold: 160 | description: Minimum consecutive successes for the probe to be 161 | considered successful after having failed 162 | format: int32 163 | type: integer 164 | timeoutSeconds: 165 | description: Number of seconds after which the probe times out 166 | format: int32 167 | type: integer 168 | type: object 169 | resources: 170 | description: Prometheus exporter resources required. 171 | properties: 172 | limits: 173 | additionalProperties: 174 | anyOf: 175 | - type: integer 176 | - type: string 177 | pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 178 | x-kubernetes-int-or-string: true 179 | description: 'Limits describes the maximum amount of compute resources 180 | allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' 181 | type: object 182 | requests: 183 | additionalProperties: 184 | anyOf: 185 | - type: integer 186 | - type: string 187 | pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 188 | x-kubernetes-int-or-string: true 189 | description: 'Requests describes the minimum amount of compute 190 | resources required. If Requests is omitted for a container, 191 | it defaults to Limits if that is explicitly specified, otherwise 192 | to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' 193 | type: object 194 | type: object 195 | sendgridAccumulatedMetrics: 196 | description: For sendgrid exporter, configures monthly acumulated 197 | metrics (true) instead of daily metrics (false) 198 | type: boolean 199 | sendgridCredentialsSecretName: 200 | description: For sendgrid exporter, Secret name containing Sendgrid 201 | username and apikey 202 | type: string 203 | sendgridLocation: 204 | description: For sendgrid exporter, configures time zone 205 | type: string 206 | sendgridTimeOffset: 207 | description: For sendgrid exporter, specifies the offset in seconds 208 | from UTC as an integer (needed along with location) 209 | type: integer 210 | serviceMonitor: 211 | properties: 212 | enabled: 213 | description: Create (true) or not (false) ServiceMonitor object 214 | type: boolean 215 | interval: 216 | description: Prometheus scrape interval (example 30s) 217 | type: string 218 | type: object 219 | tolerations: 220 | description: Tolerations allow the pods to schedule onto nodes with 221 | matching taints 222 | items: 223 | description: The pod this Toleration is attached to tolerates any 224 | taint that matches the triple using the matching 225 | operator . 226 | properties: 227 | effect: 228 | description: Effect indicates the taint effect to match. Empty 229 | means match all taint effects. When specified, allowed values 230 | are NoSchedule, PreferNoSchedule and NoExecute. 231 | type: string 232 | key: 233 | description: Key is the taint key that the toleration applies 234 | to. Empty means match all taint keys. If the key is empty, 235 | operator must be Exists; this combination means to match all 236 | values and all keys. 237 | type: string 238 | operator: 239 | description: Operator represents a key's relationship to the 240 | value. Valid operators are Exists and Equal. Defaults to Equal. 241 | Exists is equivalent to wildcard for value, so that a pod 242 | can tolerate all taints of a particular category. 243 | type: string 244 | tolerationSeconds: 245 | description: TolerationSeconds represents the period of time 246 | the toleration (which must be of effect NoExecute, otherwise 247 | this field is ignored) tolerates the taint. By default, it 248 | is not set, which means tolerate the taint forever (do not 249 | evict). Zero and negative values will be treated as 0 (evict 250 | immediately) by the system. 251 | format: int64 252 | type: integer 253 | value: 254 | description: Value is the taint value the toleration matches 255 | to. If the operator is Exists, the value should be empty, 256 | otherwise just a regular string. 257 | type: string 258 | type: object 259 | type: array 260 | type: 261 | description: Supported prometheus-exporter types 262 | enum: 263 | - memcached 264 | - redis 265 | - mysql 266 | - postgresql 267 | - sphinx 268 | - manticore 269 | - es 270 | - cloudwatch 271 | - probe 272 | - sendgrid 273 | type: string 274 | required: 275 | - type 276 | type: object 277 | x-kubernetes-preserve-unknown-fields: true 278 | status: 279 | description: Status defines the observed state of PrometheusExporter 280 | type: object 281 | x-kubernetes-preserve-unknown-fields: true 282 | type: object 283 | served: true 284 | storage: true 285 | subresources: 286 | status: {} 287 | status: 288 | acceptedNames: 289 | kind: "" 290 | plural: "" 291 | conditions: null 292 | storedVersions: null 293 | -------------------------------------------------------------------------------- /bundle/manifests/prometheus-exporter-operator-controller-manager-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: prometheus-exporter-operator-controller-manager-metrics-monitor 7 | spec: 8 | endpoints: 9 | - path: /metrics 10 | port: http 11 | selector: 12 | matchLabels: 13 | control-plane: controller-manager 14 | -------------------------------------------------------------------------------- /bundle/manifests/prometheus-exporter-operator-controller-manager-metrics-service_v1_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | creationTimestamp: null 5 | labels: 6 | control-plane: controller-manager 7 | name: prometheus-exporter-operator-controller-manager-metrics-service 8 | spec: 9 | ports: 10 | - name: http 11 | port: 8080 12 | targetPort: http 13 | selector: 14 | control-plane: controller-manager 15 | status: 16 | loadBalancer: {} 17 | -------------------------------------------------------------------------------- /bundle/metadata/annotations.yaml: -------------------------------------------------------------------------------- 1 | annotations: 2 | # Core bundle annotations. 3 | operators.operatorframework.io.bundle.mediatype.v1: registry+v1 4 | operators.operatorframework.io.bundle.manifests.v1: manifests/ 5 | operators.operatorframework.io.bundle.metadata.v1: metadata/ 6 | operators.operatorframework.io.bundle.package.v1: prometheus-exporter-operator 7 | operators.operatorframework.io.bundle.channels.v1: alpha,stable 8 | operators.operatorframework.io.bundle.channel.default.v1: alpha 9 | operators.operatorframework.io.metrics.builder: operator-sdk-v1.24.0 10 | operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 11 | operators.operatorframework.io.metrics.project_layout: ansible.sdk.operatorframework.io/v1 12 | 13 | # Annotations for testing. 14 | operators.operatorframework.io.test.mediatype.v1: scorecard+v1 15 | operators.operatorframework.io.test.config.v1: tests/scorecard/ 16 | -------------------------------------------------------------------------------- /bundle/tests/scorecard/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: scorecard.operatorframework.io/v1alpha3 2 | kind: Configuration 3 | metadata: 4 | name: config 5 | stages: 6 | - parallel: true 7 | tests: 8 | - entrypoint: 9 | - scorecard-test 10 | - basic-check-spec 11 | image: quay.io/operator-framework/scorecard-test:v1.5.0 12 | labels: 13 | suite: basic 14 | test: basic-check-spec-test 15 | storage: 16 | spec: 17 | mountPath: {} 18 | - entrypoint: 19 | - scorecard-test 20 | - olm-bundle-validation 21 | image: quay.io/operator-framework/scorecard-test:v1.24.0 22 | labels: 23 | suite: olm 24 | test: olm-bundle-validation-test 25 | storage: 26 | spec: 27 | mountPath: {} 28 | - entrypoint: 29 | - scorecard-test 30 | - olm-crds-have-validation 31 | image: quay.io/operator-framework/scorecard-test:v1.24.0 32 | labels: 33 | suite: olm 34 | test: olm-crds-have-validation-test 35 | storage: 36 | spec: 37 | mountPath: {} 38 | - entrypoint: 39 | - scorecard-test 40 | - olm-crds-have-resources 41 | image: quay.io/operator-framework/scorecard-test:v1.24.0 42 | labels: 43 | suite: olm 44 | test: olm-crds-have-resources-test 45 | storage: 46 | spec: 47 | mountPath: {} 48 | - entrypoint: 49 | - scorecard-test 50 | - olm-spec-descriptors 51 | image: quay.io/operator-framework/scorecard-test:v1.24.0 52 | labels: 53 | suite: olm 54 | test: olm-spec-descriptors-test 55 | storage: 56 | spec: 57 | mountPath: {} 58 | - entrypoint: 59 | - scorecard-test 60 | - olm-status-descriptors 61 | image: quay.io/operator-framework/scorecard-test:v1.24.0 62 | labels: 63 | suite: olm 64 | test: olm-status-descriptors-test 65 | storage: 66 | spec: 67 | mountPath: {} 68 | storage: 69 | spec: 70 | mountPath: {} 71 | -------------------------------------------------------------------------------- /catalog/Dockerfile: -------------------------------------------------------------------------------- 1 | # The base image is expected to contain 2 | # /bin/opm (with a serve subcommand) and /bin/grpc_health_probe 3 | FROM quay.io/operator-framework/opm:latest 4 | 5 | # Configure the entrypoint and command 6 | ENTRYPOINT ["/bin/opm"] 7 | CMD ["serve", "/configs"] 8 | 9 | # Copy declarative config root into image at /configs 10 | ADD prometheus-exporter-operator /configs 11 | 12 | # Set DC-specific label for the location of the DC root directory 13 | # in the image 14 | LABEL operators.operatorframework.io.index.configs.v1=/configs -------------------------------------------------------------------------------- /catalog/prometheus-exporter-operator/alpha-channel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | entries: 3 | - name: prometheus-exporter-operator.v0.4.0 4 | - name: prometheus-exporter-operator.v0.4.1 5 | replaces: prometheus-exporter-operator.v0.4.0 6 | - name: prometheus-exporter-operator.v0.5.0 7 | replaces: prometheus-exporter-operator.v0.4.1 8 | - name: prometheus-exporter-operator.v0.6.0 9 | replaces: prometheus-exporter-operator.v0.5.0 10 | - name: prometheus-exporter-operator.v0.6.1 11 | replaces: prometheus-exporter-operator.v0.6.0 12 | - name: prometheus-exporter-operator.v0.6.2 13 | replaces: prometheus-exporter-operator.v0.6.1 14 | - name: prometheus-exporter-operator.v0.7.0 15 | replaces: prometheus-exporter-operator.v0.6.2 16 | - name: prometheus-exporter-operator.v0.8.0 17 | replaces: prometheus-exporter-operator.v0.7.0 18 | - name: prometheus-exporter-operator.v0.8.1 19 | replaces: prometheus-exporter-operator.v0.8.0 20 | - name: prometheus-exporter-operator.v0.9.0-alpha.1 21 | replaces: prometheus-exporter-operator.v0.8.1 22 | - name: prometheus-exporter-operator.v0.9.0 23 | replaces: prometheus-exporter-operator.v0.9.0-alpha.1 24 | - name: prometheus-exporter-operator.v0.9.1 25 | replaces: prometheus-exporter-operator.v0.9.0 26 | name: alpha 27 | package: prometheus-exporter-operator 28 | schema: olm.channel 29 | -------------------------------------------------------------------------------- /catalog/prometheus-exporter-operator/operator.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | defaultChannel: stable 3 | icon: 4 | base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC45Mi40ICh1bmtub3duKSIKICAgaW5rc2NhcGU6ZXhwb3J0LXlkcGk9IjQxMC4xOSIKICAgaW5rc2NhcGU6ZXhwb3J0LXhkcGk9IjQxMC4xOSIKICAgaW5rc2NhcGU6ZXhwb3J0LWZpbGVuYW1lPSIvVXNlcnMvcmFlbC9Eb3dubG9hZHMvcHJvbWV0aGV1cy1leHBvcnRlci5wbmciCiAgIHNvZGlwb2RpOmRvY25hbWU9InByb21ldGhldXMtZXhwb3J0ZXItM3NjYWxlLW5ldy5zdmciCiAgIGlkPSJzdmc4NDMiCiAgIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiCiAgIHZpZXdCb3g9IjAgMCA3MzYuNDI1NzggNjE5Ljc0ODQ3IgogICBoZWlnaHQ9IjYxOS43NDg0N3B0IgogICB3aWR0aD0iNzM2LjQyNTc4cHQiCiAgIHZlcnNpb249IjEuMCI+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhODQ5Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzODQ3IiAvPgogIDxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmc4NDMiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iMjciCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiCiAgICAgaW5rc2NhcGU6Y3k9IjM1Ny4wNDcxNyIKICAgICBpbmtzY2FwZTpjeD0iMzc0LjM3OTciCiAgICAgaW5rc2NhcGU6em9vbT0iMC42ODc3ODIyNCIKICAgICBpbmtzY2FwZTpsb2NrZ3VpZGVzPSJ0cnVlIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpZD0ibmFtZWR2aWV3ODQ1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEzNzYiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIyNTYwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGdyaWR0b2xlcmFuY2U9IjEwIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgYm9yZGVyb3BhY2l0eT0iMSIKICAgICBpbmtzY2FwZTpkb2N1bWVudC1yb3RhdGlvbj0iMCIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiIC8+CiAgPHBhdGgKICAgICBkPSJtIDcxNS4xMDM4NiwzMS43NDg0NzYgYyAtMTEuNSw0LjkgLTI3LjMsMTEuNSAtMzUsMTQuNyAtMjAuNiw4LjcgLTUwLDIxLjEgLTY2LjUsMjguMSAtMTcuNSw3LjUgLTM4LjEsMTYuMiAtNzEuMywzMC4wMDAwMDQgLTEzLjYsNS43IC0yNC42LDEwLjcgLTI0LjUsMTEuMSAwLjIsMC4zIDEwLjcsOS40IDIzLjMsMjAuMSAxMi43LDEwLjggMjQuOSwyMS4zIDI3LjIsMjMuNCBsIDQuMywzLjkgLTYuNyw3LjUgYyAtMzEuOSwzNi4xIC04MS41LDg2LjkgLTExMi44LDExNS43IC0xMTAuNiwxMDEuNiAtMjIyLjQsMTcwLjIgLTMyNywyMDAuOCAtMTQuNyw0LjMgLTQxLjEwMDAwMSwxMC42IC00OS41MDAwMDEsMTEuOCAtMS45LDAuMyAtNi40LDEgLTEwLDEuNSAtMy42LDAuNiAtOS40LDEuNCAtMTMsMS43IC0zLjYsMC40IC05LjQsMSAtMTMsMS41IC0zLjYsMC40IC0xNC4yLDAuNyAtMjMuNywwLjYgLTkuNTAwMDAwMywtMC4xIC0xNy4xMDAwMDAzMiwwIC0xNi45MDAwMDAzMiwwLjEgMS40MDAwMDAwMiwxLjQgMzguMzAwMDAwMzIsNi45IDU2LjAwMDAwMDMyLDguMyAxMS41LDEgNTMuNTAwMDAxLDEuMyA2NC4xMDAwMDEsMC41IDIuOCwtMC4yIDkuMywtMC42IDE0LjUsLTEgNS4yLC0wLjMgMTAuNiwtMC44IDEyLC0xIDEuNCwtMC4yIDUuMiwtMC43IDguNSwtMSAzNy40LC0zLjkgODUuNiwtMTQuOSAxMjYuNSwtMjkuMSA5MS40LC0zMS42IDE3Ny4xLC04Mi45IDI2MSwtMTU2LjUgMjAuNSwtMTcuOSA2OC4xLC02NS4yIDg2LjQsLTg1LjcgbCAxMi44LC0xNC4yIDEuOCwyLjIgYyAwLjksMS4zIDEwLjgsMTQgMjEuOSwyOC4zIDExLjEsMTQuMyAyMC41LDI2LjEgMjEsMjYuMyAwLjQsMC4xIDEuNSwtMy43IDIuNSwtOC41IDAuOSwtNC45IDYuNCwtMzMuMSAxMi4xLC02Mi44IDUuNywtMjkuNyAxMi45LC02Ny4xIDE2LC04MyAxNywtODcuODAwMDA0IDE5LjYsLTEwMS43MDAwMDQgMTkuMywtMTAyLjkwMDAwNCAtMC4yLC0wLjggLTgsMiAtMjEuMyw3LjYgeiIKICAgICBpZD0icGF0aDgzNSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiM1YTVhNWE7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMSIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjIuMjAzODU5LDE1Ni41NDg0OCBjIDIsMTUgMTkuNiw2OS42IDI1LDc3LjUgMC44LDEuMSAxLjQsMi41IDEuNCwzLjMgMCwwLjcgMiw1LjQgNC41LDEwLjQgMi41LDUgNC41LDkuNSA0LjUsOS45IDAsMS4xIDE1LjUsMjkuNCAyMyw0MS45IDkuMywxNS43IDM2LjEwMDAwMSw1NC44IDM4LjkwMDAwMSw1NyAwLjQsMC4zIDEuOCwyLjEgMy4xLDQgMS4zLDEuOSAyLjcsMy43IDMsNCAwLjMsMC4zIDIuNCwyLjcgNC41LDUuNSAyLjIsMi43IDQuMiw1LjIgNC41LDUuNSAwLjMsMC4zIDMuNCwzLjkgNyw4IDExLjgsMTMuNyAxNy4yLDE5LjMgMzguOCw0MC43IDExLjgsMTEuNyAyMi4xLDIxLjMgMjIuNywyMS4zIDEuNywwIDYzLjksLTM0LjcgNjQuMywtMzUuOCAwLjEsLTAuNSAtNC44LC00IC0xMSwtNy43IC04MS42LC00OS4zIC0xNTYuNjAwMDAxLC0xMTcgLTE5OC41MDAwMDEsLTE3OS41IC0xNS4zLC0yMi44IC0yNywtNDUuMyAtMzUuMiwtNjcuNSAtMSwtMi43IC0xLC0yLjYgLTAuNSwxLjUgeiIKICAgICBpZD0icGF0aDgzNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYzdhMDg7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMSIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzE4LjMwMzg2LDQ3OS40NDg0OCBjIC0yNi44LDkuNyAtNDguNywxNy45IC00OC43LDE4LjMgMCwxLjIgMzEuNSwyMS42IDUyLjgsMzQuMiA1NCwzMiAxMjkuOSw2NiAxOTAuMiw4NS4xIGwgOC41LDIuNyAyNywtMC42IGMgMjUuOSwtMC42IDI3LjgsLTAuOCA0OCwtNC42IDQwLjUsLTcuNiA2OC43LC0xNy45IDg5LjIsLTMyLjYgNi4xLC00LjMgMTAuOSwtOC4xIDEwLjcsLTguNCAtMS40LC0xLjQgLTUyLjgsLTE2IC04OS40LC0yNS40IC0xNCwtMy43IC0yNi40LC03IC0yNy41LC03LjUgLTEuMSwtMC41IC02LjEsLTEuOCAtMTEuMSwtMyAtMTAsLTIuMyAtNjQuNCwtMjAuMyAtOTAuNywtMzAgLTMwLjgsLTExLjQgLTcyLjIsLTI4LjUgLTEwNC43LC00My40IGwgLTUuNiwtMi41IHoiCiAgICAgaWQ9InBhdGg4MzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWM3YTA4O2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDowLjEiIC8+Cjwvc3ZnPgo= 5 | mediatype: image/svg+xml 6 | name: prometheus-exporter-operator 7 | schema: olm.package 8 | -------------------------------------------------------------------------------- /catalog/prometheus-exporter-operator/stable-channel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | entries: 3 | - name: prometheus-exporter-operator.v0.4.0 4 | - name: prometheus-exporter-operator.v0.4.1 5 | replaces: prometheus-exporter-operator.v0.4.0 6 | - name: prometheus-exporter-operator.v0.5.0 7 | replaces: prometheus-exporter-operator.v0.4.1 8 | - name: prometheus-exporter-operator.v0.6.0 9 | replaces: prometheus-exporter-operator.v0.5.0 10 | - name: prometheus-exporter-operator.v0.6.1 11 | replaces: prometheus-exporter-operator.v0.6.0 12 | - name: prometheus-exporter-operator.v0.6.2 13 | replaces: prometheus-exporter-operator.v0.6.1 14 | - name: prometheus-exporter-operator.v0.7.0 15 | replaces: prometheus-exporter-operator.v0.6.2 16 | - name: prometheus-exporter-operator.v0.8.0 17 | replaces: prometheus-exporter-operator.v0.7.0 18 | - name: prometheus-exporter-operator.v0.8.1 19 | replaces: prometheus-exporter-operator.v0.8.0 20 | - name: prometheus-exporter-operator.v0.9.0 21 | replaces: prometheus-exporter-operator.v0.8.1 22 | - name: prometheus-exporter-operator.v0.9.1 23 | replaces: prometheus-exporter-operator.v0.9.0 24 | name: stable 25 | package: prometheus-exporter-operator 26 | schema: olm.channel 27 | -------------------------------------------------------------------------------- /config/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # This kustomization.yaml is not intended to be run by itself, 2 | # since it depends on service name and namespace that are out of this kustomize package. 3 | # It should be run by config/default 4 | resources: 5 | - bases/monitoring.3scale.net_prometheusexporters.yaml 6 | #+kubebuilder:scaffold:crdkustomizeresource 7 | -------------------------------------------------------------------------------- /config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: prometheus-exporter-operator-system 3 | 4 | # Value of this field is prepended to the 5 | # names of all resources, e.g. a deployment named 6 | # "wordpress" becomes "alices-wordpress". 7 | # Note that it should also match with the prefix (text before '-') of the namespace 8 | # field above. 9 | namePrefix: prometheus-exporter-operator- 10 | 11 | # Labels to add to all resources and selectors. 12 | #labels: 13 | #- includeSelectors: true 14 | # pairs: 15 | # someName: someValue 16 | 17 | bases: 18 | - ../crd 19 | - ../rbac 20 | - ../manager 21 | - ../prometheus 22 | 23 | patchesStrategicMerge: 24 | # Protect the /metrics endpoint by putting it behind auth. 25 | # If you want your controller-manager to expose the /metrics 26 | # endpoint w/o any authn/z, please comment the following line. 27 | #- manager_auth_proxy_patch.yaml 28 | 29 | # Mount the controller config file for loading manager configurations 30 | # through a ComponentConfig type 31 | #- manager_config_patch.yaml 32 | 33 | # Make manager deployment to listen metrics at 0.0.0.0:8080 34 | # because there is no proxy enabled 35 | - manager_metrics_patch.yaml 36 | -------------------------------------------------------------------------------- /config/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch inject a sidecar container which is a HTTP proxy for the 2 | # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: controller-manager 7 | namespace: system 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: kube-rbac-proxy 13 | securityContext: 14 | allowPrivilegeEscalation: false 15 | capabilities: 16 | drop: 17 | - "ALL" 18 | image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 19 | args: 20 | - "--secure-listen-address=0.0.0.0:8443" 21 | - "--upstream=http://127.0.0.1:8080/" 22 | - "--logtostderr=true" 23 | - "--v=0" 24 | ports: 25 | - containerPort: 8443 26 | protocol: TCP 27 | name: https 28 | resources: 29 | limits: 30 | cpu: 500m 31 | memory: 128Mi 32 | requests: 33 | cpu: 5m 34 | memory: 64Mi 35 | - name: manager 36 | args: 37 | - "--health-probe-bind-address=:6789" 38 | - "--metrics-bind-address=127.0.0.1:8080" 39 | - "--leader-elect" 40 | - "--leader-election-id=prometheus-exporter-operator" -------------------------------------------------------------------------------- /config/default/manager_config_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | args: 12 | - "--config=controller_manager_config.yaml" 13 | volumeMounts: 14 | - name: manager-config 15 | mountPath: /controller_manager_config.yaml 16 | subPath: controller_manager_config.yaml 17 | volumes: 18 | - name: manager-config 19 | configMap: 20 | name: manager-config -------------------------------------------------------------------------------- /config/default/manager_metrics_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | args: 12 | - "--health-probe-bind-address=:6789" 13 | - "--metrics-bind-address=0.0.0.0:8080" 14 | - "--leader-elect" 15 | - "--leader-election-id=prometheus-exporter-operator" 16 | ports: 17 | - containerPort: 8080 18 | name: http -------------------------------------------------------------------------------- /config/manager/controller_manager_config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 2 | kind: ControllerManagerConfig 3 | health: 4 | healthProbeBindAddress: :6789 5 | metrics: 6 | bindAddress: 127.0.0.1:8080 7 | 8 | leaderElection: 9 | leaderElect: true 10 | resourceName: 811c9dc5.3scale.net 11 | # leaderElectionReleaseOnCancel defines if the leader should step down volume 12 | # when the Manager ends. This requires the binary to immediately end when the 13 | # Manager is stopped, otherwise, this setting is unsafe. Setting this significantly 14 | # speeds up voluntary leader transitions as the new leader don't have to wait 15 | # LeaseDuration time first. 16 | # In the default scaffold provided, the program ends immediately after 17 | # the manager stops, so would be fine to enable this option. However, 18 | # if you are doing or is intended to do any operation such as perform cleanups 19 | # after the manager stops then its usage might be unsafe. 20 | # leaderElectionReleaseOnCancel: true -------------------------------------------------------------------------------- /config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manager.yaml 3 | 4 | generatorOptions: 5 | disableNameSuffixHash: true 6 | apiVersion: kustomize.config.k8s.io/v1beta1 7 | kind: Kustomization 8 | images: 9 | - name: controller 10 | newName: quay.io/3scale-sre/prometheus-exporter-operator 11 | newTag: v0.9.1 12 | -------------------------------------------------------------------------------- /config/manager/manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: system 7 | --- 8 | apiVersion: apps/v1 9 | kind: Deployment 10 | metadata: 11 | name: controller-manager 12 | namespace: system 13 | labels: 14 | control-plane: controller-manager 15 | spec: 16 | selector: 17 | matchLabels: 18 | control-plane: controller-manager 19 | replicas: 1 20 | template: 21 | metadata: 22 | annotations: 23 | kubectl.kubernetes.io/default-container: manager 24 | labels: 25 | control-plane: controller-manager 26 | spec: 27 | securityContext: 28 | runAsNonRoot: true 29 | # TODO(user): For common cases that do not require escalating privileges 30 | # it is recommended to ensure that all your Pods/Containers are restrictive. 31 | # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted 32 | # Please uncomment the following code if your project does NOT have to work on old Kubernetes 33 | # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ). 34 | # seccompProfile: 35 | # type: RuntimeDefault 36 | containers: 37 | - args: 38 | - --leader-elect 39 | - --leader-election-id=prometheus-exporter-operator 40 | image: controller:latest 41 | name: manager 42 | env: 43 | - name: ANSIBLE_GATHERING 44 | value: explicit 45 | - name: WATCH_NAMESPACE 46 | valueFrom: 47 | fieldRef: 48 | fieldPath: metadata.annotations['olm.targetNamespaces'] 49 | securityContext: 50 | allowPrivilegeEscalation: false 51 | capabilities: 52 | drop: 53 | - "ALL" 54 | livenessProbe: 55 | httpGet: 56 | path: /healthz 57 | port: 6789 58 | initialDelaySeconds: 30 59 | periodSeconds: 20 60 | timeoutSeconds: 5 61 | readinessProbe: 62 | httpGet: 63 | path: /readyz 64 | port: 6789 65 | initialDelaySeconds: 5 66 | periodSeconds: 10 67 | timeoutSeconds: 5 68 | resources: 69 | limits: 70 | cpu: 1000m 71 | memory: 1024Mi 72 | requests: 73 | cpu: 10m 74 | memory: 128Mi 75 | serviceAccountName: controller-manager 76 | terminationGracePeriodSeconds: 10 -------------------------------------------------------------------------------- /config/manifests/bases/prometheus-exporter-operator.clusterserviceversion.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operators.coreos.com/v1alpha1 2 | kind: ClusterServiceVersion 3 | metadata: 4 | annotations: 5 | alm-examples: '[]' 6 | capabilities: Deep Insights 7 | categories: Monitoring 8 | certified: "false" 9 | containerImage: quay.io/3scale/prometheus-exporter-operator 10 | createdAt: "2020-06-08 00:00:00" 11 | description: Operator to setup 3rd party prometheus exporters, with a collection 12 | of grafana dashboards 13 | repository: https://github.com/3scale-sre/prometheus-exporter-operator 14 | support: Red Hat, Inc. 15 | name: prometheus-exporter-operator.v0.0.0 16 | namespace: placeholder 17 | spec: 18 | apiservicedefinitions: {} 19 | customresourcedefinitions: 20 | owned: 21 | - description: Configures a prometheus exporter to monitor a memcached instance 22 | displayName: PrometheusExporter 23 | kind: PrometheusExporter 24 | name: prometheusexporters.monitoring.3scale.net 25 | version: v1alpha1 26 | description: | 27 | A Kubernetes Operator based on the Operator SDK to centralize the setup of third-party Prometheus exporters on **Kubernetes/OpenShift**, along with a collection of Grafana dashboards. 28 | 29 | By providing just a few parameters, such as *dbHost* or *dbPort*, the operator manages the container image, ports, arguments, commands, volumes, and also creates Prometheus `ServiceMonitor` and `GrafanaDashboard` Kubernetes objects. This allows you to easily set up Prometheus exporters to monitor: 30 | 31 | - **Internal metrics from various databases** 32 | - **HTTP/TCP endpoints** (e.g., availability, latency, SSL/TLS certificate expiration) 33 | - **CloudWatch metrics** from any AWS service 34 | - **SendGrid email statistics** (e.g., delivered, bounces, errors, spam) 35 | 36 | ### Supported Prometheus Exporter Types 37 | The Prometheus Exporter Operator currently supports the following exporter types: 38 | - `memcached` 39 | - `redis` 40 | - `mysql` 41 | - `postgresql` 42 | - `sphinx` 43 | - `manticore` 44 | - `es` (Elasticsearch) 45 | - `cloudwatch` 46 | - `probe` (Blackbox) 47 | - `sendgrid` 48 | 49 | ### Managed Kubernetes Objects 50 | The operator manages the lifecycle of the following Kubernetes objects: 51 | - **Deployment**: One per Custom Resource (CR) 52 | - **Service**: One per CR 53 | - **ServiceMonitor**: Optional, one per CR 54 | - **GrafanaDashboard**: Optional, one per namespace 55 | 56 | ### Documentation 57 | Comprehensive documentation is available on our [GitHub repository](https://github.com/3scale-sre/prometheus-exporter-operator#documentation). 58 | 59 | ### Getting Help 60 | If you encounter any issues while using the operator, you can: 61 | - Create an issue for bugs, enhancements, or other requests on our [GitHub Issues page](https://github.com/3scale-sre/prometheus-exporter-operator/issues). 62 | 63 | ### Contributing 64 | We welcome contributions! You can contribute by: 65 | - Reporting issues you encounter while using the Prometheus Exporter Operator 66 | - Fixing issues and submitting [Pull Requests](https://github.com/3scale-sre/prometheus-exporter-operator/pulls) 67 | - Submitting patches or improvements 68 | - Enhancing the [documentation](https://github.com/3scale-sre/prometheus-exporter-operator) 69 | - Spreading the word about the Prometheus Exporter Operator 70 | 71 | All bugs, tasks, and enhancements are tracked as [GitHub issues](https://github.com/3scale-sre/prometheus-exporter-operator/issues). 72 | 73 | ### License 74 | The Prometheus Exporter Operator is licensed under the [Apache 2.0 License](https://github.com/3scale-sre/prometheus-exporter-operator/blob/main/LICENSE). 75 | displayName: Prometheus Exporter Operator 76 | icon: 77 | - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC45Mi40ICh1bmtub3duKSIKICAgaW5rc2NhcGU6ZXhwb3J0LXlkcGk9IjQxMC4xOSIKICAgaW5rc2NhcGU6ZXhwb3J0LXhkcGk9IjQxMC4xOSIKICAgaW5rc2NhcGU6ZXhwb3J0LWZpbGVuYW1lPSIvVXNlcnMvcmFlbC9Eb3dubG9hZHMvcHJvbWV0aGV1cy1leHBvcnRlci5wbmciCiAgIHNvZGlwb2RpOmRvY25hbWU9InByb21ldGhldXMtZXhwb3J0ZXItM3NjYWxlLW5ldy5zdmciCiAgIGlkPSJzdmc4NDMiCiAgIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiCiAgIHZpZXdCb3g9IjAgMCA3MzYuNDI1NzggNjE5Ljc0ODQ3IgogICBoZWlnaHQ9IjYxOS43NDg0N3B0IgogICB3aWR0aD0iNzM2LjQyNTc4cHQiCiAgIHZlcnNpb249IjEuMCI+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhODQ5Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzODQ3IiAvPgogIDxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmc4NDMiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iMjciCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiCiAgICAgaW5rc2NhcGU6Y3k9IjM1Ny4wNDcxNyIKICAgICBpbmtzY2FwZTpjeD0iMzc0LjM3OTciCiAgICAgaW5rc2NhcGU6em9vbT0iMC42ODc3ODIyNCIKICAgICBpbmtzY2FwZTpsb2NrZ3VpZGVzPSJ0cnVlIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpZD0ibmFtZWR2aWV3ODQ1IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEzNzYiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIyNTYwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGdyaWR0b2xlcmFuY2U9IjEwIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgYm9yZGVyb3BhY2l0eT0iMSIKICAgICBpbmtzY2FwZTpkb2N1bWVudC1yb3RhdGlvbj0iMCIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiIC8+CiAgPHBhdGgKICAgICBkPSJtIDcxNS4xMDM4NiwzMS43NDg0NzYgYyAtMTEuNSw0LjkgLTI3LjMsMTEuNSAtMzUsMTQuNyAtMjAuNiw4LjcgLTUwLDIxLjEgLTY2LjUsMjguMSAtMTcuNSw3LjUgLTM4LjEsMTYuMiAtNzEuMywzMC4wMDAwMDQgLTEzLjYsNS43IC0yNC42LDEwLjcgLTI0LjUsMTEuMSAwLjIsMC4zIDEwLjcsOS40IDIzLjMsMjAuMSAxMi43LDEwLjggMjQuOSwyMS4zIDI3LjIsMjMuNCBsIDQuMywzLjkgLTYuNyw3LjUgYyAtMzEuOSwzNi4xIC04MS41LDg2LjkgLTExMi44LDExNS43IC0xMTAuNiwxMDEuNiAtMjIyLjQsMTcwLjIgLTMyNywyMDAuOCAtMTQuNyw0LjMgLTQxLjEwMDAwMSwxMC42IC00OS41MDAwMDEsMTEuOCAtMS45LDAuMyAtNi40LDEgLTEwLDEuNSAtMy42LDAuNiAtOS40LDEuNCAtMTMsMS43IC0zLjYsMC40IC05LjQsMSAtMTMsMS41IC0zLjYsMC40IC0xNC4yLDAuNyAtMjMuNywwLjYgLTkuNTAwMDAwMywtMC4xIC0xNy4xMDAwMDAzMiwwIC0xNi45MDAwMDAzMiwwLjEgMS40MDAwMDAwMiwxLjQgMzguMzAwMDAwMzIsNi45IDU2LjAwMDAwMDMyLDguMyAxMS41LDEgNTMuNTAwMDAxLDEuMyA2NC4xMDAwMDEsMC41IDIuOCwtMC4yIDkuMywtMC42IDE0LjUsLTEgNS4yLC0wLjMgMTAuNiwtMC44IDEyLC0xIDEuNCwtMC4yIDUuMiwtMC43IDguNSwtMSAzNy40LC0zLjkgODUuNiwtMTQuOSAxMjYuNSwtMjkuMSA5MS40LC0zMS42IDE3Ny4xLC04Mi45IDI2MSwtMTU2LjUgMjAuNSwtMTcuOSA2OC4xLC02NS4yIDg2LjQsLTg1LjcgbCAxMi44LC0xNC4yIDEuOCwyLjIgYyAwLjksMS4zIDEwLjgsMTQgMjEuOSwyOC4zIDExLjEsMTQuMyAyMC41LDI2LjEgMjEsMjYuMyAwLjQsMC4xIDEuNSwtMy43IDIuNSwtOC41IDAuOSwtNC45IDYuNCwtMzMuMSAxMi4xLC02Mi44IDUuNywtMjkuNyAxMi45LC02Ny4xIDE2LC04MyAxNywtODcuODAwMDA0IDE5LjYsLTEwMS43MDAwMDQgMTkuMywtMTAyLjkwMDAwNCAtMC4yLC0wLjggLTgsMiAtMjEuMyw3LjYgeiIKICAgICBpZD0icGF0aDgzNSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiM1YTVhNWE7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMSIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjIuMjAzODU5LDE1Ni41NDg0OCBjIDIsMTUgMTkuNiw2OS42IDI1LDc3LjUgMC44LDEuMSAxLjQsMi41IDEuNCwzLjMgMCwwLjcgMiw1LjQgNC41LDEwLjQgMi41LDUgNC41LDkuNSA0LjUsOS45IDAsMS4xIDE1LjUsMjkuNCAyMyw0MS45IDkuMywxNS43IDM2LjEwMDAwMSw1NC44IDM4LjkwMDAwMSw1NyAwLjQsMC4zIDEuOCwyLjEgMy4xLDQgMS4zLDEuOSAyLjcsMy43IDMsNCAwLjMsMC4zIDIuNCwyLjcgNC41LDUuNSAyLjIsMi43IDQuMiw1LjIgNC41LDUuNSAwLjMsMC4zIDMuNCwzLjkgNyw4IDExLjgsMTMuNyAxNy4yLDE5LjMgMzguOCw0MC43IDExLjgsMTEuNyAyMi4xLDIxLjMgMjIuNywyMS4zIDEuNywwIDYzLjksLTM0LjcgNjQuMywtMzUuOCAwLjEsLTAuNSAtNC44LC00IC0xMSwtNy43IC04MS42LC00OS4zIC0xNTYuNjAwMDAxLC0xMTcgLTE5OC41MDAwMDEsLTE3OS41IC0xNS4zLC0yMi44IC0yNywtNDUuMyAtMzUuMiwtNjcuNSAtMSwtMi43IC0xLC0yLjYgLTAuNSwxLjUgeiIKICAgICBpZD0icGF0aDgzNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYzdhMDg7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMSIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzE4LjMwMzg2LDQ3OS40NDg0OCBjIC0yNi44LDkuNyAtNDguNywxNy45IC00OC43LDE4LjMgMCwxLjIgMzEuNSwyMS42IDUyLjgsMzQuMiA1NCwzMiAxMjkuOSw2NiAxOTAuMiw4NS4xIGwgOC41LDIuNyAyNywtMC42IGMgMjUuOSwtMC42IDI3LjgsLTAuOCA0OCwtNC42IDQwLjUsLTcuNiA2OC43LC0xNy45IDg5LjIsLTMyLjYgNi4xLC00LjMgMTAuOSwtOC4xIDEwLjcsLTguNCAtMS40LC0xLjQgLTUyLjgsLTE2IC04OS40LC0yNS40IC0xNCwtMy43IC0yNi40LC03IC0yNy41LC03LjUgLTEuMSwtMC41IC02LjEsLTEuOCAtMTEuMSwtMyAtMTAsLTIuMyAtNjQuNCwtMjAuMyAtOTAuNywtMzAgLTMwLjgsLTExLjQgLTcyLjIsLTI4LjUgLTEwNC43LC00My40IGwgLTUuNiwtMi41IHoiCiAgICAgaWQ9InBhdGg4MzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWM3YTA4O2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDowLjEiIC8+Cjwvc3ZnPgo= 78 | mediatype: image/svg+xml 79 | install: 80 | spec: 81 | deployments: null 82 | strategy: "" 83 | installModes: 84 | - supported: true 85 | type: OwnNamespace 86 | - supported: true 87 | type: SingleNamespace 88 | - supported: true 89 | type: MultiNamespace 90 | - supported: true 91 | type: AllNamespaces 92 | keywords: 93 | - monitoring 94 | - metrics 95 | - observability 96 | - prometheus 97 | - exporter 98 | - grafana 99 | - mysql 100 | - postgresql 101 | - memcached 102 | - redis 103 | - sphinx 104 | - elasticsearch 105 | - cloudwatch 106 | - blackbox 107 | - sendgrid 108 | - manticore 109 | links: 110 | - name: GitHub 111 | url: https://github.com/3scale-sre/prometheus-exporter-operator 112 | maintainers: 113 | - email: 3scale-sre+olm@redhat.com 114 | name: Red Hat 3scale SRE 115 | maturity: alpha 116 | provider: 117 | name: Red Hat 118 | url: https://www.redhat.com 119 | version: 0.0.0 120 | -------------------------------------------------------------------------------- /config/manifests/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - bases/prometheus-exporter-operator.clusterserviceversion.yaml 3 | - ../default 4 | - ../samples 5 | - ../scorecard 6 | -------------------------------------------------------------------------------- /config/manual/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: prometheus-exporter-operator-system 3 | 4 | # Value of this field is prepended to the 5 | # names of all resources, e.g. a deployment named 6 | # "wordpress" becomes "alices-wordpress". 7 | # Note that it should also match with the prefix (text before '-') of the namespace 8 | # field above. 9 | namePrefix: prometheus-exporter-operator- 10 | 11 | # Labels to add to all resources and selectors. 12 | #commonLabels: 13 | # someName: someValue 14 | 15 | bases: 16 | - ../crd 17 | - ../rbac 18 | - ../manager 19 | - ../prometheus 20 | 21 | patchesStrategicMerge: 22 | # Protect the /metrics endpoint by putting it behind auth. 23 | # If you want your controller-manager to expose the /metrics 24 | # endpoint w/o any authn/z, please comment the following line. 25 | #- manager_auth_proxy_patch.yaml 26 | 27 | # Mount the controller config file for loading manager configurations 28 | # through a ComponentConfig type 29 | #- manager_config_patch.yaml 30 | 31 | # Make manager deployment to listen metrics at 0.0.0.0:8080 32 | # because there is no proxy enabled 33 | - manager_metrics_patch.yaml 34 | 35 | patches: 36 | - target: 37 | group: apps 38 | version: v1 39 | kind: Deployment 40 | name: controller-manager 41 | patch: |- 42 | - op: replace 43 | path: /spec/template/spec/containers/0/env/1 44 | value: { "name": "WATCH_NAMESPACE", "value": prometheus-exporter-operator-system } -------------------------------------------------------------------------------- /config/manual/manager_metrics_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | args: 12 | - "--health-probe-bind-address=:6789" 13 | - "--metrics-bind-address=0.0.0.0:8080" 14 | - "--leader-elect" 15 | - "--leader-election-id=prometheus-exporter-operator" 16 | ports: 17 | - containerPort: 8080 18 | name: http -------------------------------------------------------------------------------- /config/prometheus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - monitor.yaml 3 | -------------------------------------------------------------------------------- /config/prometheus/monitor.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Prometheus Monitor Service (Metrics) 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | labels: 7 | control-plane: controller-manager 8 | name: controller-manager-metrics-monitor 9 | namespace: system 10 | spec: 11 | endpoints: 12 | - path: /metrics 13 | port: http 14 | selector: 15 | matchLabels: 16 | control-plane: controller-manager 17 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_client_clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: metrics-reader 5 | rules: 6 | - nonResourceURLs: 7 | - "/metrics" 8 | verbs: 9 | - get 10 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: proxy-role 5 | rules: 6 | - apiGroups: 7 | - authentication.k8s.io 8 | resources: 9 | - tokenreviews 10 | verbs: 11 | - create 12 | - apiGroups: 13 | - authorization.k8s.io 14 | resources: 15 | - subjectaccessreviews 16 | verbs: 17 | - create 18 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: proxy-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: proxy-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: controller-manager-metrics-service 7 | namespace: system 8 | spec: 9 | ports: 10 | - name: https 11 | port: 8443 12 | targetPort: https 13 | selector: 14 | control-plane: controller-manager 15 | -------------------------------------------------------------------------------- /config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - service_account.yaml 3 | - role.yaml 4 | - role_binding.yaml 5 | - leader_election_role.yaml 6 | - leader_election_role_binding.yaml 7 | # Comment the following 4 lines if you want to disable 8 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 9 | # which protects your /metrics endpoint. 10 | #- auth_proxy_service.yaml 11 | #- auth_proxy_role.yaml 12 | #- auth_proxy_role_binding.yaml 13 | #- auth_proxy_client_clusterrole.yaml 14 | - metrics_service.yaml 15 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions to do leader election. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: leader-election-role 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - configmaps 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - create 16 | - update 17 | - patch 18 | - delete 19 | - apiGroups: 20 | - coordination.k8s.io 21 | resources: 22 | - leases 23 | verbs: 24 | - get 25 | - list 26 | - watch 27 | - create 28 | - update 29 | - patch 30 | - delete 31 | - apiGroups: 32 | - "" 33 | resources: 34 | - events 35 | verbs: 36 | - create 37 | - patch 38 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: leader-election-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: leader-election-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/rbac/metrics_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: controller-manager-metrics-service 7 | namespace: system 8 | spec: 9 | ports: 10 | - name: http 11 | port: 8080 12 | targetPort: http 13 | selector: 14 | control-plane: controller-manager 15 | -------------------------------------------------------------------------------- /config/rbac/prometheusexporter_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit prometheusexporters. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: prometheusexporter-editor-role 6 | rules: 7 | - apiGroups: 8 | - monitoring.3scale.net 9 | resources: 10 | - prometheusexporters 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - monitoring.3scale.net 21 | resources: 22 | - prometheusexporters/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/prometheusexporter_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view prometheusexporters. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: prometheusexporter-viewer-role 6 | rules: 7 | - apiGroups: 8 | - monitoring.3scale.net 9 | resources: 10 | - prometheusexporters 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - monitoring.3scale.net 17 | resources: 18 | - prometheusexporters/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: manager-role 6 | rules: 7 | - apiGroups: 8 | - apps 9 | resources: 10 | - deployments 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - "" 21 | resources: 22 | - services 23 | verbs: 24 | - create 25 | - delete 26 | - get 27 | - list 28 | - patch 29 | - update 30 | - watch 31 | - apiGroups: 32 | - "" 33 | resources: 34 | - secrets 35 | verbs: 36 | - get 37 | - list 38 | - watch 39 | - apiGroups: 40 | - "" 41 | resources: 42 | - configmaps 43 | verbs: 44 | - get 45 | - list 46 | - watch 47 | - apiGroups: 48 | - monitoring.coreos.com 49 | resources: 50 | - servicemonitors 51 | verbs: 52 | - create 53 | - delete 54 | - get 55 | - list 56 | - patch 57 | - update 58 | - watch 59 | - apiGroups: 60 | - integreatly.org 61 | - grafana.integreatly.org 62 | resources: 63 | - grafanadashboards 64 | verbs: 65 | - create 66 | - delete 67 | - get 68 | - list 69 | - patch 70 | - update 71 | - watch 72 | - apiGroups: 73 | - monitoring.3scale.net 74 | resources: 75 | - prometheusexporters 76 | - prometheusexporters/status 77 | - prometheusexporters/finalizers 78 | verbs: 79 | - create 80 | - delete 81 | - get 82 | - list 83 | - patch 84 | - update 85 | - watch 86 | #+kubebuilder:scaffold:rules 87 | -------------------------------------------------------------------------------- /config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: manager-rolebinding 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: Role 9 | name: manager-role 10 | subjects: 11 | - kind: ServiceAccount 12 | name: controller-manager 13 | namespace: system 14 | -------------------------------------------------------------------------------- /config/rbac/service_account.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: controller-manager 6 | namespace: system -------------------------------------------------------------------------------- /config/samples/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## Append samples you want in your CSV to this file as resources ## 2 | resources: 3 | - monitoring_v1alpha1_prometheusexporter.yaml 4 | #+kubebuilder:scaffold:manifestskustomizesamples 5 | -------------------------------------------------------------------------------- /config/samples/monitoring_v1alpha1_prometheusexporter.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: example-memcached 5 | spec: 6 | type: memcached 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | dbHost: your-memcached-host 12 | dbPort: 11211 -------------------------------------------------------------------------------- /config/scorecard/bases/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: scorecard.operatorframework.io/v1alpha3 2 | kind: Configuration 3 | metadata: 4 | name: config 5 | stages: 6 | - parallel: true 7 | tests: [] 8 | -------------------------------------------------------------------------------- /config/scorecard/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - bases/config.yaml 3 | patchesJson6902: 4 | - path: patches/basic.config.yaml 5 | target: 6 | group: scorecard.operatorframework.io 7 | version: v1alpha3 8 | kind: Configuration 9 | name: config 10 | - path: patches/olm.config.yaml 11 | target: 12 | group: scorecard.operatorframework.io 13 | version: v1alpha3 14 | kind: Configuration 15 | name: config 16 | #+kubebuilder:scaffold:patchesJson6902 17 | -------------------------------------------------------------------------------- /config/scorecard/patches/basic.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - basic-check-spec 7 | image: quay.io/operator-framework/scorecard-test:v1.5.0 8 | labels: 9 | suite: basic 10 | test: basic-check-spec-test 11 | -------------------------------------------------------------------------------- /config/scorecard/patches/olm.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - olm-bundle-validation 7 | image: quay.io/operator-framework/scorecard-test:v1.24.0 8 | labels: 9 | suite: olm 10 | test: olm-bundle-validation-test 11 | - op: add 12 | path: /stages/0/tests/- 13 | value: 14 | entrypoint: 15 | - scorecard-test 16 | - olm-crds-have-validation 17 | image: quay.io/operator-framework/scorecard-test:v1.24.0 18 | labels: 19 | suite: olm 20 | test: olm-crds-have-validation-test 21 | - op: add 22 | path: /stages/0/tests/- 23 | value: 24 | entrypoint: 25 | - scorecard-test 26 | - olm-crds-have-resources 27 | image: quay.io/operator-framework/scorecard-test:v1.24.0 28 | labels: 29 | suite: olm 30 | test: olm-crds-have-resources-test 31 | - op: add 32 | path: /stages/0/tests/- 33 | value: 34 | entrypoint: 35 | - scorecard-test 36 | - olm-spec-descriptors 37 | image: quay.io/operator-framework/scorecard-test:v1.24.0 38 | labels: 39 | suite: olm 40 | test: olm-spec-descriptors-test 41 | - op: add 42 | path: /stages/0/tests/- 43 | value: 44 | entrypoint: 45 | - scorecard-test 46 | - olm-status-descriptors 47 | image: quay.io/operator-framework/scorecard-test:v1.24.0 48 | labels: 49 | suite: olm 50 | test: olm-status-descriptors-test 51 | -------------------------------------------------------------------------------- /config/testing/debug_logs_patch.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | env: 13 | - name: ANSIBLE_DEBUG_LOGS 14 | value: "TRUE" 15 | -------------------------------------------------------------------------------- /config/testing/external-apis/grafanadashboards.grafana.integreatly.org.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.12.0 7 | name: grafanadashboards.grafana.integreatly.org 8 | spec: 9 | group: grafana.integreatly.org 10 | names: 11 | kind: GrafanaDashboard 12 | listKind: GrafanaDashboardList 13 | plural: grafanadashboards 14 | singular: grafanadashboard 15 | scope: Namespaced 16 | versions: 17 | - additionalPrinterColumns: 18 | - jsonPath: .status.NoMatchingInstances 19 | name: No matching instances 20 | type: boolean 21 | - format: date-time 22 | jsonPath: .status.lastResync 23 | name: Last resync 24 | type: date 25 | - jsonPath: .metadata.creationTimestamp 26 | name: Age 27 | type: date 28 | name: v1beta1 29 | schema: 30 | openAPIV3Schema: 31 | properties: 32 | apiVersion: 33 | type: string 34 | kind: 35 | type: string 36 | metadata: 37 | type: object 38 | spec: 39 | properties: 40 | allowCrossNamespaceImport: 41 | type: boolean 42 | configMapRef: 43 | properties: 44 | key: 45 | type: string 46 | name: 47 | type: string 48 | optional: 49 | type: boolean 50 | required: 51 | - key 52 | type: object 53 | x-kubernetes-map-type: atomic 54 | contentCacheDuration: 55 | type: string 56 | datasources: 57 | items: 58 | properties: 59 | datasourceName: 60 | type: string 61 | inputName: 62 | type: string 63 | required: 64 | - datasourceName 65 | - inputName 66 | type: object 67 | type: array 68 | envFrom: 69 | items: 70 | properties: 71 | configMapKeyRef: 72 | properties: 73 | key: 74 | type: string 75 | name: 76 | type: string 77 | optional: 78 | type: boolean 79 | required: 80 | - key 81 | type: object 82 | x-kubernetes-map-type: atomic 83 | secretKeyRef: 84 | properties: 85 | key: 86 | type: string 87 | name: 88 | type: string 89 | optional: 90 | type: boolean 91 | required: 92 | - key 93 | type: object 94 | x-kubernetes-map-type: atomic 95 | type: object 96 | type: array 97 | envs: 98 | items: 99 | properties: 100 | name: 101 | type: string 102 | value: 103 | type: string 104 | valueFrom: 105 | properties: 106 | configMapKeyRef: 107 | properties: 108 | key: 109 | type: string 110 | name: 111 | type: string 112 | optional: 113 | type: boolean 114 | required: 115 | - key 116 | type: object 117 | x-kubernetes-map-type: atomic 118 | secretKeyRef: 119 | properties: 120 | key: 121 | type: string 122 | name: 123 | type: string 124 | optional: 125 | type: boolean 126 | required: 127 | - key 128 | type: object 129 | x-kubernetes-map-type: atomic 130 | type: object 131 | required: 132 | - name 133 | type: object 134 | type: array 135 | folder: 136 | type: string 137 | grafanaCom: 138 | properties: 139 | id: 140 | type: integer 141 | revision: 142 | type: integer 143 | required: 144 | - id 145 | type: object 146 | gzipJson: 147 | format: byte 148 | type: string 149 | instanceSelector: 150 | properties: 151 | matchExpressions: 152 | items: 153 | properties: 154 | key: 155 | type: string 156 | operator: 157 | type: string 158 | values: 159 | items: 160 | type: string 161 | type: array 162 | required: 163 | - key 164 | - operator 165 | type: object 166 | type: array 167 | matchLabels: 168 | additionalProperties: 169 | type: string 170 | type: object 171 | type: object 172 | x-kubernetes-map-type: atomic 173 | json: 174 | type: string 175 | jsonnet: 176 | type: string 177 | jsonnetLib: 178 | properties: 179 | fileName: 180 | type: string 181 | gzipJsonnetProject: 182 | format: byte 183 | type: string 184 | jPath: 185 | items: 186 | type: string 187 | type: array 188 | required: 189 | - fileName 190 | - gzipJsonnetProject 191 | type: object 192 | plugins: 193 | items: 194 | properties: 195 | name: 196 | type: string 197 | version: 198 | type: string 199 | required: 200 | - name 201 | - version 202 | type: object 203 | type: array 204 | resyncPeriod: 205 | type: string 206 | url: 207 | type: string 208 | required: 209 | - instanceSelector 210 | type: object 211 | status: 212 | properties: 213 | NoMatchingInstances: 214 | type: boolean 215 | contentCache: 216 | format: byte 217 | type: string 218 | contentTimestamp: 219 | format: date-time 220 | type: string 221 | contentUrl: 222 | type: string 223 | hash: 224 | type: string 225 | lastResync: 226 | format: date-time 227 | type: string 228 | uid: 229 | type: string 230 | type: object 231 | type: object 232 | served: true 233 | storage: true 234 | subresources: 235 | status: {} -------------------------------------------------------------------------------- /config/testing/external-apis/grafanadashboards.integreatly.org.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1beta1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: grafanadashboards.integreatly.org 6 | spec: 7 | group: integreatly.org 8 | names: 9 | kind: GrafanaDashboard 10 | listKind: GrafanaDashboardList 11 | plural: grafanadashboards 12 | singular: grafanadashboard 13 | scope: Namespaced 14 | subresources: 15 | status: {} 16 | version: v1alpha1 17 | validation: 18 | openAPIV3Schema: 19 | properties: 20 | spec: 21 | properties: 22 | customFolderName: 23 | description: Folder name that this dashboard will be assigned to. 24 | type: string 25 | datasources: 26 | items: 27 | description: Input datasources to resolve before importing 28 | type: object 29 | type: array 30 | json: 31 | type: string 32 | jsonnet: 33 | description: Jsonnet source. Has access to grafonnet. 34 | type: string 35 | name: 36 | type: string 37 | plugins: 38 | items: 39 | description: Grafana Plugin Object 40 | type: object 41 | type: array 42 | url: 43 | description: URL to dashboard json 44 | type: string -------------------------------------------------------------------------------- /config/testing/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: default 3 | 4 | namePrefix: prometheus-exporter-operator- 5 | 6 | # Labels to add to all resources and selectors. 7 | #commonLabels: 8 | # someName: someValue 9 | 10 | patchesStrategicMerge: 11 | - debug_logs_patch.yaml 12 | 13 | apiVersion: kustomize.config.k8s.io/v1beta1 14 | kind: Kustomization 15 | resources: 16 | - ../crd 17 | - ../rbac 18 | - ../manager 19 | - external-apis/servicemonitors.monitoring.coreos.com.yaml 20 | - external-apis/grafanadashboards.integreatly.org.yaml 21 | - external-apis/grafanadashboards.grafana.integreatly.org.yaml 22 | images: 23 | - name: testing 24 | newName: testing-operator 25 | 26 | patches: 27 | - target: 28 | group: apps 29 | version: v1 30 | kind: Deployment 31 | name: controller-manager 32 | patch: |- 33 | - op: replace 34 | path: /spec/template/spec/containers/0/env/2 35 | value: { "name": "WATCH_NAMESPACE", "value": default } -------------------------------------------------------------------------------- /config/testing/pull_policy/Always.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | imagePullPolicy: Always 13 | -------------------------------------------------------------------------------- /config/testing/pull_policy/IfNotPresent.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | imagePullPolicy: IfNotPresent 13 | -------------------------------------------------------------------------------- /config/testing/pull_policy/Never.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: controller-manager 6 | namespace: system 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: manager 12 | imagePullPolicy: Never 13 | -------------------------------------------------------------------------------- /docs/development.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | To run the operator locally without creating any new image: 4 | * You can run the operator locally watching all namespaces (default behaviour): 5 | ```bash 6 | make run 7 | ``` 8 | * Or watching a specific namespace using envvar `WATCH_NAMESPACE`: 9 | ```bash 10 | make run WATCH_NAMESPACE=example 11 | ``` -------------------------------------------------------------------------------- /docs/install.md: -------------------------------------------------------------------------------- 1 | # Install 2 | 3 | ## OperatorHub.io 4 | 5 | - **The recommendd way to install the operator is to install it via OLM with the version published at [OperatorHub.io](https://operatorhub.io/operator/prometheus-exporter-operator) (on both Kubernetes/OpenShift OLM catalogs)** 6 | - However, there are other options to install it using `kustomize` or `operator-sdk` 7 | 8 | ## Manual deploy 9 | 10 | - To manually install the operator (on all its dependant resources) on default namespace `prometheus-exporter-operator-system` without using OLM, you can use the following make target (which uses `kustomize`): 11 | 12 | ```bash 13 | $ make deploy 14 | ``` 15 | 16 | - Then create any `PrometheusExporter` resource type (you can find examples on [examples](../examples/) directory). 17 | - Once tested, delete created operator resources using the following make target: 18 | 19 | ```bash 20 | $ make undeploy 21 | ``` 22 | 23 | ## OLM deploy 24 | 25 | - If you want to install a specific version of the operator via OLM without using the version published at [OperatorHub.io](https://operatorhub.io/operator/prometheus-exporter-operator), you can use for example the following command: 26 | 27 | ```bash 28 | operator-sdk run bundle quay.io/3scale-sre/prometheus-exporter-operator-bundle:0.3.0-alpha.11 --namespace prom-exporter 29 | ``` 30 | 31 | - Then create any `PrometheusExporter` resource type (you can find examples on [examples](../examples/) directory). 32 | - If for example you want to test an operator upgrade of a newer version, execute for example: 33 | 34 | ```bash 35 | operator-sdk run bundle-upgrade quay.io/3scale-sre/prometheus-exporter-operator-bundle:0.3.0-alpha.12 --namespace prom-exporter 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/release.md: -------------------------------------------------------------------------------- 1 | # Release 2 | 3 | - Update Makefile variable `VERSION` to the appropiate release version. Allowed formats: 4 | - alpha: `VERSION ?= 0.3.0-alpha.12` 5 | - stable: `VERSION ?= 0.3.0` 6 | 7 | ## Alpha 8 | 9 | Execute following target to generate, build and push the operator, bundle and catalog images. 10 | 11 | ```bash 12 | make release-publish 13 | ``` 14 | 15 | ## Stable 16 | 17 | If it is an **stable** release, container images will be built in GitHub Actions, 18 | so you only need to create and commit appropiate bundle files executing: 19 | 20 | ```bash 21 | make prepare-release 22 | ``` 23 | 24 | - Then open a [Pull Request](https://github.com/3scale-sre/prometheus-exporter-operator/pulls), and the [Release GitHub Action](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/release.yaml) will automatically detect if it is new release or not, in order to create it by building/pushing new operator and bundle. 25 | 26 | - As part of the release workflow, a: 27 | 28 | - Release Draft will be published, review the changelog, adding any missing information and publish the release. 29 | - A new Pull Request will open with the updated catalog including the new release. 30 | 31 | - Review the Catalog Pull Request and merge it to publish the trigger the [Release Catalog GitHub Action](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/release-catalog.yaml). This action will automatically build and publish the new catalog image. 32 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help all clean 2 | 3 | .DEFAULT_GOAL := help 4 | 5 | MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) 6 | THISDIR_PATH := $(patsubst %/,%,$(abspath $(dir $(MKFILE_PATH)))) 7 | 8 | KUBE_CLIENT ?= kubectl # It can be used "oc" or "kubectl" 9 | NAMESPACE ?= prometheus-exporter-operator-system 10 | 11 | ## General ## 12 | 13 | all: memcached-create redis-create mysql-create postgresql-create sphinx-create elasticsearch-create cloudwatch-create probe-create sendgrid-create ## GENERAL - Create all examples 14 | 15 | clean: memcached-delete redis-delete mysql-delete postgresql-delete sphinx-delete elasticsearch-delete cloudwatch-delete probe-delete sendgrid-delete ## GENERAL - Delete all examples 16 | 17 | ## Memcached ## 18 | 19 | memcached-create: ## MEMCACHED EXAMPLE - Create: CR-DB, CR 20 | $(KUBE_CLIENT) apply -f memcached/ --validate=false -n $(NAMESPACE) 21 | 22 | memcached-delete: ## MEMCACHED EXAMPLE - Delete: CR, CR-DB 23 | $(KUBE_CLIENT) delete -f memcached/ -n $(NAMESPACE) || true 24 | 25 | ## Redis ## 26 | 27 | redis-create: ## REDIS EXAMPLES - Create: CR-DB, CR, CR-2 28 | $(KUBE_CLIENT) apply -f redis/ --validate=false -n $(NAMESPACE) 29 | 30 | redis-delete: ## REDIS EXAMPLES - Delete: CR, CR-2, CR-DB 31 | $(KUBE_CLIENT) delete -f redis/ -n $(NAMESPACE) || true 32 | 33 | ## MySQL ## 34 | 35 | mysql-create: ## MYSQL EXAMPLE - Create: CR-secret (connection string), CR-DB (with specific grants), CR 36 | $(KUBE_CLIENT) apply -f mysql/ --validate=false -n $(NAMESPACE) 37 | sleep 30 38 | $(KUBE_CLIENT) wait --timeout=180s --for condition=ready pod mysql-server-0 -n $(NAMESPACE) 39 | $(KUBE_CLIENT) exec mysql-server-0 -n $(NAMESPACE) -- mysql -u root -h localhost -e "CREATE USER 'exporter'@'%' IDENTIFIED BY '123456789';" 40 | $(KUBE_CLIENT) exec mysql-server-0 -n $(NAMESPACE) -- mysql -u root -h localhost -e "GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';" 41 | 42 | mysql-delete: ## MYSQL EXAMPLE - Delete: CR, CR-DB, CR-secret 43 | $(KUBE_CLIENT) delete -f mysql/ -n $(NAMESPACE) || true 44 | 45 | ## PostgreSQL ## 46 | 47 | postgresql-create: ## POSTGRESQL EXAMPLE - Create: CR-secret (connection string), CR-DB, CR 48 | $(KUBE_CLIENT) apply -f postgresql/ --validate=false -n $(NAMESPACE) 49 | 50 | postgresql-delete: ## POSTGRESQL EXAMPLE - Delete: CR, CR-DB, CR-secret 51 | $(KUBE_CLIENT) delete -f postgresql/ -n $(NAMESPACE) || true 52 | 53 | ## Sphinx ## 54 | 55 | sphinx-create: ## SPHINX EXAMPLE - Create: CR (you need to provide a sphinx instance in advance) 56 | $(KUBE_CLIENT) apply -f sphinx/ --validate=false -n $(NAMESPACE) 57 | 58 | sphinx-delete: ## SPHINX EXAMPLE - Delete: CR 59 | $(KUBE_CLIENT) delete -f sphinx/ -n $(NAMESPACE) || true 60 | 61 | ## Manticore ## 62 | 63 | manticore-create: ## MANTICORE EXAMPLE - Create: CR (you need to provide a manticore instance in advance) 64 | $(KUBE_CLIENT) apply -f manticore/ --validate=false -n $(NAMESPACE) 65 | 66 | manticore-delete: ## MANTICORE EXAMPLE - Delete: CR 67 | $(KUBE_CLIENT) delete -f manticore/ -n $(NAMESPACE) || true 68 | 69 | ## Elasticsearch ## 70 | 71 | elasticsearch-create: ## ELASTICSEARCH EXAMPLE - Create: CR (you need to provide a ES cluster in advance) 72 | $(KUBE_CLIENT) apply -f elasticsearch/ --validate=false -n $(NAMESPACE) 73 | 74 | elasticsearch-delete: ## ELASTICSEARCH EXAMPLE - Delete: CR 75 | $(KUBE_CLIENT) delete -f elasticsearch/ -n $(NAMESPACE) || true 76 | 77 | ## CloudWatch ## 78 | 79 | cloudwatch-create: ## CLOUDWATCH EXAMPLE - Create: CR-secret (AWS IAM creds), CR-configmap (CW exporter config), CR 80 | $(KUBE_CLIENT) apply -f cloudwatch/ --validate=false -n $(NAMESPACE) 81 | 82 | cloudwatch-delete: ## CLOUDWATCH EXAMPLE - Delete: CR, CR-secret, CR-configmap 83 | $(KUBE_CLIENT) delete -f cloudwatch/ -n $(NAMESPACE) || true 84 | 85 | ## Probe ## 86 | 87 | probe-create: ## PROBE EXAMPLE - Create: CR-configmap (blackbox modules config), CR, Target-SM 88 | $(KUBE_CLIENT) apply -f probe/ --validate=false -n $(NAMESPACE) 89 | 90 | probe-delete: ## PROBE EXAMPLE - Delete: Target-SM, CR, CR-configmap 91 | $(KUBE_CLIENT) delete -f probe/ -n $(NAMESPACE) || true 92 | 93 | ## Sendgrid ## 94 | 95 | sendgrid-create: ## SENDGRID EXAMPLE - Create: CR-secret (username/apikey), CR 96 | $(KUBE_CLIENT) apply -f sendgrid/ --validate=false -n $(NAMESPACE) 97 | 98 | sendgrid-delete: ## SENDGRID EXAMPLE - Delete: CR, CR-secret 99 | $(KUBE_CLIENT) delete -f sendgrid/ -n $(NAMESPACE) || true 100 | 101 | help: ## Print this help 102 | @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-33s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) 103 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Prometheus Exporter Examples 2 | 3 | Once the deployed prometheus-exporter operator is up and running and watching for any `PrometheusExporter` resource type, you can setup any prometheus exporter following the next examples: 4 | 5 | 1. [Memcached](#memcached) 6 | 1. [Redis](#redis) 7 | 1. [MySQL](#mysql) 8 | 1. [PostgreSQL](#postgresql) 9 | 1. [Sphinx](#sphinx) 10 | 1. [Elasticsearch](#elasticsearch) 11 | 1. [AWS CloudWatch](#aws-cloudwatch) 12 | 1. [Probe](#probe) 13 | 1. [Sendgrid](#sendgrid) 14 | 15 | ## Memcached 16 | 17 | - Official doc: https://github.com/prometheus/memcached_exporter 18 | 19 | ### Deploy example 20 | 21 | - Create `memcached-exporter` example ([example-DB](memcached/memcached-db-service.yaml), [example-CR](memcached/memcached-cr.yaml)): 22 | 23 | ```bash 24 | $ make memcached-create 25 | ``` 26 | 27 | - Once tested, delete created objects: 28 | 29 | ```bash 30 | $ make memcached-delete 31 | ``` 32 | 33 | ## Redis 34 | 35 | - Official doc: https://github.com/oliver006/redis_exporter 36 | 37 | ### Deploy example 38 | 39 | - Create `redis-exporter` example ([example-DB](redis/redis-db-service.yaml), [example-CR](redis/redis-cr.yaml), [example-CR-2](redis/redis-cr-2.yaml)): 40 | 41 | ```bash 42 | $ make redis-create 43 | ``` 44 | 45 | - Once tested, delete created objects: 46 | 47 | ```bash 48 | $ make redis-delete 49 | ``` 50 | 51 | ## MySQL 52 | 53 | - Official doc: https://github.com/prometheus/mysqld_exporter 54 | 55 | ### CR needed extra object 56 | 57 | - **The Secret should have been previously created as the operator expects it**: 58 | - **[mysql-secret-example](mysql/mysql-secret.yaml) (Remember to set object name on CR field `dbConnectionStringSecretName`)** 59 | 60 | ### Permission requirements 61 | 62 | - In addition, a database user with specific grants is needed _(this is just an example, go to the official doc for the latest information)_: 63 | 64 | ```sql 65 | CREATE USER 'exporter'@'%' IDENTIFIED BY 'XXXXXXXX' WITH MAX_USER_CONNECTIONS 3; 66 | GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%'; 67 | ``` 68 | 69 | > **NOTE** >
It is recommended to set a max connection limit for the user to avoid overloading the server with monitoring scrapes under heavy load. 70 | 71 | ### Deploy example 72 | 73 | - Create `mysql-exporter` example ([example-secret](mysql/mysql-secret.yaml), [example-DB](mysql/mysql-db-service.yaml), [example-CR](mysql/mysql-cr.yaml)): 74 | 75 | ```bash 76 | $ make mysql-create 77 | ``` 78 | 79 | - Once tested, delete created objects: 80 | 81 | ```bash 82 | $ make mysql-delete 83 | ``` 84 | 85 | ## PostgreSQL 86 | 87 | - Official doc: https://github.com/prometheus-community/postgres_exporter 88 | 89 | ### CR needed extra object 90 | 91 | - **The Secret should have been previously created as the operator expects it**: 92 | - **[postgresql-secret-example](postgresql/postgresql-secret.yaml) (Remember to set the object name on the CR field `dbConnectionStringSecretName`)** 93 | 94 | ### Permission requirements 95 | 96 | - To be able to collect metrics from `pg_stat*` views as non-superuser in PostgreSQL 97 | server versions >= 10 you can grant the `pg_monitor` or `pg_read_all_stats` [built-in roles](https://www.postgresql.org/docs/current/predefined-roles.html) to the `postgres_exporter` user. 98 | 99 | Run following command if you use PostgreSQL versions >= 10 100 | 101 | ```sql 102 | GRANT pg_monitor to postgres_exporter; 103 | ``` 104 | 105 | If you need to monitor older PostgreSQL servers, [check the official documentation](https://github.com/prometheus-community/postgres_exporter/blob/master/README.md). 106 | 107 | > **NOTE** >
Remember to use `postgres` database name in the connection string: 108 | > 109 | > ``` 110 | > DATA_SOURCE_NAME=postgresql://postgres_exporter:password@localhost:5432/postgres?sslmode=disable 111 | > ``` 112 | 113 | ### Deploy example 114 | 115 | - Create `postgresql-exporter` example ([example-secret](postgresql/postgresql-secret.yaml), [example-DB](postgresql/postgresql-db-service.yaml), [example-CR](postgresql/postgresql-cr.yaml)): 116 | 117 | ```bash 118 | $ make postgresql-create 119 | ``` 120 | 121 | - Once tested, delete created objects: 122 | 123 | ```bash 124 | $ make postgresql-delete 125 | ``` 126 | 127 | ## Sphinx 128 | 129 | - Official doc: https://github.com/foxdalas/sphinx_exporter 130 | 131 | ### Deploy example 132 | 133 | - **Make sure you have a Sphinx instance available, and dbHost/dbPort are correctly set on CR example file** 134 | - Create `sphinx-exporter` example ([example-CR](sphinx/sphinx-cr.yaml)): 135 | 136 | ```bash 137 | $ make sphinx-create 138 | ``` 139 | 140 | - Once tested, delete created objects: 141 | 142 | ```bash 143 | $ make sphinx-delete 144 | ``` 145 | 146 | ## Manticore 147 | 148 | - Official doc: https://github.com/manticoresoftware/manticoresearch-prometheus 149 | 150 | ### Deploy example 151 | 152 | - **Make sure you have a Manticore instance available, and dbHost/dbPort are correctly set on CR example file** 153 | - Create `manticore-exporter` example ([example-CR](manticore/manticore-cr.yaml)): 154 | 155 | ```bash 156 | $ make manticore-create 157 | ``` 158 | 159 | - Once tested, delete created objects: 160 | 161 | ```bash 162 | $ make manticore-delete 163 | ``` 164 | 165 | ## Elasticsearch 166 | 167 | - Official doc: https://github.com/prometheus-community/elasticsearch_exporter 168 | 169 | ### Deploy example 170 | 171 | - **Make sure you have an Elasticsearch cluster available and that dbHost/dbPort are correctly set on CR example file** 172 | - Create `elasticsearch-exporter` example ([example-CR](elasticsearch/es-cr.yaml)): 173 | 174 | ```bash 175 | $ make elasticsearch-create 176 | ``` 177 | 178 | - Once tested, delete created objects: 179 | 180 | ```bash 181 | $ make elasticsearch-delete 182 | ``` 183 | 184 | ## AWS CloudWatch 185 | 186 | - Official doc: https://github.com/prometheus/cloudwatch_exporter 187 | > **NOTE** >
The metrics from some services like `AWSClientVPN` are reported to AWS CloudWatch every **5 minutes** (instead of default **1 minute**), because they are not critical services like databases (RDS/EC) where details are more important. So on thoses cases, scrapping AWS Cloudwatch metrics every 1 minute makes no sense, so it is better to specify the var `period_seconds: 300` (instead of default `period_seconds: 60`) in the metric definition in the configmap. In addition, for those cases reporting metrics every 5 minutes, empty spaces (null values) could appear empty in the prometheus time series database, so in order to configure alerts, you can use queries like `max_over_time(aws_clientvpn_crl_days_to_expiry_average[10m]) < 2`, which takes max value within last 10 minutes, so we guarantee there is always a value that can fire an alert that won't disappear from time to time although alert might not be really recovered. 188 | 189 | ### CR needed extra objects 190 | 191 | - **The Secret/ConfigMap should have been previously created as the operator expects them**: 192 | - **[cw-secret-example](cloudwatch/cloudwatch-secret.yaml) (Remember to set the object name on the CR field `awsCredentialsSecretName`)** 193 | - **[cw-configmap-example](cloudwatch/cloudwatch-configmap.yaml) (Remember to set the object name on the CR field `configurationConfigmapName`)** 194 | 195 | ### Permission requirements 196 | 197 | - In addition, the created IAM user requires some specific IAM permissions: 198 | - `cloudwatch:ListMetrics` 199 | - `cloudwatch:GetMetricStatistics` 200 | - `tag:GetResources` 201 | 202 | ### Deploy example 203 | 204 | - Create `cloudwatch-exporter` example ([example-secret](cloudwatch/cloudwatch-secret.yaml), [example-configmap](cloudwatch/cloudwatch-configmap.yaml), [example-CR](cloudwatch/cloudwatch-cr.yaml)): 205 | 206 | ```bash 207 | $ make cloudwatch-create 208 | ``` 209 | 210 | - Once tested, delete the created objects: 211 | 212 | ```bash 213 | $ make cloudwatch-delete 214 | ``` 215 | 216 | ## Probe 217 | 218 | - Official doc: https://github.com/prometheus/blackbox_exporter 219 | 220 | ### CR needed extra object 221 | 222 | - **The ConfigMap should have been previously created as the operator expects it**: 223 | - **[probe-configmap-example](probe/probe-configmap.yaml) (Remember to set the object name on the CR field `configurationConfigmapName`)** 224 | - **The optional Secret (replacing previous ConfigMap) should have been previously created as the operator expects it (in case config includes sensitive data and so you prefer to use a Secret** 225 | - **[probe-secret-example](probe/probe-secret.yaml) (Remember to set the object name on the CR field `configurationSecretName` replacing previous `configurationConfigmapName`)** 226 | 227 | > **NOTE** >
To deploy a probe exporter (blackbox exporter) it is just needed the configmap (or secret) with blackbox modules configuration, and a single `PrometheusExporter` custom resource of type `probe`. But then, in order to be able to scrape different targets, you need to deploy for every endpoint that you want to monitor, a prometheus `Probe` resource with the `prober.url` pointing to the deployed probe exporter service `prometheus-exporter-probe-${CR_NAME}.${NAMESPACE}.svc:9115`, and then configure the specific module and target. 228 | 229 | ### Target Probe extra objects 230 | 231 | - **[probe-target-probe-example](probe/probe-target-probe.yaml) (Remember to set the `prober.url` pointing to the deployed probe exporter service `prometheus-exporter-probe-${CR_NAME}.${NAMESPACE}.svc:9115`)** 232 | 233 | ### Deploy example 234 | 235 | - Create `probe-exporter` example ([example-configmap](probe/probe-configmap.yaml), [example-CR](probe/probe-cr.yaml), [example-target-probe](probe/probe-target-probe.yaml)): 236 | 237 | ```bash 238 | $ make probe-create 239 | ``` 240 | 241 | - Once tested, delete the created objects: 242 | 243 | ```bash 244 | $ make probe-delete 245 | ``` 246 | 247 | ## Sendgrid 248 | 249 | - Official doc: https://github.com/chatwork/sendgrid-stats-exporter 250 | 251 | ### CR needed extra object 252 | 253 | - **The Secret should have been previously created as the operator expects it**: 254 | - **[sendgrid-secret-example](sendgrid/sendgrid-secret.yaml) (Remember to set the object name on the CR field `sendgridCredentialsSecretName`)** 255 | 256 | ### Deploy example 257 | 258 | - Create `sendgrid-exporter` example ([example-secret](sendgrid/sendgrid-secret.yaml), [example-CR](sendgrid/sendgrid-cr.yaml)): 259 | 260 | ```bash 261 | $ make sendgrid-create 262 | ``` 263 | 264 | - Once tested, delete the created objects: 265 | 266 | ```bash 267 | $ make sendgrid-delete 268 | ``` 269 | -------------------------------------------------------------------------------- /examples/cloudwatch/cloudwatch-configmap.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: prometheus-exporter-cloudwatch-staging-aws-cw 6 | data: 7 | config.yml: | 8 | --- 9 | region: us-east-1 10 | delay_seconds: 120 11 | range_seconds: 120 12 | metrics: 13 | - aws_namespace: AWS/ElastiCache 14 | aws_metric_name: CPUUtilization 15 | aws_dimensions: [CacheClusterId] 16 | aws_statistics: [Average] 17 | - aws_namespace: AWS/ElastiCache 18 | aws_metric_name: FreeableMemory 19 | aws_dimensions: [CacheClusterId] 20 | aws_statistics: [Average] 21 | - aws_namespace: AWS/ElastiCache 22 | aws_metric_name: NetworkBytesIn 23 | aws_dimensions: [CacheClusterId] 24 | aws_statistics: [Average] 25 | - aws_namespace: AWS/ElastiCache 26 | aws_metric_name: NetworkBytesOut 27 | aws_dimensions: [CacheClusterId] 28 | aws_statistics: [Average] 29 | - aws_namespace: AWS/ElastiCache 30 | aws_metric_name: SwapUsage 31 | aws_dimensions: [CacheClusterId] 32 | aws_statistics: [Average] 33 | - aws_namespace: AWS/ElastiCache 34 | aws_metric_name: CurrConnections 35 | aws_dimensions: [CacheClusterId] 36 | aws_statistics: [Average] 37 | - aws_namespace: AWS/ElastiCache 38 | aws_metric_name: Evictions 39 | aws_dimensions: [CacheClusterId] 40 | aws_statistics: [Average] 41 | - aws_namespace: AWS/ElastiCache 42 | aws_metric_name: CurrItems 43 | aws_dimensions: [CacheClusterId] 44 | aws_statistics: [Average] 45 | - aws_namespace: AWS/RDS 46 | aws_metric_name: FreeStorageSpace 47 | aws_dimensions: [DBInstanceIdentifier] 48 | aws_statistics: [Average] 49 | - aws_namespace: AWS/RDS 50 | aws_metric_name: CPUUtilization 51 | aws_dimensions: [DBInstanceIdentifier] 52 | aws_statistics: [Average] 53 | - aws_namespace: AWS/RDS 54 | aws_metric_name: FreeableMemory 55 | aws_dimensions: [DBInstanceIdentifier] 56 | aws_statistics: [Average] 57 | - aws_namespace: AWS/RDS 58 | aws_metric_name: DatabaseConnections 59 | aws_dimensions: [DBInstanceIdentifier] 60 | aws_statistics: [Average] 61 | - aws_namespace: AWS/ES 62 | aws_metric_name: ClusterStatus.green 63 | aws_dimensions: [DomainName, ClientId] 64 | aws_statistics: [Maximum] 65 | - aws_namespace: AWS/ES 66 | aws_metric_name: ClusterStatus.yellow 67 | aws_dimensions: [DomainName, ClientId] 68 | aws_statistics: [Maximum] 69 | - aws_namespace: AWS/ES 70 | aws_metric_name: ClusterStatus.red 71 | aws_dimensions: [DomainName, ClientId] 72 | aws_statistics: [Maximum] 73 | - aws_namespace: AWS/ES 74 | aws_metric_name: Nodes 75 | aws_dimensions: [DomainName, ClientId] 76 | aws_statistics: [Maximum] 77 | - aws_namespace: AWS/ES 78 | aws_metric_name: AutomatedSnapshotFailure 79 | aws_dimensions: [DomainName, ClientId] 80 | aws_statistics: [Maximum] 81 | - aws_namespace: AWS/ES 82 | aws_metric_name: FreeStorageSpace 83 | aws_dimensions: [DomainName, ClientId] 84 | aws_statistics: [Sum] 85 | - aws_namespace: AWS/ES 86 | aws_metric_name: FreeStorageSpace 87 | aws_dimensions: [DomainName, ClientId, NodeId] 88 | aws_statistics: [Minimum] 89 | - aws_namespace: AWS/ES 90 | aws_metric_name: CPUUtilization 91 | aws_dimensions: [DomainName, ClientId, NodeId] 92 | aws_statistics: [Maximum] 93 | - aws_namespace: AWS/ES 94 | aws_metric_name: JVMMemoryPressure 95 | aws_dimensions: [DomainName, ClientId, NodeId] 96 | aws_statistics: [Maximum] 97 | - aws_namespace: AWS/ES 98 | aws_metric_name: MasterFreeStorageSpace 99 | aws_dimensions: [DomainName, ClientId, NodeId] 100 | aws_statistics: [Minimum] 101 | - aws_namespace: AWS/ES 102 | aws_metric_name: MasterCPUUtilization 103 | aws_dimensions: [DomainName, ClientId, NodeId] 104 | aws_statistics: [Maximum] 105 | - aws_namespace: AWS/ES 106 | aws_metric_name: MasterJVMMemoryPressure 107 | aws_dimensions: [DomainName, ClientId, NodeId] 108 | aws_statistics: [Maximum] 109 | - aws_namespace: AWS/ApplicationELB 110 | aws_metric_name: HealthyHostCount 111 | aws_dimensions: [LoadBalancer, TargetGroup] 112 | aws_statistics: [Average] 113 | - aws_namespace: AWS/ApplicationELB 114 | aws_metric_name: UnHealthyHostCount 115 | aws_dimensions: [LoadBalancer, TargetGroup] 116 | aws_statistics: [Average] 117 | - aws_namespace: AWS/ApplicationELB 118 | aws_metric_name: HTTPCode_Target_2XX_Count 119 | aws_dimensions: [LoadBalancer, TargetGroup] 120 | aws_statistics: [Sum] 121 | - aws_namespace: AWS/ApplicationELB 122 | aws_metric_name: HTTPCode_Target_3XX_Count 123 | aws_dimensions: [LoadBalancer, TargetGroup] 124 | aws_statistics: [Sum] 125 | - aws_namespace: AWS/ApplicationELB 126 | aws_metric_name: HTTPCode_Target_4XX_Count 127 | aws_dimensions: [LoadBalancer, TargetGroup] 128 | aws_statistics: [Sum] 129 | - aws_namespace: AWS/ApplicationELB 130 | aws_metric_name: HTTPCode_Target_5XX_Count 131 | aws_dimensions: [LoadBalancer, TargetGroup] 132 | aws_statistics: [Sum] 133 | - aws_namespace: AWS/ApplicationELB 134 | aws_metric_name: TargetResponseTime 135 | aws_dimensions: [LoadBalancer, TargetGroup] 136 | aws_statistics: [Average] 137 | - aws_namespace: AWS/ApplicationELB 138 | aws_metric_name: RequestCount 139 | aws_dimensions: [LoadBalancer, TargetGroup] 140 | aws_statistics: [Sum] 141 | - aws_namespace: AWS/NetworkELB 142 | aws_metric_name: HealthyHostCount 143 | aws_dimensions: [LoadBalancer, TargetGroup] 144 | aws_statistics: [Average] 145 | - aws_namespace: AWS/NetworkELB 146 | aws_metric_name: UnHealthyHostCount 147 | aws_dimensions: [LoadBalancer, TargetGroup] 148 | aws_statistics: [Average] 149 | - aws_namespace: AWS/NetworkELB 150 | aws_metric_name: ActiveFlowCount 151 | aws_dimensions: [LoadBalancer] 152 | aws_statistics: [Sum] 153 | - aws_namespace: AWS/NetworkELB 154 | aws_metric_name: NewFlowCount 155 | aws_dimensions: [LoadBalancer] 156 | aws_statistics: [Sum] 157 | - aws_namespace: AWS/ELB 158 | aws_metric_name: HealthyHostCount 159 | aws_dimensions: [LoadBalancerName] 160 | aws_statistics: [Average] 161 | - aws_namespace: AWS/ELB 162 | aws_metric_name: UnHealthyHostCount 163 | aws_dimensions: [LoadBalancerName] 164 | aws_statistics: [Average] 165 | - aws_namespace: AWS/ELB 166 | aws_metric_name: RequestCount 167 | aws_dimensions: [LoadBalancerName] 168 | aws_statistics: [Sum] 169 | - aws_namespace: AWS/ELB 170 | aws_metric_name: Latency 171 | aws_dimensions: [LoadBalancerName] 172 | aws_statistics: [Average] 173 | - aws_namespace: AWS/ELB 174 | aws_metric_name: HTTPCode_Backend_2XX 175 | aws_dimensions: [LoadBalancerName] 176 | aws_statistics: [Sum] 177 | - aws_namespace: AWS/ELB 178 | aws_metric_name: HTTPCode_Backend_3XX 179 | aws_dimensions: [LoadBalancerName] 180 | aws_statistics: [Sum] 181 | - aws_namespace: AWS/ELB 182 | aws_metric_name: HTTPCode_Backend_4XX 183 | aws_dimensions: [LoadBalancerName] 184 | aws_statistics: [Sum] 185 | - aws_namespace: AWS/ELB 186 | aws_metric_name: HTTPCode_Backend_5XX 187 | aws_dimensions: [LoadBalancerName] 188 | aws_statistics: [Sum] 189 | - aws_namespace: AWS/ClientVPN 190 | aws_metric_name: CrlDaysToExpiry 191 | aws_dimensions: [Endpoint] 192 | aws_statistics: [Average] 193 | period_seconds: 300 194 | - aws_namespace: AWS/ClientVPN 195 | aws_metric_name: ActiveConnectionsCount 196 | aws_dimensions: [Endpoint] 197 | aws_statistics: [Average] 198 | period_seconds: 300 199 | - aws_namespace: AWS/ClientVPN 200 | aws_metric_name: AuthenticationFailures 201 | aws_dimensions: [Endpoint] 202 | aws_statistics: [Average] 203 | period_seconds: 300 204 | - aws_namespace: AWS/ClientVPN 205 | aws_metric_name: IngressBytes 206 | aws_dimensions: [Endpoint] 207 | aws_statistics: [Average] 208 | period_seconds: 300 209 | - aws_namespace: AWS/ClientVPN 210 | aws_metric_name: EgressBytes 211 | aws_dimensions: [Endpoint] 212 | aws_statistics: [Average] 213 | period_seconds: 300 -------------------------------------------------------------------------------- /examples/cloudwatch/cloudwatch-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-aws-cw 5 | spec: 6 | type: cloudwatch 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | awsCredentialsSecretName: prometheus-exporter-cloudwatch-staging-aws-cw 12 | configurationConfigmapName: prometheus-exporter-cloudwatch-staging-aws-cw 13 | -------------------------------------------------------------------------------- /examples/cloudwatch/cloudwatch-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: prometheus-exporter-cloudwatch-staging-aws-cw 5 | type: Opaque 6 | stringData: 7 | AWS_ACCESS_KEY_ID: "XXX_YOUR_AWS_ACCESS_KEY_ID_XXX" 8 | AWS_SECRET_ACCESS_KEY: "XXXXXXXX-YOUR_AWS_SECRET_ACCESS_KEY-XXXXXXX" 9 | -------------------------------------------------------------------------------- /examples/elasticsearch/es-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-es 5 | spec: 6 | type: es 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | dbHost: https://vpc-staging-es.us-east-1.es.amazonaws.com 12 | dbPort: 443 13 | -------------------------------------------------------------------------------- /examples/manticore/manticore-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-system-searchd 5 | spec: 6 | type: manticore 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | extraLabel: 12 | key: threescale_component 13 | value: system 14 | dbHost: system-searchd 15 | dbPort: 9306 16 | -------------------------------------------------------------------------------- /examples/memcached/memcached-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-system-memcached 5 | spec: 6 | type: memcached 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | extraLabel: 12 | key: threescale_component 13 | value: system 14 | dbHost: system-memcache 15 | dbPort: 11211 16 | -------------------------------------------------------------------------------- /examples/memcached/memcached-db-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: StatefulSet 4 | metadata: 5 | name: memcached 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: memcached 10 | serviceName: memcached 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: memcached 16 | spec: 17 | containers: 18 | - name: memcached 19 | image: memcached:1.5 20 | resources: 21 | requests: 22 | cpu: 100m 23 | memory: 100Mi 24 | limits: 25 | cpu: 200m 26 | memory: 200Mi 27 | ports: 28 | - containerPort: 11211 29 | name: memcached 30 | --- 31 | apiVersion: v1 32 | kind: Service 33 | metadata: 34 | name: system-memcache 35 | labels: 36 | app: memcached 37 | spec: 38 | type: ClusterIP 39 | ports: 40 | - port: 11211 41 | targetPort: 11211 42 | name: memcached 43 | selector: 44 | app: memcached 45 | -------------------------------------------------------------------------------- /examples/mysql/mysql-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-system-mysql 5 | spec: 6 | type: mysql 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | extraLabel: 12 | key: threescale_component 13 | value: system 14 | dbConnectionStringSecretName: prometheus-exporter-mysql-staging-system-mysql 15 | -------------------------------------------------------------------------------- /examples/mysql/mysql-db-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: StatefulSet 4 | metadata: 5 | name: mysql-server 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: mysql-server 10 | serviceName: mysql-server 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql-server 16 | spec: 17 | containers: 18 | - name: mysql-server 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ALLOW_EMPTY_PASSWORD 22 | value: "yes" 23 | readinessProbe: 24 | tcpSocket: 25 | port: 3306 26 | resources: 27 | requests: 28 | cpu: 100m 29 | memory: 100Mi 30 | limits: 31 | cpu: 200m 32 | memory: 512Mi 33 | ports: 34 | - containerPort: 3306 35 | volumeMounts: 36 | - mountPath: /var/lib/mysql 37 | name: mysql-vol 38 | volumes: 39 | - name: mysql-vol 40 | emptyDir: {} 41 | --- 42 | apiVersion: v1 43 | kind: Service 44 | metadata: 45 | name: system-mysql 46 | spec: 47 | ports: 48 | - name: mysql-server 49 | port: 3306 50 | targetPort: 3306 51 | protocol: TCP 52 | selector: 53 | app: mysql-server 54 | -------------------------------------------------------------------------------- /examples/mysql/mysql-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: prometheus-exporter-mysql-staging-system-mysql 5 | type: Opaque 6 | stringData: 7 | DATA_SOURCE_NAME: "exporter:123456789@(system-mysql:3306)/" 8 | -------------------------------------------------------------------------------- /examples/postgresql/postgresql-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-zync-postgresql 5 | spec: 6 | type: postgresql 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | extraLabel: 12 | key: threescale_component 13 | value: zync 14 | dbConnectionStringSecretName: prometheus-exporter-postgresql-staging-zync-postgresql 15 | -------------------------------------------------------------------------------- /examples/postgresql/postgresql-db-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: StatefulSet 4 | metadata: 5 | name: postgresql-server 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: postgresql-server 10 | serviceName: postgresql-server 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: postgresql-server 16 | spec: 17 | containers: 18 | - name: postgresql-server 19 | image: postgres:9.6 20 | env: 21 | - name: POSTGRES_USER 22 | value: postgres_exporter 23 | - name: POSTGRES_PASSWORD 24 | value: "123456789" 25 | - name: POSTGRES_DB 26 | value: postgres_exporter 27 | - name: PGDATA 28 | value: /var/lib/postgresql/data/pgdata 29 | resources: 30 | requests: 31 | cpu: 100m 32 | memory: 100Mi 33 | limits: 34 | cpu: 200m 35 | memory: 200Mi 36 | ports: 37 | - containerPort: 5432 38 | volumeMounts: 39 | - mountPath: /var/lib/postgresql/data 40 | name: pg-data 41 | volumes: 42 | - name: pg-data 43 | emptyDir: {} 44 | --- 45 | apiVersion: v1 46 | kind: Service 47 | metadata: 48 | name: zync-database 49 | spec: 50 | ports: 51 | - name: postgresql-server 52 | port: 5432 53 | targetPort: 5432 54 | protocol: TCP 55 | selector: 56 | app: postgresql-server 57 | -------------------------------------------------------------------------------- /examples/postgresql/postgresql-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: prometheus-exporter-postgresql-staging-zync-postgresql 5 | type: Opaque 6 | stringData: 7 | DATA_SOURCE_NAME: "postgresql://postgres_exporter:123456789@zync-database:5432/postgres?sslmode=disable" 8 | -------------------------------------------------------------------------------- /examples/probe/probe-configmap.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: prometheus-exporter-probe-staging-blackbox 6 | data: 7 | config.yml: | 8 | modules: 9 | http_2xx: 10 | prober: http 11 | timeout: 5s 12 | http: 13 | method: GET 14 | no_follow_redirects: false 15 | fail_if_ssl: false 16 | fail_if_not_ssl: false 17 | tls_config: 18 | insecure_skip_verify: false 19 | preferred_ip_protocol: "ip4" # defaults to "ip6" 20 | ip_protocol_fallback: false # no fallback to "ip6" 21 | tcp_connect: 22 | prober: tcp 23 | timeout: 5s -------------------------------------------------------------------------------- /examples/probe/probe-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-blackbox 5 | spec: 6 | type: probe 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | configurationConfigmapName: prometheus-exporter-probe-staging-blackbox 12 | -------------------------------------------------------------------------------- /examples/probe/probe-secret.yaml: -------------------------------------------------------------------------------- 1 | # In case you don't want to use a Configmap for the blackbox modules config.yml because it might contain sensitive data like keys... 2 | # you can use a Secret instead, and so specify the Secret name on CR field configurationSecretName (instead of using configurationConfigmapName) 3 | --- 4 | apiVersion: v1 5 | kind: Secret 6 | metadata: 7 | name: prometheus-exporter-probe-staging-blackbox 8 | stringData: 9 | config.yml: | 10 | modules: 11 | http_2xx: 12 | prober: http 13 | timeout: 5s 14 | http: 15 | method: GET 16 | no_follow_redirects: false 17 | fail_if_ssl: false 18 | fail_if_not_ssl: false 19 | tls_config: 20 | insecure_skip_verify: false 21 | preferred_ip_protocol: "ip4" # defaults to "ip6" 22 | ip_protocol_fallback: false # no fallback to "ip6" 23 | tcp_connect: 24 | prober: tcp 25 | timeout: 5s -------------------------------------------------------------------------------- /examples/probe/probe-target-probe.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: Probe 3 | metadata: 4 | name: prometheus-exporter-probe-http-kubernetes-io 5 | spec: 6 | module: http_2xx 7 | prober: 8 | url: prometheus-exporter-probe-staging-blackbox.prometheus-exporter-operator-system.svc:9115 9 | targets: 10 | staticConfig: 11 | static: 12 | - https://kubernetes.io -------------------------------------------------------------------------------- /examples/redis/redis-cr-2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-system-redis 5 | spec: 6 | type: redis 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | extraLabel: 12 | key: threescale_component 13 | value: system 14 | dbHost: system-redis 15 | dbPort: 6379 16 | dbCheckKeys: "db1=queue:backend_sync,db1=queue:billing,db1=queue:critical,db1=queue:default,db1=queue:deletion,db1=queue:events,db1=queue:low,db1=queue:priority,db1=queue:web_hooks,db1=queue:zync" 17 | -------------------------------------------------------------------------------- /examples/redis/redis-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-backend-redis 5 | spec: 6 | type: redis 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | extraLabel: 12 | key: threescale_component 13 | value: backend 14 | dbHost: backend-redis 15 | dbPort: 6379 16 | dbCheckKeys: "db1=resque:queue:stats,db1=resque:queue:priority,db1=resque:queue:main,db1=resque:failed" 17 | -------------------------------------------------------------------------------- /examples/redis/redis-db-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: StatefulSet 4 | metadata: 5 | name: redis-server 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: redis-server 10 | serviceName: redis-server 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: redis-server 16 | spec: 17 | containers: 18 | - name: redis-server 19 | image: redis:6.2.6 20 | resources: 21 | requests: 22 | cpu: 100m 23 | memory: 100Mi 24 | limits: 25 | cpu: 200m 26 | memory: 200Mi 27 | ports: 28 | - containerPort: 6379 29 | name: redis-server 30 | livenessProbe: 31 | initialDelaySeconds: 30 32 | periodSeconds: 10 33 | timeoutSeconds: 5 34 | successThreshold: 1 35 | failureThreshold: 5 36 | exec: 37 | command: 38 | - redis-cli 39 | - ping 40 | readinessProbe: 41 | initialDelaySeconds: 5 42 | periodSeconds: 10 43 | timeoutSeconds: 1 44 | successThreshold: 1 45 | failureThreshold: 5 46 | exec: 47 | command: 48 | - redis-cli 49 | - ping 50 | --- 51 | apiVersion: v1 52 | kind: Service 53 | metadata: 54 | name: backend-redis 55 | labels: 56 | app: redis-server 57 | spec: 58 | type: ClusterIP 59 | ports: 60 | - port: 6379 61 | targetPort: 6379 62 | name: redis-server 63 | selector: 64 | app: redis-server 65 | --- 66 | apiVersion: v1 67 | kind: Service 68 | metadata: 69 | name: system-redis 70 | labels: 71 | app: redis-server 72 | spec: 73 | type: ClusterIP 74 | ports: 75 | - port: 6379 76 | targetPort: 6379 77 | name: redis-server 78 | selector: 79 | app: redis-server 80 | -------------------------------------------------------------------------------- /examples/sendgrid/sendgrid-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: production 5 | spec: 6 | type: sendgrid 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | sendgridCredentialsSecretName: prometheus-exporter-sendgrid-production 12 | -------------------------------------------------------------------------------- /examples/sendgrid/sendgrid-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: prometheus-exporter-sendgrid-production 5 | type: Opaque 6 | stringData: 7 | SENDGRID_USER_NAME: "username" 8 | SENDGRID_API_KEY: "apikey" -------------------------------------------------------------------------------- /examples/sphinx/sphinx-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: staging-system-sphinx 5 | spec: 6 | type: sphinx 7 | grafanaDashboard: 8 | label: 9 | key: discovery 10 | value: enabled 11 | extraLabel: 12 | key: threescale_component 13 | value: system 14 | dbHost: system-sphinx 15 | dbPort: 9306 16 | -------------------------------------------------------------------------------- /hack/new-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | REPO="3scale-sre/prometheus-exporter-operator" 4 | 5 | # Skip if alpha release 6 | [[ ${1} == *"-alpha"* ]] && echo "" && exit 0 7 | 8 | # Skip if release already exists 9 | curl -o /dev/null --fail --silent "https://api.github.com/repos/${REPO}/releases/tags/${1}" && echo "" && exit 0 10 | 11 | echo ${1} 12 | -------------------------------------------------------------------------------- /img/example-cloudwatch-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-cloudwatch-dashboard.png -------------------------------------------------------------------------------- /img/example-es-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-es-dashboard.png -------------------------------------------------------------------------------- /img/example-manticore-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-manticore-dashboard.png -------------------------------------------------------------------------------- /img/example-memcached-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-memcached-dashboard.png -------------------------------------------------------------------------------- /img/example-mysql-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-mysql-dashboard.png -------------------------------------------------------------------------------- /img/example-postgresql-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-postgresql-dashboard.png -------------------------------------------------------------------------------- /img/example-probe-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-probe-dashboard.png -------------------------------------------------------------------------------- /img/example-redis-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-redis-dashboard.png -------------------------------------------------------------------------------- /img/example-sendgrid-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-sendgrid-dashboard.png -------------------------------------------------------------------------------- /img/example-sphinx-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/img/example-sphinx-dashboard.png -------------------------------------------------------------------------------- /img/prometheus-exporter-operator-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 21 | 23 | 24 | 26 | image/svg+xml 27 | 29 | 30 | 31 | 32 | 34 | 56 | 61 | 66 | 71 | 72 | -------------------------------------------------------------------------------- /kuttl-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestSuite 3 | timeout: 120 4 | testDirs: 5 | - ./test/e2e/ -------------------------------------------------------------------------------- /molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: localhost 4 | connection: local 5 | gather_facts: no 6 | collections: 7 | - kubernetes.core 8 | 9 | tasks: 10 | - name: Create Namespace 11 | k8s: 12 | api_version: v1 13 | kind: Namespace 14 | name: '{{ namespace }}' 15 | 16 | - import_tasks: kustomize.yml 17 | vars: 18 | state: present 19 | -------------------------------------------------------------------------------- /molecule/default/create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | tasks: [] 7 | -------------------------------------------------------------------------------- /molecule/default/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Destroy 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | collections: 7 | - kubernetes.core 8 | 9 | tasks: 10 | - import_tasks: kustomize.yml 11 | vars: 12 | state: absent 13 | 14 | - name: Destroy Namespace 15 | k8s: 16 | api_version: v1 17 | kind: Namespace 18 | name: '{{ namespace }}' 19 | state: absent 20 | 21 | - name: Unset pull policy 22 | command: '{{ kustomize }} edit remove patch pull_policy/{{ operator_pull_policy }}.yaml' 23 | args: 24 | chdir: '{{ config_dir }}/testing' 25 | -------------------------------------------------------------------------------- /molecule/default/kustomize.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Build kustomize testing overlay 3 | # load_restrictor must be set to none so we can load patch files from the default overlay 4 | command: '{{ kustomize }} build --load-restrictor LoadRestrictionsNone' 5 | args: 6 | chdir: '{{ config_dir }}/testing' 7 | register: resources 8 | changed_when: false 9 | 10 | - name: Set resources to {{ state }} 11 | k8s: 12 | definition: '{{ item }}' 13 | state: '{{ state }}' 14 | wait: no 15 | loop: '{{ resources.stdout | from_yaml_all | list }}' 16 | 17 | - name: Wait for resources to get to {{ state }} 18 | k8s: 19 | definition: '{{ item }}' 20 | state: '{{ state }}' 21 | wait: yes 22 | loop: '{{ resources.stdout | from_yaml_all | list }}' 23 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: delegated 6 | lint: | 7 | set -e 8 | yamllint -d "{extends: relaxed, rules: {line-length: {max: 120}}}" . 9 | platforms: 10 | - name: cluster 11 | groups: 12 | - k8s 13 | provisioner: 14 | name: ansible 15 | lint: | 16 | set -e 17 | ansible-lint 18 | inventory: 19 | group_vars: 20 | all: 21 | namespace: ${TEST_OPERATOR_NAMESPACE:-osdk-test} 22 | host_vars: 23 | localhost: 24 | ansible_python_interpreter: '{{ ansible_playbook_python }}' 25 | config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config 26 | samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples 27 | operator_image: ${OPERATOR_IMAGE:-""} 28 | operator_pull_policy: ${OPERATOR_PULL_POLICY:-"Always"} 29 | kustomize: ${KUSTOMIZE_PATH:-kustomize} 30 | env: 31 | K8S_AUTH_KUBECONFIG: ${KUBECONFIG:-"~/.kube/config"} 32 | verifier: 33 | name: ansible 34 | lint: | 35 | set -e 36 | ansible-lint 37 | -------------------------------------------------------------------------------- /molecule/default/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Ensure operator image is set 9 | fail: 10 | msg: | 11 | You must specify the OPERATOR_IMAGE environment variable in order to run the 12 | 'default' scenario 13 | when: not operator_image 14 | 15 | - name: Set testing image 16 | command: '{{ kustomize }} edit set image testing={{ operator_image }}' 17 | args: 18 | chdir: '{{ config_dir }}/testing' 19 | 20 | - name: Set pull policy 21 | command: '{{ kustomize }} edit add patch --path pull_policy/{{ operator_pull_policy }}.yaml' 22 | args: 23 | chdir: '{{ config_dir }}/testing' 24 | 25 | - name: Set testing namespace 26 | command: '{{ kustomize }} edit set namespace {{ namespace }}' 27 | args: 28 | chdir: '{{ config_dir }}/testing' 29 | -------------------------------------------------------------------------------- /molecule/default/tasks/prometheusexporter_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create the monitoring.3scale.net/v1alpha1.PrometheusExporter 3 | k8s: 4 | state: present 5 | namespace: '{{ namespace }}' 6 | definition: "{{ lookup('template', '/'.join([samples_dir, cr_file])) | from_yaml }}" 7 | wait: yes 8 | wait_timeout: 300 9 | wait_condition: 10 | type: Successful 11 | status: "True" 12 | vars: 13 | cr_file: 'monitoring_v1alpha1_prometheusexporter.yaml' 14 | 15 | - name: Add assertions here 16 | assert: 17 | that: false 18 | fail_msg: FIXME Add real assertions for your operator 19 | -------------------------------------------------------------------------------- /molecule/default/verify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Verify 3 | hosts: localhost 4 | connection: local 5 | gather_facts: no 6 | collections: 7 | - kubernetes.core 8 | 9 | vars: 10 | ctrl_label: control-plane=controller-manager 11 | 12 | tasks: 13 | - block: 14 | - name: Import all test files from tasks/ 15 | include_tasks: '{{ item }}' 16 | with_fileglob: 17 | - tasks/*_test.yml 18 | rescue: 19 | - name: Retrieve relevant resources 20 | k8s_info: 21 | api_version: '{{ item.api_version }}' 22 | kind: '{{ item.kind }}' 23 | namespace: '{{ namespace }}' 24 | loop: 25 | - api_version: v1 26 | kind: Pod 27 | - api_version: apps/v1 28 | kind: Deployment 29 | - api_version: v1 30 | kind: Secret 31 | - api_version: v1 32 | kind: ConfigMap 33 | register: debug_resources 34 | 35 | - name: Retrieve Pod logs 36 | k8s_log: 37 | name: '{{ item.metadata.name }}' 38 | namespace: '{{ namespace }}' 39 | container: manager 40 | loop: "{{ q('k8s', api_version='v1', kind='Pod', namespace=namespace, label_selector=ctrl_label) }}" 41 | register: debug_logs 42 | 43 | - name: Output gathered resources 44 | debug: 45 | var: debug_resources 46 | 47 | - name: Output gathered logs 48 | debug: 49 | var: item.log_lines 50 | loop: '{{ debug_logs.results }}' 51 | 52 | - name: Re-emit failure 53 | vars: 54 | failed_task: 55 | result: '{{ ansible_failed_result }}' 56 | fail: 57 | msg: '{{ failed_task }}' 58 | -------------------------------------------------------------------------------- /molecule/kind/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: localhost 4 | connection: local 5 | gather_facts: no 6 | 7 | tasks: 8 | - name: Build operator image 9 | docker_image: 10 | build: 11 | path: '{{ project_dir }}' 12 | pull: no 13 | name: '{{ operator_image }}' 14 | tag: latest 15 | push: no 16 | source: build 17 | force_source: yes 18 | 19 | - name: Load image into kind cluster 20 | command: kind load docker-image --name osdk-test '{{ operator_image }}' 21 | register: result 22 | changed_when: '"not yet present" in result.stdout' 23 | 24 | - import_playbook: ../default/converge.yml 25 | -------------------------------------------------------------------------------- /molecule/kind/create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | tasks: 7 | - name: Create test kind cluster 8 | command: kind create cluster --name osdk-test --kubeconfig {{ kubeconfig }} 9 | -------------------------------------------------------------------------------- /molecule/kind/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Destroy 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | collections: 7 | - kubernetes.core 8 | 9 | tasks: 10 | - name: Destroy test kind cluster 11 | command: kind delete cluster --name osdk-test --kubeconfig {{ kubeconfig }} 12 | 13 | - name: Unset pull policy 14 | command: '{{ kustomize }} edit remove patch pull_policy/{{ operator_pull_policy }}.yaml' 15 | args: 16 | chdir: '{{ config_dir }}/testing' 17 | -------------------------------------------------------------------------------- /molecule/kind/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: delegated 6 | lint: | 7 | set -e 8 | yamllint -d "{extends: relaxed, rules: {line-length: {max: 120}}}" . 9 | platforms: 10 | - name: cluster 11 | groups: 12 | - k8s 13 | provisioner: 14 | name: ansible 15 | playbooks: 16 | prepare: ../default/prepare.yml 17 | verify: ../default/verify.yml 18 | lint: | 19 | set -e 20 | ansible-lint 21 | inventory: 22 | group_vars: 23 | all: 24 | namespace: ${TEST_OPERATOR_NAMESPACE:-osdk-test} 25 | host_vars: 26 | localhost: 27 | ansible_python_interpreter: '{{ ansible_playbook_python }}' 28 | config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config 29 | samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples 30 | project_dir: ${MOLECULE_PROJECT_DIRECTORY} 31 | operator_image: testing-operator 32 | operator_pull_policy: "Never" 33 | kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}" 34 | kustomize: ${KUSTOMIZE_PATH:-kustomize} 35 | env: 36 | K8S_AUTH_KUBECONFIG: ${MOLECULE_EPHEMERAL_DIRECTORY}/kubeconfig 37 | KUBECONFIG: ${MOLECULE_EPHEMERAL_DIRECTORY}/kubeconfig 38 | verifier: 39 | name: ansible 40 | lint: | 41 | set -e 42 | ansible-lint 43 | -------------------------------------------------------------------------------- /playbooks/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3scale-sre/prometheus-exporter-operator/008ca3b043a61907069ae8c4d846c0bbb30842b8/playbooks/.placeholder -------------------------------------------------------------------------------- /prometheus-rules/cloudwatch-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-cloudwatch 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-cloudwatch.rules 8 | rules: 9 | - alert: AWSElastiCacheCPUHigh 10 | expr: aws_elasticache_cpuutilization_average > 80 11 | for: 5m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "AWS ElastiCache instance {{ $labels.cache_cluster_id }} from {{ $labels.prometheus_exporter }} has High CPU usage (%)" 16 | - alert: AWSElastiCacheFreeableMemoryLow 17 | expr: aws_elasticache_freeable_memory_average < 1000000000 18 | for: 2m 19 | labels: 20 | severity: critical 21 | annotations: 22 | message: "AWS ElastiCache instance {{ $labels.cache_cluster_id }} from {{ $labels.prometheus_exporter }} has Low Freeable Memory usage (bytes)" 23 | - alert: AWSElastiCacheSwapMemoryHigh 24 | expr: aws_elasticache_swap_usage_average > 250000000 25 | for: 2m 26 | labels: 27 | severity: critical 28 | annotations: 29 | message: "AWS ElastiCache instance {{ $labels.cache_cluster_id }} from {{ $labels.prometheus_exporter }} has High Swap Memory usage (bytes)" 30 | - alert: AWSElastiCacheEvictionsHigh 31 | expr: aws_elasticache_evictions_average > 500 32 | for: 2m 33 | labels: 34 | severity: critical 35 | annotations: 36 | message: "AWS ElastiCache instance {{ $labels.cache_cluster_id }} from {{ $labels.prometheus_exporter }} has High number of Evictions" 37 | - alert: AWSRDSCPUHigh 38 | expr: aws_rds_cpuutilization_average > 80 39 | for: 5m 40 | labels: 41 | severity: critical 42 | annotations: 43 | message: "AWS RDS instance {{ $labels.dbinstance_identifier }} from {{ $labels.prometheus_exporter }} has High CPU usage (%)" 44 | - alert: AWSRDSFreeableMemoryLow 45 | expr: aws_rds_freeable_memory_average < 1000000000 46 | for: 2m 47 | labels: 48 | severity: critical 49 | annotations: 50 | message: "AWS RDS instance {{ $labels.dbinstance_identifier }} from {{ $labels.prometheus_exporter }} has Low Freeable Memory usage (bytes)" 51 | - alert: AWSRDSFreeStorageSpaceLow 52 | expr: aws_rds_free_storage_space_average < 5000000000 53 | for: 2m 54 | labels: 55 | severity: critical 56 | annotations: 57 | message: "AWS RDS instance {{ $labels.dbinstance_identifier }} from {{ $labels.prometheus_exporter }} has Low Free Storage Space usage (bytes)" 58 | - alert: AWSElasticsearchClusterStatusYellow 59 | expr: aws_es_cluster_status_yellow_maximum == 1 60 | for: 5m 61 | labels: 62 | severity: warning 63 | annotations: 64 | message: "AWS Elasticsearch {{ $labels.domain_name }} from {{ $labels.prometheus_exporter }} cluster status is Yellow" 65 | - alert: AWSElasticsearchClusterStatusRed 66 | expr: aws_es_cluster_status_red_maximum == 1 67 | for: 5m 68 | labels: 69 | severity: critical 70 | annotations: 71 | message: "AWS Elasticsearch {{ $labels.domain_name }} from {{ $labels.prometheus_exporter }} cluster status is Red" 72 | - alert: AWSElasticsearchAutomaticSnapshotFailed 73 | expr: aws_es_automated_snapshot_failure_maximum == 1 74 | for: 5m 75 | labels: 76 | severity: critical 77 | annotations: 78 | message: "AWS Elasticsearch {{ $labels.domain_name }} from {{ $labels.prometheus_exporter }} has failed its automated snapshot" 79 | - alert: AWSElasticsearchFreeSpaceDataTotalLow 80 | expr: aws_es_free_storage_space_sum < 1000000 81 | for: 5m 82 | labels: 83 | severity: critical 84 | annotations: 85 | message: "AWS Elasticsearch {{ $labels.domain_name }} from {{ $labels.prometheus_exporter }} has Low Data Total Free Storage Space (megabytes)" 86 | - alert: AWSElasticsearchFreeSpaceDataNodeLow 87 | expr: aws_es_free_storage_space_minimum < 100000 88 | for: 5m 89 | labels: 90 | severity: critical 91 | annotations: 92 | message: "AWS Elasticsearch {{ $labels.domain_name }} from {{ $labels.prometheus_exporter }} has Low Data Node Free Storage Space (megabytes)" 93 | - alert: AWSClientVPNCrlDaysToExpiry 94 | expr: max_over_time(aws_clientvpn_crl_days_to_expiry_average[10m]) < 2 95 | for: 5m 96 | labels: 97 | severity: warning 98 | annotations: 99 | message: "AWS ClientVPN CRL {{ $labels.endpoint }} will expire soon, maybe it is not being regenerated" 100 | -------------------------------------------------------------------------------- /prometheus-rules/es-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-es 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-es.rules 8 | rules: 9 | # Cluster status alerts 10 | - alert: ElasticsearchDown 11 | expr: elasticsearch_clusterinfo_up == 0 12 | for: 1m 13 | labels: 14 | severity: critical 15 | annotations: 16 | message: "Elasticsearch {{ $labels.prometheus_exporter }} is DOWN" 17 | - alert: ElasticsearchClusterStatusYellow 18 | expr: elasticsearch_cluster_health_status {color="yellow"} == 1 19 | for: 1m 20 | labels: 21 | severity: warning 22 | annotations: 23 | message: "Elasticsearch {{ $labels.prometheus_exporter }} Cluster Status is Yellow" 24 | - alert: ElasticsearchClusterStatusRed 25 | expr: elasticsearch_cluster_health_status {color="red"} == 1 26 | for: 1m 27 | labels: 28 | severity: critical 29 | annotations: 30 | message: "Elasticsearch {{ $labels.prometheus_exporter }} Cluster Status is Red" 31 | 32 | # Memory alerts 33 | - alert: ElasticsearchNodeHeapMemoryHigh 34 | expr: 100* elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"} > 85 35 | for: 10m 36 | labels: 37 | severity: warning 38 | annotations: 39 | message: "Elasticsearch node {{ $labels.name }} Heap Memory usage is High" 40 | - alert: ElasticsearchNodeHeapMemoryHigh 41 | expr: 100* elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"} > 95 42 | for: 10m 43 | labels: 44 | severity: critical 45 | annotations: 46 | message: "Elasticsearch node {{ $labels.name }} Heap Memory usage is High" 47 | 48 | - alert: ElasticsearchNodeFreeSpaceLow 49 | expr: 100 -( 100 * (elasticsearch_filesystem_data_size_bytes - elasticsearch_filesystem_data_free_bytes)/ elasticsearch_filesystem_data_size_bytes) < 15 50 | for: 10m 51 | labels: 52 | severity: warning 53 | annotations: 54 | message: "Elasticsearch node {{ $labels.name }} has Low Free space" 55 | - alert: ElasticsearchNodeFreeSpaceLow 56 | expr: 100 -( 100 * (elasticsearch_filesystem_data_size_bytes - elasticsearch_filesystem_data_free_bytes)/ elasticsearch_filesystem_data_size_bytes) < 5 57 | for: 10m 58 | labels: 59 | severity: critical 60 | annotations: 61 | message: "Elasticsearch node {{ $labels.name }} has Low Free space" 62 | 63 | - alert: ElasticsearchWillFillIn96h 64 | expr: predict_linear(elasticsearch_filesystem_data_free_bytes{}[24h], 96 * 3600) < 0 65 | for: 1h 66 | labels: 67 | severity: warning 68 | annotations: 69 | message: "Elasticsearch node {{ $labels.name }} will fill in 4 days" 70 | - alert: ElasticsearchNodeWillFillIn24h 71 | expr: predict_linear(elasticsearch_filesystem_data_free_bytes{}[24h], 24 * 3600) < 0 72 | for: 1h 73 | labels: 74 | severity: critical 75 | annotations: 76 | message: "Elasticsearch node {{ $labels.name }} will fill in 24h" 77 | 78 | # CPU alerts 79 | - alert: ElasticSeachNodeHighCPU 80 | expr: elasticsearch_os_cpu_percent > 85 81 | for: 10m 82 | labels: 83 | severity: warning 84 | annotations: 85 | message: "Elasticsearch node {{ $labels.name }} has high CPU usage" 86 | - alert: ElasticSeachNodeHighCPU 87 | expr: elasticsearch_os_cpu_percent > 95 88 | for: 10m 89 | labels: 90 | severity: critical 91 | annotations: 92 | message: "Elasticsearch node {{ $labels.name }} has high CPU usage" 93 | -------------------------------------------------------------------------------- /prometheus-rules/general-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-general 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-general.rules 8 | rules: 9 | - alert: PrometheusExporterJobDown 10 | expr: up { service=~"prometheus-exporter-.*" } == 0 11 | for: 2m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "Prometheus Exporter Job {{ $labels.job }} is DOWN, maybe connection to monitored host is lost" 16 | -------------------------------------------------------------------------------- /prometheus-rules/manticore-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-manticore 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-manticore.rules 8 | rules: 9 | - alert: ManticoreDown 10 | expr: absent(manticore_uptime_seconds) == 1 11 | for: 1m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "Manticore instance {{ $labels.prometheus_exporter }} is DOWN" 16 | -------------------------------------------------------------------------------- /prometheus-rules/memcached-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-memcached 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-memcached.rules 8 | rules: 9 | - alert: MemcachedDown 10 | expr: memcached_up == 0 11 | for: 1m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "Memcached instance {{ $labels.prometheus_exporter }} is DOWN" 16 | -------------------------------------------------------------------------------- /prometheus-rules/mysql-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-mysql 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-mysql.rules 8 | rules: 9 | - alert: MySQLDown 10 | expr: mysql_up == 0 11 | for: 1m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "MySQL instance {{ $labels.prometheus_exporter }} is DOWN" 16 | - alert: MySQLInnoDBRowLockTimeHigh 17 | expr: increase(mysql_global_status_innodb_row_lock_time [5m]) > 600000 18 | for: 1m 19 | labels: 20 | severity: warning 21 | annotations: 22 | message: "MySQL instance {{ $labels.prometheus_exporter }} InnoDB Row Lock Time is High during last 5 minutes" 23 | - alert: MySQLInnoDBRowLockWaitsHigh 24 | expr: increase(mysql_global_status_innodb_row_lock_waits [5m]) > 4500 25 | for: 1m 26 | labels: 27 | severity: warning 28 | annotations: 29 | message: "MySQL instance {{ $labels.prometheus_exporter }} InnoDB Row Lock Wait is High during last 5 minutes" 30 | - alert: MySQLSlowQueriesHigh 31 | expr: increase(mysql_global_status_slow_queries [5m]) > 150000 32 | for: 1m 33 | labels: 34 | severity: warning 35 | annotations: 36 | message: "MySQL instance {{ $labels.prometheus_exporter }} Slow Queries is High during last 5 minutes" 37 | - alert: MySQLTableLocksWaitedHigh 38 | expr: increase(mysql_global_status_table_locks_waited [5m]) > 9000 39 | for: 1m 40 | labels: 41 | severity: warning 42 | annotations: 43 | message: "MySQL instance {{ $labels.prometheus_exporter }} Table Locks Waited is High during last 5 minutes" 44 | - alert: MySQLTableLocksImmediateHigh 45 | expr: increase(mysql_global_status_table_locks_immediate [5m]) > 150000 46 | for: 1m 47 | labels: 48 | severity: warning 49 | annotations: 50 | message: "MySQL instance {{ $labels.prometheus_exporter }} Table Locks Immediate is High during last 5 minutes" 51 | - alert: MySQLTableLockWaitHigh 52 | expr: 100 * mysql_global_status_table_locks_waited / (mysql_global_status_table_locks_waited + mysql_global_status_table_locks_immediate ) > 30 53 | for: 1m 54 | labels: 55 | severity: warning 56 | annotations: 57 | message: "MySQL instance {{ $labels.prometheus_exporter }} Table Lock Waited % is High" 58 | - alert: MySQLQueriesDoingTableScansNotIndexHigh 59 | expr: increase(mysql_global_status_handlers_total{handler="read_rnd_next"}[5m]) > 500000000 60 | for: 1m 61 | labels: 62 | severity: warning 63 | annotations: 64 | message: "MySQL instance {{ $labels.prometheus_exporter }} has High number of queries doing table scans (not using indexes or tables not indexed) during last 5 minutes" 65 | -------------------------------------------------------------------------------- /prometheus-rules/postgresql-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-postgresql 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-postgresql.rules 8 | rules: 9 | - alert: PostgreSQLDown 10 | expr: pg_up == 0 11 | for: 1m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "PostgreSQL instance {{ $labels.prometheus_exporter }} is DOWN" 16 | - alert: PostgreSQLConnectionsHigh 17 | expr: (sum(pg_stat_database_numbackends) by (namespace,service,prometheus_exporter)) / on (namespace,service,prometheus_exporter) (pg_settings_max_connections) > 0.8 18 | for: 1m 19 | labels: 20 | severity: warning 21 | annotations: 22 | message: "PostgreSQL instance {{ $labels.prometheus_exporter }} has High number of connections" 23 | - alert: PostgreSQLQueriesPerSecondHigh 24 | expr: avg(rate(pg_stat_database_xact_commit[5m]) + rate(pg_stat_database_xact_rollback[5m])) by (namespace,service,prometheus_exporter,datname) > 10000 25 | for: 1m 26 | labels: 27 | severity: warning 28 | annotations: 29 | message: "PostgreSQL instance {{ $labels.prometheus_exporter }} has High number of queries per second" 30 | - alert: PostgreSQLCacheHitRateLow 31 | expr: (sum(irate(pg_stat_database_xact_commit[5m])) by (namespace,service,prometheus_exporter) + sum(irate(pg_stat_database_xact_rollback{datname!~"template.*|"}[5m])) by (namespace,service,prometheus_exporter)) > 10000 32 | for: 1m 33 | labels: 34 | severity: warning 35 | annotations: 36 | message: "PostgreSQL instance {{ $labels.prometheus_exporter }} has Low cache hit rate" 37 | -------------------------------------------------------------------------------- /prometheus-rules/probe-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-probe 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-probe.rules 8 | rules: 9 | - alert: ProbeDown 10 | expr: probe_success < 1 11 | for: 2m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "Probe target {{ $labels.instance }} is DOWN" 16 | - alert: ProbeSSLCertExpireWarning 17 | expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 30 18 | for: 5m 19 | labels: 20 | severity: warning 21 | annotations: 22 | message: "SSL certificate from probe target {{ $labels.instance }} is going to expire in 30 days" 23 | - alert: ProbeSSLCertExpireCritical 24 | expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 14 25 | for: 5m 26 | labels: 27 | severity: critical 28 | annotations: 29 | message: "SSL certificate from probe target {{ $labels.instance }} is going to expire in 14 days" -------------------------------------------------------------------------------- /prometheus-rules/redis-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-redis 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-redis.rules 8 | rules: 9 | - alert: RedisDown 10 | expr: redis_up == 0 11 | for: 1m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "Redis instance {{ $labels.prometheus_exporter }} is DOWN" 16 | - alert: RedisQueueSizeHigh 17 | expr: redis_key_size > 120000 18 | for: 1m 19 | labels: 20 | severity: critical 21 | annotations: 22 | message: "Redis instance {{ $labels.prometheus_exporter }} has {{ $labels.key }} queue size increasing, probably workers are failing" 23 | - alert: RedisMemoryHigh 24 | expr: 100 * (redis_memory_used_bytes / redis_memory_max_bytes ) > 85 25 | for: 1m 26 | labels: 27 | severity: critical 28 | annotations: 29 | message: "Redis instance {{ $labels.prometheus_exporter }} Memory usage is High" 30 | - alert: RedisEvictionsHigh 31 | expr: sum(rate(redis_evicted_keys_total[5m])) by (prometheus_exporter) > 500 32 | for: 1m 33 | labels: 34 | severity: critical 35 | annotations: 36 | message: "Redis instance {{ $labels.prometheus_exporter }} number of Evictions is High" 37 | -------------------------------------------------------------------------------- /prometheus-rules/sendgrid-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-sendgrid 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-sendgrid.rules 8 | rules: 9 | - alert: SendgridDown 10 | expr: absent(sendgrid_delivered) 11 | for: 5m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "Sendgrid {{ $labels.prometheus_exporter }} is DOWN" 16 | - alert: SendgridRequestsHigh 17 | expr: sendgrid_requests > 10000 18 | for: 5m 19 | labels: 20 | severity: warning 21 | annotations: 22 | message: "Sendgrid {{ $labels.prometheus_exporter }} requests emails is High above contracted plan" 23 | - alert: SendgridSpamReportsHigh 24 | expr: sendgrid_spam_reports > 100 25 | for: 5m 26 | labels: 27 | severity: warning 28 | annotations: 29 | message: "Sendgrid {{ $labels.prometheus_exporter }} spam reports emails (marked as spam) is High" 30 | - alert: SendgridBlocksHourlyRateHigh 31 | expr: increase(sendgrid_blocks{}[1h]) > 20 32 | for: 5m 33 | labels: 34 | severity: warning 35 | annotations: 36 | message: "Sendgrid {{ $labels.prometheus_exporter }}blocks hourly rate is High" -------------------------------------------------------------------------------- /prometheus-rules/sphinx-prometheusrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | name: prometheus-exporter-sphinx 5 | spec: 6 | groups: 7 | - name: prometheus-exporter-sphinx.rules 8 | rules: 9 | - alert: SphinxDown 10 | expr: sphinx_up == 0 11 | for: 1m 12 | labels: 13 | severity: critical 14 | annotations: 15 | message: "Sphinx instance {{ $labels.prometheus_exporter }} is DOWN" 16 | -------------------------------------------------------------------------------- /requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | collections: 3 | - name: community.kubernetes 4 | version: "2.0.1" 5 | - name: operator_sdk.util 6 | version: "0.4.0" 7 | - name: kubernetes.core 8 | version: "2.3.1" 9 | - name: cloud.common 10 | version: "2.1.1" -------------------------------------------------------------------------------- /roles/prometheusexporter/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Main 4 | type: "none" # memcached, redis, mysql, postgresql, sphinx, es, cloudwatch, sendgrid, manticore 5 | 6 | ## ServiceMonitor config 7 | service_monitor_state: "present" # Converted to ansible state "absent" with an ansible set_fact task if CR boolean serviceMonitor.enabled = false 8 | service_monitor_interval: "30s" 9 | 10 | ## GrafanaDashboard config 11 | grafana_dashboard_state: "present" # Converted to ansible state "absent" with an ansible set_fact task if CR boolean grafanaDashboard.enabled = false 12 | grafana_dashboard_label_key: "discovery" 13 | grafana_dashboard_label_value: "enabled" 14 | grafana_dashboard_api_version: "v1alpha1" # Converted to ansible "v1beta1" with an ansible set_fact task if CR grafanaDashboard.apiVersion = v1beta1 -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/cloudwatch/container.yml.j2: -------------------------------------------------------------------------------- 1 | env: 2 | - name: AWS_ACCESS_KEY_ID 3 | valueFrom: 4 | secretKeyRef: 5 | name: "{{ aws_credentials_secret_name }}" 6 | key: AWS_ACCESS_KEY_ID 7 | - name: AWS_SECRET_ACCESS_KEY 8 | valueFrom: 9 | secretKeyRef: 10 | name: "{{ aws_credentials_secret_name }}" 11 | key: AWS_SECRET_ACCESS_KEY 12 | volumeMounts: 13 | - mountPath: /config/ 14 | name: config-volume 15 | readOnly: true -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/cloudwatch/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Exporter 3 | image_name: "prom/cloudwatch-exporter" 4 | image_version: "v0.16.0" 5 | port: 9106 6 | liveness_probe_timeout_seconds: 45 7 | liveness_probe_period_seconds: 60 8 | liveness_probe_success_threshold: 1 9 | liveness_probe_failure_threshold: 5 10 | readiness_probe_timeout_seconds: 45 11 | readiness_probe_period_seconds: 60 12 | readiness_probe_success_threshold: 1 13 | readiness_probe_failure_threshold: 5 14 | resources_requests_cpu: "50m" 15 | resources_requests_memory: "128Mi" 16 | resources_limits_cpu: "500m" 17 | resources_limits_memory: "256Mi" 18 | 19 | # Custom 20 | aws_credentials_secret_name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 21 | configuration_configmap_name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 22 | ###### Example of Secret 23 | # 24 | # If you don't specify CR field awsCredentialsSecretName, it will be used default Secret name "prometheus-exporter-cloudwatch-{{ CR_NAME }}" 25 | # 26 | #apiVersion: v1 27 | #kind: Secret 28 | #metadata: 29 | # name: "prometheus-exporter-cloudwatch-aws-example" 30 | #type: Opaque 31 | #stringData: 32 | # AWS_ACCESS_KEY_ID: "XXX_YOUR_AWS_ACCESS_KEY_ID_XXX" 33 | # AWS_SECRET_ACCESS_KEY: "XXXXXXXX-YOUR_AWS_SECRET_ACCESS_KEY-XXXXXXX" 34 | 35 | ###### Example of ConfigMap 36 | # 37 | # If you don't specify CR field configurationConfigmapName, it will be used default ConfigMap name "prometheus-exporter-cloudwatch-{{ CR_NAME }}" 38 | # 39 | #apiVersion: v1 40 | #kind: ConfigMap 41 | #metadata: 42 | # name: "prometheus-exporter-cloudwatch-aws-example" 43 | #data: 44 | # config.yml: | 45 | # --- 46 | # region: us-east-1 47 | # metrics: 48 | # - aws_namespace: AWS/ELB 49 | # aws_metric_name: RequestCount 50 | # aws_dimensions: [AvailabilityZone, LoadBalancerName] 51 | # aws_tag_select: 52 | # tag_selections: 53 | # Monitoring: ["enabled"] 54 | # resource_type_selection: "elasticloadbalancing:loadbalancer" 55 | # resource_id_dimension: LoadBalancerName 56 | # aws_statistics: [Sum] 57 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/cloudwatch/volumes.yml.j2: -------------------------------------------------------------------------------- 1 | volumes: 2 | - name: config-volume 3 | configMap: 4 | name: "{{ configuration_configmap_name }}" 5 | items: 6 | - key: config.yml 7 | path: config.yml -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/es/container.yml.j2: -------------------------------------------------------------------------------- 1 | args: 2 | - "--es.uri={{ db_host }}:{{ db_port }}" 3 | - "--es.all" -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/es/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Exporter 3 | image_name: "quay.io/prometheuscommunity/elasticsearch-exporter" 4 | image_version: "v1.8.0" 5 | port: 9114 6 | liveness_probe_timeout_seconds: 10 7 | liveness_probe_period_seconds: 15 8 | liveness_probe_success_threshold: 1 9 | liveness_probe_failure_threshold: 5 10 | readiness_probe_timeout_seconds: 10 11 | readiness_probe_period_seconds: 30 12 | readiness_probe_success_threshold: 1 13 | readiness_probe_failure_threshold: 5 14 | resources_requests_cpu: "25m" 15 | resources_requests_memory: "64Mi" 16 | resources_limits_cpu: "750m" 17 | resources_limits_memory: "128Mi" 18 | 19 | # Custom 20 | db_host: "http://elasticsearch" 21 | db_port: 9200 22 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/manticore/container.yml.j2: -------------------------------------------------------------------------------- 1 | env: 2 | - name: MANTICORE_HOST 3 | value: "{{ db_host }}" 4 | - name: MANTICORE_PORT 5 | value: "{{ db_port }}" 6 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/manticore/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Exporter 3 | image_name: "manticoresearch/prometheus-exporter" 4 | image_version: "6.3.2.0" 5 | port: 8081 6 | liveness_probe_timeout_seconds: 3 7 | liveness_probe_period_seconds: 15 8 | liveness_probe_success_threshold: 1 9 | liveness_probe_failure_threshold: 5 10 | readiness_probe_timeout_seconds: 3 11 | readiness_probe_period_seconds: 30 12 | readiness_probe_success_threshold: 1 13 | readiness_probe_failure_threshold: 5 14 | resources_requests_cpu: "25m" 15 | resources_requests_memory: "32Mi" 16 | resources_limits_cpu: "200m" 17 | resources_limits_memory: "64Mi" 18 | 19 | # Custom 20 | db_host: "system-searchd" 21 | db_port: 9306 22 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/memcached/container.yml.j2: -------------------------------------------------------------------------------- 1 | args: 2 | - "--memcached.address={{ db_host }}:{{ db_port }}" -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/memcached/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Exporter 3 | image_name: "prom/memcached-exporter" 4 | image_version: "v0.15.0" 5 | port: 9150 6 | liveness_probe_timeout_seconds: 3 7 | liveness_probe_period_seconds: 15 8 | liveness_probe_success_threshold: 1 9 | liveness_probe_failure_threshold: 5 10 | readiness_probe_timeout_seconds: 3 11 | readiness_probe_period_seconds: 30 12 | readiness_probe_success_threshold: 1 13 | readiness_probe_failure_threshold: 5 14 | resources_requests_cpu: "25m" 15 | resources_requests_memory: "32Mi" 16 | resources_limits_cpu: "200m" 17 | resources_limits_memory: "64Mi" 18 | 19 | # Custom 20 | db_host: "system-memcache" 21 | db_port: 11211 22 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/mysql/container.yml.j2: -------------------------------------------------------------------------------- 1 | env: 2 | - name: DATA_SOURCE_NAME 3 | valueFrom: 4 | secretKeyRef: 5 | name: "{{ db_connection_string_secret_name }}" 6 | key: DATA_SOURCE_NAME -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/mysql/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Exporter 3 | image_name: "prom/mysqld-exporter" 4 | image_version: "v0.14.0" # v0.15 and above introduces breaking changes, replacing connection string secret with a .my.cnf based configuration 5 | port: 9104 6 | liveness_probe_timeout_seconds: 3 7 | liveness_probe_period_seconds: 15 8 | liveness_probe_success_threshold: 1 9 | liveness_probe_failure_threshold: 5 10 | readiness_probe_timeout_seconds: 3 11 | readiness_probe_period_seconds: 30 12 | readiness_probe_success_threshold: 1 13 | readiness_probe_failure_threshold: 5 14 | resources_requests_cpu: "100m" 15 | resources_requests_memory: "32Mi" 16 | resources_limits_cpu: "300m" 17 | resources_limits_memory: "64Mi" 18 | 19 | # Custom 20 | db_connection_string_secret_name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 21 | ###### Example of Secret 22 | # 23 | # If you don't specify CR field dbConnectionStringSecretName, it will be used default Secret name "prometheus-exporter-mysql-{{ CR_NAME }}" 24 | # 25 | #apiVersion: v1 26 | #kind: Secret 27 | #metadata: 28 | # name: "prometheus-exporter-mysql-system-mysql" 29 | #type: Opaque 30 | #stringData: 31 | # DATA_SOURCE_NAME: "exporter:123456789@(system-mysql:3306)/" 32 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/postgresql/container.yml.j2: -------------------------------------------------------------------------------- 1 | env: 2 | - name: DATA_SOURCE_NAME 3 | valueFrom: 4 | secretKeyRef: 5 | name: "{{ db_connection_string_secret_name }}" 6 | key: DATA_SOURCE_NAME -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/postgresql/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Exporter 3 | image_name: "quay.io/prometheuscommunity/postgres-exporter" 4 | image_version: "v0.16.0" 5 | port: 9187 6 | liveness_probe_timeout_seconds: 3 7 | liveness_probe_period_seconds: 15 8 | liveness_probe_success_threshold: 1 9 | liveness_probe_failure_threshold: 5 10 | readiness_probe_timeout_seconds: 3 11 | readiness_probe_period_seconds: 30 12 | readiness_probe_success_threshold: 1 13 | readiness_probe_failure_threshold: 5 14 | resources_requests_cpu: "25m" 15 | resources_requests_memory: "32Mi" 16 | resources_limits_cpu: "200m" 17 | resources_limits_memory: "64Mi" 18 | 19 | # Custom 20 | db_connection_string_secret_name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 21 | ###### Example of Secret 22 | # 23 | # If you don't specify CR field dbConnectionStringSecretName, it will be used default Secret name "prometheus-exporter-postgresql-{{ CR_NAME }}" 24 | # 25 | #apiVersion: v1 26 | #kind: Secret 27 | #metadata: 28 | # name: "prometheus-exporter-postgresql-zync-database" 29 | #type: Opaque 30 | #stringData: 31 | # DATA_SOURCE_NAME: "postgresql://postgres_exporter:123456789@zync-database:5432/postgres?sslmode=disable" 32 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/probe/container.yml.j2: -------------------------------------------------------------------------------- 1 | args: 2 | - --config.file=/etc/blackbox_exporter/config.yml 3 | - --log.level={{ log_level }} 4 | volumeMounts: 5 | - mountPath: /etc/blackbox_exporter 6 | name: config-volume 7 | readOnly: true -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/probe/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Exporter 4 | image_name: "quay.io/prometheus/blackbox-exporter" 5 | image_version: "v0.25.0" 6 | port: 9115 7 | liveness_probe_timeout_seconds: 3 8 | liveness_probe_period_seconds: 15 9 | liveness_probe_success_threshold: 1 10 | liveness_probe_failure_threshold: 5 11 | readiness_probe_timeout_seconds: 3 12 | readiness_probe_period_seconds: 30 13 | readiness_probe_success_threshold: 1 14 | readiness_probe_failure_threshold: 5 15 | resources_requests_cpu: "25m" 16 | resources_requests_memory: "32Mi" 17 | resources_limits_cpu: "250m" 18 | resources_limits_memory: "64Mi" 19 | 20 | # Custom 21 | configuration_configmap_name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 22 | log_level: "debug" 23 | probe_target_label: "instance" 24 | 25 | ###### Example of ConfigMap 26 | # 27 | # If you don't specify CR field configurationConfigmapName, it will be used default ConfigMap name "prometheus-exporter-probe-{{ CR_NAME }}" 28 | # 29 | #apiVersion: v1 30 | #kind: ConfigMap 31 | #metadata: 32 | # name: "prometheus-exporter-probe-example" 33 | #data: 34 | # config.yml: | 35 | # modules: 36 | # http_2xx: 37 | # prober: http 38 | # timeout: 5s 39 | # http: 40 | # method: GET 41 | # no_follow_redirects: false 42 | # fail_if_ssl: false 43 | # fail_if_not_ssl: false 44 | # tls_config: 45 | # insecure_skip_verify: false 46 | # preferred_ip_protocol: "ip4" # defaults to "ip6" 47 | # ip_protocol_fallback: false # no fallback to "ip6" 48 | # tcp_connect: 49 | # prober: tcp 50 | # timeout: 5s -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/probe/volumes.yml.j2: -------------------------------------------------------------------------------- 1 | volumes: 2 | - name: config-volume 3 | {% if configuration_secret_name is defined %} 4 | secret: 5 | secretName: "{{ configuration_secret_name }}" 6 | {% else %} 7 | configMap: 8 | name: "{{ configuration_configmap_name }}" 9 | {% endif %} 10 | items: 11 | - key: config.yml 12 | path: config.yml 13 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/redis/container.yml.j2: -------------------------------------------------------------------------------- 1 | env: 2 | - name: REDIS_ADDR 3 | value: "{{ db_host }}:{{ db_port }}" 4 | {% if db_check_keys is defined %} 5 | - name: REDIS_EXPORTER_CHECK_KEYS 6 | value: "{{ db_check_keys }}" 7 | {% endif %} -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/redis/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Exporter 3 | image_name: "oliver006/redis_exporter" 4 | image_version: "v1.66.0" 5 | port: 9121 6 | liveness_probe_timeout_seconds: 3 7 | liveness_probe_period_seconds: 15 8 | liveness_probe_success_threshold: 1 9 | liveness_probe_failure_threshold: 5 10 | readiness_probe_timeout_seconds: 3 11 | readiness_probe_period_seconds: 30 12 | readiness_probe_success_threshold: 1 13 | readiness_probe_failure_threshold: 5 14 | resources_requests_cpu: "25m" 15 | resources_requests_memory: "32Mi" 16 | resources_limits_cpu: "200m" 17 | resources_limits_memory: "64Mi" 18 | 19 | # Custom 20 | db_host: "backend-redis" 21 | db_port: 6379 22 | ## Optional: 23 | # Example 3scale backend: 24 | #db_check_keys: "resque:queue:stats,resque:queue:priority,resque:queue:main,resque:failed" 25 | # Example 3scale system: 26 | #db_check_keys: "queue:backend_sync,queue:billing,queue:critical,queue:default,queue:deletion,queue:events,queue:low,queue:priority,queue:web_hooks,queue_zync" 27 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/sendgrid/container.yml.j2: -------------------------------------------------------------------------------- 1 | env: 2 | - name: SENDGRID_USER_NAME 3 | valueFrom: 4 | secretKeyRef: 5 | name: "{{ sendgrid_credentials_secret_name }}" 6 | key: SENDGRID_USER_NAME 7 | - name: SENDGRID_API_KEY 8 | valueFrom: 9 | secretKeyRef: 10 | name: "{{ sendgrid_credentials_secret_name }}" 11 | key: SENDGRID_API_KEY 12 | - name: SENDGRID_ACCUMULATED_METRICS 13 | value: "{{ sendgrid_accumulated_metrics }}" 14 | - name: SENDGRID_LOCATION 15 | value: "{{ sendgrid_location }}" 16 | - name: SENDGRID_TIME_OFFSET 17 | value: "{{ sendgrid_time_offset }}" -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/sendgrid/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Exporter 3 | image_name: "chatwork/sendgrid-stats-exporter" 4 | image_version: "v0.0.10" 5 | port: 9154 6 | liveness_probe_timeout_seconds: 3 7 | liveness_probe_period_seconds: 15 8 | liveness_probe_success_threshold: 1 9 | liveness_probe_failure_threshold: 5 10 | readiness_probe_timeout_seconds: 3 11 | readiness_probe_period_seconds: 30 12 | readiness_probe_success_threshold: 1 13 | readiness_probe_failure_threshold: 5 14 | resources_requests_cpu: "100m" 15 | resources_requests_memory: "128Mi" 16 | resources_limits_cpu: "200m" 17 | resources_limits_memory: "256Mi" 18 | 19 | # Custom 20 | sendgrid_credentials_secret_name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 21 | sendgrid_accumulated_metrics: "True" 22 | sendgrid_location: "" 23 | sendgrid_time_offset: "0" 24 | ###### Example of Secret 25 | # 26 | # If you don't specify CR field sendgridCredentialsSecretName, it will be used default Secret name "prometheus-exporter-sendgrid-{{ CR_NAME }}" 27 | # 28 | #apiVersion: v1 29 | #kind: Secret 30 | #metadata: 31 | # name: "prometheus-exporter-sendgrid-production" 32 | #type: Opaque 33 | #stringData: 34 | # SENDGRID_USER_NAME: "username" 35 | # SENDGRID_API_KEY: "apikey" 36 | -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/sphinx/container.yml.j2: -------------------------------------------------------------------------------- 1 | args: 2 | - "--sphinx.address={{ db_host }}" 3 | - "--sphinx.port={{ db_port }}" -------------------------------------------------------------------------------- /roles/prometheusexporter/exporters/sphinx/vars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Exporter 3 | image_name: "foxdalas/sphinx-exporter" 4 | image_version: "v0.3.0" 5 | port: 9247 6 | liveness_probe_timeout_seconds: 3 7 | liveness_probe_period_seconds: 15 8 | liveness_probe_success_threshold: 1 9 | liveness_probe_failure_threshold: 5 10 | readiness_probe_timeout_seconds: 3 11 | readiness_probe_period_seconds: 30 12 | readiness_probe_success_threshold: 1 13 | readiness_probe_failure_threshold: 5 14 | resources_requests_cpu: "25m" 15 | resources_requests_memory: "32Mi" 16 | resources_limits_cpu: "200m" 17 | resources_limits_memory: "64Mi" 18 | 19 | # Custom 20 | db_host: "system-sphinx" 21 | db_port: 9306 22 | -------------------------------------------------------------------------------- /roles/prometheusexporter/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: 3scale SRE team 4 | description: Prometheus Exporters 5 | company: Red Hat 6 | license: license (GPLv2, CC-BY, etc) 7 | min_ansible_version: 2.9 8 | galaxy_tags: [] 9 | dependencies: [] 10 | collections: 11 | - operator_sdk.util 12 | - kubernetes.core -------------------------------------------------------------------------------- /roles/prometheusexporter/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include_vars: "exporters/{{ type }}/vars.yml" 4 | 5 | - name: Manage Deployment for PrometheusExporter {{ ansible_operator_meta.name }} on Namespace {{ ansible_operator_meta.namespace }} 6 | k8s: 7 | definition: "{{ lookup('template', 'deployment.yml.j2') }}" 8 | 9 | - name: Manage Service for PrometheusExporter {{ ansible_operator_meta.name }} on Namespace {{ ansible_operator_meta.namespace }} 10 | k8s: 11 | definition: "{{ lookup('template', 'service.yml.j2') }}" 12 | 13 | - name: Get information about existing api-groups in the cluster for PrometheusExporter {{ ansible_operator_meta.name }} on Namespace {{ ansible_operator_meta.namespace }} 14 | set_fact: 15 | api_groups: "{{ lookup('kubernetes.core.k8s', cluster_info='api_groups') }}" 16 | 17 | - name: Convert serviceMonitor.enabled boolean var into ansible service_monitor_state state var for PrometheusExporter {{ ansible_operator_meta.name }} on Namespace { ansible_operator_meta.namespace }} 18 | set_fact: 19 | service_monitor_state: "absent" 20 | when: service_monitor.enabled is defined and service_monitor.enabled|bool == false 21 | 22 | - name: Manage ServiceMonitor (if monitoring.coreos.com api-group exists) for PrometheusExporter {{ ansible_operator_meta.name }} on Namespace {{ ansible_operator_meta.namespace }} 23 | k8s: 24 | state: "{{ service_monitor_state }}" 25 | definition: "{{ lookup('template', item.name) | from_yaml }}" 26 | when: item.api_exists | default(True) 27 | loop: 28 | - name: servicemonitor.yml.j2 29 | api_exists: "{{ True if 'monitoring.coreos.com' in api_groups else False }}" 30 | 31 | - name: Convert grafanaDashboard.enabled boolean var into ansible grafana_dashboard_state state var for PrometheusExporter {{ ansible_operator_meta.name }} on Namespace {{ ansible_operator_meta.namespace }} 32 | set_fact: 33 | grafana_dashboard_state: "absent" 34 | when: grafana_dashboard.enabled is defined and grafana_dashboard.enabled|bool == false 35 | 36 | - name: Convert possible grafanaDashboard.apiVersion v1alpha1 string var into ansible grafana_dashboard_api_version var for PrometheusExporter {{ ansible_operator_meta.name }} on Namespace { ansible_operator_meta.namespace }} 37 | set_fact: 38 | grafana_dashboard_api_version: "v1alpha1" 39 | when: grafana_dashboard.api_version is defined and grafana_dashboard.api_version|string == "v1alpha1" 40 | 41 | - name: Convert possible grafanaDashboard.apiVersion v1beta1 string var into ansible grafana_dashboard_api_version var for PrometheusExporter {{ ansible_operator_meta.name }} on Namespace { ansible_operator_meta.namespace }} 42 | set_fact: 43 | grafana_dashboard_api_version: "v1beta1" 44 | when: grafana_dashboard.api_version is defined and grafana_dashboard.api_version|string == "v1beta1" 45 | 46 | - name: Manage GrafanaDashboard (if integreatly.org api-group exists) for PrometheusExporter {{ ansible_operator_meta.name }} on Namespace {{ ansible_operator_meta.namespace }} 47 | k8s: 48 | state: "{{ grafana_dashboard_state }}" 49 | definition: "{{ lookup('template', item.name) | from_yaml }}" 50 | when: item.api_exists | default(True) 51 | loop: 52 | - name: "grafanadashboard.yml.j2" 53 | api_exists: "{{ True if 'integreatly.org' in api_groups else False }}" 54 | - name: "grafanadashboard.yml.j2" 55 | api_exists: "{{ True if 'grafana.integreatly.org' in api_groups else False }}" -------------------------------------------------------------------------------- /roles/prometheusexporter/templates/deployment.yml.j2: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 5 | namespace: "{{ ansible_operator_meta.namespace }}" 6 | labels: 7 | prometheus_exporter: "{{ ansible_operator_meta.name }}" 8 | prometheus_exporter_type: "{{ type }}" 9 | app: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 10 | {% if extra_label.key is defined and extra_label.value is defined %} 11 | {{ extra_label.key }}: "{{ extra_label.value }}" 12 | {% endif %} 13 | spec: 14 | replicas: 1 15 | selector: 16 | matchLabels: 17 | app: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 18 | template: 19 | metadata: 20 | labels: 21 | prometheus_exporter: "{{ ansible_operator_meta.name }}" 22 | prometheus_exporter_type: "{{ type }}" 23 | app: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 24 | {% if extra_label.key is defined and extra_label.value is defined %} 25 | {{ extra_label.key }}: "{{ extra_label.value }}" 26 | {% endif %} 27 | spec: 28 | containers: 29 | - name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 30 | image: "{{ image.name | default(image_name) }}:{{ image.version | default(image_version) }}" 31 | imagePullPolicy: IfNotPresent 32 | ports: 33 | - name: metrics 34 | containerPort: {{ port }} 35 | protocol: TCP 36 | livenessProbe: 37 | tcpSocket: 38 | port: metrics 39 | timeoutSeconds: {{ liveness_probe.timeout_seconds | default(liveness_probe_timeout_seconds) }} 40 | periodSeconds: {{ liveness_probe.period_seconds | default (liveness_probe_period_seconds) }} 41 | successThreshold: {{ liveness_probe.success_threshold | default(liveness_probe_success_threshold) }} 42 | failureThreshold: {{ liveness_probe.failure_threshold | default(liveness_probe_failure_threshold) }} 43 | readinessProbe: 44 | tcpSocket: 45 | port: metrics 46 | timeoutSeconds: {{ readiness_probe.timeout_seconds | default(readiness_probe_timeout_seconds) }} 47 | periodSeconds: {{ readiness_probe.period_seconds | default(readiness_probe_period_seconds) }} 48 | successThreshold: {{ readiness_probe.success_threshold | default(readiness_probe_success_threshold) }} 49 | failureThreshold: {{ readiness_probe.failure_threshold | default(readiness_probe_failure_threshold) }} 50 | resources: 51 | limits: 52 | cpu: "{{ resources.limits.cpu | default(resources_limits_cpu) }}" 53 | memory: "{{ resources.limits.memory | default(resources_limits_memory) }}" 54 | requests: 55 | cpu: "{{ resources.requests.cpu | default(resources_requests_cpu) }}" 56 | memory: "{{ resources.requests.memory | default(resources_requests_memory) }}" 57 | {## ##} 58 | {% filter indent(10, True) %} 59 | 60 | {% include "exporters/"+type+"/container.yml.j2" ignore missing %} 61 | 62 | {% endfilter %} 63 | {## ##} 64 | {% if node_selector is defined %} 65 | nodeSelector: 66 | {% for key, value in node_selector.items() %} 67 | {{ key | safe }}: {{ value | safe }} 68 | {% endfor %} 69 | {% endif %} 70 | 71 | {% if tolerations is defined %} 72 | tolerations: 73 | {% filter indent(8, True) %} 74 | {{ tolerations | to_nice_yaml }} 75 | {% endfilter %} 76 | {% endif %} 77 | 78 | {## ##} 79 | {% filter indent(6, True) %} 80 | 81 | {% include "exporters/"+type+"/volumes.yml.j2" ignore missing %} 82 | 83 | {% endfilter %} 84 | {## ##} 85 | -------------------------------------------------------------------------------- /roles/prometheusexporter/templates/grafanadashboard.yml.j2: -------------------------------------------------------------------------------- 1 | {% if grafana_dashboard_api_version == "v1alpha1" %} 2 | apiVersion: integreatly.org/v1alpha1 3 | {% elif grafana_dashboard_api_version == "v1beta1" %} 4 | apiVersion: grafana.integreatly.org/v1beta1 5 | {% endif %} 6 | kind: GrafanaDashboard 7 | metadata: 8 | name: "prometheus-exporter-{{ type }}" 9 | namespace: "{{ ansible_operator_meta.namespace }}" 10 | labels: 11 | prometheus_exporter_type: "{{ type }}" 12 | {% if grafana_dashboard_api_version == "v1alpha1" %} 13 | "{{ grafana_dashboard.label.key | default(grafana_dashboard_label_key) }}": "{{ grafana_dashboard.label.value | default(grafana_dashboard_label_value) }}" 14 | {% endif %} 15 | spec: 16 | {% if grafana_dashboard_api_version == "v1beta1" %} 17 | allowCrossNamespaceImport: true 18 | instanceSelector: 19 | matchLabels: 20 | "{{ grafana_dashboard.label.key | default(grafana_dashboard_label_key) }}": "{{ grafana_dashboard.label.value | default(grafana_dashboard_label_value) }}" 21 | {% endif %} 22 | json: > 23 | {## ##} 24 | {% filter indent(4, True) %} 25 | {% include "exporters/"+type+"/grafanadashboard.json.j2" %} 26 | {% endfilter %} 27 | {## ##} -------------------------------------------------------------------------------- /roles/prometheusexporter/templates/service.yml.j2: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 5 | namespace: "{{ ansible_operator_meta.namespace }}" 6 | labels: 7 | prometheus_exporter: "{{ ansible_operator_meta.name }}" 8 | prometheus_exporter_type: "{{ type }}" 9 | app: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 10 | {% if extra_label.key is defined and extra_label.value is defined %} 11 | {{ extra_label.key }}: "{{ extra_label.value }}" 12 | {% endif %} 13 | spec: 14 | ports: 15 | - name: metrics 16 | port: {{ port }} 17 | targetPort: {{ port }} 18 | selector: 19 | app: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 20 | type: ClusterIP 21 | -------------------------------------------------------------------------------- /roles/prometheusexporter/templates/servicemonitor.yml.j2: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | name: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 5 | namespace: "{{ ansible_operator_meta.namespace }}" 6 | labels: 7 | prometheus_exporter: "{{ ansible_operator_meta.name }}" 8 | prometheus_exporter_type: "{{ type }}" 9 | app: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 10 | {% if extra_label.key is defined and extra_label.value is defined %} 11 | {{ extra_label.key }}: "{{ extra_label.value }}" 12 | {% endif %} 13 | spec: 14 | selector: 15 | matchLabels: 16 | app: "prometheus-exporter-{{ type }}-{{ ansible_operator_meta.name }}" 17 | endpoints: 18 | - interval: {{ service_monitor.interval | default (service_monitor_interval) }} 19 | port: metrics 20 | path: /metrics 21 | relabelings: 22 | - sourceLabels: [__meta_kubernetes_service_label_prometheus_exporter] 23 | targetLabel: prometheus_exporter 24 | - sourceLabels: [__meta_kubernetes_service_label_prometheus_exporter_type] 25 | targetLabel: prometheus_exporter_type 26 | -------------------------------------------------------------------------------- /test/e2e/operator/00-assert.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: prometheus-exporter-operator-manager-role 6 | namespace: default 7 | --- 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: RoleBinding 10 | metadata: 11 | name: prometheus-exporter-operator-manager-rolebinding 12 | namespace: default 13 | --- 14 | apiVersion: v1 15 | kind: ServiceAccount 16 | metadata: 17 | name: prometheus-exporter-operator-controller-manager 18 | namespace: default 19 | --- 20 | apiVersion: apps/v1 21 | kind: Deployment 22 | metadata: 23 | name: prometheus-exporter-operator-controller-manager 24 | namespace: default 25 | status: 26 | readyReplicas: 1 27 | -------------------------------------------------------------------------------- /test/e2e/prometheusexporter-grafanadashboard-apiversion/01-assert.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: prometheus-exporter-memcached-example2-memcached 6 | namespace: default 7 | status: 8 | readyReplicas: 1 9 | --- 10 | apiVersion: v1 11 | kind: Service 12 | metadata: 13 | name: prometheus-exporter-memcached-example2-memcached 14 | namespace: default 15 | --- 16 | apiVersion: monitoring.coreos.com/v1 17 | kind: ServiceMonitor 18 | metadata: 19 | name: prometheus-exporter-memcached-example2-memcached 20 | namespace: default 21 | --- 22 | apiVersion: grafana.integreatly.org/v1beta1 23 | kind: GrafanaDashboard 24 | metadata: 25 | name: prometheus-exporter-memcached 26 | namespace: default -------------------------------------------------------------------------------- /test/e2e/prometheusexporter-grafanadashboard-apiversion/01-prometheusexporter.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: example2-memcached 5 | namespace: default 6 | spec: 7 | type: memcached 8 | grafanaDashboard: 9 | label: 10 | key: discovery 11 | value: enabled 12 | apiVersion: v1beta1 13 | dbHost: your-memcached-host 14 | dbPort: 11211 -------------------------------------------------------------------------------- /test/e2e/prometheusexporter/01-assert.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: prometheus-exporter-memcached-example-memcached 6 | namespace: default 7 | status: 8 | readyReplicas: 1 9 | --- 10 | apiVersion: v1 11 | kind: Service 12 | metadata: 13 | name: prometheus-exporter-memcached-example-memcached 14 | namespace: default 15 | --- 16 | apiVersion: monitoring.coreos.com/v1 17 | kind: ServiceMonitor 18 | metadata: 19 | name: prometheus-exporter-memcached-example-memcached 20 | namespace: default 21 | --- 22 | apiVersion: integreatly.org/v1alpha1 23 | kind: GrafanaDashboard 24 | metadata: 25 | name: prometheus-exporter-memcached 26 | namespace: default -------------------------------------------------------------------------------- /test/e2e/prometheusexporter/01-prometheusexporter.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.3scale.net/v1alpha1 2 | kind: PrometheusExporter 3 | metadata: 4 | name: example-memcached 5 | namespace: default 6 | spec: 7 | type: memcached 8 | grafanaDashboard: 9 | label: 10 | key: discovery 11 | value: enabled 12 | dbHost: your-memcached-host 13 | dbPort: 11211 -------------------------------------------------------------------------------- /watches.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Use the 'create api' subcommand to add watches to this file. 3 | - version: v1alpha1 4 | group: monitoring.3scale.net 5 | kind: PrometheusExporter 6 | role: prometheusexporter 7 | #+kubebuilder:scaffold:watch 8 | --------------------------------------------------------------------------------