├── .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 |
4 |
5 | [](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/test.yaml)
6 | [](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/release.yaml)
7 | [](https://github.com/3scale-sre/prometheus-exporter-operator/actions/workflows/release-catalog.yaml)
8 | [](https://github.com/3scale-sre/prometheus-exporter-operator/releases)
9 | [](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 |
73 |
74 | ### Redis example dashboard
75 |
76 |
77 |
78 | ### MySQL example dashboard
79 |
80 |
81 |
82 | ### PostgreSQL example dashboard
83 |
84 |
85 |
86 | ### Sphinx example dashboard
87 |
88 |
89 |
90 | ### Manticore example dashboard
91 |
92 |
93 |
94 | ### Elasticsearch example dashboard
95 |
96 |
97 |
98 | ### AWS CloudWatch example dashboard
99 |
100 |
101 |
102 | ### Blackbox probe example dashboard
103 |
104 |
105 |
106 | ### Sendgrid example dashboard
107 |
108 |
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 |
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 |
--------------------------------------------------------------------------------