Compare commits

...

744 Commits

Author SHA1 Message Date
stakater-user
f7de66d67f [skip-ci] Update artifacts 2023-08-02 07:02:10 +00:00
Muhammad Shahid Hussain
a74845aab2 Merge pull request #467 from PatrickSpies/feat/chart-netpol
feat: add optional networkpolicy to helm-chart
2023-08-02 11:55:31 +05:00
Karl-Johan Grahn
b228cb4c8b Merge branch 'master' into feat/chart-netpol 2023-07-26 10:04:30 +02:00
renovate[bot]
ffe6c6577d Update stakater/.github action to v0.0.44 (#502)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-26 10:04:00 +02:00
stakater-user
6df7459937 [skip-ci] Update artifacts 2023-07-21 08:07:45 +00:00
Bharath Nallapeta
f847f2ff46 Merge pull request #501 from stakater/fix_token
Updated checkout step of push action to use our token instead of the default github token
2023-07-21 13:31:36 +05:30
bnallapeta
b29fbc9ace Updated checkout step of all actions to use our token instead of the default github token 2023-07-21 13:21:12 +05:30
Bharath Nallapeta
d9e742cf7f Merge pull request #500 from stakater/remove-persist-cred
Remove persist-credentials flag in checkout step of the actions
2023-07-21 12:55:11 +05:30
Bharath Nallapeta
ad70134967 Remove persist-credentials flag in checkout step of the actions
- Setting this to false causes the GitHub action to use the PAT of the person who pushed the changes to the repo. 
- Removing this will set the value to true by default thereby persisting inbuilt github_token across all the steps including the commit step which is currently failing.
- GitHub removes this in post-run step.
2023-07-21 12:45:38 +05:30
stakater-user
18dad59d13 [skip-ci] Update artifacts 2023-07-21 07:07:53 +00:00
Bharath Nallapeta
bef48f3cff Merge pull request #460 from stakater/renovate/golang-1.x
Update golang Docker tag to v1.20.6
2023-07-21 11:49:33 +05:30
renovate[bot]
5efcc588d2 Update golang Docker tag to v1.20.6 2023-07-19 14:18:04 +00:00
Bharath Nallapeta
0bc229fad9 Merge pull request #499 from gmodzelewski/master
#491 Readme: Add OpenShift 4.13 runAsUser unset part
2023-07-19 19:46:23 +05:30
Georg Modzelewski
ef380c480a #491 Readme: Add OpenShift 4.13 runAsUser unset part 2023-07-19 11:37:01 +02:00
stakater-user
2bdb469179 [skip-ci] Update artifacts 2023-07-17 07:08:09 +00:00
Itai Spiegel
d018bbd7d3 Change pull_request trigger to pull_request_target (#498) 2023-07-17 08:46:37 +02:00
Spies, Patrick - F0217791
e9e2647e69 fix typo 2023-07-13 09:44:49 +02:00
Spies, Patrick - F0217791
b0fa2f6b36 fix: add missing new chart-yaml 2023-07-13 09:44:49 +02:00
Spies, Patrick - F0217791
c1bec21d4d fix: do not git-ignore reloader-chart 2023-07-13 09:44:49 +02:00
Spies, Patrick - F0217791
ded69baa8b feat: add optional networkpolicy to helm-chart 2023-07-13 09:44:49 +02:00
stakater-user
efbbe3cb59 [skip-ci] Update artifacts 2023-06-27 14:46:58 +00:00
Karl-Johan Grahn
87ecf87af6 Helm chart unit tests (#484)
* update

* update
2023-06-27 16:39:03 +02:00
stakater-user
cd4f9487f6 [skip-ci] Update artifacts 2023-06-27 14:00:34 +00:00
Karl-Johan Grahn
6fdced56d8 Update README.md (#483) 2023-06-27 13:13:17 +02:00
Karl-Johan Grahn
29310fe3ae Enterprise version and doc QA checks (#480)
* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update
2023-06-26 20:32:02 +02:00
Karl-Johan Grahn
845a6d85c6 Delete dependabot.yml (#475) 2023-06-12 10:55:59 +02:00
stakater-user
11fb414965 [skip-ci] Update artifacts 2023-06-08 08:11:18 +00:00
Hussnain Ahmad
6eae8353a1 Merge pull request #447 from jkroepke/patch-1
Remove v version prefix from helm chart
2023-06-08 13:03:07 +05:00
Jan-Otto Kröpke
12f5515197 Merge branch 'master' into patch-1 2023-05-31 11:00:55 +02:00
stakater-user
306a988ace [skip-ci] Update artifacts 2023-05-31 08:19:27 +00:00
renovate[bot]
c0067a2608 Add renovate.json (#456)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-31 10:11:51 +02:00
stakater-user
93160891f5 [skip-ci] Update artifacts 2023-05-24 08:31:42 +00:00
Moulick Aggarwal
385b3c7684 Update Go setup for GitHub Actions workflows (#444) 2023-05-24 10:10:17 +02:00
Jan-Otto Kröpke
05f84acbf8 Remove v version prefix from helm chart 2023-05-11 09:20:41 +02:00
Jan-Otto Kröpke
d08b0afe0f Remove v version prefix from helm chart 2023-05-11 09:19:34 +02:00
stakater-user
b6e6c17df4 [skip-ci] Update artifacts 2023-04-27 11:58:42 +00:00
Faizan Ahmad
123cdbdf6b Merge pull request #442 from stakater/update-golang-and-dependencies
Update golang version and dependencies
2023-04-27 13:37:36 +02:00
stakater-user
b7220dac28 [skip-ci] Update artifacts 2023-04-27 10:50:23 +00:00
Hussnain Ahmad
e156cfb167 Merge pull request #443 from stakater/readme-update
Updated broken links in readme
2023-04-27 15:41:45 +05:00
hussnain612
9ff2c349af Updated broken links in readme 2023-04-27 15:10:26 +05:00
faizanahmad055
197cd078e2 Update golang version and dependencies
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-04-27 09:27:54 +02:00
stakater-user
09e8e5a4cb [skip-ci] Update artifacts 2023-04-05 07:39:25 +00:00
Muneeb Aijaz
c84cf916be Merge pull request #430 from ctrought/feat-enhancelabelselectors
feat: Configmap/secret label selector & refactor namespace selector
2023-04-05 12:20:01 +05:00
stakater-user
c3c700a7a9 [skip-ci] Update artifacts 2023-04-05 06:40:47 +00:00
Hussnain Ahmad
1bdc540700 Merge pull request #298 from karl-johan-grahn/fix-255
fix(255): push image to ghcr instead of docker hub
2023-04-05 11:32:09 +05:00
Hussnain
ddbe3036af Merge remote-tracking branch 'upstream/master' into fix-255 2023-04-05 11:19:34 +05:00
Hussnain
aab8f66b34 Updated actions dependencies 2023-04-05 11:17:26 +05:00
Hussnain
3e88e06199 Updated image path 2023-04-05 11:04:31 +05:00
Hussnain
32ab2ada09 Updated github actions to push to ghcr and dockerHub 2023-04-05 11:04:18 +05:00
stakater-user
71a2b2347a [skip-ci] Update artifacts 2023-04-05 05:55:18 +00:00
Muneeb Aijaz
ca9715b231 Merge pull request #427 from Whisper40/master
 feat: Implement topologySpreadConstraints to improve redundancy (fix #426)
2023-04-05 10:49:14 +05:00
stakater-user
32bda1a2ed [skip-ci] Update artifacts 2023-04-05 05:44:22 +00:00
Muneeb Aijaz
7f706bc130 Merge pull request #431 from Whisper40/patch-1
 feat: Implement initialDelaySeconds for readinessProbe & livenessPr…
2023-04-05 10:36:29 +05:00
Kévin PEREZ
7d08a6a28f feat: Implement initialDelaySeconds for readinessProbe & livenessProbe (fix #429)
PR respond to this feature request : https://github.com/stakater/Reloader/issues/429
2023-04-03 16:17:41 +02:00
ctrought
9ac351c219 fix: controller label selectors as string
Signed-off-by: Craig Trought <k8s@trought.ca>
2023-04-02 16:47:54 -04:00
ctrought
24e794bb38 fix: skip controller creation for namespace in test
Signed-off-by: Craig Trought <k8s@trought.ca>
2023-04-02 16:47:17 -04:00
ctrought
8e8ce51313 docs: update label selector usage
Signed-off-by: Craig Trought <k8s@trought.ca>
2023-04-02 15:48:12 -04:00
ctrought
8ed0899ff3 fix: use apimachinery labelSelector parser to align with string implementation, supports != operator
Signed-off-by: Craig Trought <k8s@trought.ca>
2023-04-02 15:38:58 -04:00
ctrought
f00448dfbd docs: cleanup labelSelector documentation
Signed-off-by: Craig Trought <k8s@trought.ca>
2023-04-02 15:38:56 -04:00
ctrought
2b619a9243 fix: namespace list/watch permission when using namespaceSelectors
Signed-off-by: Craig Trought <k8s@trought.ca>
2023-04-02 01:31:53 -04:00
ctrought
27c0a9b328 feat: additional labelSelector support
* add option to configure labelSelectors on configmaps & secrets
* support all labelSelectors
* label selector tests
* legacy support for ':' delimited selectors and wildcards

Signed-off-by: Craig Trought <k8s@trought.ca>
2023-03-31 19:08:10 -04:00
ctrought
e39a8f6bcf refactor: use Namespace controller for namespaceSelector
Signed-off-by: Craig Trought <k8s@trought.ca>
2023-03-31 19:08:10 -04:00
stakater-user
3907495a42 [skip-ci] Update artifacts 2023-03-30 19:19:37 +00:00
Rasheed Amir
07889755d9 fix email address (#425) 2023-03-30 21:12:57 +02:00
Kévin PEREZ
49c8f78cff Add topologySpreadConstraints 2023-03-30 09:49:49 +02:00
stakater-user
08ceb6126c [skip-ci] Update artifacts 2023-03-30 05:48:32 +00:00
dhia-gharsallaoui
4b13852de0 fix typo (#423) 2023-03-30 07:27:33 +02:00
stakater-user
197f009fc9 [skip-ci] Update artifacts 2023-03-27 06:54:41 +00:00
Faizan Ahmad
4bc71b145e Merge pull request #421 from stakater/update-go-version-and-dependencies 2023-03-27 08:32:12 +02:00
faizanahmad055
be83553487 Update go version to 1.20.2 and update dependencies
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-03-25 21:45:33 +01:00
stakater-user
b193a7b94c [skip-ci] Update artifacts 2023-03-10 23:25:51 +00:00
Faizan Ahmad
ba64c8ff4d Merge pull request #412 from jstewart612/patch-1
[helm] deployment replicas int comparison fix
2023-03-11 00:19:17 +01:00
John Stewart
1c165c86da [helm] make sure comparison for deployment replicas is always doing so against an int 2023-03-10 16:31:09 -05:00
stakater-user
6498f5a536 [skip-ci] Update artifacts 2023-03-10 17:03:18 +00:00
Faizan Ahmad
7745a1ff52 Merge pull request #410 from jordanfelle/patch-1
Fixing eval for enabling HA
2023-03-10 17:54:51 +01:00
jordanfelle
a8ee7068a5 Fixing eval for enabling HA
When set to 1.0

 <gt .Values.reloader.deployment.replicas 1.0>: error calling gt: incompatible types for comparison

But works when set to 1
2023-03-10 06:44:06 -05:00
stakater-user
8f8b95bf57 [skip-ci] Update artifacts 2023-03-10 09:13:06 +00:00
Tanveer Alam
a32789f13b Merge pull request #409 from stakater/add-sync-after-restart
Implement sync after restart
2023-03-10 14:36:44 +05:30
faizanahmad055
77b725c598 Update readme
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-03-09 23:16:50 +01:00
faizanahmad055
cf40b431a3 Implement sync after restart
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-03-09 23:02:19 +01:00
stakater-user
e0a1c25fee [skip-ci] Update artifacts 2023-03-06 14:31:59 +00:00
Usama Ahmad
a746df7a03 Merge pull request #404 from stakater/update-golang-and-dependencies
Update go version and dependencies
2023-03-06 19:10:43 +05:00
faizanahmad055
47190ec8b1 Update k8s.io dependencies
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-03-06 08:43:18 +01:00
faizanahmad055
a00f7bf83e Remove namespace from clusterrole and clusterrolebinding
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-03-05 17:59:44 +01:00
stakater-user
2b29700fa4 [skip-ci] Update artifacts 2023-03-03 22:20:53 +00:00
frits-v
84e927fd60 fix: remove cluster-scoped resources namespace (#402)
`/metadata/namespace` is invalid for cluster-scoped resources. Having it
defined results in errors in certain tooling.

```
KNV1052: cluster-scoped resources MUST NOT declare metadata.namespace
```
2023-03-03 23:12:42 +01:00
faizanahmad055
2d1af6429e Update golang version and dependencies
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-27 20:22:13 +01:00
stakater-user
80a7f1ee9f [skip-ci] Update artifacts 2023-02-26 15:15:01 +00:00
Faizan Ahmad
fdc99f8dd3 Merge pull request #398 from yu-croco/add-fullname-override-on-values
[helm] Add nameOverride and fullnameOverride explicitly on values.yaml
2023-02-26 15:55:31 +01:00
yu-croco
d660f9dbdf Merge branch 'master' into add-fullname-override-on-values 2023-02-26 22:45:11 +09:00
yu-croco
ad03e5830d chore: Add nameOverride and fullnameOverride explicitly on values.yaml
Signed-off-by: yu-croco <yu.croco@gmail.com>
2023-02-26 22:42:17 +09:00
stakater-user
032c391cb8 [skip-ci] Update artifacts 2023-02-26 12:43:03 +00:00
Faizan Ahmad
9173f446ab Merge pull request #396 from stakater/update-push-workflow
Remove outdated manifests
2023-02-26 13:23:25 +01:00
stakater-user
f795fa2aec [skip-ci] Update artifacts 2023-02-26 12:07:53 +00:00
Faizan Ahmad
34c1f389bc Merge pull request #393 from stakater/dependabot/go_modules/golang.org/x/net-0.7.0
Bump golang.org/x/net from 0.5.0 to 0.7.0
2023-02-26 12:48:16 +01:00
stakater-user
fdc8a61fc6 [skip-ci] Update artifacts 2023-02-26 11:35:45 +00:00
Faizan Ahmad
c7f507a4b9 Merge pull request #386 from d3adb5/feat/set-rootfs-ro
feat: set read-only root filesystem at container level
2023-02-26 12:16:42 +01:00
stakater-user
70aef8a871 [skip-ci] Update artifacts 2023-02-26 10:59:11 +00:00
Faizan Ahmad
54d0681340 Merge pull request #385 from d3adb5/chore/stop-listening-on-9091
chore: listen on only 9090 for /metrics and /live
2023-02-26 11:39:45 +01:00
MahnoorAsghar
b279aabae3 Remove changes from push workflow 2023-02-24 13:50:48 +05:00
MahnoorAsghar
63022fe4d0 Remove optional manifests which are outdated 2023-02-24 13:48:38 +05:00
MahnoorAsghar
8c4523db69 update push workflow to render manifests correctly 2023-02-22 16:45:43 +05:00
dependabot[bot]
646c64a326 Bump golang.org/x/net from 0.5.0 to 0.7.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.5.0 to 0.7.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.5.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-18 04:14:25 +00:00
d3adb5
5a9ccbf01f fix: properly capitalize 'filesystem' in values
Use the proper capitalization in the reference to the value
reloader.readOnlyRootFileSystem: FileSystem instead of Filesystem.
2023-02-08 14:15:28 -08:00
stakater-user
0f7403b7bf [skip-ci] Update artifacts 2023-02-07 17:35:32 +00:00
Faizan Ahmad
2bc83a26ff Merge pull request #383 from jkroepke/service-monitor
[helm] Add support for relabelings and metricRelabelings for serviceMonitor/podMonitor
2023-02-07 18:12:31 +01:00
Jan-Otto Kröpke
09babe46d9 [helm] Add support for relabelings and metricRelabelings for serviceMonitor/podMonitor 2023-02-07 11:20:29 +01:00
d3adb5
451e4f636b feat: set read-only root filesystem at container level
Change the securityContext field of the Reloader container if
reloader.readOnlyFilesystem is set to true. The change takes effect even
if not container securityContext is defined.

Closes #339.
2023-02-07 00:16:16 -08:00
d3adb5
2f8999e3cb chore: listen on only 9090 for /metrics and /live
Previously, 9091 and 9090 both led to the same web server, meaning both
/metrics and /live were reachable and fully functional through both.
This commit changes that so that only port 9090 is used for both.

Closes #381.
2023-02-07 00:15:17 -08:00
stakater-user
9463cd5fc2 [skip-ci] Update artifacts 2023-02-06 22:59:31 +00:00
Faizan Ahmad
5e2f4a0826 Merge pull request #391 from stakater/remove-depreciated-seed
Remove depreciated Seed
2023-02-06 23:37:53 +01:00
faizanahmad055
0083edb3ca Remove depreciated Seed
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-06 23:13:07 +01:00
Faizan Ahmad
d020c666b7 Merge pull request #390 from stakater/update-golangci-lint
Update golangci-lint version
2023-02-06 22:25:13 +01:00
faizanahmad055
3d29651267 Update golangci-lint version
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-06 22:22:36 +01:00
Faizan Ahmad
795aae0c78 Merge pull request #389 from stakater/update-pipeline
Update pipeline
2023-02-06 22:14:50 +01:00
faizanahmad055
364d66b90f Remove extra line
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-06 22:13:58 +01:00
faizanahmad055
2d8f0336dc Fix go version
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-06 22:13:16 +01:00
faizanahmad055
5716c1b35e Update pipeline
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-06 22:08:31 +01:00
Faizan Ahmad
fecd21deca Merge pull request #388 from stakater/update-github-actions
[skip-ci] Update github actions
2023-02-06 22:04:31 +01:00
faizanahmad055
5cd8b3d4ca [skip-ci] Update github actions
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-06 22:02:22 +01:00
Faizan Ahmad
991613bd13 Merge pull request #384 from stakater/update-go-1.20
Update golang version to 1.20
2023-02-05 17:17:43 +01:00
faizanahmad055
ef93197da1 Remove unused dependencies
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-05 16:10:34 +01:00
faizanahmad055
35754ccd73 Update dependencies
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-05 16:01:03 +01:00
faizanahmad055
d6d531e08e Update golang version to 1.20
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-02-05 15:11:23 +01:00
stakater-user
adff75f040 [skip-ci] Update artifacts 2023-01-30 14:39:35 +00:00
Faizan Ahmad
3e364186c9 Merge pull request #380 from Allex1/master
[helm] - Add template option to pod/servicemonitor ns/labels
2023-01-30 15:33:01 +01:00
birca
edb482d4ba remove version 2023-01-30 16:22:35 +02:00
birca
1f2d75898b [helm] - Add template option to pod/servicemonitor ns/labels 2023-01-27 13:09:47 +02:00
stakater-user
7f331907d3 [skip-ci] Update artifacts 2023-01-19 16:48:47 +00:00
Faizan Ahmad
29aa52a1c7 Merge pull request #377 from stakater/update-golang-dependencies
Update golang version and dependencies
2023-01-19 17:41:34 +01:00
faizanahmad055
ada8dbb5f3 Update golang version and dependencies
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-01-19 17:02:03 +01:00
Karl-Johan Grahn
cfe1754c44 Add dependabot (#371)
* Add dependabot

* update
2023-01-18 11:43:45 +01:00
stakater-user
2cfce5144b [skip-ci] Update artifacts 2023-01-12 20:29:14 +00:00
Faizan Ahmad
2fe863a054 Merge pull request #369 from stakater/create-release-1.0.0
Create release 1.0.0
2023-01-12 21:22:29 +01:00
faizanahmad055
3e01091d01 Create release 1.0.0
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2023-01-12 20:47:09 +01:00
stakater-user
7f85a8e53b [skip-ci] Update artifacts 2023-01-05 22:05:37 +00:00
Faizan Ahmad
c679157e24 Merge pull request #356 from avihuly/feature/namespace-selector
Namespace selector
2023-01-05 22:45:22 +01:00
avihuly
9e7b70964e Added wildcard label vaule option 2023-01-05 14:28:08 +02:00
avihuly
8ebbb476b2 Added logs on startup & get ns opration 2023-01-05 12:54:08 +02:00
avihuly
9263b812eb Added namespace get verb to reloder clusterrole 2023-01-05 12:51:41 +02:00
stakater-user
f70dd52b2d [skip-ci] Update artifacts 2022-12-29 17:33:11 +00:00
Faizan Ahmad
e0a8f1ad04 Merge pull request #354 from joaoubaldo/support-imagepullsecrets
[Helm chart] Add support for ImagePullSecrets
2022-12-29 18:26:28 +01:00
stakater-user
45dac417cb [skip-ci] Update artifacts 2022-12-29 17:02:47 +00:00
Faizan Ahmad
1514c5bcd2 Merge pull request #366 from zv0n/master
Add option to use existing secret to Helm chart
2022-12-29 17:44:57 +01:00
Avi Huli
e7cfafd6d6 Handle empty selector & ns label key not exists 2022-12-27 18:49:23 +02:00
Avi Huli
15d7263c95 Handle empty selector & ns label key not exists 2022-12-27 18:44:59 +02:00
Avi Huli
de21a400ab Readme namespace selector 2022-12-22 14:28:15 +02:00
Avi Huly
e702610dc6 Readme 2022-12-19 14:35:28 +02:00
Avi Huly
481eeeffc4 Merge pull request #2 from stakater/master
Updates from master
2022-12-18 15:23:24 +02:00
Tomáš Zvoník
801e1dabed Add option to use existing secret to Helm chart 2022-12-16 13:55:50 +01:00
stakater-user
5c44c1e8f5 [skip-ci] Update artifacts 2022-12-07 15:46:37 +00:00
Tehreem
0ef6dcb510 Merge pull request #365 from stakater/make-namespace-configurable
Enable ability to override Release.Namespace for target namespace
2022-12-07 20:40:04 +05:00
Callum MacDonald
0ef5e75673 fix indentation 2022-12-07 09:18:15 +01:00
Callum MacDonald
e5f85ae37b Enable ability to override Release.Namespace for target namespace 2022-12-07 09:11:46 +01:00
stakater-user
5d0e9ca70b [skip-ci] Update artifacts 2022-12-01 06:34:43 +00:00
Faizan Ahmad
297baa08d5 Update helm version in pipeline (#364) 2022-12-01 07:15:22 +01:00
Faizan Ahmad
dd1433a7a9 Merge pull request #363 from stakater/update-log-level
Update log level
2022-12-01 00:08:09 +01:00
faizanahmad055
9875c416df Update log level to error and debug
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-11-30 22:43:06 +01:00
faizanahmad055
b414e3b350 Update log level
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-11-30 22:37:50 +01:00
faizanahmad055
e417e8bc12 Add error log
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-11-30 22:35:39 +01:00
faizanahmad055
aafe3365eb Update log level
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-11-30 22:34:02 +01:00
Faizan Ahmad
694baf715c Merge pull request #361 from AgustinRamiroDiaz/update-okteto-yaml
Upgrade okteto yaml manifest to v2
2022-11-30 22:31:15 +01:00
Faizan Ahmad
48b188d7b4 Merge pull request #362 from stakater/bump-go-version
Update go version and dependencies
2022-11-30 22:12:34 +01:00
faizanahmad055
d1cb53b65a Update go version and dependencies
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-11-30 21:31:59 +01:00
Agustin Ramiro Diaz
cefd633176 upgrade okteto yaml to v2
Signed-off-by: Agustin Ramiro Diaz <agustin.ramiro.diaz@gmail.com>
2022-11-25 09:36:27 -03:00
Avi Huly
08e6f81a15 Lint fix 2022-11-15 16:23:24 +02:00
Avi Huly
edbad45637 namespaceSelector chart value 2022-11-15 11:22:23 +02:00
Avi Huly
363fbd3b77 Test for namespace selector 2022-11-15 11:11:11 +02:00
Avi Huly
82ee3ef3d1 Added namespace-selector to helm chart deployment 2022-11-13 16:38:54 +02:00
Avi Huly
21502e2bb4 Added namespace selector functionality
Changes:
	modified:   internal/pkg/cmd/reloader.go
	modified:   internal/pkg/controller/controller.go
	modified:   internal/pkg/util/util.go
2022-11-12 23:00:56 +02:00
Joao Ubaldo
9d3b70d4d2 Add support for ImagePullSecrets 2022-11-03 10:02:18 +00:00
stakater-user
5662919f72 [skip-ci] Update artifacts 2022-10-10 10:56:58 +00:00
Faizan Ahmad
445d0f870e Merge pull request #345 from avestuk/podDisruptionBudget
Add pod disruption budget
2022-10-10 12:50:26 +02:00
stakater-user
81e74fe830 [skip-ci] Update artifacts 2022-10-10 09:03:48 +00:00
Faizan Ahmad
50791ad51a Merge pull request #341 from avestuk/leadership-election
Leadership election
2022-10-10 10:57:25 +02:00
Alex Vest
6a65657e27 Add pod disruption budget 2022-10-06 11:51:28 +01:00
Alex Vest
1c7190884a Merge branch 'master' into leadership-election 2022-10-06 11:17:35 +01:00
stakater-user
e0fcc3bfa6 [skip-ci] Update artifacts 2022-10-04 18:37:34 +00:00
Faizan Ahmad
504b5a8eb0 Merge pull request #343 from junnplus/record-event
support record event
2022-10-04 20:30:45 +02:00
Alex Vest
488eaa9bef Run leadership election as non blocking
Liveness probe endpoint will always be blocking on the main thread
2022-10-04 16:41:34 +01:00
Alex Vest
676c3703aa Set replicas = 1 by default, override if HA is enabled 2022-10-04 16:41:34 +01:00
Alex Vest
deec4df125 Fix pod antiaffinity 2022-10-04 16:41:34 +01:00
Alex Vest
eedc8e81d0 Set enableHA and reloadOnCreate to false 2022-10-04 16:41:34 +01:00
Alex Vest
28456ffafe Add PodAntiAffinity if HA is enabled 2022-10-04 16:41:34 +01:00
Alex Vest
a7c3ae37aa Expand documentation about reloadOnCreate 2022-10-04 16:41:34 +01:00
Alex Vest
d043bcf7be Fix roles 2022-10-04 16:41:34 +01:00
Alex Vest
72a1c59cac Err check response writer 2022-10-04 16:41:34 +01:00
Alex Vest
6299b1d8e9 Update helm chart with new liveness probe 2022-10-04 16:41:34 +01:00
Alex Vest
11ae057b0a Add tests for leadership election
Pull liveness into leadership to ease testing, logically the liveness
probe is directly affected by leadership so it makes sense here.

Moved some of the components of the controller tests into the testutil
package for reuse in my own tests.
2022-10-04 16:41:34 +01:00
Alex Vest
d34c99baf4 Add liveness probe 2022-10-04 16:41:34 +01:00
Alex Vest
b7e83b74d8 Move leadership to its own package 2022-10-04 16:41:34 +01:00
Alex Vest
919f75bb62 Shutdown on leader election loss 2022-10-04 16:41:34 +01:00
Alex Vest
16079bd1d4 Update helm chart for HA in global mode 2022-10-04 16:41:34 +01:00
Alex Vest
401d4227d1 Move consts to const pkg
Should move leadership bits to own pkg?
2022-10-04 16:41:34 +01:00
Alex Vest
7f9f32ca58 Add leadership election 2022-10-04 16:41:34 +01:00
Ye Sijun
6937b8120b support record event
Signed-off-by: Ye Sijun <junnplus@gmail.com>
2022-09-30 21:30:16 +09:00
stakater-user
be80ce35b2 [skip-ci] Update artifacts 2022-09-29 14:30:10 +00:00
Faizan Ahmad
99349ce361 Merge pull request #329 from kenske/patch-1
Remove server side call from podmonitoring template
2022-09-29 16:09:18 +02:00
stakater-user
3a1b808169 [skip-ci] Update artifacts 2022-09-27 22:01:25 +00:00
Faizan Ahmad
798079eb53 Merge pull request #327 from AnuragEkkati/master
Reloader Reporting and Alerting #320
2022-09-27 23:38:34 +02:00
Anurag Ekkati
98749f2c9b Fixing Merge failures 2022-09-26 20:24:00 -07:00
Anurag Ekkati
3a675696cd Merge branch 'master' into master 2022-09-26 20:12:20 -07:00
Anurag Ekkati
632eeaa527 Adding Alerting Docs 2022-09-26 19:33:07 -07:00
stakater-user
9c85ce404b [skip-ci] Update artifacts 2022-09-20 06:40:06 +00:00
Karl-Johan Grahn
f8f8afca88 Merge pull request #338 from krouser/master
extra space removed
2022-09-20 08:33:30 +02:00
Stanlee
11dc048709 extra space removed
removed extra space in the yaml
2022-09-14 18:24:33 +02:00
Kenneth
328442c121 Remove server side call from podmonitoring template
The `.Capabilities.APIVersions.Has` is server side, which means it breaks in workflows where `helm template` is used (ArgoCD for example)
2022-08-12 11:27:28 -05:00
stakater-user
4304880b6b [skip-ci] Update artifacts 2022-07-15 06:10:21 +00:00
Tanveer Alam
aef99a7bb8 Merge pull request #328 from stakater/update-dep-version
Update go-reloader version to v3.8.0
2022-07-15 11:32:54 +05:30
hussnain612
e387b21ed6 Updated dependencies 2022-07-14 17:51:40 +05:00
hussnain612
b6de33d501 Updated replaced dependencies 2022-07-14 17:36:33 +05:00
MahnoorAsghar
48160e0414 Update go-reloader version 2022-07-14 15:22:05 +03:00
Anurag Ekkati
d998c1a19e Reloader Reporting and Alerting #320
Alert a webhook supporting service ( e.g, slack ) whenever reloader reloads
workload on change
2022-07-06 16:32:18 -07:00
stakater-user
0b7ca82218 [skip-ci] Update artifacts 2022-06-20 07:26:00 +00:00
Faizan Ahmad
88fe843285 Merge pull request #311 from stakater/update-golang-version
Update golang version
2022-06-20 09:06:43 +02:00
faizanahmad055
cf31fed9d3 Merge branch 'master' of github.com:stakater/Reloader into update-golang-version 2022-06-18 23:56:53 +02:00
stakater-user
ba7f7537fb [skip-ci] Update artifacts 2022-06-18 21:55:13 +00:00
Faizan Ahmad
499ecf9da5 Merge pull request #314 from maxwell-jiang/reloader-update2
the specific configmap/secret name can be regexp-ly selected
2022-06-18 23:33:52 +02:00
stakater-user
6188811b94 [skip-ci] Update artifacts 2022-06-18 21:29:26 +00:00
faizanahmad055
0f2395309f Fix readme
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-06-18 23:17:38 +02:00
faizanahmad055
41d4fa56ca Merge branch 'master' of github.com:stakater/Reloader into update-golang-version 2022-06-18 23:13:35 +02:00
Faizan Ahmad
bf21677357 Merge pull request #316 from scottd018/fix-cve-crypto-golang-version
fix: Fixes #315, upgraded version of crypto package to non-vulnerable…
2022-06-18 22:54:47 +02:00
Karl-Johan Grahn
2cca412425 Merge branch 'master' into fix-255 2022-06-14 09:05:26 +02:00
stakater-user
c58d0965d5 [skip-ci] Update artifacts 2022-06-09 16:35:12 +00:00
Faizan Ahmad
ec1f7a68de Merge pull request #318 from daconstenla/patch-1
Set the namespace for the service
2022-06-09 18:11:53 +02:00
David Constenla
68a353d097 Set the namespace for the service
like for the other resources
2022-06-09 08:11:06 +02:00
Dustin Scott
c82886c921 fix: Fixes #315, upgraded version of crypto package to non-vulnerable version
As per CVE at https://nvd.nist.gov/vuln/detail/CVE-2020-29652, upgraded to the acceptable version.
It should be noted that this PR was originally in place to cover an upgrade to go version 1.17.9, however
a PR was discovered at https://github.com/stakater/Reloader/pull/311 which can be merged
independently of this one.  Once this commit is merged as well as https://github.com/stakater/Reloader/pull/311,
the fix for #315 is complete.

Signed-off-by: Dustin Scott <sdustin@vmware.com>
2022-06-01 11:52:16 -05:00
Maxwell Jiang
4b9844f5c3 the specific configmap/secret name can be regexp-ly selected 2022-05-31 01:34:56 -05:00
stakater-user
1e4016587c [skip-ci] Update artifacts 2022-05-27 10:08:24 +00:00
faizanahmad055
198e5631d4 Merge branch 'master' of github.com:stakater/Reloader into update-golang-version 2022-05-27 11:46:17 +02:00
Faizan Ahmad
f21ad29188 Merge pull request #312 from stakater/remove-spell-checker
Remove spell-checker
2022-05-27 11:45:22 +02:00
faizanahmad055
cd7ec500a7 Remove deadlink
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-05-27 11:36:07 +02:00
faizanahmad055
030e51351a Remove spell-checker
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-05-27 11:18:24 +02:00
faizanahmad055
8703c150e0 Remove deadlink
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-05-27 10:37:43 +02:00
faizanahmad055
1d7192180f Merge branch 'master' of github.com:stakater/Reloader into update-golang-version 2022-05-26 18:24:38 +02:00
stakater-user
9d1733200a [skip-ci] Update artifacts 2022-05-26 15:33:56 +00:00
Faizan Ahmad
841db3c829 Merge pull request #310 from stakater/remove-docker-lint
Remove docker linting from Pull request
2022-05-26 17:11:18 +02:00
stakater-user
1155c981d6 [skip-ci] Update artifacts 2022-05-26 14:18:53 +00:00
faizanahmad055
d29c99ffef Remove docker linting from Pull request
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-05-26 14:57:51 +02:00
faizanahmad055
3b572568be Update golang version to 1.18.2
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-05-26 14:50:23 +02:00
Abdul Haseeb
3e5b1d09b8 Merge pull request #308 from stakater/update-golang-cli-version
Update golang-cli package versions
2022-05-26 17:47:59 +05:00
faizanahmad055
61b7a88462 Update golang-cli package versions
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-05-26 14:46:32 +02:00
Faizan Ahmad
d9d986f1f2 Merge pull request #297 from karl-johan-grahn/doc-qa
feat(qa): add qa checks for dockerfile and documentation
2022-04-04 21:06:56 +02:00
stakater-user
42a25bfe64 [skip-ci] Update artifacts 2022-03-25 12:04:59 +00:00
Faizan Ahmad
df667b9c15 Merge pull request #296 from stefan-work/master
feat(kubernetes/chart): explicitly mount service-account-token in dep…
2022-03-25 12:57:47 +01:00
Stefan Klein
f1c71731d9 feat(kubernetes/chart): explicitly mount service-account-token in deployment 2022-03-25 12:09:10 +01:00
Karl-Johan Grahn
72ae858c14 fix(255): add back 2022-03-21 22:40:17 +01:00
Karl-Johan Grahn
77e2df9dfb fix(255): checkout does not work as expected 2022-03-21 22:34:45 +01:00
Karl-Johan Grahn
a5bb0392b1 fix(255): add registry var 2022-03-21 21:58:44 +01:00
Karl-Johan Grahn
cb39cf1a03 fix(255): update pr workflow too 2022-03-21 21:57:56 +01:00
Karl-Johan Grahn
3b94615934 fix(255): push image to ghcr instead of docker hub 2022-03-21 21:51:33 +01:00
Karl-Johan Grahn
e2b14ab7b5 fix(qa): update dockerfile path 2022-03-21 21:32:49 +01:00
Karl-Johan Grahn
4592bd4331 feat(qa): add qa checks for dockerfile and documentation 2022-03-21 21:03:39 +01:00
stakater-user
e380fbaf03 [skip-ci] Update artifacts 2022-03-02 20:49:44 +00:00
Faizan Ahmad
2bce1352a3 Merge pull request #292 from alin-taranu/upgrade-go-version-to-1.17.7
Update go version to fix critical vulnerabilities
2022-03-02 21:42:39 +01:00
Alin Taranu
5b3b617f06 Update go version to fix critical vulnerabilites
The following CVEs should be fix by upgrading go version:
* CVE-2022-23806
* CVE-2022-23772
* CVE-2021-44717
* CVE-2022-23773
* CVE-2021-44716
* CVE-2021-41771
* CVE-2021-41772
2022-03-02 13:41:07 +01:00
stakater-user
5040a4236a [skip-ci] Update artifacts 2022-02-27 18:58:50 +00:00
Faizan Ahmad
f6cbc005fc Merge pull request #281 from ruinshe/add-container-sc-support
Add container security context support for Helm chart
2022-02-27 19:50:15 +01:00
stakater-user
91774c941f [skip-ci] Update artifacts 2022-02-27 18:40:03 +00:00
Faizan Ahmad
db0e127563 Merge pull request #282 from AyoyAB/feature/enable-internal-build
Enable internal builds without direct Internet access
2022-02-27 19:31:29 +01:00
John Allberg
3671d33447 Enable setting GOPROXY and GOPRIVATE during build. 2022-02-27 10:16:42 +01:00
John Allberg
e85176b5a7 Make build command more readable. 2022-02-27 10:16:42 +01:00
John Allberg
7941de60ac Enable setting builder and base image during build. 2022-02-27 10:16:38 +01:00
stakater-user
565612e421 [skip-ci] Update artifacts 2022-02-26 22:43:34 +00:00
Faizan Ahmad
31e247e3ae Merge pull request #291 from stakater/fix-reloading-on-create
Make reload on create optional
2022-02-26 23:22:54 +01:00
faizanahmad055
1e79b86f72 Update readme
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-02-20 00:00:04 +01:00
faizanahmad055
b5b684c67b Fix reload on create flag
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-02-19 23:23:33 +01:00
faizanahmad055
bbc6bd2dea Update go version
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-02-14 10:33:55 +01:00
faizanahmad055
61ce150d7c Make reload on create optional
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2022-02-13 19:53:49 +01:00
stakater-user
56e83ecde9 [skip-ci] Update artifacts 2022-02-13 12:16:49 +00:00
Faizan Ahmad
c33876508c Merge pull request #290 from ctschubel/master
add replicas config to helm-chart
2022-02-13 13:07:37 +01:00
ctschubel
55ea2e430e add replicas to values.yaml.tmpl 2022-02-10 19:33:29 +01:00
ctschubel
4beefc3f43 fix replica config value name in helm-chart 2022-02-10 16:05:03 +01:00
ctschubel
3b1d30141c add replicas config to helm-chart 2022-02-10 15:21:16 +01:00
Ruins He
fa75df8e96 feat(kubernetes/chart): add container security context configuration into values.yaml.tpl
Signed-off-by: Ruins He <lyhypacm@gmail.com>
2022-01-03 18:22:43 +08:00
Ruins He
21087aaddc feat(kubernetes/chart): add container security context support for Helm chart
Signed-off-by: Ruins He <lyhypacm@gmail.com>
2022-01-03 18:00:15 +08:00
stakater-user
766bc24241 [skip-ci] Update artifacts 2022-01-02 13:43:49 +00:00
Faizan Ahmad
8e3aad3b0e Merge pull request #280 from jsoref/issue-278
Add .Release.Namespace
2022-01-02 14:35:19 +01:00
Josh Soref
ce2866bf6a Add .Release.Namespace
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-01-02 01:46:17 -05:00
stakater-user
bcbaad8495 [skip-ci] Update artifacts 2021-11-08 21:27:34 +00:00
Faizan Ahmad
3346319082 Merge pull request #271 from stakater/fix-deployment-pipeline
Fix yaml error in deployment manifest
2021-11-08 22:17:38 +01:00
faizanahmad055
139aa43c1c Fix yaml error in deployment manifest
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2021-11-08 22:02:06 +01:00
Faizan Ahmad
11fdd40e41 Merge pull request #263 from Aenima4six2/aenima4six2/176
Issue 176 - Use pod templates annotations
2021-11-08 16:47:29 +01:00
aenima4six2
c4ce86cb0b 176 - Update helm chart with reloadStrategy support 2021-11-06 18:14:46 -04:00
aenima4six2
dfe7e9b3ca 176 - Add reload strategies to support pod annotation templates 2021-10-17 19:09:50 -04:00
stakater-user
1c29bfc084 [skip-ci] Update artifacts 2021-10-12 07:03:12 +00:00
Faizan Ahmad
c48e2bb8bb Merge pull request #269 from stakater/fix-reloader
Fix update path of reloader
2021-10-12 08:45:48 +02:00
hanzala1234
df40b5d02e Delete reloader.yam 2021-10-11 19:58:59 +05:00
hanzala1234
aa26a2222b Fix update path of reloader 2021-10-11 19:58:13 +05:00
stakater-user
f9d1a967c7 [skip-ci] Update artifacts 2021-10-11 14:43:27 +00:00
Faizan Ahmad
b2e1d3f0dd Merge pull request #268 from stakater/fix-pipeline
Generate manifest in separate file
2021-10-11 16:28:20 +02:00
hanzala
24478a9dd4 Update jumbo manifest in pipeline 2021-10-11 19:12:39 +05:00
hanzala
160525bd1f Fix command 2021-10-11 18:38:13 +05:00
hanzala
d9158ab602 Fix helm template command 2021-10-08 17:36:54 +05:00
hanzala
2b4cc64026 Generate manifest in separate file 2021-10-08 17:34:44 +05:00
stakater-user
ccd7dcb867 [skip-ci] Update artifacts 2021-09-30 08:29:26 +00:00
Faizan Ahmad
5c5c555a7f Merge pull request #264 from jamesgoodhouse/update_helm_notes
Update NOTES for Helm chart to be dynamic
2021-09-30 10:13:30 +02:00
James J. Goodhouse
273e4768f3 update helm chart NOTES to be dynamic 2021-09-28 09:16:49 -07:00
Ahmed Waleed Malik
69e359e9fc Merge pull request #259 from iamNoah1/better-readability
[skip-ci] better readiblity for example templates
2021-08-30 09:41:23 +05:00
Noah Ispas (iamNoah1)
e5352df348 better readiblity for example templates 2021-08-28 20:34:30 +02:00
stakater-user
f2b4e8e6c6 [skip-ci] Update artifacts 2021-07-30 06:35:22 +00:00
Ahmed Waleed Malik
99a38bff8e Merge pull request #254 from stakater/handle-resource-redeploy
fix: Reload pods after redeploy secrets or configmap
2021-07-30 11:20:35 +05:00
Ahmed Waleed Malik
d0aa627715 Merge pull request #253 from stakater/remove-unused-files
[skip-ci] Remove unused files
2021-07-30 10:56:58 +05:00
Waleed Malik
953cbe9d28 Reload resource if secret/configmap is re-created 2021-07-30 10:24:50 +05:00
Waleed Malik
f7873aba7b Update dependencies 2021-07-29 15:24:41 +05:00
Waleed Malik
f9728ecfff Add run target in Makefile 2021-07-29 15:24:30 +05:00
Waleed Malik
96a44153de Non-root user should be specified in numeric form in Dockerfile 2021-07-29 15:24:09 +05:00
Waleed Malik
cafbcbd2cb Update build image targetC 2021-07-29 14:56:43 +05:00
Waleed Malik
6397a35e32 Remove unused files 2021-07-29 14:33:04 +05:00
Waleed Malik
aea8592880 Update golangci-lint step in workflows 2021-07-29 14:32:56 +05:00
stakater-user
2aa514a34c [skip-ci] Update artifacts 2021-07-28 10:36:56 +00:00
Faizan Ahmad
ac39bc4eba Merge pull request #251 from aslafy-z/patch-1
docs(helm): podmonitor does not need service
2021-07-28 12:20:07 +02:00
Zadkiel
284d21686e docs(helm): podmonitor does not need service 2021-07-20 17:42:59 +02:00
stakater-user
00c0c11c76 [skip-ci] Update artifacts 2021-07-11 07:51:39 +00:00
Brandon Clifford
96ebfa8e62 Fix typo in Chart.yaml sources (#248) 2021-07-11 09:37:32 +02:00
stakater-user
95d442d80f [skip-ci] Update artifacts 2021-07-09 07:43:58 +00:00
Faizan Ahmad
e4e58882ab Merge pull request #246 from gciria/add-chart-liveness-readiness
Add Liveness and readiness probe timeout values
2021-07-09 09:29:41 +02:00
Gustavo Ciria
ea71fc0eec Create Chart.yaml 2021-07-08 13:07:43 -03:00
Gustavo Ciria
462b225d92 Delete Chart.yaml
Version and appVersion do not need to be updated manually.
2021-07-08 12:55:03 -03:00
Gustavo Ciria
d8728092f8 Add Liveness and readiness probe timeout values 2021-07-08 11:44:49 -03:00
stakater-user
2c8ef70c43 [skip-ci] Update artifacts 2021-06-28 14:19:33 +00:00
Faizan Ahmad
4d2c8a451e Merge pull request #243 from sfynx/master
Only enable Rollouts when enabled in Helm chart.
2021-06-28 16:03:38 +02:00
Henno Schooljan
f7927c85b1 Disable OpenShift by default, add notes in README. 2021-06-25 21:28:16 +02:00
Henno Schooljan
2e2fd2a11b Only enable Rollouts when enabled in Helm chart.
This prevents a permission issue in case Rollouts is available on a cluster, but the user does not have permission to use it (e.g. as a tenant on a cluster without cluster admin rights), and therefore also may not set permissions for it.

See issue #231.
2021-06-16 20:46:51 +02:00
stakater-user
0e6ec1d36b [skip-ci] Update artifacts 2021-06-15 17:40:07 +00:00
Faizan Ahmad
85b33d9104 Merge pull request #242 from stakater/actions-update
Added helm template step in push action
2021-06-15 19:25:54 +02:00
talha0324
c838ecbbc7 Updated command to one line 2021-06-15 19:52:28 +05:00
stakater-user
068a5c1e64 [skip-ci] Update artifacts 2021-06-15 14:13:35 +00:00
Faizan Ahmad
4d559a1864 Merge pull request #240 from stakater/file-name-fix
Fixed file name
2021-06-15 15:57:30 +02:00
talha0324
322142dd66 syntax fix 2021-06-15 18:24:56 +05:00
talha0324
39f37b706c Added helm template step in push action 2021-06-15 18:23:43 +05:00
talha0324
4e10dd4f80 Merge branch 'master' into file-name-fix
merging master into this branch
2021-06-15 17:58:49 +05:00
stakater-user
ccaa600ff4 [skip-ci] Update artifacts 2021-06-15 11:42:02 +00:00
Faizan Ahmad
a3fcfeb62f Merge pull request #241 from stakater/actions-fix
Fixed helm version tag and PR message
2021-06-15 13:28:07 +02:00
talha0324
d2cbbafeb1 Fixed helm version tag and PR message 2021-06-15 16:07:49 +05:00
talha0324
eaf8e16414 Fixed file name 2021-06-15 15:48:52 +05:00
stakater-user
5a65cf9f6d [skip-ci] Update artifacts 2021-06-13 19:48:18 +00:00
Faizan Ahmad
a8a68ae1b0 Merge pull request #236 from tete17/Update-dependencies-for-Argo-Rollouts
Update ArgoCD Rollouts to 1.0.1 to fix a compatibility issue
2021-06-13 21:33:59 +02:00
tete17
7643a27fb1 Upgrade argo-rollouts to v1.0.1 2021-06-04 18:32:02 +02:00
tete17
71fdb53c2e Update ArgoCD Rollouts to 0.10.2 to fix a compatibility issue and update necessary k8s machinery 2021-05-31 15:35:51 +02:00
stakater-user
d6312f6f83 [skip-ci] Update artifacts 2021-05-25 03:26:20 +00:00
Ahmed Waleed Malik
19220f5e6e Merge pull request #235 from phillebaba/feature/chart-priority-class
Add priority class name to helm chart
2021-05-25 08:13:08 +05:00
Philip Laine
05456b0905 Remove priority class name value 2021-05-24 21:19:20 +02:00
Philip Laine
10328dee8d Update deployments/kubernetes/chart/reloader/templates/deployment.yaml
Co-authored-by: Ahmed Waleed Malik <ahmedwaleedmalik@gmail.com>
2021-05-24 21:18:42 +02:00
Philip Laine
fd174ed691 Add priority class name to helm chart 2021-05-19 22:06:35 +02:00
stakater-user
2e47f1740c [skip-ci] Update artifacts 2021-04-26 04:52:02 +00:00
Ahmed Waleed Malik
15cb96f945 Merge pull request #228 from stakater/fix-issue-221
Add Optional pod monitor
2021-04-26 09:38:29 +05:00
faizanahmad055
1e987db54d Add endline in podmonitor.yaml
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2021-04-25 23:10:23 +02:00
faizanahmad055
12a7fed3ae Add endline in values.yaml.tmpl
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2021-04-25 23:09:40 +02:00
stakater-user
f18fac66c2 [skip-ci] Update artifacts 2021-04-25 21:05:39 +00:00
faizanahmad055
b5c95f9cbf Add Optional pod monitor
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2021-04-25 23:05:36 +02:00
Faizan Ahmad
46b948388f Merge pull request #226 from tenstad/propagate-error-to-fix-retry
Propagate error to enable retry
2021-04-25 22:52:06 +02:00
Amund Tenstad
78be58b090 Do not log content of secrets 2021-04-21 16:12:53 +02:00
Amund Tenstad
54a8e0683b Propagate PerformRollingUpgrade error to Handle 2021-04-21 13:25:08 +02:00
stakater-user
702f0caa93 [skip-ci] Update artifacts 2021-04-11 18:21:36 +00:00
Faizan Ahmad
2e709e85ae Merge pull request #223 from sfynx/master
fix: read isArgoRollouts correctly in Helm chart
2021-04-11 20:08:10 +02:00
Henno Schooljan
debfd57a91 fix: read isArgoRollouts correctly in Helm chart 2021-04-07 23:21:41 +02:00
stakater-user
c3b8af34ac [skip-ci] Update artifacts 2021-03-22 13:47:07 +00:00
Ahmed Waleed Malik
7a65bcb35b Merge pull request #218 from stakater/fix-issue-207
Make argo rollouts optional
2021-03-22 18:32:15 +05:00
faizanahmad055
af6cd9e37c Add isArgoRollouts in values.yaml.tmpl
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2021-03-22 11:34:47 +01:00
faizanahmad055
344004d0b3 Make argo rollouts optional
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2021-03-22 11:30:22 +01:00
stakater-user
a5bc586f09 [skip-ci] Update artifacts 2021-03-17 04:30:18 +00:00
Ahmed Waleed Malik
81ca7ab601 Merge pull request #212 from corco/multi_arch_dockerfile
Dockerfile now use the platform supplied by buildx
2021-03-17 09:15:39 +05:00
Jonathan Drolet
69c9ccb2ea Merge remote-tracking branch 'stakater/master' into multi_arch_dockerfile 2021-03-16 09:05:32 -04:00
Ahmed Waleed Malik
0ec3effab8 Merge pull request #215 from stakater/use-commit-hash
Update pull_request.yaml
2021-03-16 16:26:17 +05:00
Ahmed Waleed Malik
dba42e91bc Update pull_request.yaml 2021-03-16 16:20:16 +05:00
Jonathan Drolet
68fd3bebe5 Dockerfile now use the platform supplied by buildx 2021-03-15 21:11:18 -04:00
Ahmed Waleed Malik
52b975ef0d Merge pull request #211 from stakater/update-pr-workflow
Update pull_request.yaml
2021-03-15 20:38:18 +05:00
Ahmed Waleed Malik
0679af76f4 Update pull_request.yaml 2021-03-15 20:23:53 +05:00
Ahmed Waleed Malik
309c10f632 Merge pull request #206 from stakater/update-modules
Update modules
2021-03-10 09:49:27 +05:00
Waleed Malik
07ddec9fd1 Clean up unused dependencies 2021-03-10 09:19:23 +05:00
Waleed Malik
69a80fd1d9 Update modules 2021-03-10 09:18:51 +05:00
stakater-user
04975de060 [skip-ci] Update artifacts 2021-03-09 19:20:58 +00:00
Ahmed Waleed Malik
459a808371 Merge pull request #205 from tete17/Support-Rollouts-on-Helm-deployment
Allow reloader to modify rollouts when installed through helm
2021-03-09 23:50:42 +05:00
tete17
ef8a335c93 Allow reloader to modify rollouts when installed through helm 2021-03-09 20:19:33 +01:00
stakater-user
93a52500d1 [skip-ci] Update artifacts 2021-03-09 18:23:56 +00:00
Ahmed Waleed Malik
ac2dac330e Merge pull request #202 from tete17/Add-support-for-Argo-Rollouts
Add support for argo rollouts
2021-03-09 22:55:44 +05:00
stakater-user
e9843c7c7d [skip-ci] Update artifacts 2021-03-05 05:55:14 +00:00
Ahmed Waleed Malik
1f154d0572 Merge pull request #204 from corco/master
Added multi-arch docker image for Github actions
2021-03-05 10:29:52 +05:00
Jonathan Drolet
7ccb17392e Added multi-arch docker image for Github actions 2021-03-04 10:52:44 -05:00
tete17
e8da3f48ec Modify documentation to reflect feature with rollout 2021-02-23 18:37:46 +01:00
tete17
614865a8d7 Add support for ArgoCD Rollout CRD 2021-02-23 18:24:39 +01:00
stakater-user
4f551ada6e [skip-ci] Update artifacts 2021-02-18 09:08:37 +00:00
Ahmed Waleed Malik
608a928967 Merge pull request #201 from wtayyeb/patch-1
fix deployment args indentation and add search, match custom_annotations
2021-02-18 13:57:36 +05:00
wtayyeb
5a14798341 simplify auto-search, search-match annotations 2021-02-18 10:59:46 +03:30
wtayyeb
e7516e82e3 fix deployment args, add custom_annotations.auto_search, search_match 2021-02-18 10:44:13 +03:30
stakater-user
dc3494c041 [skip-ci] Update artifacts 2021-02-08 04:48:48 +00:00
Ahmed Waleed Malik
79e3588389 Merge pull request #200 from stakater/fix-issue-199
Add custom annotation support in service account
2021-02-08 09:37:43 +05:00
faizanahmad055
45a833bbb2 Add custom annotation support in service account
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2021-02-06 14:29:47 +01:00
stakater-user
1f22ebe132 [skip-ci] Update artifacts 2021-01-26 13:00:36 +00:00
Ahmed Waleed Malik
1846b31936 Merge pull request #198 from stakater/version-bump-fix
Fixed version bump command in Makefile
2021-01-26 17:49:18 +05:00
talha0324
935a17b1c7 Fixed version bump command in Makefile 2021-01-26 17:31:54 +05:00
stakater-user
7b44a472ad [skip-ci] Update artifacts 2021-01-26 11:12:27 +00:00
Ahmed Waleed Malik
a46b56271c Merge pull request #197 from stakater/fix-pipeline
Fix version env var in Makefile
2021-01-26 16:00:48 +05:00
Waleed Malik
2f9dd7c422 Fix version env var in Makefile 2021-01-26 15:57:25 +05:00
Ahmed Waleed Malik
f373686b75 Merge pull request #195 from stakater/fix-chart-path
Fix chart path for helm publish step
2021-01-26 15:36:32 +05:00
Ahmed Waleed Malik
80557ce43e Fix chart path for helm publish step 2021-01-26 15:34:58 +05:00
Ahmed Waleed Malik
c4f6d93eb9 Merge pull request #194 from stakater/ahmedwaleedmalik-patch-1
Update push.yaml
2021-01-26 15:17:16 +05:00
Ahmed Waleed Malik
c75c787738 Update push.yaml 2021-01-26 15:16:12 +05:00
Ahmed Waleed Malik
ba18bbfd72 Merge pull request #193 from stakater/update-chart-publish
Update chart publish step
2021-01-26 15:01:24 +05:00
Waleed Malik
610b4e5716 Update chart publish step 2021-01-26 14:56:06 +05:00
Ahmed Waleed Malik
dc0715de61 Merge pull request #192 from stakater/use-pr-target-hook
[skip-ci] use pull_request_target hook for pipelines against PRs
2021-01-26 14:51:15 +05:00
Waleed Malik
4f6ff420e8 Fix chart publish step 2021-01-26 14:31:04 +05:00
Waleed Malik
966d5e61c0 [skip-ci] use pull_request_target hook for pipelines against PRs 2021-01-26 14:10:56 +05:00
Ahmed Waleed Malik
d017747792 Merge pull request #189 from stakater/workflow-implementation
Workflow implementation
2021-01-26 14:10:10 +05:00
Waleed Malik
70099fdc8f Fix helm lint step 2021-01-26 13:54:14 +05:00
Waleed Malik
aaddec1103 Skip failing test cases 2021-01-26 12:59:49 +05:00
Waleed Malik
b5fdcd577d Refactor controller test cases 2021-01-26 12:04:40 +05:00
Waleed Malik
8b9bf07631 Temporarily switch to pull_request hook for testing 2021-01-26 11:42:40 +05:00
Waleed Malik
674444850d Merge latest master 2021-01-26 11:35:44 +05:00
Waleed Malik
e74dcc3cbd Update workflows 2021-01-26 11:30:38 +05:00
Waleed Malik
dcae4c98ac Add updated Dockerfile 2021-01-26 11:30:22 +05:00
Waleed Malik
94a83c5974 Bump golang version to 1.15 2021-01-26 11:14:52 +05:00
Waleed Malik
592976bf09 Run go mod tidy 2021-01-26 11:11:30 +05:00
Waleed Malik
ed736c8e20 Remove .VERSION file 2021-01-26 11:11:21 +05:00
Ahmed Waleed Malik
84133742b1 Merge pull request #186 from coldfire84/pr-docker-multi-arch
Enable support for multi-arch container image build/ publish: linux/arm, linux/arm64 and linux/amd64.
2021-01-26 11:09:00 +05:00
stakater-user
04e19a733b Bump Version to v0.0.77 2021-01-21 08:32:24 +00:00
Ahmed Waleed Malik
c1ae5efb7b Merge pull request #190 from gracedo/gracedo/check_api_legacy
[helm chart] Check api version availability instead of using legacy value
2021-01-21 13:00:23 +05:00
Grace Do
f630336fed Check api version availability instead of using legacy value 2021-01-19 10:18:27 -08:00
talha0324
fde312edcc Update golang code lint errors 2021-01-19 15:54:30 +05:00
talha0324
57eb4f4eaa Updates to the workflow 2021-01-19 15:22:31 +05:00
talha0324
1490a1feaa Updates to workflow and few path updates 2021-01-18 17:43:07 +05:00
talha0324
58c622eb91 Added workflow files for Jenkins replacement 2021-01-18 17:33:02 +05:00
stakater-user
2fd8b190b1 Bump Version to v0.0.76 2021-01-11 04:45:48 +00:00
Ahmed Waleed Malik
81c840ea30 Merge pull request #187 from stakater/fix-issue-166
Remove redundant reload on resource creation
2021-01-11 09:36:26 +05:00
faizanahmad055
21dbeb9810 Remove redundant reload on resource creation
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2021-01-08 17:28:50 +01:00
Chris Bradford
fba004d655 Enable support for multi-arch container images: arm, arm64 and amd64.
Add Container Build documentation.
2020-12-19 12:38:32 +00:00
stakater-user
631781aa8a Bump Version to v0.0.75 2020-12-01 12:11:52 +00:00
Ali Kahoot
707dccf6b8 Merge pull request #184 from stakater/fix-helm-chart-template
Fix helm chart template
2020-12-01 17:02:49 +05:00
Waleed Malik
5edd29b8e9 Remove redundant fields from service in helm chart 2020-12-01 16:58:51 +05:00
Waleed Malik
27815ea3b3 Update values.service.ports to values.service.port 2020-12-01 16:48:10 +05:00
Waleed Malik
5fd275a05c Add waleed as reviewer and approver 2020-12-01 16:39:11 +05:00
Waleed Malik
b22694d3c2 Add servicemonitor in values template 2020-12-01 16:38:55 +05:00
Ahmed Waleed Malik
5c95c6898b Merge pull request #180 from dpetersen/service-monitor
Add optional ServiceMonitor object to Helm chart
2020-12-01 15:08:00 +05:00
Jose Bautista
46bc4b71db update readme 2020-11-28 17:28:37 +02:00
Don Petersen
cee81b4757 Add optional ServiceMonitor object to Helm chart
This adds the ability to create a ServiceMonitor instance to configure
Prometheus to monitor reloader for metrics. ServiceMonitor is a CRD that
comes with the prometheus-operator project.
2020-11-25 13:25:07 -08:00
stakater-user
1cec52637f Bump Version to v0.0.74 2020-10-28 17:08:26 +00:00
Ahmed Waleed Malik
1901a4eb49 Merge pull request #146 from mnach/add-metrics-service
add metrics endpoints to kubernetes specs
2020-10-28 21:57:15 +05:00
Mikhail Vladimirovich Nacharov
710396f66e add metrics endpoints to kubernetes specs 2020-10-28 01:13:49 +05:00
stakater-user
11bafa9f36 Bump Version to v0.0.73 2020-10-27 10:13:10 +00:00
Ahmed Waleed Malik
9a45318fc9 Merge pull request #175 from stakater/fix-issue-173
Fix issue 173
2020-10-26 12:50:12 +05:00
faizanahmad055
843f47600a Fix formatting of documenation to support helm3 migration
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2020-10-25 19:28:37 +01:00
faizanahmad055
3d9dee27b5 Fix formatting of documenation to support helm3 migration
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2020-10-25 19:27:58 +01:00
faizanahmad055
63fd3c2635 Add documenation to support helm3 migration
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2020-10-25 19:24:41 +01:00
faizanahmad055
284ca59ca4 Add annotations, labels and documenation to support helm3
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2020-10-25 19:22:05 +01:00
stakater-user
2ce24abe40 Bump Version to v0.0.72 2020-10-20 07:36:45 +00:00
Usama Ahmad
6419444663 Merge pull request #172 from stakater/fix-chart
Fix helm chart template
2020-10-20 12:26:56 +05:00
Waleed Malik
1a6fd3e302 Fix helm chart template 2020-10-20 10:44:59 +05:00
Ahmed Waleed Malik
7ac90b8c88 Merge pull request #170 from stakater/fix-issue-169
Fix#169 - Update Rbac api versions
2020-10-20 09:33:08 +05:00
faizanahmad055
faf27c2d5d Add support for legacy rbac
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2020-10-19 16:00:54 +02:00
faizanahmad055
6a0dfd3ce0 Update Rbac api versions
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2020-10-19 10:32:32 +02:00
stakater-user
fdbc3067ce Bump Version to v0.0.71 2020-10-13 03:56:54 +00:00
Ahmed Waleed Malik
c4ead210ee Merge pull request #168 from booleanbetrayal/namespaces-to-ignore_helm_support
Add Helm chart support for --namespaces-to-ignore flag
2020-10-13 08:47:22 +05:00
Brent Dearth
0441f6d481 Add Helm chart support for --namespaces-to-ignore flag 2020-10-12 15:04:08 -06:00
stakater-user
09b9a073a0 Bump Version to v0.0.70 2020-10-05 10:28:03 +00:00
Ahmed Waleed Malik
d6d188f224 Merge pull request #162 from pchico83/master
Add okteto manifest to develop Reloader directly on Kubernetes
2020-10-05 15:18:27 +05:00
stakater-user
422c291b06 Bump Version to v0.0.69 2020-09-22 13:39:09 +00:00
Júlia Biró
ed6ea026a8 Trim spaces in annotation list (#165)
* strip whitespace

* only trim spaces
2020-09-22 15:29:29 +02:00
Pablo Chico de Guzman
da30b4744b Add okteto manifest to develop Reloader directly on Kubernetes 2020-09-04 11:26:59 +02:00
stakater-user
503e357349 Bump Version to v0.0.68 2020-09-01 05:42:04 +00:00
Josh Soref
61e9202781 Spelling (#161)
* spelling: create-or
2020-09-01 10:32:16 +05:00
stakater-user
8dbe7a85af Bump Version to v0.0.67 2020-08-08 18:46:03 +00:00
Ahmad Iqbal Ali
e86f616305 update slack links in readme (#156) 2020-08-08 20:36:09 +02:00
stakater-user
0c36cfd602 Bump Version to v0.0.66 2020-08-06 18:20:25 +00:00
Faizan Ahmad
f38f86a45c Merge pull request #154 from clive-jevons/respect-configmap-binarydata-for-hash
Include data from ConfigMap.BinaryData when calculating SHA
2020-08-06 20:09:59 +02:00
Faizan Ahmad
5033b8fcdc Merge pull request #155 from kostyrev/master
Add fullnameOverride to helm chart
2020-08-06 20:09:45 +02:00
Aleksandr Kostyrev
be4285742a Add fullnameOverride to helm chart 2020-08-06 16:54:50 +03:00
Clive Jevons
6a008999f5 Include data from ConfigMap.BinaryData when calculating SHA 2020-08-06 13:37:50 +02:00
stakater-user
93f4ea240f Bump Version to v0.0.65 2020-08-04 09:17:57 +00:00
stakater-user
c6fbae2f62 Bump Version to v0.0.64 2020-08-04 08:15:47 +00:00
Ahmed Waleed Malik
3fe0ebb48a Merge pull request #152 from liuming-dev/refactor--code-polish
Polishing code
2020-08-04 13:02:17 +05:00
Ahmed Waleed Malik
67b847bf41 Merge pull request #151 from liuming-dev/style--gofmt
style: gofmt -l -w -s .
2020-08-04 13:01:44 +05:00
Liu Ming
eaa3db48f5 Polish code
Signed-off-by: Liu Ming <hit_oak_tree@126.com>
2020-07-29 10:25:55 +08:00
Liu Ming
a505d2e3b1 style: gofmt -l -w -s .
Signed-off-by: Liu Ming <hit_oak_tree@126.com>
2020-07-28 21:45:56 +08:00
stakater-user
9ec5515a39 Bump Version to v0.0.63 2020-07-20 17:56:16 +00:00
Ahmed Waleed Malik
8db17acf67 Merge pull request #150 from stakater/fix-watch-global
Fix watch global
2020-07-20 22:46:29 +05:00
faizanahmad055
b43719cf34 Remove duplicate condition
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2020-07-20 19:33:38 +02:00
faizanahmad055
e8216069a5 Fix issue for watch global variable 2020-07-20 18:48:58 +02:00
stakater-user
732d35e45f Bump Version to v0.0.62 2020-07-17 09:17:35 +00:00
Ahmed Waleed Malik
dcedaa2cfe Merge pull request #147 from alexconlin/patch-1
Remove empty fields from kustomize deployment
2020-07-17 14:07:01 +05:00
Alex Conlin-Oakley
8d77121c3b only include env and args in container when needed 2020-07-15 17:42:08 +01:00
Alex Conlin
013cd92219 Merge branch 'master' into patch-1 2020-07-10 17:24:33 +01:00
stakater-user
39b5be37af Bump Version to v0.0.61 2020-07-10 15:54:41 +00:00
kahootali
86c2ed265d Add non-root security context 2020-07-10 20:40:48 +05:00
LucasBoisserie
87130f06bc Run as Non Root (#149) 2020-07-10 17:34:49 +02:00
Ali Kahoot
17f702f510 Merge pull request #148 from TBBle/patch-1
Typo fix "resatart"
2020-07-10 20:27:40 +05:00
Paul "TBBle" Hampson
16f3055e10 Typo fix "resatart" 2020-07-10 11:34:47 +10:00
Alex Conlin
4800af8e28 Remove empty fields from deployment manifest 2020-07-08 11:22:43 +01:00
Alex Conlin
db79c65334 Remove empty fields from kustomize deployment
Fixes #115
2020-07-07 22:52:53 +01:00
stakater-user
d2223f313f Bump Version to v0.0.60 2020-06-23 07:15:27 +00:00
Ahmed Waleed Malik
c9dabc3a14 Merge pull request #142 from vladlosev/feat-track-secrets-configmaps-by-annotation
Adds support for auto-reloading secrets and configmaps by annotation.
2020-06-23 12:05:22 +05:00
Vlad Losev
e61f9a6bdb Adds note on incompatibility with 'reloader.stakater.com/auto'. 2020-06-21 14:15:58 -07:00
Vlad Losev
6bcec06052 Fixes missing import. 2020-06-09 19:45:12 -07:00
Vlad Losev
0988e8947f Removes unused import. 2020-06-09 19:18:12 -07:00
Vlad Losev
ff27cc0f51 Simplifies test. 2020-06-09 19:17:19 -07:00
Vlad Losev
be7d454504 Fixes test using auto annotations. 2020-06-09 19:16:04 -07:00
Vlad Losev
3131116ed6 Re-adds sleep statements. 2020-06-09 19:16:04 -07:00
Vlad Losev
965cacf1ba Updates documentation. 2020-06-09 19:16:04 -07:00
Vlad Losev
e81b49d81b Renames search annotation. 2020-06-09 19:16:03 -07:00
Vlad Losev
17f8b81110 Simplifies annotations for searching secrets for reload. 2020-06-09 19:16:03 -07:00
Vlad Losev
5980c91560 Abstracts out configmap and deployment creation. 2020-06-09 19:16:01 -07:00
Vlad Losev
fda733ea5a Adds support for auto-reloading secrets and configmaps by annotation. 2020-06-09 19:14:14 -07:00
stakater-user
732cd5b53a Bump Version to v0.0.59 2020-06-09 16:50:55 +00:00
stakater-user
aae0c5c443 Merge pull request #141 from cucxabong/support-projected-volume
Support projected volume
2020-06-09 20:16:24 +05:00
Quan Hoang
d4223311de Support projected volume 2020-06-02 23:36:08 +07:00
stakater-user
29173c7364 Bump Version to v0.0.58 2020-03-30 15:12:34 +00:00
inductor
7767809a38 Refactor Dockerfile (#133)
* refactor dockerfile

* update go version on Dockerfile
2020-03-30 16:52:33 +02:00
stakater-user
f0d6a9e646 Bump Version to v0.0.57 2020-03-18 09:26:04 +00:00
Usama Ahmad
d1538dbeec Merge pull request #131 from stakater/fix-pipeline
Update pipeline library and pipeline tools version
2020-03-18 14:15:55 +05:00
Waleed Malik
8470962383 Update pipeline library and pipeline tools version 2020-03-18 14:02:05 +05:00
Ali Kahoot
139bc1ca38 Merge pull request #128 from katainaka0503/add-prometheus-endpoint
Implement prometheus endpoint
2020-03-17 20:43:03 +05:00
kahootali
6d9f89a452 add service manifest 2020-03-17 15:27:47 +05:00
Ali Kahoot
5ba914d6bb Fix documentation 2020-03-17 15:10:42 +05:00
katainaka0503
9a5094a4ed Add document of prometheus endpoint 2020-03-01 21:56:05 +09:00
katainaka0503
3fe7ad04e9 Implement prometheus endpoint 2020-03-01 21:56:02 +09:00
stakater-user
bf6a247f54 Bump Version to v0.0.56 2020-03-01 12:47:59 +00:00
stakater-user
8203cc3c11 Bump Version to v0.0.55 2020-03-01 12:37:09 +00:00
stakater-user
f287d84b6a Bump Version to v0.0.54 2020-03-01 12:26:27 +00:00
katainaka
205d36512c Remove redundant namePrefix from kustomization.yaml sample (#126) 2020-03-01 13:16:35 +01:00
stakater-user
0b39353c12 Bump Version to v0.0.53 2020-02-28 12:53:28 +00:00
Ali Kahoot
97a5616e60 Merge pull request #125 from stakater/update-library-version
update library version and toolsImage
2020-02-28 17:43:19 +05:00
usamaahmadkhan
b274ac0947 update library version and toolsImage 2020-02-28 17:28:26 +05:00
stakater-user
ed29d1d18c Bump Version to v0.0.52 2020-02-14 06:45:57 +00:00
aure-olli
2384d65953 feat: allow annotations in the pod template too (#123)
Several public charts only allow to edit the annotations of the pod template, not the deployment. Annotations will also be checked in the pod template if not present in the deployment.

fix: #122

Signed-off-by: Aurélien Lambert <aure@olli-ai.com>
2020-02-14 07:32:31 +01:00
stakater-user
7b19601423 Bump Version to v0.0.51 2020-01-13 13:33:00 +00:00
Usama Ahmad
76bf43cb13 Merge pull request #121 from elblivion/json-logging
JSON logging
2020-01-13 18:22:46 +05:00
kahootali
1b7bb3bead add support for logFormat argument in deployment 2020-01-13 17:10:08 +05:00
kahootali
c844f12f73 add logFormat default value 2020-01-13 17:09:53 +05:00
kahootali
5ac2164a1c add logFormat parameter in Readme 2020-01-13 17:09:25 +05:00
Anthony Stanton
c9b89c37c1 Update README 2020-01-03 13:44:01 +01:00
Anthony Stanton
55bc4c3e22 JSON logging 2020-01-02 22:10:41 +01:00
stakater-user
77c7d63296 Bump Version to v0.0.50 2019-12-31 05:49:32 +00:00
Irtiza Ali
2ae4753efb Merge pull request #119 from rjshrjndrn/patch-1
Include annotations in templating.
2019-12-31 10:39:13 +05:00
Rajesh Rajendran
68d0349793 Include annotations in templating.
for example, If I have istio enabled in a namespace, and I want to deploy reloader in that, It doesn't make sense to include envoy there. So there should be an option to add `sidecar.istio.io/inject: "false"` annotation.
2019-12-31 10:52:19 +05:30
stakater-user
ded923b12a Bump Version to v0.0.49 2019-10-22 12:21:42 +00:00
Waseem Hassan Shahid
0726999bf9 Merge pull request #109 from alexandrsemak/patch-1
fix value for helm template
2019-10-22 14:11:26 +02:00
Alexandr Semak
f89c321a50 fix value for helm template 2019-10-22 06:43:19 -04:00
stakater-user
225427cec1 Bump Version to v0.0.48 2019-10-21 07:12:07 +00:00
Waseem Hassan Shahid
be86e8417f Update .goreleaser.yml 2019-10-21 09:01:55 +02:00
stakater-user
bf961c0456 Bump Version to v0.0.47 2019-10-21 07:01:11 +00:00
Waseem Hassan Shahid
3248ca9578 Change name template of archives 2019-10-21 08:50:39 +02:00
stakater-user
d517626033 Bump Version to v0.0.46 2019-10-21 06:39:52 +00:00
Waseem Hassan Shahid
28c9696bdf Update Jenkinsfile 2019-10-21 08:29:14 +02:00
stakater-user
d0baf7a5cc Bump Version to v0.0.45 2019-10-18 11:59:28 +00:00
Waseem Hassan
492fae7b52 Merge pull request #108 from stakater/add-github-token
Add github token to goreleaser
2019-10-18 13:30:31 +02:00
waseem
4999bdbd96 Add github token to goreleaser 2019-10-18 13:29:01 +02:00
stakater-user
fd7d0f9f99 Bump Version to v0.0.44 2019-10-18 11:26:06 +00:00
Waseem Hassan
0359c3040a Merge pull request #107 from stakater/use-goreleaser
Use goreleaser for releasing binaries
2019-10-18 13:11:34 +02:00
waseem
d710c16774 Use stk compatible version file 2019-10-18 12:38:47 +02:00
waseem
e57db0dc56 Remove version file 2019-10-18 12:38:13 +02:00
waseem
e1a6a1ed87 Change library function to use 2019-10-18 12:35:44 +02:00
waseem
f8b3b21bbd Use goreleaser for releasing binaries 2019-10-18 12:34:26 +02:00
stakater-user
b6a333ea73 Bump Version to v0.0.43 2019-10-16 08:08:06 +00:00
Waseem Hassan
efa30662ae Merge pull request #106 from stakater/compatibility-1.16
Make reloader compatible with kubernetes 1.16
2019-10-16 09:57:50 +02:00
waseem
5fff0c9bb7 Add compatibility note 2019-10-16 08:05:03 +02:00
waseem
ec35f653b1 Fix labels 2019-10-16 07:25:02 +02:00
waseem
9229775f11 Make reloader compatible with kubernetes 1.16 2019-10-16 07:03:43 +02:00
stakater-user
e14b0c81b0 Bump Version to v0.0.42 2019-10-15 06:39:28 +00:00
Waseem Hassan
6aa016f6dd Merge pull request #104 from stakater/go-modules
Use Go modules
2019-10-15 08:29:12 +02:00
waseem
02cab487c4 Add missing global field in values template 2019-10-15 08:10:33 +02:00
waseem
4ecdc0acaa Update toolsImage 2019-10-15 08:07:44 +02:00
waseem
4b02478210 Use go mod to download dependencies 2019-10-15 08:03:09 +02:00
waseem
6ec1f9add8 Use go modules 2019-10-15 07:58:12 +02:00
Waseem Hassan
fe3499ee26 Merge pull request #102 from stakater/ignore-namespace-flag
Add support for ignoring namespaces
2019-10-15 07:49:13 +02:00
waseem
aee5d84f45 Add to update method 2019-10-14 14:20:17 +02:00
waseem
a10b2fa747 Add support for ignoring namespaces 2019-10-14 14:14:40 +02:00
Irtiza Ali
6d8a81fa26 Merge pull request #101 from marcostvz/reloader-sc-ips
Sync with upstream helm/charts/stable/reloader
2019-10-14 10:13:26 +05:00
Marcos Estevez
734b33ba55 Sync with upstream helm/charts/stable/reloader
Signed-off-by: Marcos Estevez <marcos.stvz@gmail.com>
2019-10-10 14:29:51 +02:00
Irtiza Ali
5265c14760 Merge pull request #100 from stakater/fix-vanilla-manifest-usage-guideline
fix-vanilla-manifest-usage-guideline
2019-10-09 13:01:13 +05:00
irti
5fb1a8b5ef [fix-vanilla-manifest-usage-guideline] update the vanilla manifest usage guidelines 2019-10-09 12:17:32 +05:00
stakater-user
29f4c66274 Bump Version to v0.0.41 2019-10-09 06:55:17 +00:00
Ali Kahoot
82b94d8b57 Merge pull request #98 from stakater/fix-direct-installation-issue
[fix-direct-installation-issue] update Jenkinsfile
2019-10-09 11:44:37 +05:00
irti
984794850b [fix-direct-installation-issue] remove the chartRepositoryURL arg from the goBuildAndRelease method 2019-10-09 11:27:32 +05:00
Ali Kahoot
de0d588406 Merge pull request #99 from stakater/remove-chartmuseum-from-pipeline
remove chartmuseum from pipeline
2019-10-07 12:35:08 +05:00
Usama Ahmad
5665a5c424 remove chartmuseum from pipeline 2019-10-07 12:17:43 +05:00
irti
4598bf0f7d [fix-direct-installation-issue] update Jenkinsfile 2019-10-01 20:14:16 +05:00
irti
c8ab70f80d [fix-direct-installation-issue] update Jenkinsfile 2019-10-01 15:37:35 +05:00
irti
2d720809d9 [fix-direct-installation-issue] change the pipeline library version 2019-09-23 12:15:39 +05:00
irti
2c2beb91c7 [fix-direct-installation-issue] update Jenkinsfile 2019-09-20 11:27:30 +05:00
Ali Kahoot
d3f2eb794f Merge pull request #93 from stakater/add-info-for-manifest-issue
add-info-for-manifest-issue
2019-08-28 19:08:54 +05:00
irti
02ddd80280 [add-info-for-manifest-issue] update the README.md by adding the info to replace the RELEASE-NAME with a proper value 2019-08-28 18:57:25 +05:00
stakater-user
503776c2a5 Bump Version to v0.0.40 2019-08-27 07:51:00 +00:00
Ali Kahoot
4c7afbcb71 Merge pull request #90 from stakater/update-manifests
[update-manifests] update values manifest
2019-08-27 12:40:17 +05:00
irti
b11514ec13 [update-manifests] update values.yaml.tmlp manifest 2019-08-27 12:39:03 +05:00
irti
ef7d98f5e3 [update-manifests] update values manifest 2019-08-27 11:36:59 +05:00
Ali Kahoot
a336304fb3 Merge pull request #85 from stakater/fix-issue-81
[fix-issue-81] remove reloader binary file
2019-08-21 12:08:19 +05:00
irti
65365e5fef [fix-issue-81] remove reloader binary file 2019-08-21 11:39:21 +05:00
stakater-user
7c2121b7c9 Bump Version to v0.0.39 2019-08-20 09:59:32 +00:00
Ali Kahoot
008f4b0fd2 Merge pull request #80 from stakater/fix-issue-79
fix-issue-79
2019-08-20 14:47:41 +05:00
irti
0bf2fc66cc [fix-issue-79] add reloader-name template in _helpers.tpl 2019-08-20 14:20:40 +05:00
irti
d599340549 [fix-issue-79] remove reloader-name template and replace it with reloader-fullname 2019-08-20 10:28:35 +05:00
irti
83a711885c [fix-issue-79] add nodeSelector, affinity and tolerations in deployment manifest 2019-08-13 18:14:51 +05:00
irti
0ddfe8406d [fix-issue-79] fix for default value issue for service account 2019-08-13 17:58:53 +05:00
stakater-user
036882b588 Bump Version to v0.0.38 2019-08-05 08:09:38 +00:00
Irtiza Ali
63619e360c Merge pull request #78 from stakater/fix-openshift-rbac
Add openshift flag to explicitly add rbac for openshift if desired
2019-08-05 12:58:55 +05:00
waseem
6d54f9faca Added brackets to isOpenshift 2019-08-05 09:45:04 +02:00
waseem
18254666a6 Add openshift flag to explicitly add rbac for openshift 2019-08-05 09:20:37 +02:00
Ali Kahoot
b0dcb4c5e2 Merge pull request #76 from stakater/update-readme
update-readme-by-adding-guideline-to-ignore-resource
2019-07-11 11:19:25 +05:00
irti
cd4a4fb324 [update-readme] update README.md file by fixing issue in table template 2019-07-10 11:16:09 +05:00
irti
7ae3a4259e [update-readme] update README.md file by adding not about ignore parameters 2019-07-10 11:14:30 +05:00
irti
e82926a9f6 [update-readme] update README.md file by adding the guideline on how ignore some resource configMaps and secrets 2019-07-10 10:35:20 +05:00
stakater-user
e462f7ab26 Bump Version to v0.0.37 2019-07-08 10:21:39 +00:00
Waseem Hassan
da4ffc9432 Merge pull request #74 from stakater/deploymentconfigs
Add support for DeploymentConfigs for openshift
2019-07-08 12:10:45 +02:00
waseem
cc65a1c039 Fix conflicts 2019-07-08 10:38:46 +02:00
waseem
8c1a9317ee Fix conflicts 2019-07-08 10:38:19 +02:00
Waseem Hassan
33d1918d71 Merge branch 'master' into deploymentconfigs 2019-07-08 10:35:23 +02:00
stakater-user
5fc34e885e Bump Version to v0.0.36 2019-07-08 08:28:55 +00:00
Ali Kahoot
acc61d504f Merge pull request #75 from stakater/fix-deployment-template
fix-deployment-template
2019-07-08 13:05:40 +05:00
irti
cf9c0fc685 [fix-deployment-template] fix deployment template. Custom annotations check causing the ignore-resources field addition to fail 2019-07-08 12:32:19 +05:00
waseem
4822dbae86 Remove GetClient from testutil 2019-07-05 12:30:11 +02:00
waseem
16d75d1d47 Fix merge conflicts 2019-07-05 12:24:46 +02:00
waseem
878bc5c442 Refactor Openshift detection 2019-07-05 12:23:14 +02:00
stakater-user
e7ccc40035 Bump Version to v0.0.35 2019-07-05 05:38:24 +00:00
Irtiza Ali
0197dec568 Merge pull request #72 from henryaj/master
Optionally disable secret checking
2019-07-04 22:40:36 +05:00
hstanley
795de2399b Fail if user tries to ignore all resource types 2019-07-04 10:21:19 +01:00
hstanley
a69674ba4c Remove errant 'resources-to-watch' flags 2019-07-04 10:03:14 +01:00
waseem
ff5f28ba00 Add comments where needed 2019-07-04 11:00:52 +02:00
waseem
df777332a9 Lint go 2019-07-04 10:56:17 +02:00
waseem
daca09e65e Add deploymentconfigs to clusterrole 2019-07-04 10:53:19 +02:00
waseem
50a908a59f Update minor version 2019-07-04 10:42:30 +02:00
waseem
121a550da5 Update readme 2019-07-04 10:42:06 +02:00
waseem
9f3c8379a6 Add IsOpenshift flag 2019-07-04 10:32:17 +02:00
waseem
9b48d320be Add check for openshift 2019-07-04 10:25:22 +02:00
waseem
a8edefcdde Fix install command 2019-07-04 10:21:35 +02:00
waseem
1689a9560b Add deploymentconfigs in rbac if platform is openshift 2019-07-04 10:16:48 +02:00
waseem
4f8377de15 Fix glide command in docker build 2019-07-04 10:10:26 +02:00
waseem
765ddbdf43 Update go version 2019-07-04 09:59:35 +02:00
waseem
181477de05 Update glide with openshift packages 2019-07-04 09:59:20 +02:00
waseem
6d8c0cf6cb Add controller tests and fixes 2019-07-04 09:58:58 +02:00
waseem
2dc7d20a37 Fix upgrade test cases 2019-07-04 09:58:49 +02:00
waseem
9cd5b87dab Add openshift apps client 2019-07-04 09:58:39 +02:00
waseem
20d88e0668 Fix test cases 2019-07-04 09:58:33 +02:00
waseem
de77785d4f Add support for DeploymentConfigs 2019-07-04 09:58:26 +02:00
waseem
bf6cb73fd7 Merge branch 'master' of github.com:stakater/Reloader into deploymentconfigs 2019-07-04 08:32:20 +02:00
stakater-user
b3d3c3704a Bump Version to v0.0.34 2019-07-04 06:29:52 +00:00
Ali Kahoot
58514e8610 Merge pull request #73 from stakater/fix-dnsPolicy-issue
fix-dnsPolicy-issue
2019-07-04 11:06:41 +05:00
irti
a26f7fc4ad [fix-dnsPolicy-issue] bump package version in glide.yaml file. k8s.io/api version 1.8.0 to 1.10.0 and client go version 5.0.0 to 6.0.0 2019-07-04 10:12:55 +05:00
waseem
e06394c940 Reduce wait times and fix indentations 2019-07-03 22:17:36 +02:00
waseem
362ea70e26 Fix test cases 2019-07-03 22:14:36 +02:00
hstanley
3e6c4a3f60 Switch from list of resources to monitor to list of resources to ignore 2019-07-03 16:01:15 +01:00
hstanley
8cf105726f Update helm charts (deployments and RBAC) 2019-07-03 10:56:09 +01:00
hstanley
361bea4373 move List to util.go 2019-07-03 10:32:33 +01:00
hstanley
59fd71d15f Add 'resources-to-watch' flag 2019-07-02 14:09:27 +01:00
hstanley
6c6776f2b4 Optionally disable checking k8s Secrets 2019-07-02 11:51:14 +01:00
stakater-user
8b824ef26a Bump Version to v0.0.33 2019-07-01 12:09:23 +00:00
Irtiza Ali
5fd170a7ca Merge pull request #69 from chrisns/kustomize
add Kustomize deployment code docs
2019-07-01 16:44:50 +05:00
Chris Nesbitt-Smith
69487f6caf update readme for kustomize 2019-06-27 14:34:07 +01:00
Chris Nesbitt-Smith
401a94bd36 add kustomization.yaml 2019-06-27 10:59:02 +01:00
stakater-user
bf12cbec15 Bump Version to v0.0.32 2019-06-27 08:30:31 +00:00
Irtiza Ali
fdc223a4a6 Merge pull request #68 from DevotedHealth/affinity_tolerations
Permit passing resources, tolerations, affinity to Helm chart
2019-06-27 13:07:34 +05:00
Steve Huff
dcbc0e0de0 Permit passing resources, tolerations, affinity to Helm chart
These values are all empty by default.
2019-06-26 18:44:39 +00:00
stakater-user
aff377718c Bump Version to v0.0.31 2019-06-25 09:27:27 +00:00
Ali Kahoot
112e8ba89d Merge pull request #67 from stakater/add-node-selector-support
add-node-selector-support
2019-06-25 14:04:40 +05:00
irti
c2e6231a46 [add-node-selector-support] revert README.md doc change 2019-06-20 12:21:35 +05:00
irti
51b42dc098 [add-node-selector-support] add char in README.md 2019-06-20 12:18:31 +05:00
irti
43200e127a [add-node-selector-support] add nodeSelector param in values.yaml file 2019-06-20 12:03:37 +05:00
irti
6db5106f85 [add-node-selector-support] fix issue 2019-06-20 11:55:21 +05:00
irti
703c0ea56e [add-node-selector-support] add nodeSelector support 2019-06-20 11:36:12 +05:00
stakater-user
21563abc07 Bump Version to v0.0.30 2019-06-11 07:36:19 +00:00
Ali Kahoot
ce96eb3810 Merge pull request #65 from blurpy/filesys_and_role
Fix issue with readOnlyRootFilesystem and statefulsets permissions
2019-06-11 12:13:13 +05:00
Christian Ihle
b5c8ee2ab9 Add optional support for readOnlyRootFilesystem 2019-06-06 11:59:42 +02:00
Christian Ihle
c27bb3929b Split permissions for apps and extensions apigroups since statefulsets does not have extensions 2019-06-06 11:54:14 +02:00
stakater-user
67913c9985 Bump Version to v0.0.29 2019-05-23 10:04:32 +00:00
Ali Kahoot
9dac1a30b6 Merge pull request #64 from cko/alpine_update
Update alpine container base image to 3.9
2019-05-23 14:41:30 +05:00
Christine Koppelt
ac7f9d09cc update alpine container base image to 3.9 2019-05-23 10:55:06 +02:00
stakater-user
d8ae3c76da Bump Version to v0.0.28 2019-05-08 10:22:39 +00:00
Ali Kahoot
3f115618cc Merge pull request #62 from stakater/issue-61
Initial implementation of fix for issue 61
2019-05-08 14:59:43 +05:00
faizanahmad055
06aa382910 Initial implementation of fix for issue 61
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-05-07 10:51:58 +02:00
stakater-user
3b69599c77 Bump Version to v0.0.27 2019-04-25 10:18:02 +00:00
Ali Kahoot
125e7536af Merge pull request #60 from stakater/fix-config-change-logs-issue
fix-config-change-logs-issue
2019-04-25 14:55:07 +05:00
irti
66f9b07817 [fix-config-change-logs-issue] fixed log statement placement 2019-04-25 14:19:52 +05:00
irti
40aa9955cd [fix-config-change-logs-issue] fixed the issue in create.go file 2019-04-25 14:16:42 +05:00
irti
bfff7104aa [fix-config-change-logs-issue] logs issue fixed 2019-04-25 14:11:31 +05:00
Ali Kahoot
c0acfd0503 Merge pull request #58 from stakater/sealed-secret-doc
Sealed secret doc
2019-03-18 20:18:11 +05:00
faizanahmad055
379b6c0131 Add doc for how to use sealed secrets with reloader
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-03-18 16:14:47 +01:00
faizanahmad055
3bf427e985 Add doc for how to use sealed secrets with reloader
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-03-18 16:13:55 +01:00
stakater-user
2b6e5455dc Bump Version to v0.0.26 2019-02-20 10:57:07 +00:00
Ali Kahoot
9bc8d6b67d Merge pull request #56 from stakater/add-initContainer-support
Initial implementation for init container support
2019-02-20 15:32:44 +05:00
faizanahmad055
0c340fcb48 Fix same name configmap and secret conflict
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-02-18 12:09:53 +01:00
faizanahmad055
889b16718a Add test cases
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-02-18 10:20:52 +01:00
faizanahmad055
512cbd8c85 Fix incorrect container update
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-02-16 16:52:12 +01:00
faizanahmad055
39944497f3 Implement golang-ci comment
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-02-16 15:50:47 +01:00
faizanahmad055
6fb1266637 Initial implementation for init container support
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-02-16 15:43:56 +01:00
stakater-user
724cda887e Bump Version to v0.0.25 2019-02-12 08:28:39 +00:00
Muhammad Ahsan
d29f3716b2 Merge pull request #53 from stakater/fix-helper-func
append reloader- to serviceAccountName
2019-02-12 13:03:43 +05:00
kahootali
2131f0ebf3 append reloader- to serviceAccountName 2019-02-12 12:20:28 +05:00
stakater-user
0f052162a2 Bump Version to v0.0.24 2019-02-08 10:55:07 +00:00
Faizan Ahmad
02c6de97c8 Merge pull request #50 from ParticleDecay/feat/annotation-flag
Parameterize all annotations
2019-02-08 11:31:38 +01:00
kahootali
16bce16f81 add custom annotation 2019-02-08 15:05:18 +05:00
Joey Espinosa
33443ccb29 feat: add cli flags to helm chart 2019-02-06 12:46:17 -05:00
Joey Espinosa
75b00733bf feat: parameterize all annotations 2019-02-04 12:33:53 -05:00
stakater-user
d2335f8ffd Bump Version to v0.0.23 2019-02-01 12:21:59 +00:00
Ali Kahoot
87f3a32f68 Merge pull request #49 from stakater/fix-48
Add support for envFrom for autoUpdate
2019-02-01 16:57:46 +05:00
faizanahmad055
95bd5e497f Use single container loop for envs
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-02-01 12:06:18 +01:00
faizanahmad055
333957d82a Implemented golang CI comment
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-01-31 16:32:47 +01:00
faizanahmad055
75f67ffa6e Add support for envFrom for autoUpdate
Signed-off-by: faizanahmad055 <faizanahmad@217-212-164-26.customer.telia.com>
2019-01-31 16:03:53 +01:00
Ziming Miao
0558fc3723 fix typo (#47) 2019-01-30 10:38:23 +05:00
stakater-user
b637e33d9d Bump Version to v0.0.22 2019-01-25 13:24:41 +00:00
Faizan Ahmad
130741480e Auto update referenced resource (#45)
* Add implementation for create event

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Add sleep in testcase

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Fix test case data

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Remove unnecessary dashes from chart

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Fix new env var creation issue

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Optimize upgrade code

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Update logs

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Initial implementation to perform rolling upgrades by auto referencing the resources

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Fix nil pointer exception

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Fix test cases

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Add test cases

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Update test case verify method

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Add missing name for envs

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Update annotation name

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Update readme

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Update readme

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Implement Golang CI comment

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Implement Golang CI comment

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-01-25 14:00:21 +01:00
stakater-user
cd19d739ab Bump Version to v0.0.21 2019-01-21 08:54:49 +00:00
Ali Kahoot
f15ec9b4d4 Merge pull request #44 from stakater/update-jenkins-file
updates pipeline library version
2019-01-21 13:34:39 +05:00
ahsan-storm
013fcdc052 updates pipeline library version 2019-01-21 13:10:31 +05:00
stakater-user
78e98c7999 Bump Version to 0.0.20 2019-01-15 07:34:03 +00:00
Ali Kahoot
44c6333910 Merge pull request #42 from stakater/update-jenkins-file
updates jenkins file
2019-01-15 12:14:33 +05:00
ahsan-storm
0316bcd938 updates jenkins file with latest changes 2019-01-15 12:13:42 +05:00
stakater-user
8c77c230e0 Bump Version to 0.0.19 2019-01-15 07:06:57 +00:00
Ali Kahoot
bcffb62e3f Merge pull request #41 from stakater/update-start-controller-log
Update start controller log
2019-01-15 11:46:29 +05:00
ahsan-storm
85c10da63d updates jenkins file 2019-01-10 19:56:18 +05:00
faizanahmad055
b17ab76a24 Update start controller log
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2019-01-10 18:34:23 +05:00
Faizan Ahmad
23ab5692fa Update chart for public helm repo (#36)
* Update chart according to practices of helm public repo

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>

* Add new line at the end of files

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2018-12-10 23:50:54 +01:00
Ali Kahoot
55c93a4dd8 Merge pull request #35 from stakater/update-readme-annotation-location
Update readme to explain annotation position
2018-12-05 16:06:14 +05:00
faizanahmad055
32eb9e7959 Update readme to explain annotation position
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2018-12-05 15:43:18 +05:00
Ahmad Iqbal Ali
09046c45ff Set Reloader specific slack channel url 2018-12-05 15:32:36 +05:00
Faizan Ahmad
f346ca84ab Update readme and docs (#34)
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2018-12-04 21:33:20 +01:00
stakater-user
5041d1a1cf Bump Version to 0.0.18 2018-10-11 11:55:45 +00:00
Faizan Ahmad
1ad93145b4 Merge pull request #31 from stakater/fix-annotation-placement-confusion
Fix annotation placement confusion in readme
2018-10-11 16:33:27 +05:00
faizanahmad055
61b398539e Fix annotation placement confusion in readme
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2018-10-11 15:38:26 +05:00
stakater-user
0cb86cf665 Bump Version to 0.0.17 2018-10-08 11:24:46 +00:00
Ali Kahoot
b973c37a4f Merge pull request #30 from stakater/issue-29
Update readme about how to define multiple configmaps and secrets
2018-10-08 16:02:55 +05:00
faizanahmad055
1cfa756178 Remove spaces from comma seperated list in readme
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2018-10-08 14:08:13 +05:00
faizanahmad055
e8854000cb Update readme about how to define multiple configmaps and secrets
Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
2018-10-08 12:22:04 +05:00
stakater-user
291f25fd0e Bump Version to 0.0.16 2018-10-01 12:30:26 +00:00
Ali Kahoot
19d5704bf9 Merge pull request #28 from stakater/update-library-version
Update library version
2018-10-01 17:04:07 +05:00
Waseem Hassan
d24b112150 Update library version 2018-10-01 17:02:48 +05:00
Ali Kahoot
c5e00d7614 Merge pull request #27 from stakater/update-library-version
Update Jenkinsfile
2018-10-01 16:42:02 +05:00
Waseem Hassan
4779ef93c8 Update Jenkinsfile 2018-10-01 16:40:47 +05:00
Ahmad Iqbal Ali
b73f14aef9 add logo (#25) 2018-08-16 11:44:56 +05:00
stakater-user
67012d9544 Bump Version to 0.0.15 2018-08-10 10:24:31 +00:00
Waseem Hassan
f36c3e4dbb Merge pull request #23 from stakater/lean-readme
cleanup readme
2018-08-10 15:02:26 +05:00
faizanahmad055
b7ac8b8f07 Fix typo 2018-08-10 14:14:16 +05:00
faizanahmad055
9bef611a1a Add flags and add license 2018-08-10 14:11:55 +05:00
stakater-user
ea62b0036c Bump Version to 0.0.14 2018-08-10 08:18:14 +00:00
Faizan Ahmad
decb9b06be Merge pull request #24 from stakater/fix-reloader-vs-configmapcontroller
fix Reloader vs ConfigmapController doc
2018-08-10 12:56:26 +05:00
faizanahmad055
94bd7bb694 Fix reloader vs configmapcontroller layout 2018-08-10 12:53:53 +05:00
stakater-user
67843f839a Bump Version to 0.0.13 2018-08-10 06:15:54 +00:00
Rasheed Amir
342395cd84 fix Reloader vs ConfigmapController doc
improve the doc quality
2018-08-10 08:05:12 +02:00
Rasheed Amir
695c5b05d2 create a feature docs for seo purposes (#22)
this doc will/might help users to find this git repo and use it
2018-08-10 07:53:38 +02:00
Rasheed Amir
163aede486 cleanup readme
- add acknowledgements section
- configmap or secret name doesn't need to be same as deployment name
2018-08-10 07:53:14 +02:00
stakater-user
4d6da476ee Bump Version to 0.0.12 2018-08-10 00:34:51 +00:00
Ahmad Iqbal Ali
d5ea5d810d add docs link in README (#21) 2018-08-10 05:13:30 +05:00
stakater-user
0d10b35d3a Bump Version to 0.0.11 2018-08-03 21:38:04 +00:00
Rasheed Amir
807e0c0c1b cleanup the readme 2018-08-03 23:16:33 +02:00
stakater-user
052bbb23e5 Bump Version to 0.0.10 2018-08-02 10:27:58 +00:00
Ahmad Iqbal Ali
28fb50598c use generic slack details (#18)
since we don't have a reloader channel at the moment.
2018-08-02 12:05:53 +02:00
95 changed files with 10692 additions and 1665 deletions

1
.dockerignore Normal file
View File

@@ -0,0 +1 @@
vendor

7
.github/md_config.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"ignorePatterns": [
{
"pattern": "^(?!http).+"
}
]
}

171
.github/workflows/pull_request.yaml vendored Normal file
View File

@@ -0,0 +1,171 @@
name: Pull Request
on:
pull_request_target:
branches:
- master
env:
DOCKER_FILE_PATH: Dockerfile
KUBERNETES_VERSION: "1.18.0"
KIND_VERSION: "0.10.0"
REGISTRY: ghcr.io
jobs:
qa:
uses: stakater/.github/.github/workflows/pull_request_doc_qa.yaml@v0.0.44
with:
MD_CONFIG: .github/md_config.json
DOC_SRC: README.md docs
MD_LINT_CONFIG: .markdownlint.yaml
build:
runs-on: ubuntu-latest
name: Build
if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')"
steps:
- name: Check out code
uses: actions/checkout@v3
with:
ref: ${{github.event.pull_request.head.sha}}
# Setting up helm binary
- name: Set up Helm
uses: azure/setup-helm@v3
- name: Helm chart unit tests
uses: d3adb5/helm-unittest-action@v2
with:
charts: deployments/kubernetes/chart/reloader
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
check-latest: true
cache: true
- name: Install Dependencies
run: |
make install
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.51.1
only-new-issues: false
args: --timeout 10m
- name: Helm Lint
run: |
cd deployments/kubernetes/chart/reloader
helm lint
- name: Install kubectl
run: |
curl -LO "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl"
sudo install ./kubectl /usr/local/bin/ && rm kubectl
kubectl version --short --client
kubectl version --short --client | grep -q ${KUBERNETES_VERSION}
- name: Install Kind
run: |
curl -L -o kind https://github.com/kubernetes-sigs/kind/releases/download/v${KIND_VERSION}/kind-linux-amd64
sudo install ./kind /usr/local/bin && rm kind
kind version
kind version | grep -q ${KIND_VERSION}
- name: Create Kind Cluster
run: |
kind create cluster
kubectl cluster-info
- name: Test
run: make test
- name: Generate Tag
id: generate_tag
run: |
sha=${{ github.event.pull_request.head.sha }}
tag="SNAPSHOT-PR-${{ github.event.pull_request.number }}-${sha:0:8}"
echo "GIT_TAG=$(echo ${tag})" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Registry
uses: docker/login-action@v2
with:
username: ${{ secrets.STAKATER_DOCKERHUB_USERNAME }}
password: ${{ secrets.STAKATER_DOCKERHUB_PASSWORD }}
- name: Generate image repository path for Docker registry
run: |
echo DOCKER_IMAGE_REPOSITORY=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
- name: Build and Push Docker Image to Docker registry
uses: docker/build-push-action@v4
with:
context: .
file: ${{ env.DOCKER_FILE_PATH }}
pull: true
push: true
build-args: BUILD_PARAMETERS=${{ env.BUILD_PARAMETERS }}
cache-to: type=inline
platforms: linux/amd64,linux/arm,linux/arm64
tags: |
${{ env.DOCKER_IMAGE_REPOSITORY }}:${{ steps.generate_tag.outputs.GIT_TAG }}
labels: |
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Login to ghcr registry
uses: docker/login-action@v2
with:
registry: ${{env.REGISTRY}}
username: ${{github.actor}}
password: ${{secrets.GITHUB_TOKEN}}
- name: Generate image repository path for ghcr registry
run: |
echo GHCR_IMAGE_REPOSITORY=${{env.REGISTRY}}/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
- name: Build and Push Docker Image to ghcr registry
uses: docker/build-push-action@v4
with:
context: .
file: ${{ env.DOCKER_FILE_PATH }}
pull: true
push: true
build-args: BUILD_PARAMETERS=${{ env.BUILD_PARAMETERS }}
cache-to: type=inline
platforms: linux/amd64,linux/arm,linux/arm64
tags: |
${{ env.GHCR_IMAGE_REPOSITORY }}:${{ steps.generate_tag.outputs.GIT_TAG }}
labels: |
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Comment on PR
uses: mshick/add-pr-comment@v2
if: always()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
message-success: '@${{ github.actor }} Image is available for testing. `docker pull ghcr.io/${{ env.IMAGE_REPOSITORY }}:${{ steps.generate_tag.outputs.GIT_TAG }}`'
message-failure: '@${{ github.actor }} Yikes! You better fix it before anyone else finds out! [Build](https://github.com/${{ github.repository }}/commit/${{ github.event.pull_request.head.sha }}/checks) has Failed!'
allow-repeats: true
- name: Notify Slack
uses: 8398a7/action-slack@v3
if: always() # Pick up events even if the job fails or is canceled.
with:
status: ${{ job.status }}
fields: repo,author,action,eventName,ref,workflow
env:
GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.STAKATER_DELIVERY_SLACK_WEBHOOK }}

212
.github/workflows/push.yaml vendored Normal file
View File

@@ -0,0 +1,212 @@
name: Push
on:
push:
branches:
- master
env:
DOCKER_FILE_PATH: Dockerfile
KUBERNETES_VERSION: "1.18.0"
KIND_VERSION: "0.10.0"
HELM_REGISTRY_URL: "https://stakater.github.io/stakater-charts"
REGISTRY: ghcr.io
jobs:
build:
name: Build
if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')"
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
with:
token: ${{ secrets.STAKATER_GITHUB_TOKEN }}
fetch-depth: 0 # otherwise, you will fail to push refs to dest repo
# Setting up helm binary
- name: Set up Helm
uses: azure/setup-helm@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
check-latest: true
cache: true
- name: Install Dependencies
run: |
make install
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.51.1
only-new-issues: false
args: --timeout 10m
- name: Install kubectl
run: |
curl -LO "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl"
sudo install ./kubectl /usr/local/bin/ && rm kubectl
kubectl version --short --client
kubectl version --short --client | grep -q ${KUBERNETES_VERSION}
- name: Install Kind
run: |
curl -L -o kind https://github.com/kubernetes-sigs/kind/releases/download/v${KIND_VERSION}/kind-linux-amd64
sudo install ./kind /usr/local/bin && rm kind
kind version
kind version | grep -q ${KIND_VERSION}
- name: Create Kind Cluster
run: |
kind create cluster
kubectl cluster-info
- name: Test
run: make test
- name: Generate Tag
id: generate_tag
uses: anothrNick/github-tag-action@1.61.0
env:
GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }}
WITH_V: true
DEFAULT_BUMP: patch
DRY_RUN: true
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Registry
uses: docker/login-action@v2
with:
username: ${{ secrets.STAKATER_DOCKERHUB_USERNAME }}
password: ${{ secrets.STAKATER_DOCKERHUB_PASSWORD }}
- name: Generate image repository path for Docker registry
run: |
echo DOCKER_IMAGE_REPOSITORY=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
- name: Build and Push Docker Image to Docker registry
uses: docker/build-push-action@v4
with:
context: .
file: ${{ env.DOCKER_FILE_PATH }}
pull: true
push: true
build-args: BUILD_PARAMETERS=${{ env.BUILD_PARAMETERS }}
cache-to: type=inline
platforms: linux/amd64,linux/arm,linux/arm64
tags: |
${{ env.DOCKER_IMAGE_REPOSITORY }}:${{ steps.generate_tag.outputs.new_tag }}
labels: |
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Login to ghcr registry
uses: docker/login-action@v2
with:
registry: ${{env.REGISTRY}}
username: ${{github.actor}}
password: ${{secrets.GITHUB_TOKEN}}
- name: Generate image repository path for ghcr registry
run: |
echo GHCR_IMAGE_REPOSITORY=${{env.REGISTRY}}/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
- name: Build and Push Docker Image to ghcr registry
uses: docker/build-push-action@v4
with:
context: .
file: ${{ env.DOCKER_FILE_PATH }}
pull: true
push: true
build-args: BUILD_PARAMETERS=${{ env.BUILD_PARAMETERS }}
cache-to: type=inline
platforms: linux/amd64,linux/arm,linux/arm64
tags: |
${{ env.GHCR_IMAGE_REPOSITORY }}:${{ steps.generate_tag.outputs.new_tag }}
labels: |
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
##############################
## Add steps to generate required artifacts for a release here(helm chart, operator manifest etc.)
##############################
# Generate tag for operator without "v"
- name: Generate Operator Tag
id: generate_operator_tag
uses: anothrNick/github-tag-action@1.61.0
env:
GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }}
WITH_V: false
DEFAULT_BUMP: patch
DRY_RUN: true
# Update chart tag to the latest semver tag
- name: Update Chart Version
env:
VERSION: ${{ steps.generate_operator_tag.outputs.new_tag }}
run: make bump-chart
- name: Helm Template
run: |
helm template reloader deployments/kubernetes/chart/reloader/ > deployments/kubernetes/reloader.yaml
helm template reloader deployments/kubernetes/chart/reloader/ --output-dir deployments/kubernetes/manifests && mv deployments/kubernetes/manifests/reloader/templates/* deployments/kubernetes/manifests/ && rm -r deployments/kubernetes/manifests/reloader
# Publish helm chart
- name: Publish Helm chart
uses: stefanprodan/helm-gh-pages@master
with:
branch: master
repository: stakater-charts
target_dir: docs
token: ${{ secrets.STAKATER_GITHUB_TOKEN }}
charts_dir: deployments/kubernetes/chart/
charts_url: ${{ env.HELM_REGISTRY_URL }}
owner: stakater
linting: on
commit_username: stakater-user
commit_email: stakater@gmail.com
# Commit back changes
- name: Commit files
run: |
git config --local user.email "stakater@gmail.com"
git config --local user.name "stakater-user"
git status
git add .
git commit -m "[skip-ci] Update artifacts" -a
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.STAKATER_GITHUB_TOKEN }}
branch: ${{ github.ref }}
- name: Push Latest Tag
uses: anothrNick/github-tag-action@1.61.0
env:
GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }}
WITH_V: true
DEFAULT_BUMP: patch
- name: Notify Slack
uses: 8398a7/action-slack@v3
if: always() # Pick up events even if the job fails or is canceled.
with:
status: ${{ job.status }}
fields: repo,author,action,eventName,ref,workflow
env:
GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.STAKATER_DELIVERY_SLACK_WEBHOOK }}

42
.github/workflows/release.yaml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: Release Go project
on:
push:
tags:
- "v*"
jobs:
build:
name: GoReleaser build
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
with:
fetch-depth: 0 # See: https://goreleaser.com/ci/actions/
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: "go.mod"
check-latest: true
cache: true
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@master
with:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }}
- name: Notify Slack
uses: 8398a7/action-slack@v3
if: always()
with:
status: ${{ job.status }}
fields: repo,author,action,eventName,ref,workflow
env:
GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.STAKATER_DELIVERY_SLACK_WEBHOOK }}

5
.gitignore vendored
View File

@@ -7,4 +7,7 @@ out/
_gopath/
.DS_Store
.vscode
vendor
vendor
dist
Reloader
!**/chart/reloader

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "vocabulary"]
path = vocabulary
url = git@github.com:stakater/vocabulary.git

26
.goreleaser.yml Normal file
View File

@@ -0,0 +1,26 @@
builds:
- env:
- CGO_ENABLED=0
goos:
- windows
- darwin
- linux
goarch:
- 386
- amd64
- arm
- arm64
archives:
- name_template: "{{ .ProjectName }}_v{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
snapshot:
name_template: "{{ .Tag }}-next"
checksum:
name_template: "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
env_files:
github_token: /home/jenkins/.apitoken/hub

6
.markdownlint.yaml Normal file
View File

@@ -0,0 +1,6 @@
{
"MD007": { "indent": 4 },
"MD013": false,
"MD024": false,
"MD029": { "style": one },
}

3
.stignore Normal file
View File

@@ -0,0 +1,3 @@
.git
Reloader
__debug_bin

9
.vale.ini Normal file
View File

@@ -0,0 +1,9 @@
StylesPath = "vocabulary/styles"
MinAlertLevel = warning
Vocab = "Stakater"
# Only check MarkDown files
[*.md]
BasedOnStyles = Vale

View File

@@ -1 +0,0 @@
0.0.9

45
Dockerfile Normal file
View File

@@ -0,0 +1,45 @@
ARG BUILDER_IMAGE
ARG BASE_IMAGE
# Build the manager binary
FROM --platform=${BUILDPLATFORM} ${BUILDER_IMAGE:-golang:1.20.6} as builder
ARG TARGETOS
ARG TARGETARCH
ARG GOPROXY
ARG GOPRIVATE
WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go mod download
# Copy the go source
COPY main.go main.go
COPY internal/ internal/
COPY pkg/ pkg/
# Build
RUN CGO_ENABLED=0 \
GOOS=${TARGETOS} \
GOARCH=${TARGETARCH} \
GOPROXY=${GOPROXY} \
GOPRIVATE=${GOPRIVATE} \
GO111MODULE=on \
go build -mod=mod -a -o manager main.go
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM ${BASE_IMAGE:-gcr.io/distroless/static:nonroot}
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532
# Port for metrics and probes
EXPOSE 9090
ENTRYPOINT ["/manager"]

8
Jenkinsfile vendored
View File

@@ -1,8 +0,0 @@
#!/usr/bin/groovy
@Library('github.com/stakater/fabric8-pipeline-library@v2.5.3')
def dummy
goBuildAndRelease {
}

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,35 +1,73 @@
# note: call scripts from /scripts
.PHONY: default build builder-image binary-image test stop clean-images clean push apply deploy
.PHONY: default build build-image test stop push apply deploy release release-all manifest push
BUILDER ?= reloader-builder
OS ?= linux
ARCH ?= ???
ALL_ARCH ?= arm64 arm amd64
BUILDER_IMAGE ?=
BASE_IMAGE ?=
BINARY ?= Reloader
DOCKER_IMAGE ?= stakater/reloader
# Default value "dev"
DOCKER_TAG ?= 1.0.0
REPOSITORY = ${DOCKER_IMAGE}:${DOCKER_TAG}
DOCKER_IMAGE ?= ghcr.io/stakater/reloader
VERSION=$(shell cat .version)
# Default value "dev"
VERSION ?= 0.0.1
REPOSITORY_GENERIC = ${DOCKER_IMAGE}:${VERSION}
REPOSITORY_ARCH = ${DOCKER_IMAGE}:v${VERSION}-${ARCH}
BUILD=
GOCMD = go
GLIDECMD = glide
GOFLAGS ?= $(GOFLAGS:)
LDFLAGS =
GOPROXY ?=
GOPRIVATE ?=
default: build test
install:
"$(GLIDECMD)" install
"$(GOCMD)" mod download
run:
go run ./main.go
build:
"$(GOCMD)" build ${GOFLAGS} ${LDFLAGS} -o "${BINARY}"
builder-image:
@docker build --network host -t "${BUILDER}" -f build/package/Dockerfile.build .
build-image:
docker buildx build \
--platform ${OS}/${ARCH} \
--build-arg GOARCH=$(ARCH) \
--build-arg BUILDER_IMAGE=$(BUILDER_IMAGE) \
--build-arg BASE_IMAGE=${BASE_IMAGE} \
--build-arg GOPROXY=${GOPROXY} \
--build-arg GOPRIVATE=${GOPRIVATE} \
-t "${REPOSITORY_ARCH}" \
--load \
-f Dockerfile \
.
binary-image: builder-image
@docker run --network host --rm "${BUILDER}" | docker build --network host -t "${REPOSITORY}" -f Dockerfile.run -
push:
docker push ${REPOSITORY_ARCH}
release: build-image push manifest
release-all:
-rm -rf ~/.docker/manifests/*
# Make arch-specific release
@for arch in $(ALL_ARCH) ; do \
echo Make release: $$arch ; \
make release ARCH=$$arch ; \
done
set -e
docker manifest push --purge $(REPOSITORY_GENERIC)
manifest:
set -e
docker manifest create -a $(REPOSITORY_GENERIC) $(REPOSITORY_ARCH)
docker manifest annotate --arch $(ARCH) $(REPOSITORY_GENERIC) $(REPOSITORY_ARCH)
test:
"$(GOCMD)" test -timeout 1800s -v ./...
@@ -37,16 +75,14 @@ test:
stop:
@docker stop "${BINARY}"
clean-images: stop
@docker rmi "${BUILDER}" "${BINARY}"
clean:
"$(GOCMD)" clean -i
push: ## push the latest Docker image to DockerHub
docker push $(REPOSITORY)
apply:
kubectl apply -f deployments/manifests/ -n temp-reloader
deploy: binary-image push apply
# Bump Chart
bump-chart:
sed -i "s/^version:.*/version: $(VERSION)/" deployments/kubernetes/chart/reloader/Chart.yaml
sed -i "s/^appVersion:.*/appVersion: v$(VERSION)/" deployments/kubernetes/chart/reloader/Chart.yaml
sed -i "s/tag:.*/tag: v$(VERSION)/" deployments/kubernetes/chart/reloader/values.yaml
sed -i "s/version:.*/version: v$(VERSION)/" deployments/kubernetes/chart/reloader/values.yaml

344
README.md
View File

@@ -1,74 +1,350 @@
# RELOADER
# ![Reloader-logo](assets/web/reloader-round-100px.png) Reloader
[![Go Report Card](https://goreportcard.com/badge/github.com/stakater/reloader?style=flat-square)](https://goreportcard.com/report/github.com/stakater/reloader)
[![Go Doc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/stakater/reloader)
[![Release](https://img.shields.io/github/release/stakater/reloader.svg?style=flat-square)](https://github.com/stakater/reloader/releases/latest)
[![GitHub tag](https://img.shields.io/github/tag/stakater/reloader.svg?style=flat-square)](https://github.com/stakater/reloader/releases/latest)
[![Docker Pulls](https://img.shields.io/docker/pulls/stakater/reloader.svg?style=flat-square)](https://hub.docker.com/r/stakater/reloader/)
[![Docker Stars](https://img.shields.io/docker/stars/stakater/reloader.svg?style=flat-square)](https://hub.docker.com/r/stakater/reloader/)
[![license](https://img.shields.io/github/license/stakater/reloader.svg?style=flat-square)](LICENSE)
[![Get started with Stakater](https://stakater.github.io/README/stakater-github-banner.png)](https://stakater.com/?utm_source=Reloader&utm_medium=github)
## Problem
We would like to watch if some change happens in `ConfigMap` and `Secret` objects and then perform rolling upgrade on relevant `Deployment`, `Deamonset` and `Statefulset`
We would like to watch if some change happens in `ConfigMap` and/or `Secret`; then perform a rolling upgrade on relevant `DeploymentConfig`, `Deployment`, `Daemonset`, `Statefulset` and `Rollout`
## Solution
Reloader can watch changes in `ConfigMap` and `Secret` and do rolling upgrades on Pods with their associated `Deployments`, `Deamonsets` and `Statefulsets`.
Reloader can watch changes in `ConfigMap` and `Secret` and do rolling upgrades on Pods with their associated `DeploymentConfigs`, `Deployments`, `Daemonsets` `Statefulsets` and `Rollouts`.
**NOTE:** This controller has been inspired from [configmapController](https://github.com/fabric8io/configmapcontroller)
## Enterprise Version
Reloader is available in two different versions:
1. Open Source Version
1. Enterprise Version, which includes:
- SLA (Service Level Agreement) for support and unique requests
- Slack support
- Certified images
Contact [`sales@stakater.com`](mailto:sales@stakater.com) for info about Reloader Enterprise.
## Compatibility
Reloader is compatible with Kubernetes >= 1.9
## How to use Reloader
For a `Deployment` called `foo` have a `ConfigMap` called `foo`. Then add this annotation to your `Deployment`
For a `Deployment` called `foo` have a `ConfigMap` called `foo-configmap` or `Secret` called `foo-secret` or both. Then add your annotation (by default `reloader.stakater.com/auto`) to main metadata of your `Deployment`
```yaml
kind: Deployment
metadata:
annotations:
configmap.reloader.stakater.com/reload: "foo"
reloader.stakater.com/auto: "true"
spec:
template:
metadata:
```
OR
This will discover deploymentconfigs/deployments/daemonsets/statefulset/rollouts automatically where `foo-configmap` or `foo-secret` is being used either via environment variable or from volume mount. And it will perform rolling upgrade on related pods when `foo-configmap` or `foo-secret`are updated.
For a `Deployment` called `foo` have a `Secret` called `foo`. Then add this annotation to your `Deployment`
You can restrict this discovery to only `ConfigMap` or `Secret` objects that
are tagged with a special annotation. To take advantage of that, annotate
your deploymentconfigs/deployments/daemonsets/statefulset/rollouts like this:
```yaml
kind: Deployment
metadata:
annotations:
secret.reloader.stakater.com/reload: "foo"
reloader.stakater.com/search: "true"
spec:
template:
```
and Reloader will trigger the rolling upgrade upon modification of any
`ConfigMap` or `Secret` annotated like this:
```yaml
kind: ConfigMap
metadata:
annotations:
reloader.stakater.com/match: "true"
data:
key: value
```
provided the secret/configmap is being used in an environment variable, or a
volume mount.
Please note that `reloader.stakater.com/search` and
`reloader.stakater.com/auto` do not work together. If you have the
`reloader.stakater.com/auto: "true"` annotation on your deployment, then it
will always restart upon a change in configmaps or secrets it uses, regardless
of whether they have the `reloader.stakater.com/match: "true"` annotation or
not.
We can also specify a specific configmap or secret which would trigger rolling upgrade only upon change in our specified configmap or secret, this way, it will not trigger rolling upgrade upon changes in all configmaps or secrets used in a `deploymentconfig`, `deployment`, `daemonset`, `statefulset` or `rollout`.
To do this either set the auto annotation to `"false"` (`reloader.stakater.com/auto: "false"`) or remove it altogether, and use annotations for [Configmap](.#Configmap) or [Secret](.#Secret).
### Configmap
To perform rolling upgrade when change happens only on specific configmaps use below annotation.
For a `Deployment` called `foo` have a `ConfigMap` called `foo-configmap`. Then add this annotation to main metadata of your `Deployment`
```yaml
kind: Deployment
metadata:
annotations:
configmap.reloader.stakater.com/reload: "foo-configmap"
spec:
template:
metadata:
```
Use comma separated list to define multiple configmaps.
```yaml
kind: Deployment
metadata:
annotations:
configmap.reloader.stakater.com/reload: "foo-configmap,bar-configmap,baz-configmap"
spec:
template:
metadata:
```
### Secret
To perform rolling upgrade when change happens only on specific secrets use below annotation.
For a `Deployment` called `foo` have a `Secret` called `foo-secret`. Then add this annotation to main metadata of your `Deployment`
```yaml
kind: Deployment
metadata:
annotations:
secret.reloader.stakater.com/reload: "foo-secret"
spec:
template:
metadata:
```
Use comma separated list to define multiple secrets.
```yaml
kind: Deployment
metadata:
annotations:
secret.reloader.stakater.com/reload: "foo-secret,bar-secret,baz-secret"
spec:
template:
metadata:
```
### NOTES
- Reloader also supports [sealed-secrets](https://github.com/bitnami-labs/sealed-secrets). [Here](docs/Reloader-with-Sealed-Secrets.md) are the steps to use sealed-secrets with Reloader.
- For [`rollouts`](https://github.com/argoproj/argo-rollouts/) Reloader simply triggers a change is up to you how you configure the `rollout` strategy.
- `reloader.stakater.com/auto: "true"` will only reload the pod, if the configmap or secret is used (as a volume mount or as an env) in `DeploymentConfigs/Deployment/Daemonsets/Statefulsets`
- `secret.reloader.stakater.com/reload` or `configmap.reloader.stakater.com/reload` annotation will reload the pod upon changes in specified configmap or secret, irrespective of the usage of configmap or secret.
- you may override the auto annotation with the `--auto-annotation` flag
- you may override the search annotation with the `--auto-search-annotation` flag
and the match annotation with the `--search-match-annotation` flag
- you may override the configmap annotation with the `--configmap-annotation` flag
- you may override the secret annotation with the `--secret-annotation` flag
- you may want to prevent watching certain namespaces with the `--namespaces-to-ignore` flag
- you may want to watch only a set of namespaces with certain labels by using the `--namespace-selector` flag
- you may want to watch only a set of secrets/configmaps with certain labels by using the `--resource-label-selector` flag
- you may want to prevent watching certain resources with the `--resources-to-ignore` flag
- you can configure logging in JSON format with the `--log-format=json` option
- you can configure the "reload strategy" with the `--reload-strategy=<strategy-name>` option (details below)
## Reload Strategies
Reloader supports multiple "reload" strategies for performing rolling upgrades to resources. The following list describes them:
- **env-vars**: When a tracked `configMap`/`secret` is updated, this strategy attaches a Reloader specific environment variable to any containers referencing the changed `configMap` or `secret` on the owning resource (e.g., `Deployment`, `StatefulSet`, etc.). This strategy can be specified with the `--reload-strategy=env-vars` argument. Note: This is the default reload strategy.
- **annotations**: When a tracked `configMap`/`secret` is updated, this strategy attaches a `reloader.stakater.com/last-reloaded-from` pod template annotation on the owning resource (e.g., `Deployment`, `StatefulSet`, etc.). This strategy is useful when using resource syncing tools like ArgoCD, since it will not cause these tools to detect configuration drift after a resource is reloaded. Note: Since the attached pod template annotation only tracks the last reload source, this strategy will reload any tracked resource should its `configMap` or `secret` be deleted and recreated. This strategy can be specified with the `--reload-strategy=annotations` argument.
## Deploying to Kubernetes
You can deploy Reloader by following methods:
### Vanilla Manifests
You can apply vanilla manifests by running the following command
You can apply vanilla manifests by changing `RELEASE-NAME` placeholder provided in manifest with a proper value and apply it by running the command given below:
```bash
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
```
By default, Reloader gets deployed in `default` namespace and watches changes `secrets` and `configmaps` in all namespaces.
Reloader can be configured to ignore the resources `secrets` and `configmaps` by passing the following arguments (`spec.template.spec.containers.args`) to its container :
| Argument | Description |
| -------------------------------- | -------------------- |
| --resources-to-ignore=configMaps | To ignore configMaps |
| --resources-to-ignore=secrets | To ignore secrets |
**Note:** At one time only one of these resource can be ignored, trying to do it will cause error in Reloader. Workaround for ignoring both resources is by scaling down the Reloader pods to `0`.
Reloader can be configured to only watch secrets/configmaps with one or more labels using the `--resource-label-selector` parameter. Supported operators are `!, in, notin, ==, =, !=`, if no operator is found the 'exists' operator is inferred (i.e. key only). Additional examples of these selectors can be found in the [Kubernetes Docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors).
**Note:** The old `:` delimited key value mappings are deprecated and if provided will be translated to `key=value`. Likewise, if a wildcard value is provided (e.g. `key:*`) it will be translated to the standalone `key` which checks for key existence.
These selectors can be combined together, for example with:
```yaml
--resource-label-selector=reloader=enabled,key-exists,another-label in (value1,value2,value3)
```
Only configmaps or secrets labeled like the following will be watched:
```yaml
kind: ConfigMap
apiVersion: v1
metadata:
...
labels:
reloader: enabled
key-exists: yes
another-label: value1
...
```
Reloader can be configured to only watch namespaces labeled with one or more labels using the `--namespace-selector` parameter. Supported operators are `!, in, notin, ==, =, !=`, if no operator is found the 'exists' operator is inferred (i.e. key only). Additional examples of these selectors can be found in the [Kubernetes Docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors).
**Note:** The old `:` delimited key value mappings are deprecated and if provided will be translated to `key=value`. Likewise, if a wildcard value is provided (e.g. `key:*`) it will be translated to the standalone `key` which checks for key existence.
These selectors can be combined together, for example with:
```yaml
--namespace-selector=reloader=enabled,test=true
```
Only namespaces labeled as below would be watched and eligible for reloads:
```yaml
kind: Namespace
apiVersion: v1
metadata:
...
labels:
reloader: enabled
test: true
...
```
### Vanilla Kustomize
You can also apply the vanilla manifests by running the following command
```bash
kubectl apply -k https://github.com/stakater/Reloader/deployments/kubernetes
```
Similarly to vanilla manifests get deployed in `default` namespace and watches changes `secrets` and `configmaps` in all namespaces.
### Kustomize
You can write your own `kustomization.yaml` using ours as a 'base' and write patches to tweak the configuration.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- https://github.com/stakater/Reloader/deployments/kubernetes
namespace: reloader
```
### Helm Charts
Alternatively if you have configured helm on your cluster, you can add reloader to helm from our public chart repository and deploy it via helm using below mentioned commands
Alternatively if you have configured helm on your cluster, you can add Reloader to helm from our public chart repository and deploy it via helm using below-mentioned commands. Follow [this](docs/Helm2-to-Helm3.md) guide, in case you have trouble migrating Reloader from Helm2 to Helm3.
```bash
```bash
helm repo add stakater https://stakater.github.io/stakater-charts
helm repo update
helm install stakater/reloader
helm install stakater/reloader # For helm3 add --generate-name flag or set the release name
```
## Monitor All namespaces
**Note:** By default Reloader watches in all namespaces. To watch in single namespace, please run following command. It will install Reloader in `test` namespace which will only watch `Deployments`, `Daemonsets` `Statefulsets` and `Rollouts` in `test` namespace.
By default Reloader gets deployed in `default` namespace and watches changes `secrets` and `configmaps` in all namespaces.
```bash
helm install stakater/reloader --set reloader.watchGlobally=false --namespace test # For helm3 add --generate-name flag or set the release name
```
Reloader can be configured to ignore the resources `secrets` and `configmaps` by using the following parameters of `values.yaml` file:
| Parameter | Description | Type |
| ---------------- | -------------------------------------------------------------- | ------- |
| ignoreSecrets | To ignore secrets. Valid value are either `true` or `false` | boolean |
| ignoreConfigMaps | To ignore configMaps. Valid value are either `true` or `false` | boolean |
**Note:** At one time only one of these resource can be ignored, trying to do it will cause error in helm template compilation.
Reloader can be configured to only watch namespaces labeled with one or more labels using the `namespaceSelector` parameter
| Parameter | Description | Type |
| ---------------- | ---------------------------------------------------------------------------------- | ------- |
| namespaceSelector | list of comma separated label selectors, if multiple are provided they are combined with the AND operator | string |
Reloader can be configured to only watch configmaps/secrets labeled with one or more labels using the `resourceLabelSelector` parameter
| Parameter | Description | Type |
| ---------------------- | ---------------------------------------------------------------------------------- | ------- |
| resourceLabelSelector | list of comma separated label selectors, if multiple are provided they are combined with the AND operator | string |
**Note:** Both `namespaceSelector` & `resourceLabelSelector` can be used together. If they are then both conditions must be met for the configmap or secret to be eligible to trigger reload events. (e.g. If a configMap matches `resourceLabelSelector` but `namespaceSelector` does not match the namespace the configmap is in, it will be ignored).
You can also set the log format of Reloader to json by setting `logFormat` to `json` in values.yaml and apply the chart.
You can enable to scrape Reloader's Prometheus metrics by setting `serviceMonitor.enabled` or `podMonitor.enabled` to `true` in values.yaml file. Service monitor will be removed in future releases of Reloader in favour of Pod monitor.
**Note:** Reloading of OpenShift (DeploymentConfig) and/or Argo `Rollouts` has to be enabled explicitly because it might not be always possible to use it on a cluster with restricted permissions. This can be done by changing the following parameters:
| Parameter | Description | Type |
|------------------|------------------------------------------------------------------------------------------------------------------------------------------| ------- |
| isOpenshift | Enable OpenShift DeploymentConfigs. Valid value are either `true` or `false` | boolean |
| isArgoRollouts | Enable Argo `Rollouts`. Valid value are either `true` or `false` | boolean |
| reloadOnCreate | Enable reload on create events. Valid value are either `true` or `false` | boolean |
| syncAfterRestart | Enable sync after Reloader restarts for **Add** events, works only when reloadOnCreate is `true`. Valid value are either `true` or `false` | boolean |
**isOpenShift** Recent versions of OpenShift (tested on 4.13.3) require the specified user to be in an uid range which is dynamically assigned by the namespace. The solution is to unset the runAsUser variable via ``deployment.securityContext.runAsUser=null`` and let OpenShift assign it at install.
**ReloadOnCreate** reloadOnCreate controls how Reloader handles secrets being added to the cache for the first time. If reloadOnCreate is set to true:
- Configmaps/secrets being added to the cache will cause Reloader to perform a rolling update of the associated workload.
- When applications are deployed for the first time, Reloader will perform a rolling update of the associated workload.
- If you are running Reloader in HA mode all workloads will have a rolling update performed when a new leader is elected.
If ReloadOnCreate is set to false:
- Updates to configMaps/Secrets that occur while there is no leader will not be picked up by the new leader until a subsequent update of the configmap/secret occurs. In the worst case the window in which there can be no leader is 15s as this is the LeaseDuration.
## Help
**Got a question?**
File a GitHub [issue](https://github.com/stakater/Reloader/issues), or send us an [email](mailto:stakater@gmail.com).
### Documentation
You can find more documentation [here](docs)
### Have a question?
File a GitHub [issue](https://github.com/stakater/Reloader/issues).
### Talk to us on Slack
Join and talk to us on the #tools-imc channel for discussing Reloader
Join and talk to us on Slack for discussing Reloader
[![Join Slack](https://stakater.github.io/README/stakater-join-slack-btn.png)](https://stakater-slack.herokuapp.com/)
[![Chat](https://stakater.github.io/README/stakater-chat-btn.png)](https://stakater.slack.com/messages/CAN960CTG/)
[![Join Slack](https://stakater.github.io/README/stakater-join-slack-btn.png)](https://slack.stakater.com/)
[![Chat](https://stakater.github.io/README/stakater-chat-btn.png)](https://stakater-community.slack.com/messages/CC5S05S12)
## Contributing
@@ -78,15 +354,20 @@ Please use the [issue tracker](https://github.com/stakater/Reloader/issues) to r
### Developing
1. Deploy Reloader.
1. Run `okteto up` to activate your development container.
1. `make build`.
1. `./Reloader`
PRs are welcome. In general, we follow the "fork-and-pull" Git workflow.
1. **Fork** the repo on GitHub
2. **Clone** the project to your own machine
3. **Commit** changes to your own branch
4. **Push** your work back up to your fork
5. Submit a **Pull request** so that we can review your changes
1. **Fork** the repo on GitHub
1. **Clone** the project to your own machine
1. **Commit** changes to your own branch
1. **Push** your work back up to your fork
1. Submit a **Pull request** so that we can review your changes
NOTE: Be sure to merge the latest from "upstream" before making a pull request!
**NOTE:** Be sure to merge the latest from "upstream" before making a pull request!
## Changelog
@@ -94,14 +375,17 @@ View our closed [Pull Requests](https://github.com/stakater/Reloader/pulls?q=is%
## License
Apache2 © [Stakater](http://stakater.com)
Apache2 © [Stakater][website]
## About
`Reloader` is maintained by [Stakater][website]. Like it? Please let us know at <hello@stakater.com>
See [our other projects][community]
See [our other projects](https://github.com/stakater)
or contact us in case of professional services and queries on <hello@stakater.com>
[website]: http://stakater.com/
[community]: https://github.com/stakater/
[website]: https://stakater.com
## Acknowledgements
- [ConfigmapController](https://github.com/fabric8io/configmapcontroller); We documented [here](docs/Reloader-vs-ConfigmapController.md) why we re-created Reloader

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,21 +0,0 @@
FROM stakater/go-glide:1.9.3
MAINTAINER "Stakater Team"
RUN apk update
RUN apk -v --update \
add git build-base && \
rm -rf /var/cache/apk/* && \
mkdir -p "$GOPATH/src/github.com/stakater/Reloader"
ADD . "$GOPATH/src/github.com/stakater/Reloader"
RUN cd "$GOPATH/src/github.com/stakater/Reloader" && \
glide update && \
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a --installsuffix cgo --ldflags="-s" -o /Reloader
COPY build/package/Dockerfile.run /
# Running this image produces a tarball suitable to be piped into another
# Docker build command.
CMD tar -cf - -C / Dockerfile.run Reloader

View File

@@ -1,8 +0,0 @@
FROM alpine:3.4
MAINTAINER "Stakater Team"
RUN apk add --update ca-certificates
COPY Reloader /bin/Reloader
ENTRYPOINT ["/bin/Reloader"]

Binary file not shown.

View File

@@ -0,0 +1,2 @@
# OWNERS file for Kubernetes
OWNERS

View File

@@ -3,11 +3,19 @@
apiVersion: v1
name: reloader
description: Reloader chart that runs on kubernetes
version: 0.0.9
version: 1.0.33
appVersion: v1.0.33
keywords:
- Reloader
- kubernetes
home: https://github.com/stakater/Reloader
sources:
- https://github.com/stakater/Reloader
icon: https://raw.githubusercontent.com/stakater/Reloader/master/assets/web/reloader-round-100px.png
maintainers:
- name: Stakater
email: hello@stakater.com
- name: Stakater
email: hello@stakater.com
- name: rasheedamir
email: rasheed@stakater.com
- name: faizanahmad055
email: faizan.ahmad55@outlook.com

View File

@@ -0,0 +1,16 @@
approvers:
- faizanahmad055
- kahootali
- ahmadiq
- waseem-h
- rasheedamir
- ahsan-storm
- ahmedwaleedmalik
reviewers:
- faizanahmad055
- kahootali
- ahmadiq
- waseem-h
- rasheedamir
- ahsan-storm
- ahmedwaleedmalik

View File

@@ -0,0 +1,7 @@
- For a `Deployment` called `foo` have a `ConfigMap` called `foo-configmap`. Then add this annotation to main metadata of your `Deployment`
{{ .Values.reloader.custom_annotations.configmap | default "configmap.reloader.stakater.com/reload" }}: "foo-configmap"
- For a `Deployment` called `foo` have a `Secret` called `foo-secret`. Then add this annotation to main metadata of your `Deployment`
{{ .Values.reloader.custom_annotations.secret | default "secret.reloader.stakater.com/reload" }}: "foo-secret"
- After successful installation, your pods will get rolling updates when a change in data of configmap or secret will happen.

View File

@@ -2,6 +2,7 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "reloader-name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" | lower -}}
{{- end -}}
@@ -11,23 +12,54 @@ Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "reloader-fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "reloader-labels.selector" -}}
app: {{ template "reloader-name" . }}
group: {{ .Values.reloader.labels.group }}
provider: {{ .Values.reloader.labels.provider }}
{{- end -}}
{{- define "reloader-labels.stakater" -}}
{{ template "reloader-labels.selector" . }}
version: {{ .Values.reloader.labels.version }}
{{- end -}}
{{- define "reloader-labels.chart" -}}
app: {{ template "reloader-fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
{{- end -}}
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
{{- end -}}
{{/*
Create pod anti affinity labels
*/}}
{{- define "reloader-podAntiAffinity" -}}
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- {{ template "reloader-fullname" . }}
topologyKey: "kubernetes.io/hostname"
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "reloader-serviceAccountName" -}}
{{- if .Values.reloader.serviceAccount.create -}}
{{ default (include "reloader-fullname" .) .Values.reloader.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.reloader.serviceAccount.name }}
{{- end -}}
{{- end -}}
{{/*
Create the annotations to support helm3
*/}}
{{- define "reloader-helm3.annotations" -}}
meta.helm.sh/release-namespace: {{ .Release.Namespace | quote }}
meta.helm.sh/release-name: {{ .Release.Name | quote }}
{{- end -}}

View File

@@ -0,0 +1,106 @@
{{- if and .Values.reloader.watchGlobally (.Values.reloader.rbac.enabled) }}
{{- if (.Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1") }}
apiVersion: rbac.authorization.k8s.io/v1
{{ else }}
apiVersion: rbac.authorization.k8s.io/v1beta1
{{- end }}
kind: ClusterRole
metadata:
annotations:
{{ include "reloader-helm3.annotations" . | indent 4 }}
labels:
{{ include "reloader-labels.chart" . | indent 4 }}
{{- if .Values.reloader.rbac.labels }}
{{ toYaml .Values.reloader.rbac.labels | indent 4 }}
{{- end }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 4 }}
{{- end }}
name: {{ template "reloader-fullname" . }}-role
rules:
- apiGroups:
- ""
resources:
{{- if .Values.reloader.ignoreSecrets }}{{- else }}
- secrets
{{- end }}
{{- if .Values.reloader.ignoreConfigMaps }}{{- else }}
- configmaps
{{- end }}
verbs:
- list
- get
- watch
{{- if .Values.reloader.namespaceSelector }}
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
{{- end }}
{{- if and (.Capabilities.APIVersions.Has "apps.openshift.io/v1") (.Values.reloader.isOpenshift) }}
- apiGroups:
- "apps.openshift.io"
- ""
resources:
- deploymentconfigs
verbs:
- list
- get
- update
- patch
{{- end }}
{{- if and (.Capabilities.APIVersions.Has "argoproj.io/v1alpha1") (.Values.reloader.isArgoRollouts) }}
- apiGroups:
- "argoproj.io"
- ""
resources:
- rollouts
verbs:
- list
- get
- update
- patch
{{- end }}
- apiGroups:
- "apps"
resources:
- deployments
- daemonsets
- statefulsets
verbs:
- list
- get
- update
- patch
- apiGroups:
- "extensions"
resources:
- deployments
- daemonsets
verbs:
- list
- get
- update
- patch
{{- if .Values.reloader.enableHA }}
- apiGroups:
- "coordination.k8s.io"
resources:
- leases
verbs:
- create
- get
- update
{{- end}}
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
{{- end }}

View File

@@ -0,0 +1,28 @@
{{- if and .Values.reloader.watchGlobally (.Values.reloader.rbac.enabled) }}
{{- if (.Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1") }}
apiVersion: rbac.authorization.k8s.io/v1
{{ else }}
apiVersion: rbac.authorization.k8s.io/v1beta1
{{- end }}
kind: ClusterRoleBinding
metadata:
annotations:
{{ include "reloader-helm3.annotations" . | indent 4 }}
labels:
{{ include "reloader-labels.chart" . | indent 4 }}
{{- if .Values.reloader.rbac.labels }}
{{ toYaml .Values.reloader.rbac.labels | indent 4 }}
{{- end }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 4 }}
{{- end }}
name: {{ template "reloader-fullname" . }}-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "reloader-fullname" . }}-role
subjects:
- kind: ServiceAccount
name: {{ template "reloader-serviceAccountName" . }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
{{- end }}

View File

@@ -1,31 +1,241 @@
apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
{{ include "reloader-helm3.annotations" . | indent 4 }}
{{- if .Values.reloader.deployment.annotations }}
{{ toYaml .Values.reloader.deployment.annotations | indent 4 }}
{{- end }}
labels:
{{ include "reloader-labels.stakater" . | indent 4 }}
{{ include "reloader-labels.chart" . | indent 4 }}
name: {{ template "reloader-name" . }}
{{- if .Values.reloader.deployment.labels }}
{{ toYaml .Values.reloader.deployment.labels | indent 4 }}
{{- end }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 4 }}
{{- end }}
name: {{ template "reloader-fullname" . }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
spec:
{{- if not (.Values.reloader.enableHA) }}
replicas: 1
{{- else }}
replicas: {{ .Values.reloader.deployment.replicas }}
{{- end}}
revisionHistoryLimit: 2
selector:
matchLabels:
{{ include "reloader-labels.selector" . | indent 6 }}
app: {{ template "reloader-fullname" . }}
release: {{ .Release.Name | quote }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 6 }}
{{- end }}
template:
metadata:
{{- if .Values.reloader.deployment.pod.annotations }}
annotations:
{{ toYaml .Values.reloader.deployment.pod.annotations | indent 8 }}
{{- end }}
labels:
{{ include "reloader-labels.selector" . | indent 8 }}
{{ include "reloader-labels.chart" . | indent 8 }}
{{- if .Values.reloader.deployment.labels }}
{{ toYaml .Values.reloader.deployment.labels | indent 8 }}
{{- end }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 8 }}
{{- end }}
spec:
{{- with .Values.reloader.deployment.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.reloader.deployment.nodeSelector }}
nodeSelector:
{{ toYaml .Values.reloader.deployment.nodeSelector | indent 8 }}
{{- end }}
{{- if or (.Values.reloader.deployment.affinity) (.Values.reloader.enableHA) }}
affinity:
{{- if .Values.reloader.deployment.affinity }}
{{ toYaml .Values.reloader.deployment.affinity | indent 8 }}
{{- end}}
{{ include "reloader-podAntiAffinity" . | indent 8 }}
{{- end }}
{{- if .Values.reloader.deployment.tolerations }}
tolerations:
{{ toYaml .Values.reloader.deployment.tolerations | indent 8 }}
{{- end }}
{{- if .Values.reloader.deployment.topologySpreadConstraints }}
topologySpreadConstraints:
{{ toYaml .Values.reloader.deployment.topologySpreadConstraints | indent 8 }}
{{- end }}
{{- if .Values.reloader.deployment.priorityClassName }}
priorityClassName: {{ .Values.reloader.deployment.priorityClassName }}
{{- end }}
containers:
- env:
- image: "{{ .Values.reloader.deployment.image.name }}:{{ .Values.reloader.deployment.image.tag }}"
imagePullPolicy: {{ .Values.reloader.deployment.image.pullPolicy }}
name: {{ template "reloader-fullname" . }}
{{- if or (.Values.reloader.deployment.env.open) (.Values.reloader.deployment.env.secret) (.Values.reloader.deployment.env.field) (.Values.reloader.deployment.env.existing) (eq .Values.reloader.watchGlobally false) (.Values.reloader.enableHA)}}
env:
{{- range $name, $value := .Values.reloader.deployment.env.open }}
{{- if not (empty $value) }}
- name: {{ $name | quote }}
value: {{ $value | quote }}
{{- end }}
{{- end }}
{{- $secret_name := include "reloader-fullname" . }}
{{- range $name, $value := .Values.reloader.deployment.env.secret }}
{{- if not ( empty $value) }}
- name: {{ $name | quote }}
valueFrom:
secretKeyRef:
name: {{ $secret_name }}
key: {{ $name | quote }}
{{- end }}
{{- end }}
{{- range $secret, $values := .Values.reloader.deployment.env.existing }}
{{- range $name, $key := $values }}
{{- if not ( empty $name) }}
- name: {{ $name | quote }}
valueFrom:
secretKeyRef:
name: {{ $secret | quote }}
key: {{ $key | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- range $name, $value := .Values.reloader.deployment.env.field }}
{{- if not ( empty $value) }}
- name: {{ $name | quote }}
valueFrom:
fieldRef:
fieldPath: {{ $value | quote}}
{{- end }}
{{- end }}
{{- if eq .Values.reloader.watchGlobally false }}
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- end }}
image: "{{ .Values.reloader.image.name }}:{{ .Values.reloader.image.tag }}"
imagePullPolicy: {{ .Values.reloader.image.pullPolicy }}
name: {{ template "reloader-name" . }}
serviceAccountName: {{ template "reloader-name" . }}
{{- if .Values.reloader.enableHA }}
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- end }}
{{- end }}
ports:
- name: http
containerPort: 9090
livenessProbe:
httpGet:
path: /live
port: http
timeoutSeconds: {{ .Values.reloader.deployment.livenessProbe.timeoutSeconds | default "5" }}
failureThreshold: {{ .Values.reloader.deployment.livenessProbe.failureThreshold | default "5" }}
periodSeconds: {{ .Values.reloader.deployment.livenessProbe.periodSeconds | default "10" }}
successThreshold: {{ .Values.reloader.deployment.livenessProbe.successThreshold | default "1" }}
initialDelaySeconds: {{ .Values.reloader.deployment.livenessProbe.initialDelaySeconds | default "10" }}
readinessProbe:
httpGet:
path: /metrics
port: http
timeoutSeconds: {{ .Values.reloader.deployment.readinessProbe.timeoutSeconds | default "5" }}
failureThreshold: {{ .Values.reloader.deployment.readinessProbe.failureThreshold | default "5" }}
periodSeconds: {{ .Values.reloader.deployment.readinessProbe.periodSeconds | default "10" }}
successThreshold: {{ .Values.reloader.deployment.readinessProbe.successThreshold | default "1" }}
initialDelaySeconds: {{ .Values.reloader.deployment.readinessProbe.initialDelaySeconds | default "10" }}
{{- $containerSecurityContext := .Values.reloader.deployment.containerSecurityContext | default dict }}
{{- if .Values.reloader.readOnlyRootFileSystem }}
{{- $_ := set $containerSecurityContext "readOnlyRootFilesystem" true }}
{{- end }}
securityContext:
{{- toYaml $containerSecurityContext | nindent 10 }}
{{- if eq .Values.reloader.readOnlyRootFileSystem true }}
volumeMounts:
- mountPath: /tmp/
name: tmp-volume
{{- end }}
{{- if or (.Values.reloader.logFormat) (.Values.reloader.ignoreSecrets) (.Values.reloader.ignoreNamespaces) (.Values.reloader.namespaceSelector) (.Values.reloader.resourceLabelSelector) (.Values.reloader.ignoreConfigMaps) (.Values.reloader.custom_annotations) (eq .Values.reloader.isArgoRollouts true) (eq .Values.reloader.reloadOnCreate true) (ne .Values.reloader.reloadStrategy "default") (.Values.reloader.enableHA)}}
args:
{{- if .Values.reloader.logFormat }}
- "--log-format={{ .Values.reloader.logFormat }}"
{{- end }}
{{- if .Values.reloader.ignoreSecrets }}
- "--resources-to-ignore=secrets"
{{- end }}
{{- if .Values.reloader.ignoreConfigMaps }}
- "--resources-to-ignore=configMaps"
{{- end }}
{{- if .Values.reloader.ignoreNamespaces }}
- "--namespaces-to-ignore={{ .Values.reloader.ignoreNamespaces }}"
{{- end }}
{{- if .Values.reloader.namespaceSelector }}
- "--namespace-selector={{ .Values.reloader.namespaceSelector }}"
{{- end }}
{{- if .Values.reloader.resourceLabelSelector }}
- "--resource-label-selector={{ .Values.reloader.resourceLabelSelector }}"
{{- end }}
{{- if .Values.reloader.custom_annotations }}
{{- if .Values.reloader.custom_annotations.configmap }}
- "--configmap-annotation"
- "{{ .Values.reloader.custom_annotations.configmap }}"
{{- end }}
{{- if .Values.reloader.custom_annotations.secret }}
- "--secret-annotation"
- "{{ .Values.reloader.custom_annotations.secret }}"
{{- end }}
{{- if .Values.reloader.custom_annotations.auto }}
- "--auto-annotation"
- "{{ .Values.reloader.custom_annotations.auto }}"
{{- end }}
{{- if .Values.reloader.custom_annotations.search }}
- "--auto-search-annotation"
- "{{ .Values.reloader.custom_annotations.search }}"
{{- end }}
{{- if .Values.reloader.custom_annotations.match }}
- "--search-match-annotation"
- "{{ .Values.reloader.custom_annotations.match }}"
{{- end }}
{{- end }}
{{- if eq .Values.reloader.isArgoRollouts true }}
- "--is-Argo-Rollouts={{ .Values.reloader.isArgoRollouts }}"
{{- end }}
{{- if eq .Values.reloader.reloadOnCreate true }}
- "--reload-on-create={{ .Values.reloader.reloadOnCreate }}"
{{- end }}
{{- if eq .Values.reloader.syncAfterRestart true }}
- "--sync-after-restart={{ .Values.reloader.syncAfterRestart }}"
{{- end }}
{{- if ne .Values.reloader.reloadStrategy "default" }}
- "--reload-strategy={{ .Values.reloader.reloadStrategy }}"
{{- end }}
{{- if or (gt (int .Values.reloader.deployment.replicas) 1) (.Values.reloader.enableHA) }}
- "--enable-ha=true"
{{- end}}
{{- end }}
{{- if .Values.reloader.deployment.resources }}
resources:
{{ toYaml .Values.reloader.deployment.resources | indent 10 }}
{{- end }}
{{- if .Values.reloader.deployment.securityContext }}
securityContext: {{ toYaml .Values.reloader.deployment.securityContext | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "reloader-serviceAccountName" . }}
{{- if hasKey .Values.reloader.deployment "automountServiceAccountToken" }}
automountServiceAccountToken: {{ .Values.reloader.deployment.automountServiceAccountToken }}
{{- end }}
{{- if eq .Values.reloader.readOnlyRootFileSystem true }}
volumes:
- emptyDir: {}
name: tmp-volume
{{- end }}

View File

@@ -0,0 +1,30 @@
{{- if and ( .Values.reloader.netpol.enabled ) }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
annotations:
{{ include "reloader-helm3.annotations" . | indent 4 }}
labels:
{{ include "reloader-labels.chart" . | indent 4 }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 4 }}
{{- end }}
name: {{ template "reloader-fullname" . }}
spec:
podSelector:
matchLabels:
app: {{ template "reloader-fullname" . }}
release: {{ .Release.Name | quote }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 6 }}
{{- end }}
policyTypes:
- Ingress
ingress:
- ports:
- port: http
{{- with .Values.reloader.netpol.from}}
from:
{{- toYaml .| nindent 8 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,11 @@
{{- if .Values.reloader.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ template "reloader-fullname" . }}
spec:
minAvailable: {{ .Values.reloader.podDisruptionBudget.minAvailable }}
selector:
matchLabels:
app: {{ template "reloader-fullname" . }}
{{- end }}

View File

@@ -0,0 +1,58 @@
{{- if ( .Values.reloader.podMonitor.enabled ) }}
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
{{- if .Values.reloader.podMonitor.annotations }}
annotations:
{{ tpl (toYaml .Values.reloader.podMonitor.annotations) . | indent 4 }}
{{- end }}
labels:
{{ include "reloader-labels.chart" . | indent 4 }}
{{- if .Values.reloader.podMonitor.labels }}
{{ tpl (toYaml .Values.reloader.podMonitor.labels) . | indent 4 }}
{{- end }}
name: {{ template "reloader-fullname" . }}
{{- if .Values.reloader.podMonitor.namespace }}
namespace: {{ tpl .Values.reloader.podMonitor.namespace . }}
{{- end }}
spec:
podMetricsEndpoints:
- port: http
path: "/metrics"
{{- with .Values.reloader.podMonitor.interval }}
interval: {{ . }}
{{- end }}
{{- with .Values.reloader.podMonitor.scheme }}
scheme: {{ . }}
{{- end }}
{{- with .Values.reloader.podMonitor.bearerTokenSecret }}
bearerTokenSecret: {{ . }}
{{- end }}
{{- with .Values.reloader.podMonitor.tlsConfig }}
tlsConfig:
{{- toYaml .| nindent 6 }}
{{- end }}
{{- with .Values.reloader.podMonitor.timeout }}
scrapeTimeout: {{ . }}
{{- end }}
honorLabels: {{ .Values.reloader.podMonitor.honorLabels }}
{{- with .Values.reloader.podMonitor.metricRelabelings }}
metricRelabelings:
{{- tpl (toYaml . | nindent 6) $ }}
{{- end }}
{{- with .Values.reloader.podMonitor.relabelings }}
relabelings:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.reloader.podMonitor.podTargetLabels }}
podTargetLabels:
{{- toYaml . | nindent 4 }}
{{- end }}
jobLabel: {{ template "reloader-fullname" . }}
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
{{ include "reloader-labels.chart" . | nindent 6 }}
{{- end }}

View File

@@ -1,107 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
{{ include "reloader-labels.stakater" . | indent 4 }}
{{ include "reloader-labels.chart" . | indent 4 }}
name: {{ template "reloader-name" . }}
---
{{- if .Values.reloader.watchGlobally }}
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
labels:
{{ include "reloader-labels.stakater" . | indent 4 }}
{{ include "reloader-labels.chart" . | indent 4 }}
name: {{ template "reloader-name" . }}-role
namespace: {{ .Release.Namespace }}
rules:
- apiGroups:
- ""
resources:
- secrets
- configmaps
verbs:
- list
- get
- watch
- apiGroups:
- ""
- "extensions"
- "apps"
resources:
- deployments
- daemonsets
- statefulsets
verbs:
- list
- get
- update
- patch
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
labels:
{{ include "reloader-labels.stakater" . | indent 4 }}
{{ include "reloader-labels.chart" . | indent 4 }}
name: {{ template "reloader-name" . }}-role-binding
namespace: {{ .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "reloader-name" . }}-role
subjects:
- kind: ServiceAccount
name: {{ template "reloader-name" . }}
namespace: {{ .Release.Namespace }}
{{- else }}
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
labels:
{{ include "reloader-labels.stakater" . | indent 4 }}
{{ include "reloader-labels.chart" . | indent 4 }}
name: {{ template "reloader-name" . }}-role
namespace: {{ .Release.Namespace }}
rules:
- apiGroups:
- ""
resources:
- secrets
- configmaps
verbs:
- list
- get
- watch
- apiGroups:
- ""
- "extensions"
- "apps"
resources:
- deployments
- daemonsets
- statefulsets
verbs:
- list
- get
- update
- patch
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
labels:
{{ include "reloader-labels.stakater" . | indent 4 }}
{{ include "reloader-labels.chart" . | indent 4 }}
name: {{ template "reloader-name" . }}-role-binding
namespace: {{ .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "reloader-name" . }}-role
subjects:
- kind: ServiceAccount
name: {{ template "reloader-name" . }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,97 @@
{{- if and (not (.Values.reloader.watchGlobally)) (.Values.reloader.rbac.enabled) }}
{{- if (.Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1") }}
apiVersion: rbac.authorization.k8s.io/v1
{{ else }}
apiVersion: rbac.authorization.k8s.io/v1beta1
{{- end }}
kind: Role
metadata:
annotations:
{{ include "reloader-helm3.annotations" . | indent 4 }}
labels:
{{ include "reloader-labels.chart" . | indent 4 }}
{{- if .Values.reloader.rbac.labels }}
{{ toYaml .Values.reloader.rbac.labels | indent 4 }}
{{- end }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 4 }}
{{- end }}
name: {{ template "reloader-fullname" . }}-role
namespace: {{ .Values.namespace | default .Release.Namespace }}
rules:
- apiGroups:
- ""
resources:
{{- if .Values.reloader.ignoreSecrets }}{{- else }}
- secrets
{{- end }}
{{- if .Values.reloader.ignoreConfigMaps }}{{- else }}
- configmaps
{{- end }}
verbs:
- list
- get
- watch
{{- if and (.Capabilities.APIVersions.Has "apps.openshift.io/v1") (.Values.reloader.isOpenshift) }}
- apiGroups:
- "apps.openshift.io"
- ""
resources:
- deploymentconfigs
verbs:
- list
- get
- update
- patch
{{- end }}
{{- if and (.Capabilities.APIVersions.Has "argoproj.io/v1alpha1") (.Values.reloader.isArgoRollouts) }}
- apiGroups:
- "argoproj.io"
- ""
resources:
- rollouts
verbs:
- list
- get
- update
- patch
{{- end }}
- apiGroups:
- "apps"
resources:
- deployments
- daemonsets
- statefulsets
verbs:
- list
- get
- update
- patch
- apiGroups:
- "extensions"
resources:
- deployments
- daemonsets
verbs:
- list
- get
- update
- patch
{{- if .Values.reloader.enableHA }}
- apiGroups:
- "coordination.k8s.io"
resources:
- leases
verbs:
- create
- get
- update
{{- end}}
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
{{- end }}

View File

@@ -0,0 +1,29 @@
{{- if and (not (.Values.reloader.watchGlobally)) (.Values.reloader.rbac.enabled) }}
{{- if (.Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1") }}
apiVersion: rbac.authorization.k8s.io/v1
{{ else }}
apiVersion: rbac.authorization.k8s.io/v1beta1
{{- end }}
kind: RoleBinding
metadata:
annotations:
{{ include "reloader-helm3.annotations" . | indent 4 }}
labels:
{{ include "reloader-labels.chart" . | indent 4 }}
{{- if .Values.reloader.rbac.labels }}
{{ toYaml .Values.reloader.rbac.labels | indent 4 }}
{{- end }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 4 }}
{{- end }}
name: {{ template "reloader-fullname" . }}-role-binding
namespace: {{ .Values.namespace | default .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "reloader-fullname" . }}-role
subjects:
- kind: ServiceAccount
name: {{ template "reloader-serviceAccountName" . }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,21 @@
{{- if .Values.reloader.deployment.env.secret -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "reloader-fullname" . }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
type: Opaque
data:
{{ if .Values.reloader.deployment.env.secret.ALERT_ON_RELOAD -}}
ALERT_ON_RELOAD: {{ .Values.reloader.deployment.env.secret.ALERT_ON_RELOAD | b64enc | quote }}
{{ end }}
{{- if .Values.reloader.deployment.env.secret.ALERT_SINK -}}
ALERT_SINK: {{ .Values.reloader.deployment.env.secret.ALERT_SINK | b64enc | quote }}
{{ end }}
{{- if .Values.reloader.deployment.env.secret.ALERT_WEBHOOK_URL -}}
ALERT_WEBHOOK_URL: {{ .Values.reloader.deployment.env.secret.ALERT_WEBHOOK_URL | b64enc | quote }}
{{ end }}
{{- if .Values.reloader.deployment.env.secret.ALERT_ADDITIONAL_INFO -}}
ALERT_ADDITIONAL_INFO: {{ .Values.reloader.deployment.env.secret.ALERT_ADDITIONAL_INFO | b64enc | quote }}
{{ end }}
{{ end }}

View File

@@ -0,0 +1,30 @@
{{- if .Values.reloader.service }}
apiVersion: v1
kind: Service
metadata:
annotations:
{{ include "reloader-helm3.annotations" . | indent 4 }}
{{- if .Values.reloader.service.annotations }}
{{ toYaml .Values.reloader.service.annotations | indent 4 }}
{{- end }}
labels:
{{ include "reloader-labels.chart" . | indent 4 }}
{{- if .Values.reloader.service.labels }}
{{ toYaml .Values.reloader.service.labels | indent 4 }}
{{- end }}
name: {{ template "reloader-fullname" . }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
spec:
selector:
{{- if .Values.reloader.deployment.labels }}
{{ toYaml .Values.reloader.deployment.labels | indent 4 }}
{{- end }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 4 }}
{{- end }}
ports:
- port: {{ .Values.reloader.service.port }}
name: http
protocol: TCP
targetPort: http
{{- end }}

View File

@@ -0,0 +1,26 @@
{{- if .Values.reloader.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
{{- if .Values.global.imagePullSecrets }}
imagePullSecrets: {{ toYaml .Values.global.imagePullSecrets | nindent 2 }}
{{- end }}
{{- if hasKey .Values.reloader.serviceAccount "automountServiceAccountToken" }}
automountServiceAccountToken: {{ .Values.reloader.serviceAccount.automountServiceAccountToken }}
{{- end }}
metadata:
annotations:
{{ include "reloader-helm3.annotations" . | indent 4 }}
{{- if .Values.reloader.serviceAccount.annotations }}
{{ toYaml .Values.reloader.serviceAccount.annotations | indent 4 }}
{{- end }}
labels:
{{ include "reloader-labels.chart" . | indent 4 }}
{{- if .Values.reloader.serviceAccount.labels }}
{{ toYaml .Values.reloader.serviceAccount.labels | indent 4 }}
{{- end }}
{{- if .Values.reloader.matchLabels }}
{{ toYaml .Values.reloader.matchLabels | indent 4 }}
{{- end }}
name: {{ template "reloader-serviceAccountName" . }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,58 @@
{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) ( .Values.reloader.serviceMonitor.enabled ) }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
{{- if .Values.reloader.serviceMonitor.annotations }}
annotations:
{{ tpl (toYaml .Values.reloader.serviceMonitor.annotations) . | indent 4 }}
{{- end }}
labels:
{{ include "reloader-labels.chart" . | indent 4 }}
{{- if .Values.reloader.serviceMonitor.labels }}
{{ tpl (toYaml .Values.reloader.serviceMonitor.labels) . | indent 4 }}
{{- end }}
name: {{ template "reloader-fullname" . }}
{{- if .Values.reloader.serviceMonitor.namespace }}
namespace: {{ tpl .Values.reloader.serviceMonitor.namespace . }}
{{- end }}
spec:
endpoints:
- targetPort: http
path: "/metrics"
{{- with .Values.reloader.serviceMonitor.interval }}
interval: {{ . }}
{{- end }}
{{- with .Values.reloader.serviceMonitor.scheme }}
scheme: {{ . }}
{{- end }}
{{- with .Values.reloader.serviceMonitor.bearerTokenFile }}
bearerTokenFile: {{ . }}
{{- end }}
{{- with .Values.reloader.serviceMonitor.tlsConfig }}
tlsConfig:
{{- toYaml .| nindent 6 }}
{{- end }}
{{- with .Values.reloader.serviceMonitor.timeout }}
scrapeTimeout: {{ . }}
{{- end }}
honorLabels: {{ .Values.reloader.serviceMonitor.honorLabels }}
{{- with .Values.reloader.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{- tpl (toYaml . | nindent 6) $ }}
{{- end }}
{{- with .Values.reloader.serviceMonitor.relabelings }}
relabelings:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.reloader.serviceMonitor.targetLabels }}
targetLabels:
{{- toYaml . | nindent 4 }}
{{- end }}
jobLabel: {{ template "reloader-fullname" . }}
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
{{ include "reloader-labels.chart" . | nindent 6 }}
{{- end }}

View File

@@ -0,0 +1,50 @@
suite: Deployment
templates:
- deployment.yaml
tests:
- it: sets readOnlyRootFilesystem in container securityContext when reloader.readOnlyRootFileSystem is true
set:
reloader:
readOnlyRootFileSystem: true
deployment:
containerSecurityContext:
readOnlyRootFilesystem: false
asserts:
- equal:
path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem
value: true
- it: sets readOnlyRootFilesystem in container securityContext even if reloader.deployment.containerSecurityContext is null
set:
reloader:
readOnlyRootFileSystem: true
deployment:
containerSecurityContext: null
asserts:
- equal:
path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem
value: true
- it: does not override readOnlyRootFilesystem in container securityContext based on reloader.readOnlyRootFileSystem
set:
reloader:
readOnlyRootFileSystem: false
deployment:
containerSecurityContext:
readOnlyRootFilesystem: true
asserts:
- equal:
path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem
value: true
- it: template is still valid with no defined containerSecurityContext
set:
reloader:
readOnlyRootFileSystem: false
deployment:
containerSecurityContext: null
asserts:
- isEmpty:
path: spec.template.spec.containers[0].securityContext

View File

@@ -0,0 +1,19 @@
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"properties": {
"reloader": {
"type": "object",
"properties": {
"reloadStrategy": {
"type": "string",
"enum": [
"default",
"env-vars",
"annotations"
]
}
}
}
}
}

View File

@@ -1,15 +1,277 @@
# Generated from deployments/kubernetes/templates/chart/values.yaml.tmpl
global:
## Reference to one or more secrets to be used when pulling images
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
imagePullSecrets: []
kubernetes:
host: https://kubernetes.default
nameOverride: ""
fullnameOverride: ""
reloader:
labels:
provider: stakater
group: com.stakater.platform
version: 0.0.9
image:
name: stakater/reloader
tag: "0.0.9"
pullPolicy: IfNotPresent
watchGlobally: true
isArgoRollouts: false
isOpenshift: false
ignoreSecrets: false
ignoreConfigMaps: false
reloadOnCreate: false
syncAfterRestart: false
reloadStrategy: default # Set to default, env-vars or annotations
ignoreNamespaces: "" # Comma separated list of namespaces to ignore
namespaceSelector: "" # Comma separated list of k8s label selectors for namespaces selection
resourceLabelSelector: "" # Comma separated list of k8s label selectors for configmap/secret selection
logFormat: "" #json
watchGlobally: true
# Set to true to enable leadership election allowing you to run multiple replicas
enableHA: false
# Set to true if you have a pod security policy that enforces readOnlyRootFilesystem
readOnlyRootFileSystem: false
legacy:
rbac: false
matchLabels: {}
deployment:
# If you wish to run multiple replicas set reloader.enableHA = true
replicas: 1
nodeSelector:
# cloud.google.com/gke-nodepool: default-pool
# An affinity stanza to be applied to the Deployment.
# Example:
# affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: "node-role.kubernetes.io/infra-worker"
# operator: "Exists"
affinity: {}
securityContext:
runAsNonRoot: true
runAsUser: 65534
containerSecurityContext: {}
# capabilities:
# drop:
# - ALL
# allowPrivilegeEscalation: false
# readOnlyRootFilesystem: true
# A list of tolerations to be applied to the Deployment.
# Example:
# tolerations:
# - key: "node-role.kubernetes.io/infra-worker"
# operator: "Exists"
# effect: "NoSchedule"
tolerations: []
# Topology spread constraints for pod assignment
# Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
# Example:
# topologySpreadConstraints:
# - maxSkew: 1
# topologyKey: zone
# whenUnsatisfiable: DoNotSchedule
# labelSelector:
# matchLabels:
# app: my-app
topologySpreadConstraints: []
annotations: {}
labels:
provider: stakater
group: com.stakater.platform
version: v1.0.33
image:
name: ghcr.io/stakater/reloader
tag: v1.0.33
pullPolicy: IfNotPresent
# Support for extra environment variables.
env:
# Open supports Key value pair as environment variables.
open:
# secret supports Key value pair as environment variables. It gets the values based on keys from default reloader secret if any.
secret:
# ALERT_ON_RELOAD: <"true"|"false">
# ALERT_SINK: <"slack"> # By default it will be a raw text based webhook
# ALERT_WEBHOOK_URL: <"webhook_url">
# ALERT_ADDITIONAL_INFO: <"Additional Info like Cluster Name if needed">
# field supports Key value pair as environment variables. It gets the values from other fields of pod.
field:
# existing secret, you can specify multiple existing secrets, for each
# specify the env var name followed by the key in existing secret that
# will be used to populate the env var
existing:
# existing_secret_name:
# ALERT_ON_RELOAD: alert_on_reload_key
# ALERT_SINK: alert_sink_key
# ALERT_WEBHOOK_URL: alert_webhook_key
# ALERT_ADDITIONAL_INFO: alert_additional_info_key
# Liveness and readiness probe timeout values.
livenessProbe: {}
# timeoutSeconds: 5
# failureThreshold: 5
# periodSeconds: 10
# successThreshold: 1
readinessProbe: {}
# timeoutSeconds: 15
# failureThreshold: 5
# periodSeconds: 10
# successThreshold: 1
# Specify resource requests/limits for the deployment.
# Example:
# resources:
# limits:
# cpu: "100m"
# memory: "512Mi"
# requests:
# cpu: "10m"
# memory: "128Mi"
resources: {}
pod:
annotations: {}
priorityClassName: ""
# imagePullSecrets:
# - name: myregistrykey
service: {}
# labels: {}
# annotations: {}
# port: 9090
rbac:
enabled: true
labels: {}
# Service account config for the agent pods
serviceAccount:
# Specifies whether a ServiceAccount should be created
create: true
labels: {}
annotations: {}
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name:
# Optional flags to pass to the Reloader entrypoint
# Example:
# custom_annotations:
# configmap: "my.company.com/configmap"
# secret: "my.company.com/secret"
custom_annotations: {}
serviceMonitor:
# Deprecated: Service monitor will be removed in future releases of reloader in favour of Pod monitor
# Enabling this requires service to be enabled as well, or no endpoints will be found
enabled: false
# Set the namespace the ServiceMonitor should be deployed
# namespace: monitoring
# Fallback to the prometheus default unless specified
# interval: 10s
## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS.
# scheme: ""
## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS.
## Of type: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#tlsconfig
# tlsConfig: {}
# bearerTokenFile:
# Fallback to the prometheus default unless specified
# timeout: 30s
## Used to pass Labels that are used by the Prometheus installed in your cluster to select Service Monitors to work with
## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec
labels: {}
## Used to pass annotations that are used by the Prometheus installed in your cluster to select Service Monitors to work with
## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec
annotations: {}
# Retain the job and instance labels of the metrics pushed to the Pushgateway
# [Scraping Pushgateway](https://github.com/prometheus/pushgateway#configure-the-pushgateway-as-a-target-to-scrape)
honorLabels: true
## Metric relabel configs to apply to samples before ingestion.
## [Metric Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs)
metricRelabelings: []
# - action: keep
# regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'
# sourceLabels: [__name__]
## Relabel configs to apply to samples before ingestion.
## [Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config)
relabelings: []
# - sourceLabels: [__meta_kubernetes_pod_node_name]
# separator: ;
# regex: ^(.*)$
# targetLabel: nodename
# replacement: $1
# action: replace
targetLabels: []
podMonitor:
enabled: false
# Set the namespace the podMonitor should be deployed
# namespace: monitoring
# Fallback to the prometheus default unless specified
# interval: 10s
## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS.
# scheme: ""
## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS.
## Of type: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#tlsconfig
# tlsConfig: {}
# bearerTokenSecret:
# Fallback to the prometheus default unless specified
# timeout: 30s
## Used to pass Labels that are used by the Prometheus installed in your cluster to select Service Monitors to work with
## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec
labels: {}
## Used to pass annotations that are used by the Prometheus installed in your cluster to select Service Monitors to work with
## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec
annotations: {}
# Retain the job and instance labels of the metrics pushed to the Pushgateway
# [Scraping Pushgateway](https://github.com/prometheus/pushgateway#configure-the-pushgateway-as-a-target-to-scrape)
honorLabels: true
## Metric relabel configs to apply to samples before ingestion.
## [Metric Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs)
metricRelabelings: []
# - action: keep
# regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'
# sourceLabels: [__name__]
## Relabel configs to apply to samples before ingestion.
## [Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config)
relabelings: []
# - sourceLabels: [__meta_kubernetes_pod_node_name]
# separator: ;
# regex: ^(.*)$
# targetLabel: nodename
# replacement: $1
# action: replace
podTargetLabels: []
podDisruptionBudget:
enabled: false
# Set the minimum available replicas
# minAvailable: 1
netpol:
enabled: false
from: []
# - podSelector:
# matchLabels:
# app.kubernetes.io/name: prometheus

View File

@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- manifests/clusterrole.yaml
- manifests/clusterrolebinding.yaml
- manifests/serviceaccount.yaml
- manifests/deployment.yaml

View File

@@ -0,0 +1,54 @@
---
# Source: reloader/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
meta.helm.sh/release-namespace: "default"
meta.helm.sh/release-name: "reloader"
labels:
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
name: reloader-reloader-role
rules:
- apiGroups:
- ""
resources:
- secrets
- configmaps
verbs:
- list
- get
- watch
- apiGroups:
- "apps"
resources:
- deployments
- daemonsets
- statefulsets
verbs:
- list
- get
- update
- patch
- apiGroups:
- "extensions"
resources:
- deployments
- daemonsets
verbs:
- list
- get
- update
- patch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch

View File

@@ -0,0 +1,24 @@
---
# Source: reloader/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
meta.helm.sh/release-namespace: "default"
meta.helm.sh/release-name: "reloader"
labels:
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
name: reloader-reloader-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: reloader-reloader-role
subjects:
- kind: ServiceAccount
name: reloader-reloader
namespace: default

View File

@@ -1,36 +1,71 @@
---
# Source: reloader/templates/deployment.yaml
apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
meta.helm.sh/release-namespace: "default"
meta.helm.sh/release-name: "reloader"
labels:
app: reloader
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
group: com.stakater.platform
provider: stakater
version: 0.0.9
chart: "reloader-0.0.9"
release: "RELEASE-NAME"
heritage: "Tiller"
name: reloader
version: v1.0.33
name: reloader-reloader
namespace: default
spec:
replicas: 1
revisionHistoryLimit: 2
selector:
matchLabels:
app: reloader
group: com.stakater.platform
provider: stakater
app: reloader-reloader
release: "reloader"
template:
metadata:
labels:
app: reloader
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
group: com.stakater.platform
provider: stakater
version: v1.0.33
spec:
containers:
- env:
image: "stakater/reloader:0.0.9"
- image: "ghcr.io/stakater/reloader:v1.0.33"
imagePullPolicy: IfNotPresent
name: reloader
serviceAccountName: reloader
name: reloader-reloader
ports:
- name: http
containerPort: 9090
livenessProbe:
httpGet:
path: /live
port: http
timeoutSeconds: 5
failureThreshold: 5
periodSeconds: 10
successThreshold: 1
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /metrics
port: http
timeoutSeconds: 5
failureThreshold: 5
periodSeconds: 10
successThreshold: 1
initialDelaySeconds: 10
securityContext:
{}
securityContext:
runAsNonRoot: true
runAsUser: 65534
serviceAccountName: reloader-reloader

View File

@@ -1,73 +0,0 @@
---
# Source: reloader/templates/rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: reloader
group: com.stakater.platform
provider: stakater
version: 0.0.9
chart: "reloader-0.0.9"
release: "RELEASE-NAME"
heritage: "Tiller"
name: reloader
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
labels:
app: reloader
group: com.stakater.platform
provider: stakater
version: 0.0.9
chart: "reloader-0.0.9"
release: "RELEASE-NAME"
heritage: "Tiller"
name: reloader-role
namespace: default
rules:
- apiGroups:
- ""
resources:
- secrets
- configmaps
verbs:
- list
- get
- watch
- apiGroups:
- ""
- "extensions"
- "apps"
resources:
- deployments
- daemonsets
- statefulsets
verbs:
- list
- get
- update
- patch
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
labels:
app: reloader
group: com.stakater.platform
provider: stakater
version: 0.0.9
chart: "reloader-0.0.9"
release: "RELEASE-NAME"
heritage: "Tiller"
name: reloader-role-binding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: reloader-role
subjects:
- kind: ServiceAccount
name: reloader
namespace: default

View File

@@ -0,0 +1,16 @@
---
# Source: reloader/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
meta.helm.sh/release-namespace: "default"
meta.helm.sh/release-name: "reloader"
labels:
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
name: reloader-reloader
namespace: default

View File

@@ -1,71 +1,39 @@
---
# Source: reloader/templates/deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: reloader
group: com.stakater.platform
provider: stakater
version: 0.0.9
chart: "reloader-0.0.9"
release: "RELEASE-NAME"
heritage: "Tiller"
name: reloader
spec:
replicas: 1
revisionHistoryLimit: 2
selector:
matchLabels:
app: reloader
group: com.stakater.platform
provider: stakater
template:
metadata:
labels:
app: reloader
group: com.stakater.platform
provider: stakater
spec:
containers:
- env:
image: "stakater/reloader:0.0.9"
imagePullPolicy: IfNotPresent
name: reloader
serviceAccountName: reloader
---
# Source: reloader/templates/rbac.yaml
# Source: reloader/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
meta.helm.sh/release-namespace: "default"
meta.helm.sh/release-name: "reloader"
labels:
app: reloader
group: com.stakater.platform
provider: stakater
version: 0.0.9
chart: "reloader-0.0.9"
release: "RELEASE-NAME"
heritage: "Tiller"
name: reloader
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
name: reloader-reloader
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1beta1
# Source: reloader/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app: reloader
group: com.stakater.platform
provider: stakater
version: 0.0.9
chart: "reloader-0.0.9"
release: "RELEASE-NAME"
heritage: "Tiller"
name: reloader-role
namespace: default
annotations:
meta.helm.sh/release-namespace: "default"
meta.helm.sh/release-name: "reloader"
labels:
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
name: reloader-reloader-role
rules:
- apiGroups:
- ""
resources:
resources:
- secrets
- configmaps
verbs:
@@ -73,8 +41,6 @@ rules:
- get
- watch
- apiGroups:
- ""
- "extensions"
- "apps"
resources:
- deployments
@@ -85,25 +51,115 @@ rules:
- get
- update
- patch
- apiGroups:
- "extensions"
resources:
- deployments
- daemonsets
verbs:
- list
- get
- update
- patch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1beta1
# Source: reloader/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app: reloader
group: com.stakater.platform
provider: stakater
version: 0.0.9
chart: "reloader-0.0.9"
release: "RELEASE-NAME"
heritage: "Tiller"
name: reloader-role-binding
namespace: default
annotations:
meta.helm.sh/release-namespace: "default"
meta.helm.sh/release-name: "reloader"
labels:
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
name: reloader-reloader-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: reloader-role
name: reloader-reloader-role
subjects:
- kind: ServiceAccount
name: reloader
name: reloader-reloader
namespace: default
---
# Source: reloader/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
meta.helm.sh/release-namespace: "default"
meta.helm.sh/release-name: "reloader"
labels:
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
group: com.stakater.platform
provider: stakater
version: v1.0.33
name: reloader-reloader
namespace: default
spec:
replicas: 1
revisionHistoryLimit: 2
selector:
matchLabels:
app: reloader-reloader
release: "reloader"
template:
metadata:
labels:
app: reloader-reloader
chart: "reloader-1.0.33"
release: "reloader"
heritage: "Helm"
app.kubernetes.io/managed-by: "Helm"
group: com.stakater.platform
provider: stakater
version: v1.0.33
spec:
containers:
- image: "ghcr.io/stakater/reloader:v1.0.33"
imagePullPolicy: IfNotPresent
name: reloader-reloader
ports:
- name: http
containerPort: 9090
livenessProbe:
httpGet:
path: /live
port: http
timeoutSeconds: 5
failureThreshold: 5
periodSeconds: 10
successThreshold: 1
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /metrics
port: http
timeoutSeconds: 5
failureThreshold: 5
periodSeconds: 10
successThreshold: 1
initialDelaySeconds: 10
securityContext:
{}
securityContext:
runAsNonRoot: true
runAsUser: 65534
serviceAccountName: reloader-reloader

View File

@@ -4,10 +4,26 @@ apiVersion: v1
name: reloader
description: Reloader chart that runs on kubernetes
version: {{ getenv "VERSION" }}
appVersion: {{ getenv "VERSION" }}
keywords:
- Reloader
- kubernetes
home: https://github.com/stakater/Reloader
sources:
- https://github.com/stakater/IngressMonitorController
icon: https://raw.githubusercontent.com/stakater/Reloader/master/assets/web/reloader-round-100px.png
maintainers:
- name: Stakater
email: hello@stakater.com
email: hello@stakater.com
- name: rasheedamir
email: rasheed@aurorasolutions.io
- name: waseem-h
email: waseemhassan@stakater.com
- name: faizanahmad055
email: faizan.ahmad55@outlook.com
- name: kahootali
email: ali.kahoot@aurorasolutions.io
- name: ahmadiq
email: ahmad@aurorasolutions.io
- name: ahsan-storm
email: ahsanmuhammad1@outlook.com

View File

@@ -1,15 +1,138 @@
# Generated from deployments/kubernetes/templates/chart/values.yaml.tmpl
global:
## Reference to one or more secrets to be used when pulling images
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
imagePullSecrets: []
kubernetes:
host: https://kubernetes.default
reloader:
labels:
provider: stakater
group: com.stakater.platform
version: {{ getenv "VERSION" }}
image:
name: {{ getenv "DOCKER_IMAGE" }}
tag: "{{ getenv "VERSION" }}"
pullPolicy: IfNotPresent
watchGlobally: true
isArgoRollouts: false
isOpenshift: false
ignoreSecrets: false
ignoreConfigMaps: false
reloadOnCreate: false
reloadStrategy: default # Set to default, env-vars or annotations
ignoreNamespaces: "" # Comma separated list of namespaces to ignore
logFormat: "" #json
watchGlobally: true
# Set to true if you have a pod security policy that enforces readOnlyRootFilesystem
readOnlyRootFileSystem: false
legacy:
rbac: false
matchLabels: {}
deployment:
replicas: 1
nodeSelector:
# cloud.google.com/gke-nodepool: default-pool
# An affinity stanza to be applied to the Deployment.
# Example:
# affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: "node-role.kubernetes.io/infra-worker"
# operator: "Exists"
affinity: {}
securityContext:
runAsNonRoot: true
runAsUser: 65534
containerSecurityContext: {}
# capabilities:
# drop:
# - ALL
# allowPrivilegeEscalation: false
# readOnlyRootFilesystem: true
# A list of tolerations to be applied to the Deployment.
# Example:
# tolerations:
# - key: "node-role.kubernetes.io/infra-worker"
# operator: "Exists"
# effect: "NoSchedule"
tolerations: []
annotations: {}
labels:
provider: stakater
group: com.stakater.platform
version: {{ getenv "VERSION" }}
image:
name: {{ getenv "DOCKER_IMAGE" }}
tag: "{{ getenv "VERSION" }}"
pullPolicy: IfNotPresent
# Support for extra environment variables.
env:
# Open supports Key value pair as environment variables.
open:
# secret supports Key value pair as environment variables. It gets the values based on keys from default reloader secret if any.
secret:
# field supports Key value pair as environment variables. It gets the values from other fields of pod.
field:
# Specify resource requests/limits for the deployment.
# Example:
# resources:
# limits:
# cpu: "100m"
# memory: "512Mi"
# requests:
# cpu: "10m"
# memory: "128Mi"
resources: {}
pod:
annotations: {}
service: {}
# labels: {}
# annotations: {}
# port: 9090
rbac:
enabled: true
labels: {}
# Service account config for the agent pods
serviceAccount:
# Specifies whether a ServiceAccount should be created
create: true
labels: {}
annotations: {}
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name:
# Optional flags to pass to the Reloader entrypoint
# Example:
# custom_annotations:
# configmap: "my.company.com/configmap"
# secret: "my.company.com/secret"
custom_annotations: {}
serviceMonitor:
# enabling this requires service to be enabled as well, or no endpoints will be found
enabled: false
# Set the namespace the ServiceMonitor should be deployed
# namespace: monitoring
# Set how frequently Prometheus should scrape
# interval: 30s
# Set labels for the ServiceMonitor, use this to define your scrape label for Prometheus Operator
# labels:
# Set timeout for scrape
# timeout: 10s
podMonitor:
# enabling this requires service to be enabled as well, or no endpoints will be found
enabled: false
# Set the namespace the podMonitor should be deployed
# namespace: monitoring
# Set how frequently Prometheus should scrape
# interval: 30s
# Set labels for the podMonitor, use this to define your scrape label for Prometheus Operator
# labels:
# Set timeout for scrape
# timeout: 10s

18
docs/Alerting.md Normal file
View File

@@ -0,0 +1,18 @@
# Alerting on Reload
Reloader can alert when it triggers a rolling upgrade on Deployments or StatefulSets. Webhook notification alert would be sent to the configured webhook server with all the required information.
## Enabling the feature
In-order to enable this feature, you need to update the `reloader.env.secret` section of values.yaml providing the information needed for alert.
```yaml
ALERT_ON_RELOAD: [ true/false ] Default: false
ALERT_SINK: [ slack/webhook ] Default: webhook
ALERT_WEBHOOK_URL: Required if ALERT_ON_RELOAD is true
ALERT_ADDITIONAL_INFO: Any additional information to be added to alert
```
## Slack incoming-webhook creation docs
[Sending messages using Incoming Webhooks](https://api.slack.com/messaging/webhooks)

53
docs/Container Build.md Normal file
View File

@@ -0,0 +1,53 @@
# Container Build
> **WARNING:** As a user of Reloader there is no need to build containers, the open source version is available on [Docker Hub](https://hub.docker.com/r/stakater/reloader/).
Multi-architecture approach is based on original work by [@mdh02038](https://github.com/mdh02038/Reloader).
Images are tested on linux/arm, linux/arm64 and linux/amd64.
## Install Pre-Reqs
The build environment requires the following packages (tested on `Ubuntu 20.04`):
* Golang
* `make`
* `qemu` (for arm, arm64 etc. emulation)
* binfmt-support
* Docker engine
## Docker
Follow instructions on [Install using the apt repository](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository).
Once installed, enable the experimental CLI:
```bash
export DOCKER_CLI_EXPERIMENTAL=enabled
```
Login to enable publishing of packages:
```bash
sudo docker login
```
## Remaining Pre-Reqs
Remaining Pre-Reqs can be installed via:
```bash
sudo apt install golang make qemu-user-static binfmt-support -y
```
## Publish Multi-Architecture Image
To build/ publish multi-arch Docker images clone repository and execute from repository root:
```bash
sudo make release-all
```
## Additional Links/Info
[Building Multi-Architecture Docker Images With `Buildx`](https://medium.com/@artur.klauser/building-multi-architecture-docker-images-with-buildx-27d80f7e2408)

68
docs/Helm2-to-Helm3.md Normal file
View File

@@ -0,0 +1,68 @@
# Helm2 to Helm3 Migration
Follow below-mentioned instructions to migrate Reloader from Helm2 to Helm3
## Instructions
There are 3 steps involved in migrating the Reloader from Helm2 to Helm3.
### Step 1
Install the helm-2to3 plugin
```bash
helm3 plugin install https://github.com/helm/helm-2to3
helm3 2to3 convert <release-name>
helm3 2to3 cleanup --release-cleanup --skip-confirmation
```
### Step 2
Add the following Helm3 labels and annotations on Reloader resources.
Label:
```yaml
app.kubernetes.io/managed-by=Helm
```
Annotations:
```yaml
meta.helm.sh/release-name=<release-name>
meta.helm.sh/release-namespace=<namespace>
```
For example, to label and annotate the ClusterRoleBinding and ClusterRole:
```bash
KIND=ClusterRoleBinding
NAME=reloader-reloader-role-binding
RELEASE=reloader
NAMESPACE=kube-system
kubectl annotate $KIND $NAME meta.helm.sh/release-name=$RELEASE
kubectl annotate $KIND $NAME meta.helm.sh/release-namespace=$NAMESPACE
kubectl label $KIND $NAME app.kubernetes.io/managed-by=Helm
KIND=ClusterRole
NAME=reloader-reloader-role
RELEASE=reloader
NAMESPACE=kube-system
kubectl annotate $KIND $NAME meta.helm.sh/release-name=$RELEASE
kubectl annotate $KIND $NAME meta.helm.sh/release-namespace=$NAMESPACE
kubectl label $KIND $NAME app.kubernetes.io/managed-by=Helm
```
### Step 3
Upgrade to desired version
```bash
helm3 repo add stakater https://stakater.github.io/stakater-charts
helm3 repo update
helm3 upgrade <release-name> stakater/reloader --version=v0.0.72
```

View File

@@ -1,6 +1,6 @@
# How it works?
Reloader watches for `ConfigMap` and `Secret` and detects if there are changes in data of these objects. After change detection reloader performs rolling upgrade on relevant Pods via associated `Deployment`, `Deamonset` and `Statefulset`.
Reloader watches for `ConfigMap` and `Secret` and detects if there are changes in data of these objects. After change detection Reloader performs rolling upgrade on relevant Pods via associated `Deployment`, `Daemonset` and `Statefulset`.
## How change detection works
@@ -13,11 +13,11 @@ To perform rolling upgrade a `deployment`, `daemonset` or `statefulset` must hav
- support for rolling upgrade strategy
- specific annotation for `configmaps` or `secrets`
The annotation value is comma separated list of `configmaps` or `secrets`. If a change is detected in data of these `configmaps` or `secrets`, reloader will perform rolling upgrades on their associated `deployments`, `daemonsets` or `statefulsets`.
The annotation value is comma separated list of `configmaps` or `secrets`. If a change is detected in data of these `configmaps` or `secrets`, Reloader will perform rolling upgrades on their associated `deployments`, `daemonsets` or `statefulsets`.
### Annotation for Configmap
For a `Deployment` called `foo` have a `ConfigMap` called `foo`. Then add this annotation to your `Deployment`
For a `Deployment` called `foo` have a `ConfigMap` called `foo`. Then add this annotation* to your `Deployment`, where the default annotation can be changed with the `--configmap-annotation` flag:
```yaml
metadata:
@@ -27,7 +27,7 @@ metadata:
### Annotation for Secret
For a `Deployment` called `foo` have a `Secret` called `foo`. Then add this annotation to your `Deployment`
For a `Deployment` called `foo` have a `Secret` called `foo`. Then add this annotation to your `Deployment`, where the default annotation can be changed with the `--secret-annotation` flag:
```yaml
metadata:
@@ -35,13 +35,13 @@ metadata:
secret.reloader.stakater.com/reload: "foo"
```
Above mentioned annotation are also work for `Daemonsets` and `Statefulsets`
Above mentioned annotation are also work for `Daemonsets` `Statefulsets` and `Rollouts`
## How Rolling upgrade works?
When reloader detects changes in configmap. It gets two objects of configmap. First object is an old configmap object which has a state before the latest change. Second object is new configmap object which contains latest changes. Reloader compares both objects and see whether any change in data occurred or not. If reloader finds any change in new configmap object, only then, it move forward with rolling upgrade.
When Reloader detects changes in configmap. It gets two objects of configmap. First object is an old configmap object which has a state before the latest change. Second object is new configmap object which contains latest changes. Reloader compares both objects and see whether any change in data occurred or not. If Reloader finds any change in new configmap object, only then, it moves forward with rolling upgrade.
After that, reloader gets the list of all deployments, daemonsets and statefulset and looks for above mentioned annotation for configmap. If the annotation value contains the configmap name, it then looks for an environment variable which can contain the configmap or secret data change hash.
After that, Reloader gets the list of all `deployments`, `daemonsets` and `statefulset` and looks for above mentioned annotation for configmap. If the annotation value contains the configmap name, it then looks for an environment variable which can contain the configmap or secret data change hash.
### Environment variable for Configmap
@@ -59,7 +59,7 @@ If Secret name is foo then
STAKATER_FOO_SECRET
```
If the environment variable is found then it gets its value and compares it with new configmap hash value. If old value in environment variable is different from new hash value then reloader updates the environment variable. If the environment variable does not exist then it creates a new environment variable with latest hash value from configmap and updates the relevant `deployment`, `daemonset` or `statefulset`
If the environment variable is found then it gets its value and compares it with new configmap hash value. If old value in environment variable is different from new hash value then Reloader updates the environment variable. If the environment variable does not exist then it creates a new environment variable with latest hash value from configmap and updates the relevant `deployment`, `daemonset` or `statefulset`
Note: Rolling upgrade also works in the same way for secrets.
@@ -69,9 +69,14 @@ Reloader uses SHA1 to compute hash value. SHA1 is used because it is efficient a
## Monitor All Namespaces
By default reloader deploys in default namespace and monitors changes in all namespaces. To monitor changes in a specific namespace deploy the reloader in that namespace and set the `watchGlobally` flag to `false` in values file located under `deployments/kubernetes/chart/reloader`
And render manifest file using helm command
By default Reloader deploys in default namespace and monitors changes in all namespaces. To monitor changes in a specific namespace deploy the Reloader in that namespace and set the `watchGlobally` flag to `false` in values file located under `deployments/kubernetes/chart/reloader` and render manifest file using helm command:
```bash
helm --namespace {replace this with namespace name} template . > reloader.yaml
```
The output file can then be used to deploy reloader in specific namespace.
The output file can then be used to deploy Reloader in specific namespace.
## Compatibility with helm install and upgrade
Reloader has no impact on helm deployment cycle. Reloader only injects an environment variable in `deployment`, `daemonset` or `statefulset`. The environment variable contains the SHA1 value of configmap's or secret's data. So if a deployment is created using Helm and Reloader updates the deployment, then next time you upgrade the helm release, Reloader will do nothing except changing that environment variable value in `deployment` , `daemonset` or `statefulset`.

View File

@@ -1,10 +1,12 @@
# Reloader vs ConfigmapController
Reloader is inspired from [configmapcontroller](https://github.com/fabric8io/configmapcontroller) but there are many ways in which it differs from configmapController. Below is the small comparison between these two controllers.
Reloader is inspired from [Configmapcontroller](https://github.com/fabric8io/configmapcontroller) but there are many ways in which it differs from configmapController. Below is the small comparison between these two controllers.
| Configmap | Reloader |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ConfigmapController can only watch changes in `configmaps`. It cannot detect changes in other resources like `secrets`. | Reloader on the other hand can watch and detect changes in both `secrets` and `configmaps`. |
| ConfigmapController can only perform rolling upgrades on `deployments`. It currently does not support rolling upgrades on `statefulsets` and `daemonsets` | Reloader on the other hand can perform rolling upgrades on `deployments` as well as on `statefulsets` and `daemonsets` |
| Currently there are no unit test cases or end to end integration test cases in configmap controller. It add difficulties for any additional updates in configmap controller and one can not know for sure if new changes break any older functionality or not. | Reloader provides both unit test cases and end to end integration test cases for future updates. So one can make sure that new changes do not break any older functionality. |
| Configmap controller uses `FABRICB_FOO_REVISION` environment variable to store any change in configmap controller. It does not encode it or convert it in suitable hash value to avoid data pollution in deployment. | Reloader uses SHA1 to encode the change in configmap or secret. It then saves the SHA1 value in `STAKATER_FOO_CONFIGMAP` or `STAKATER_FOO_SECRET` environment variable depending upon where the change has happened. The use of SHA1 provides a concise 40 characters encoded value that is also very less pron to collision. |
| Reloader | Configmap |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Reloader can watch both `secrets` and `configmaps`. | ConfigmapController can only watch changes in `configmaps`. It cannot detect changes in other resources like `secrets`. |
| Reloader can perform rolling upgrades on `deployments` as well as on `statefulsets` and `daemonsets` | ConfigmapController can only perform rolling upgrades on `deployments`. It currently does not support rolling upgrades on `statefulsets` and `daemonsets` |
| Reloader provides both unit test cases and end to end integration test cases for future updates. So one can make sure that new changes do not break any old functionality. | Currently there are not any unit test cases or end to end integration test cases in configmap controller. It add difficulties for any additional updates in configmap controller and one can not know for sure whether new changes breaks any old functionality or not. |
| Reloader uses SHA1 to encode the change in configmap or secret. It then saves the SHA1 value in `STAKATER_FOO_CONFIGMAP` or `STAKATER_FOO_SECRET` environment variable depending upon where the change has happened. The use of SHA1 provides a concise 40 characters encoded value that is very less prone to collision. | Configmap controller uses `FABRICB_FOO_REVISION` environment variable to store any change in configmap controller. It does not encode it or convert it in suitable hash value to avoid data pollution in deployment. |
| Reloader allows you to customize your own annotation (for both Secrets and Configmaps) using command line flags | Configmap controller restricts you to only their provided annotation |

View File

@@ -5,24 +5,42 @@ Reloader and k8s-trigger-controller are both built for same purpose. So there ar
## Similarities
- Both controllers support change detection in configmap and secrets
- Both controllers support deployment rollout
- Both controllers support deployment `rollout`
- Both controllers use SHA1 for hashing
- Both controllers have end to end as well as unit test cases.
## Differences
### Support for Daemonsets and Statefulsets.
### Support for `Daemonsets` and `Statefulsets`
#### k8s-trigger-controller:
k8s-trigger-controller only support for deployment rollout. It does not support daemonsets and statefulsets rollout.
#### `k8s-trigger-controller`
#### Reloader:
Reloader supports deployment rollout as well as daemonsets and statefulsets rollout.
`k8s-trigger-controller` only support for deployment `rollout`. It does not support `daemonsets` and `statefulsets` `rollout`.
#### Reloader
Reloader supports deployment `rollout` as well as `daemonsets` and `statefulsets` `rollout`.
### Hashing usage
#### k8s-trigger-controller:
k8s-trigger-controller stores the hash value in an annotation `trigger.k8s.io/[secret|configMap]-NAME-last-hash`
#### `k8s-trigger-controller`
#### Reloader:
Reloader stores the hash value in an environment variable `STAKATER_NAME_[SECRET|CONFIGMAP]`
`k8s-trigger-controller` stores the hash value in an annotation `trigger.k8s.io/[secret|configMap]-NAME-last-hash`
#### Reloader
Reloader stores the hash value in an environment variable `STAKATER_NAME_[SECRET|CONFIGMAP]`
### Customization
#### `k8s-trigger-controller`
`k8s-trigger-controller` restricts you to using the `trigger.k8s.io/[secret-configMap]-NAME-last-hash` annotation
#### Reloader
Reloader allows you to customize the annotation to fit your needs with command line flags:
- `--auto-annotation <annotation>`
- `--configmap-annotation <annotation>`
- `--secret-annotation <annotation>`

View File

@@ -0,0 +1,14 @@
# Using Reloader with Sealed Secrets
Below are the steps to use Reloader with Sealed Secrets:
1. Download and install the kubeseal client from [here](https://github.com/bitnami-labs/sealed-secrets)
1. Install the controller for sealed secrets
1. Fetch the encryption certificate
1. Encrypt the secret
1. Apply the secret
1. Install the tool which uses that sealed secret
1. Install Reloader
1. Once everything is setup, update the original secret at client and encrypt it with kubeseal to see Reloader working
1. Apply the updated sealed secret
1. Reloader will restart the pod to use that updated secret

View File

@@ -1,10 +1,10 @@
# Verify Reloader's Working
Reloader's working can be verified by two ways.
Reloader's working can be verified by three ways.
## Verify from logs
Check the logs of reloader and verify that you can see logs looks like below, if you are able to find these logs then it means reloader is working.
Check the logs of Reloader and verify that you can see logs looks like below, if you are able to find these logs then it means Reloader is working.
```text
Changes Detected in test-object of type 'SECRET' in namespace: test-reloader
@@ -22,11 +22,11 @@ Below are the details that explain these logs:
`SECRET` is the type of `test-object`. It can either be `SECRET` or `CONFIGMAP`
### test-reloader
### `test-reloader`
`test-reloader` is the name of namespace in which reloader has detected the change.
`test-reloader` is the name of namespace in which Reloader has detected the change.
### test-resource
### `test-resource`
`test-resource` is the name of resource which is going to be updated
@@ -36,16 +36,27 @@ Below are the details that explain these logs:
## Verify by checking the age of Pod
A pod's age can tell whether reloader is working correctly or not. If you know that a change in a `secret` or `configmap` has occurred, then check the relevant Pod's age immediately. It should be newly created few moments ago.
A pod's age can tell whether Reloader is working correctly or not. If you know that a change in a `secret` or `configmap` has occurred, then check the relevant Pod's age immediately. It should be newly created few moments ago.
### Verify from kubernetes Dashboard
### Verify from Kubernetes Dashboard
`kubernetes dashboard` can be used to verify the working of Reloader. After a change in `secret` or `configmap`, check the relevant Pod's age from dashboard. It should be newly created few moments ago.
### Verify from command line
After a change in `secret` or `configmap`. Run the below mentioned command and verify that the pod is newly created.
After a change in `secret` or `configmap`. Run the below-mentioned command and verify that the pod is newly created.
```bash
kubectl get pods <pod name> -n <namespace name>
```
## Verify from metrics
Some metrics are exported to Prometheus endpoint `/metrics` on port `9090`.
When Reloader is unable to reload, `reloader_reload_executed_total{success="false"}` metric gets incremented and when it reloads successfully, `reloader_reload_executed_total{success="true"}` gets incremented. You will be able to see the following metrics, with some other metrics, at `/metrics` endpoint.
```text
reloader_reload_executed_total{success="false"} 15
reloader_reload_executed_total{success="true"} 12
```

8
docs/features.md Normal file
View File

@@ -0,0 +1,8 @@
# Features
These are the key features of Reloader:
1. Restart pod in a `deployment` on change in linked/related configmap's or secret's
1. Restart pod in a `daemonset` on change in linked/related configmap's or secret's
1. Restart pod in a `statefulset` on change in linked/related configmap's or secret's
1. Restart pod in a `rollout` on change in linked/related configmap's or secret's

269
glide.lock generated
View File

@@ -1,269 +0,0 @@
hash: b6fe060028bdb1249ba2413746476c2550b267eeab3c166c36a86e000a8dd354
updated: 2018-07-24T21:12:43.027181463+05:00
imports:
- name: github.com/davecgh/go-spew
version: 782f4967f2dc4564575ca782fe2d04090b5faca8
subpackages:
- spew
- name: github.com/emicklei/go-restful
version: ff4f55a206334ef123e4f79bbf348980da81ca46
subpackages:
- log
- name: github.com/emicklei/go-restful-swagger12
version: dcef7f55730566d41eae5db10e7d6981829720f6
- name: github.com/ghodss/yaml
version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee
- name: github.com/go-openapi/jsonpointer
version: 46af16f9f7b149af66e5d1bd010e3574dc06de98
- name: github.com/go-openapi/jsonreference
version: 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272
- name: github.com/go-openapi/spec
version: 6aced65f8501fe1217321abf0749d354824ba2ff
- name: github.com/go-openapi/swag
version: 1d0bd113de87027671077d3c71eb3ac5d7dbba72
- name: github.com/gogo/protobuf
version: c0656edd0d9eab7c66d1eb0c568f9039345796f7
subpackages:
- proto
- sortkeys
- name: github.com/golang/glog
version: 44145f04b68cf362d9c4df2182967c2275eaefed
- name: github.com/golang/protobuf
version: 4bd1920723d7b7c925de087aa32e2187708897f7
subpackages:
- proto
- ptypes
- ptypes/any
- ptypes/duration
- ptypes/timestamp
- name: github.com/google/btree
version: 7d79101e329e5a3adf994758c578dab82b90c017
- name: github.com/google/gofuzz
version: 44d81051d367757e1c7c6a5a86423ece9afcf63c
- name: github.com/googleapis/gnostic
version: 0c5108395e2debce0d731cf0287ddf7242066aba
subpackages:
- OpenAPIv2
- compiler
- extensions
- name: github.com/gregjones/httpcache
version: 787624de3eb7bd915c329cba748687a3b22666a6
subpackages:
- diskcache
- name: github.com/hashicorp/golang-lru
version: a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
subpackages:
- simplelru
- name: github.com/howeyc/gopass
version: bf9dde6d0d2c004a008c27aaee91170c786f6db8
- name: github.com/imdario/mergo
version: 6633656539c1639d9d78127b7d47c622b5d7b6dc
- name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/json-iterator/go
version: 36b14963da70d11297d313183d7e6388c8510e1e
- name: github.com/juju/ratelimit
version: 5b9ff866471762aa2ab2dced63c9fb6f53921342
- name: github.com/mailru/easyjson
version: d5b7844b561a7bc640052f1b935f7b800330d7e0
subpackages:
- buffer
- jlexer
- jwriter
- name: github.com/peterbourgon/diskv
version: 5f041e8faa004a95c88a202771f4cc3e991971e6
- name: github.com/PuerkitoBio/purell
version: 8a290539e2e8629dbc4e6bad948158f790ec31f4
- name: github.com/PuerkitoBio/urlesc
version: 5bd2802263f21d8788851d5305584c82a5c75d7e
- name: github.com/sirupsen/logrus
version: c155da19408a8799da419ed3eeb0cb5db0ad5dbc
- name: github.com/spf13/cobra
version: ef82de70bb3f60c65fb8eebacbb2d122ef517385
- name: github.com/spf13/pflag
version: 583c0c0531f06d5278b7d917446061adc344b5cd
- name: golang.org/x/crypto
version: 81e90905daefcd6fd217b62423c0908922eadb30
subpackages:
- ssh/terminal
- name: golang.org/x/net
version: 1c05540f6879653db88113bc4a2b70aec4bd491f
subpackages:
- context
- http2
- http2/hpack
- idna
- lex/httplex
- name: golang.org/x/sys
version: 7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce
subpackages:
- unix
- windows
- name: golang.org/x/text
version: b19bf474d317b857955b12035d2c5acb57ce8b01
subpackages:
- cases
- internal
- internal/tag
- language
- runes
- secure/bidirule
- secure/precis
- transform
- unicode/bidi
- unicode/norm
- width
- name: gopkg.in/inf.v0
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
- name: gopkg.in/yaml.v2
version: 53feefa2559fb8dfa8d81baad31be332c97d6c77
- name: k8s.io/api
version: fe29995db37613b9c5b2a647544cf627bfa8d299
subpackages:
- admissionregistration/v1alpha1
- apps/v1beta1
- apps/v1beta2
- authentication/v1
- authentication/v1beta1
- authorization/v1
- authorization/v1beta1
- autoscaling/v1
- autoscaling/v2beta1
- batch/v1
- batch/v1beta1
- batch/v2alpha1
- certificates/v1beta1
- core/v1
- extensions/v1beta1
- networking/v1
- policy/v1beta1
- rbac/v1
- rbac/v1alpha1
- rbac/v1beta1
- scheduling/v1alpha1
- settings/v1alpha1
- storage/v1
- storage/v1beta1
- name: k8s.io/apimachinery
version: 019ae5ada31de202164b118aee88ee2d14075c31
subpackages:
- pkg/api/equality
- pkg/api/errors
- pkg/api/meta
- pkg/api/resource
- pkg/apis/meta/internalversion
- pkg/apis/meta/v1
- pkg/apis/meta/v1/unstructured
- pkg/apis/meta/v1alpha1
- pkg/conversion
- pkg/conversion/queryparams
- pkg/conversion/unstructured
- pkg/fields
- pkg/labels
- pkg/runtime
- pkg/runtime/schema
- pkg/runtime/serializer
- pkg/runtime/serializer/json
- pkg/runtime/serializer/protobuf
- pkg/runtime/serializer/recognizer
- pkg/runtime/serializer/streaming
- pkg/runtime/serializer/versioning
- pkg/selection
- pkg/types
- pkg/util/cache
- pkg/util/clock
- pkg/util/diff
- pkg/util/errors
- pkg/util/framer
- pkg/util/intstr
- pkg/util/json
- pkg/util/net
- pkg/util/runtime
- pkg/util/sets
- pkg/util/validation
- pkg/util/validation/field
- pkg/util/wait
- pkg/util/yaml
- pkg/version
- pkg/watch
- third_party/forked/golang/reflect
- name: k8s.io/client-go
version: 35874c597fed17ca62cd197e516d7d5ff9a2958c
subpackages:
- discovery
- discovery/fake
- kubernetes
- kubernetes/fake
- kubernetes/scheme
- kubernetes/typed/admissionregistration/v1alpha1
- kubernetes/typed/admissionregistration/v1alpha1/fake
- kubernetes/typed/apps/v1beta1
- kubernetes/typed/apps/v1beta1/fake
- kubernetes/typed/apps/v1beta2
- kubernetes/typed/apps/v1beta2/fake
- kubernetes/typed/authentication/v1
- kubernetes/typed/authentication/v1/fake
- kubernetes/typed/authentication/v1beta1
- kubernetes/typed/authentication/v1beta1/fake
- kubernetes/typed/authorization/v1
- kubernetes/typed/authorization/v1/fake
- kubernetes/typed/authorization/v1beta1
- kubernetes/typed/authorization/v1beta1/fake
- kubernetes/typed/autoscaling/v1
- kubernetes/typed/autoscaling/v1/fake
- kubernetes/typed/autoscaling/v2beta1
- kubernetes/typed/autoscaling/v2beta1/fake
- kubernetes/typed/batch/v1
- kubernetes/typed/batch/v1/fake
- kubernetes/typed/batch/v1beta1
- kubernetes/typed/batch/v1beta1/fake
- kubernetes/typed/batch/v2alpha1
- kubernetes/typed/batch/v2alpha1/fake
- kubernetes/typed/certificates/v1beta1
- kubernetes/typed/certificates/v1beta1/fake
- kubernetes/typed/core/v1
- kubernetes/typed/core/v1/fake
- kubernetes/typed/extensions/v1beta1
- kubernetes/typed/extensions/v1beta1/fake
- kubernetes/typed/networking/v1
- kubernetes/typed/networking/v1/fake
- kubernetes/typed/policy/v1beta1
- kubernetes/typed/policy/v1beta1/fake
- kubernetes/typed/rbac/v1
- kubernetes/typed/rbac/v1/fake
- kubernetes/typed/rbac/v1alpha1
- kubernetes/typed/rbac/v1alpha1/fake
- kubernetes/typed/rbac/v1beta1
- kubernetes/typed/rbac/v1beta1/fake
- kubernetes/typed/scheduling/v1alpha1
- kubernetes/typed/scheduling/v1alpha1/fake
- kubernetes/typed/settings/v1alpha1
- kubernetes/typed/settings/v1alpha1/fake
- kubernetes/typed/storage/v1
- kubernetes/typed/storage/v1/fake
- kubernetes/typed/storage/v1beta1
- kubernetes/typed/storage/v1beta1/fake
- pkg/version
- rest
- rest/watch
- testing
- tools/auth
- tools/cache
- tools/clientcmd
- tools/clientcmd/api
- tools/clientcmd/api/latest
- tools/clientcmd/api/v1
- tools/metrics
- tools/pager
- tools/reference
- transport
- util/cert
- util/flowcontrol
- util/homedir
- util/integer
- util/workqueue
- name: k8s.io/kube-openapi
version: 868f2f29720b192240e18284659231b440f9cda5
subpackages:
- pkg/common
testImports: []

View File

@@ -1,14 +0,0 @@
package: github.com/stakater/Reloader
import:
- package: k8s.io/api
version: kubernetes-1.8.0
- package: k8s.io/apimachinery
version: kubernetes-1.8.0
- package: k8s.io/client-go
version: 5.0.0
- package: github.com/spf13/cobra
version: 0.0.3
- package: github.com/spf13/pflag
version: 1.0.1
- package: github.com/sirupsen/logrus
version: 1.0.5

92
go.mod Normal file
View File

@@ -0,0 +1,92 @@
module github.com/stakater/Reloader
go 1.20
require (
github.com/argoproj/argo-rollouts v1.4.1
github.com/openshift/api v3.9.0+incompatible
github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142
github.com/parnurzeal/gorequest v0.2.16
github.com/prometheus/client_golang v1.15.0
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.7.0
k8s.io/api v0.27.1
k8s.io/apimachinery v0.27.1
k8s.io/client-go v0.27.1
k8s.io/kubectl v0.27.1
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic v0.6.9 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/smartystreets/goconvey v1.7.2 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/oauth2 v0.5.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.90.1 // indirect
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a // indirect
moul.io/http2curl v1.0.0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
// Replacements for argo-rollouts
replace (
github.com/go-check/check => github.com/go-check/check v0.0.0-20180628173108-788fd7840127
k8s.io/api v0.0.0 => k8s.io/api v0.27.1
k8s.io/apimachinery v0.0.0 => k8s.io/apimachinery v0.27.1
k8s.io/client-go v0.0.0 => k8s.io/client-go v0.27.1
k8s.io/cloud-provider v0.0.0 => k8s.io/cloud-provider v0.24.2
k8s.io/controller-manager v0.0.0 => k8s.io/controller-manager v0.24.2
k8s.io/cri-api v0.0.0 => k8s.io/cri-api v0.20.5-rc.0
k8s.io/csi-translation-lib v0.0.0 => k8s.io/csi-translation-lib v0.24.2
k8s.io/kube-aggregator v0.0.0 => k8s.io/kube-aggregator v0.24.2
k8s.io/kube-controller-manager v0.0.0 => k8s.io/kube-controller-manager v0.24.2
k8s.io/kube-proxy v0.0.0 => k8s.io/kube-proxy v0.24.2
k8s.io/kube-scheduler v0.0.0 => k8s.io/kube-scheduler v0.24.2
k8s.io/kubectl v0.0.0 => k8s.io/kubectl v0.27.1
k8s.io/kubelet v0.0.0 => k8s.io/kubelet v0.24.2
k8s.io/legacy-cloud-providers v0.0.0 => k8s.io/legacy-cloud-providers v0.24.2
k8s.io/mount-utils v0.0.0 => k8s.io/mount-utils v0.20.5-rc.0
k8s.io/sample-apiserver v0.0.0 => k8s.io/sample-apiserver v0.24.2
k8s.io/sample-cli-plugin v0.0.0 => k8s.io/sample-cli-plugin v0.24.2
k8s.io/sample-controller v0.0.0 => k8s.io/sample-controller v0.24.2
)

599
go.sum Normal file
View File

@@ -0,0 +1,599 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/argoproj/argo-rollouts v1.4.1 h1:P+aTqdjMmWJDJfAbyVkCbONIzoGXSRVRBvim6VWxMJo=
github.com/argoproj/argo-rollouts v1.4.1/go.mod h1:KR9pcBicOYmPOu50bBLRQfp/UQVkRGoUkidHVsyjV1Q=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=
github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0=
github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
github.com/openshift/api v0.0.0-20210521075222-e273a339932a/go.mod h1:izBmoXbUu3z5kUa4FjZhvekTsyzIWiOoaIgJiZBBMQs=
github.com/openshift/api v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs=
github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
github.com/openshift/build-machinery-go v0.0.0-20210423112049-9415d7ebd33e/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142 h1:ZHRIMCFIJN1p9LsJt4HQ+akDrys4PrYnXzOWI5LK03I=
github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142/go.mod h1:fjS8r9mqDVsPb5td3NehsNOAWa4uiFkYEfVZioQ2gH0=
github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ=
github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM=
github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s=
k8s.io/api v0.27.1 h1:Z6zUGQ1Vd10tJ+gHcNNNgkV5emCyW+v2XTmn+CLjSd0=
k8s.io/api v0.27.1/go.mod h1:z5g/BpAiD+f6AArpqNjkY+cji8ueZDU/WV1jcj5Jk4E=
k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
k8s.io/apimachinery v0.27.1 h1:EGuZiLI95UQQcClhanryclaQE6xjg1Bts6/L3cD7zyc=
k8s.io/apimachinery v0.27.1/go.mod h1:5ikh59fK3AJ287GUvpUsryoMFtH9zj/ARfWCo3AyXTM=
k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs=
k8s.io/client-go v0.27.1 h1:oXsfhW/qncM1wDmWBIuDzRHNS2tLhK3BZv512Nc59W8=
k8s.io/client-go v0.27.1/go.mod h1:f8LHMUkVb3b9N8bWturc+EDtVVVwZ7ueTVquFAJb2vA=
k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a h1:gmovKNur38vgoWfGtP5QOGNOA7ki4n6qNYoFAgMlNvg=
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY=
k8s.io/kubectl v0.27.1 h1:9T5c5KdpburYiW8XKQSH0Uly1kMNE90aGSnbYUZNdcA=
k8s.io/kubectl v0.27.1/go.mod h1:QsAkSmrRsKTPlAFzF8kODGDl4p35BIwQnc9XFhkcsy8=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8=
moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

View File

@@ -0,0 +1,94 @@
package alert
import (
"fmt"
"os"
"strings"
"github.com/parnurzeal/gorequest"
"github.com/sirupsen/logrus"
)
// function to send alert msg to webhook service
func SendWebhookAlert(msg string) {
webhook_url, ok := os.LookupEnv("ALERT_WEBHOOK_URL")
if !ok {
logrus.Error("ALERT_WEBHOOK_URL env variable not provided")
return
}
webhook_url = strings.TrimSpace(webhook_url)
alert_sink := os.Getenv("ALERT_SINK")
alert_sink = strings.ToLower(strings.TrimSpace(alert_sink))
// Provision to add Proxy to reach webhook server if required
webhook_proxy := os.Getenv("ALERT_WEBHOOK_PROXY")
webhook_proxy = strings.TrimSpace(webhook_proxy)
// Provision to add Additional information in the alert. e.g ClusterName
alert_additional_info, ok := os.LookupEnv("ALERT_ADDITIONAL_INFO")
if ok {
alert_additional_info = strings.TrimSpace(alert_additional_info)
msg = fmt.Sprintf("%s : %s", alert_additional_info, msg)
}
if alert_sink == "slack" {
sendSlackAlert(webhook_url, webhook_proxy, msg)
} else {
msg = strings.Replace(msg, "*", "", -1)
sendRawWebhookAlert(webhook_url, webhook_proxy, msg)
}
}
// function to handle server redirection
func redirectPolicy(req gorequest.Request, via []gorequest.Request) error {
return fmt.Errorf("incorrect token (redirection)")
}
// function to send alert to slack
func sendSlackAlert(webhookUrl string, proxy string, msg string) []error {
attachment := Attachment{
Text: msg,
Color: "good",
AuthorName: "Reloader",
}
payload := WebhookMessage{
Attachments: []Attachment{attachment},
}
request := gorequest.New().Proxy(proxy)
resp, _, err := request.
Post(webhookUrl).
RedirectPolicy(redirectPolicy).
Send(payload).
End()
if err != nil {
return err
}
if resp.StatusCode >= 400 {
return []error{fmt.Errorf("error sending msg. status: %v", resp.Status)}
}
return nil
}
// function to send alert to webhook service as text
func sendRawWebhookAlert(webhookUrl string, proxy string, msg string) []error {
request := gorequest.New().Proxy(proxy)
resp, _, err := request.
Post(webhookUrl).
Type("text").
RedirectPolicy(redirectPolicy).
Send(msg).
End()
if err != nil {
return err
}
if resp.StatusCode >= 400 {
return []error{fmt.Errorf("error sending msg. status: %v", resp.Status)}
}
return nil
}

View File

@@ -0,0 +1,61 @@
package alert
type WebhookMessage struct {
Username string `json:"username,omitempty"`
IconEmoji string `json:"icon_emoji,omitempty"`
IconURL string `json:"icon_url,omitempty"`
Channel string `json:"channel,omitempty"`
ThreadTimestamp string `json:"thread_ts,omitempty"`
Text string `json:"text,omitempty"`
Attachments []Attachment `json:"attachments,omitempty"`
Parse string `json:"parse,omitempty"`
ResponseType string `json:"response_type,omitempty"`
ReplaceOriginal bool `json:"replace_original,omitempty"`
DeleteOriginal bool `json:"delete_original,omitempty"`
ReplyBroadcast bool `json:"reply_broadcast,omitempty"`
}
type Attachment struct {
Color string `json:"color,omitempty"`
Fallback string `json:"fallback,omitempty"`
CallbackID string `json:"callback_id,omitempty"`
ID int `json:"id,omitempty"`
AuthorID string `json:"author_id,omitempty"`
AuthorName string `json:"author_name,omitempty"`
AuthorSubname string `json:"author_subname,omitempty"`
AuthorLink string `json:"author_link,omitempty"`
AuthorIcon string `json:"author_icon,omitempty"`
Title string `json:"title,omitempty"`
TitleLink string `json:"title_link,omitempty"`
Pretext string `json:"pretext,omitempty"`
Text string `json:"text,omitempty"`
ImageURL string `json:"image_url,omitempty"`
ThumbURL string `json:"thumb_url,omitempty"`
ServiceName string `json:"service_name,omitempty"`
ServiceIcon string `json:"service_icon,omitempty"`
FromURL string `json:"from_url,omitempty"`
OriginalURL string `json:"original_url,omitempty"`
MarkdownIn []string `json:"mrkdwn_in,omitempty"`
Footer string `json:"footer,omitempty"`
FooterIcon string `json:"footer_icon,omitempty"`
}
type Field struct {
Title string `json:"title"`
Value string `json:"value"`
Short bool `json:"short"`
}
type Action struct {
Type string `json:"type"`
Text string `json:"text"`
Url string `json:"url"`
Style string `json:"style"`
}

View File

@@ -1,91 +1,307 @@
package callbacks
import (
"context"
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/util"
apps_v1beta1 "k8s.io/api/apps/v1beta1"
"k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
"github.com/stakater/Reloader/pkg/kube"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/apimachinery/pkg/runtime"
argorolloutv1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1"
openshiftv1 "github.com/openshift/api/apps/v1"
)
//ItemsFunc is a generic function to return a specific resource array in given namespace
type ItemsFunc func(kubernetes.Interface, string) []interface{}
// ItemsFunc is a generic function to return a specific resource array in given namespace
type ItemsFunc func(kube.Clients, string) []runtime.Object
//ContainersFunc is a generic func to return containers
type ContainersFunc func(interface{}) []v1.Container
// ContainersFunc is a generic func to return containers
type ContainersFunc func(runtime.Object) []v1.Container
//UpdateFunc performs the resource update
type UpdateFunc func(kubernetes.Interface, string, interface{}) error
// InitContainersFunc is a generic func to return containers
type InitContainersFunc func(runtime.Object) []v1.Container
//RollingUpgradeFuncs contains generic functions to perform rolling upgrade
// VolumesFunc is a generic func to return volumes
type VolumesFunc func(runtime.Object) []v1.Volume
// UpdateFunc performs the resource update
type UpdateFunc func(kube.Clients, string, runtime.Object) error
// AnnotationsFunc is a generic func to return annotations
type AnnotationsFunc func(runtime.Object) map[string]string
// PodAnnotationsFunc is a generic func to return annotations
type PodAnnotationsFunc func(runtime.Object) map[string]string
// RollingUpgradeFuncs contains generic functions to perform rolling upgrade
type RollingUpgradeFuncs struct {
ItemsFunc ItemsFunc
ContainersFunc ContainersFunc
UpdateFunc UpdateFunc
ResourceType string
ItemsFunc ItemsFunc
AnnotationsFunc AnnotationsFunc
PodAnnotationsFunc PodAnnotationsFunc
ContainersFunc ContainersFunc
InitContainersFunc InitContainersFunc
UpdateFunc UpdateFunc
VolumesFunc VolumesFunc
ResourceType string
}
// GetDeploymentItems returns the deployments in given namespace
func GetDeploymentItems(client kubernetes.Interface, namespace string) []interface{} {
deployments, err := client.ExtensionsV1beta1().Deployments(namespace).List(meta_v1.ListOptions{})
func GetDeploymentItems(clients kube.Clients, namespace string) []runtime.Object {
deployments, err := clients.KubernetesClient.AppsV1().Deployments(namespace).List(context.TODO(), meta_v1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to list deployments %v", err)
}
return util.InterfaceSlice(deployments.Items)
items := make([]runtime.Object, len(deployments.Items))
// Ensure we always have pod annotations to add to
for i, v := range deployments.Items {
if v.Spec.Template.ObjectMeta.Annotations == nil {
annotations := make(map[string]string)
deployments.Items[i].Spec.Template.ObjectMeta.Annotations = annotations
}
items[i] = &deployments.Items[i]
}
return items
}
// GetDaemonSetItems returns the daemonSet in given namespace
func GetDaemonSetItems(client kubernetes.Interface, namespace string) []interface{} {
daemonSets, err := client.ExtensionsV1beta1().DaemonSets(namespace).List(meta_v1.ListOptions{})
// GetDaemonSetItems returns the daemonSets in given namespace
func GetDaemonSetItems(clients kube.Clients, namespace string) []runtime.Object {
daemonSets, err := clients.KubernetesClient.AppsV1().DaemonSets(namespace).List(context.TODO(), meta_v1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to list daemonSets %v", err)
}
return util.InterfaceSlice(daemonSets.Items)
items := make([]runtime.Object, len(daemonSets.Items))
// Ensure we always have pod annotations to add to
for i, v := range daemonSets.Items {
if v.Spec.Template.ObjectMeta.Annotations == nil {
daemonSets.Items[i].Spec.Template.ObjectMeta.Annotations = make(map[string]string)
}
items[i] = &daemonSets.Items[i]
}
return items
}
// GetStatefulSetItems returns the statefulSet in given namespace
func GetStatefulSetItems(client kubernetes.Interface, namespace string) []interface{} {
statefulSets, err := client.AppsV1beta1().StatefulSets(namespace).List(meta_v1.ListOptions{})
// GetStatefulSetItems returns the statefulSets in given namespace
func GetStatefulSetItems(clients kube.Clients, namespace string) []runtime.Object {
statefulSets, err := clients.KubernetesClient.AppsV1().StatefulSets(namespace).List(context.TODO(), meta_v1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to list statefulSets %v", err)
}
return util.InterfaceSlice(statefulSets.Items)
items := make([]runtime.Object, len(statefulSets.Items))
// Ensure we always have pod annotations to add to
for i, v := range statefulSets.Items {
if v.Spec.Template.ObjectMeta.Annotations == nil {
statefulSets.Items[i].Spec.Template.ObjectMeta.Annotations = make(map[string]string)
}
items[i] = &statefulSets.Items[i]
}
return items
}
// GetDeploymentConfigItems returns the deploymentConfigs in given namespace
func GetDeploymentConfigItems(clients kube.Clients, namespace string) []runtime.Object {
deploymentConfigs, err := clients.OpenshiftAppsClient.AppsV1().DeploymentConfigs(namespace).List(context.TODO(), meta_v1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to list deploymentConfigs %v", err)
}
items := make([]runtime.Object, len(deploymentConfigs.Items))
// Ensure we always have pod annotations to add to
for i, v := range deploymentConfigs.Items {
if v.Spec.Template.ObjectMeta.Annotations == nil {
deploymentConfigs.Items[i].Spec.Template.ObjectMeta.Annotations = make(map[string]string)
}
items[i] = &deploymentConfigs.Items[i]
}
return items
}
// GetRolloutItems returns the rollouts in given namespace
func GetRolloutItems(clients kube.Clients, namespace string) []runtime.Object {
rollouts, err := clients.ArgoRolloutClient.ArgoprojV1alpha1().Rollouts(namespace).List(context.TODO(), meta_v1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to list Rollouts %v", err)
}
items := make([]runtime.Object, len(rollouts.Items))
// Ensure we always have pod annotations to add to
for i, v := range rollouts.Items {
if v.Spec.Template.ObjectMeta.Annotations == nil {
rollouts.Items[i].Spec.Template.ObjectMeta.Annotations = make(map[string]string)
}
items[i] = &rollouts.Items[i]
}
return items
}
// GetDeploymentAnnotations returns the annotations of given deployment
func GetDeploymentAnnotations(item runtime.Object) map[string]string {
return item.(*appsv1.Deployment).ObjectMeta.Annotations
}
// GetDaemonSetAnnotations returns the annotations of given daemonSet
func GetDaemonSetAnnotations(item runtime.Object) map[string]string {
return item.(*appsv1.DaemonSet).ObjectMeta.Annotations
}
// GetStatefulSetAnnotations returns the annotations of given statefulSet
func GetStatefulSetAnnotations(item runtime.Object) map[string]string {
return item.(*appsv1.StatefulSet).ObjectMeta.Annotations
}
// GetDeploymentConfigAnnotations returns the annotations of given deploymentConfig
func GetDeploymentConfigAnnotations(item runtime.Object) map[string]string {
return item.(*openshiftv1.DeploymentConfig).ObjectMeta.Annotations
}
// GetRolloutAnnotations returns the annotations of given rollout
func GetRolloutAnnotations(item runtime.Object) map[string]string {
return item.(*argorolloutv1alpha1.Rollout).ObjectMeta.Annotations
}
// GetDeploymentPodAnnotations returns the pod's annotations of given deployment
func GetDeploymentPodAnnotations(item runtime.Object) map[string]string {
return item.(*appsv1.Deployment).Spec.Template.ObjectMeta.Annotations
}
// GetDaemonSetPodAnnotations returns the pod's annotations of given daemonSet
func GetDaemonSetPodAnnotations(item runtime.Object) map[string]string {
return item.(*appsv1.DaemonSet).Spec.Template.ObjectMeta.Annotations
}
// GetStatefulSetPodAnnotations returns the pod's annotations of given statefulSet
func GetStatefulSetPodAnnotations(item runtime.Object) map[string]string {
return item.(*appsv1.StatefulSet).Spec.Template.ObjectMeta.Annotations
}
// GetDeploymentConfigPodAnnotations returns the pod's annotations of given deploymentConfig
func GetDeploymentConfigPodAnnotations(item runtime.Object) map[string]string {
return item.(*openshiftv1.DeploymentConfig).Spec.Template.ObjectMeta.Annotations
}
// GetRolloutPodAnnotations returns the pod's annotations of given rollout
func GetRolloutPodAnnotations(item runtime.Object) map[string]string {
return item.(*argorolloutv1alpha1.Rollout).Spec.Template.ObjectMeta.Annotations
}
// GetDeploymentContainers returns the containers of given deployment
func GetDeploymentContainers(item interface{}) []v1.Container {
return item.(v1beta1.Deployment).Spec.Template.Spec.Containers
func GetDeploymentContainers(item runtime.Object) []v1.Container {
return item.(*appsv1.Deployment).Spec.Template.Spec.Containers
}
// GetDaemonSetContainers returns the containers of given daemonset
func GetDaemonSetContainers(item interface{}) []v1.Container {
return item.(v1beta1.DaemonSet).Spec.Template.Spec.Containers
// GetDaemonSetContainers returns the containers of given daemonSet
func GetDaemonSetContainers(item runtime.Object) []v1.Container {
return item.(*appsv1.DaemonSet).Spec.Template.Spec.Containers
}
// GetStatefulsetContainers returns the containers of given statefulSet
func GetStatefulsetContainers(item interface{}) []v1.Container {
return item.(apps_v1beta1.StatefulSet).Spec.Template.Spec.Containers
// GetStatefulSetContainers returns the containers of given statefulSet
func GetStatefulSetContainers(item runtime.Object) []v1.Container {
return item.(*appsv1.StatefulSet).Spec.Template.Spec.Containers
}
// GetDeploymentConfigContainers returns the containers of given deploymentConfig
func GetDeploymentConfigContainers(item runtime.Object) []v1.Container {
return item.(*openshiftv1.DeploymentConfig).Spec.Template.Spec.Containers
}
// GetRolloutContainers returns the containers of given rollout
func GetRolloutContainers(item runtime.Object) []v1.Container {
return item.(*argorolloutv1alpha1.Rollout).Spec.Template.Spec.Containers
}
// GetDeploymentInitContainers returns the containers of given deployment
func GetDeploymentInitContainers(item runtime.Object) []v1.Container {
return item.(*appsv1.Deployment).Spec.Template.Spec.InitContainers
}
// GetDaemonSetInitContainers returns the containers of given daemonSet
func GetDaemonSetInitContainers(item runtime.Object) []v1.Container {
return item.(*appsv1.DaemonSet).Spec.Template.Spec.InitContainers
}
// GetStatefulSetInitContainers returns the containers of given statefulSet
func GetStatefulSetInitContainers(item runtime.Object) []v1.Container {
return item.(*appsv1.StatefulSet).Spec.Template.Spec.InitContainers
}
// GetDeploymentConfigInitContainers returns the containers of given deploymentConfig
func GetDeploymentConfigInitContainers(item runtime.Object) []v1.Container {
return item.(*openshiftv1.DeploymentConfig).Spec.Template.Spec.InitContainers
}
// GetRolloutInitContainers returns the containers of given rollout
func GetRolloutInitContainers(item runtime.Object) []v1.Container {
return item.(*argorolloutv1alpha1.Rollout).Spec.Template.Spec.InitContainers
}
// UpdateDeployment performs rolling upgrade on deployment
func UpdateDeployment(client kubernetes.Interface, namespace string, resource interface{}) error {
deployment := resource.(v1beta1.Deployment)
_, err := client.ExtensionsV1beta1().Deployments(namespace).Update(&deployment)
func UpdateDeployment(clients kube.Clients, namespace string, resource runtime.Object) error {
deployment := resource.(*appsv1.Deployment)
_, err := clients.KubernetesClient.AppsV1().Deployments(namespace).Update(context.TODO(), deployment, meta_v1.UpdateOptions{FieldManager: "Reloader"})
return err
}
// UpdateDaemonSet performs rolling upgrade on daemonSet
func UpdateDaemonSet(client kubernetes.Interface, namespace string, resource interface{}) error {
daemonSet := resource.(v1beta1.DaemonSet)
_, err := client.ExtensionsV1beta1().DaemonSets(namespace).Update(&daemonSet)
func UpdateDaemonSet(clients kube.Clients, namespace string, resource runtime.Object) error {
daemonSet := resource.(*appsv1.DaemonSet)
_, err := clients.KubernetesClient.AppsV1().DaemonSets(namespace).Update(context.TODO(), daemonSet, meta_v1.UpdateOptions{FieldManager: "Reloader"})
return err
}
// UpdateStatefulset performs rolling upgrade on statefulSet
func UpdateStatefulset(client kubernetes.Interface, namespace string, resource interface{}) error {
statefulSet := resource.(apps_v1beta1.StatefulSet)
_, err := client.AppsV1beta1().StatefulSets(namespace).Update(&statefulSet)
// UpdateStatefulSet performs rolling upgrade on statefulSet
func UpdateStatefulSet(clients kube.Clients, namespace string, resource runtime.Object) error {
statefulSet := resource.(*appsv1.StatefulSet)
_, err := clients.KubernetesClient.AppsV1().StatefulSets(namespace).Update(context.TODO(), statefulSet, meta_v1.UpdateOptions{FieldManager: "Reloader"})
return err
}
// UpdateDeploymentConfig performs rolling upgrade on deploymentConfig
func UpdateDeploymentConfig(clients kube.Clients, namespace string, resource runtime.Object) error {
deploymentConfig := resource.(*openshiftv1.DeploymentConfig)
_, err := clients.OpenshiftAppsClient.AppsV1().DeploymentConfigs(namespace).Update(context.TODO(), deploymentConfig, meta_v1.UpdateOptions{FieldManager: "Reloader"})
return err
}
// UpdateRollout performs rolling upgrade on rollout
func UpdateRollout(clients kube.Clients, namespace string, resource runtime.Object) error {
rollout := resource.(*argorolloutv1alpha1.Rollout)
rolloutBefore, _ := clients.ArgoRolloutClient.ArgoprojV1alpha1().Rollouts(namespace).Get(context.TODO(), rollout.Name, meta_v1.GetOptions{})
logrus.Warnf("Before: %+v", rolloutBefore.Spec.Template.Spec.Containers[0].Env)
logrus.Warnf("After: %+v", rollout.Spec.Template.Spec.Containers[0].Env)
_, err := clients.ArgoRolloutClient.ArgoprojV1alpha1().Rollouts(namespace).Update(context.TODO(), rollout, meta_v1.UpdateOptions{FieldManager: "Reloader"})
return err
}
// GetDeploymentVolumes returns the Volumes of given deployment
func GetDeploymentVolumes(item runtime.Object) []v1.Volume {
return item.(*appsv1.Deployment).Spec.Template.Spec.Volumes
}
// GetDaemonSetVolumes returns the Volumes of given daemonSet
func GetDaemonSetVolumes(item runtime.Object) []v1.Volume {
return item.(*appsv1.DaemonSet).Spec.Template.Spec.Volumes
}
// GetStatefulSetVolumes returns the Volumes of given statefulSet
func GetStatefulSetVolumes(item runtime.Object) []v1.Volume {
return item.(*appsv1.StatefulSet).Spec.Template.Spec.Volumes
}
// GetDeploymentConfigVolumes returns the Volumes of given deploymentConfig
func GetDeploymentConfigVolumes(item runtime.Object) []v1.Volume {
return item.(*openshiftv1.DeploymentConfig).Spec.Template.Spec.Volumes
}
// GetRolloutVolumes returns the Volumes of given rollout
func GetRolloutVolumes(item runtime.Object) []v1.Volume {
return item.(*argorolloutv1alpha1.Rollout).Spec.Template.Spec.Volumes
}

View File

@@ -1,26 +1,119 @@
package cmd
import (
"context"
"errors"
"fmt"
"net/http"
"os"
"strings"
"github.com/stakater/Reloader/internal/pkg/constants"
"github.com/stakater/Reloader/internal/pkg/leadership"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/stakater/Reloader/internal/pkg/controller"
"github.com/stakater/Reloader/internal/pkg/metrics"
"github.com/stakater/Reloader/internal/pkg/options"
"github.com/stakater/Reloader/internal/pkg/util"
"github.com/stakater/Reloader/pkg/kube"
"k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
)
// NewReloaderCommand starts the reloader controller
func NewReloaderCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "reloader",
Short: "A watcher for your Kubernetes cluster",
Run: startReloader,
Use: "reloader",
Short: "A watcher for your Kubernetes cluster",
PreRunE: validateFlags,
Run: startReloader,
}
// options
cmd.PersistentFlags().StringVar(&options.ConfigmapUpdateOnChangeAnnotation, "configmap-annotation", "configmap.reloader.stakater.com/reload", "annotation to detect changes in configmaps, specified by name")
cmd.PersistentFlags().StringVar(&options.SecretUpdateOnChangeAnnotation, "secret-annotation", "secret.reloader.stakater.com/reload", "annotation to detect changes in secrets, specified by name")
cmd.PersistentFlags().StringVar(&options.ReloaderAutoAnnotation, "auto-annotation", "reloader.stakater.com/auto", "annotation to detect changes in secrets")
cmd.PersistentFlags().StringVar(&options.AutoSearchAnnotation, "auto-search-annotation", "reloader.stakater.com/search", "annotation to detect changes in configmaps or secrets tagged with special match annotation")
cmd.PersistentFlags().StringVar(&options.SearchMatchAnnotation, "search-match-annotation", "reloader.stakater.com/match", "annotation to mark secrets or configmaps to match the search")
cmd.PersistentFlags().StringVar(&options.LogFormat, "log-format", "", "Log format to use (empty string for text, or JSON")
cmd.PersistentFlags().StringSlice("resources-to-ignore", []string{}, "list of resources to ignore (valid options 'configMaps' or 'secrets')")
cmd.PersistentFlags().StringSlice("namespaces-to-ignore", []string{}, "list of namespaces to ignore")
cmd.PersistentFlags().StringSlice("namespace-selector", []string{}, "list of key:value labels to filter on for namespaces")
cmd.PersistentFlags().StringSlice("resource-label-selector", []string{}, "list of key:value labels to filter on for configmaps and secrets")
cmd.PersistentFlags().StringVar(&options.IsArgoRollouts, "is-Argo-Rollouts", "false", "Add support for argo rollouts")
cmd.PersistentFlags().StringVar(&options.ReloadStrategy, constants.ReloadStrategyFlag, constants.EnvVarsReloadStrategy, "Specifies the desired reload strategy")
cmd.PersistentFlags().StringVar(&options.ReloadOnCreate, "reload-on-create", "false", "Add support to watch create events")
cmd.PersistentFlags().BoolVar(&options.EnableHA, "enable-ha", false, "Adds support for running multiple replicas via leadership election")
cmd.PersistentFlags().BoolVar(&options.SyncAfterRestart, "sync-after-restart", false, "Sync add events after reloader restarts")
return cmd
}
func validateFlags(*cobra.Command, []string) error {
// Ensure the reload strategy is one of the following...
var validReloadStrategy bool
valid := []string{constants.EnvVarsReloadStrategy, constants.AnnotationsReloadStrategy}
for _, s := range valid {
if s == options.ReloadStrategy {
validReloadStrategy = true
}
}
if !validReloadStrategy {
err := fmt.Sprintf("%s must be one of: %s", constants.ReloadStrategyFlag, strings.Join(valid, ", "))
return errors.New(err)
}
// Validate that HA options are correct
if options.EnableHA {
if err := validateHAEnvs(); err != nil {
return err
}
}
return nil
}
func configureLogging(logFormat string) error {
switch logFormat {
case "json":
logrus.SetFormatter(&logrus.JSONFormatter{})
default:
// just let the library use default on empty string.
if logFormat != "" {
return fmt.Errorf("unsupported logging formatter: %q", logFormat)
}
}
return nil
}
func validateHAEnvs() error {
podName, podNamespace := getHAEnvs()
if podName == "" {
return fmt.Errorf("%s not set, cannot run in HA mode without %s set", constants.PodNameEnv, constants.PodNameEnv)
}
if podNamespace == "" {
return fmt.Errorf("%s not set, cannot run in HA mode without %s set", constants.PodNamespaceEnv, constants.PodNamespaceEnv)
}
return nil
}
func getHAEnvs() (string, string) {
podName := os.Getenv(constants.PodNameEnv)
podNamespace := os.Getenv(constants.PodNamespaceEnv)
return podName, podNamespace
}
func startReloader(cmd *cobra.Command, args []string) {
err := configureLogging(options.LogFormat)
if err != nil {
logrus.Warn(err)
}
logrus.Info("Starting Reloader")
currentNamespace := os.Getenv("KUBERNETES_NAMESPACE")
if len(currentNamespace) == 0 {
@@ -29,24 +122,175 @@ func startReloader(cmd *cobra.Command, args []string) {
}
// create the clientset
clientset, err := kube.GetClient()
clientset, err := kube.GetKubernetesClient()
if err != nil {
logrus.Fatal(err)
}
ignoredResourcesList, err := getIgnoredResourcesList(cmd)
if err != nil {
logrus.Fatal(err)
}
ignoredNamespacesList, err := getIgnoredNamespacesList(cmd)
if err != nil {
logrus.Fatal(err)
}
namespaceLabelSelector, err := getNamespaceLabelSelector(cmd)
if err != nil {
logrus.Fatal(err)
}
resourceLabelSelector, err := getResourceLabelSelector(cmd)
if err != nil {
logrus.Fatal(err)
}
if len(namespaceLabelSelector) > 0 {
logrus.Warnf("namespace-selector is set, will only detect changes in namespaces with these labels: %s.", namespaceLabelSelector)
}
if len(resourceLabelSelector) > 0 {
logrus.Warnf("resource-label-selector is set, will only detect changes on resources with these labels: %s.", resourceLabelSelector)
}
collectors := metrics.SetupPrometheusEndpoint()
var controllers []*controller.Controller
for k := range kube.ResourceMap {
c, err := controller.NewController(clientset, k, currentNamespace)
if ignoredResourcesList.Contains(k) || (len(namespaceLabelSelector) == 0 && k == "namespaces") {
continue
}
c, err := controller.NewController(clientset, k, currentNamespace, ignoredNamespacesList, namespaceLabelSelector, resourceLabelSelector, collectors)
if err != nil {
logrus.Fatalf("%s", err)
}
controllers = append(controllers, c)
// If HA is enabled we only run the controller when
if options.EnableHA {
continue
}
// Now let's start the controller
stop := make(chan struct{})
defer close(stop)
logrus.Infof("Starting Controller to watch resource type: %s", k)
go c.Run(1, stop)
}
// Wait forever
select {}
// Run leadership election
if options.EnableHA {
podName, podNamespace := getHAEnvs()
lock := leadership.GetNewLock(clientset.CoordinationV1(), constants.LockName, podName, podNamespace)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go leadership.RunLeaderElection(lock, ctx, cancel, podName, controllers)
}
leadership.SetupLivenessEndpoint()
logrus.Fatal(http.ListenAndServe(constants.DefaultHttpListenAddr, nil))
}
func getIgnoredNamespacesList(cmd *cobra.Command) (util.List, error) {
return getStringSliceFromFlags(cmd, "namespaces-to-ignore")
}
func getNamespaceLabelSelector(cmd *cobra.Command) (string, error) {
slice, err := getStringSliceFromFlags(cmd, "namespace-selector")
if err != nil {
logrus.Fatal(err)
}
for i, kv := range slice {
// Legacy support for ":" as a delimiter and "*" for wildcard.
if strings.Contains(kv, ":") {
split := strings.Split(kv, ":")
if split[1] == "*" {
slice[i] = split[0]
} else {
slice[i] = split[0] + "=" + split[1]
}
}
// Convert wildcard to valid apimachinery operator
if strings.Contains(kv, "=") {
split := strings.Split(kv, "=")
if split[1] == "*" {
slice[i] = split[0]
}
}
}
namespaceLabelSelector := strings.Join(slice[:], ",")
_, err = labels.Parse(namespaceLabelSelector)
if err != nil {
logrus.Fatal(err)
}
return namespaceLabelSelector, nil
}
func getResourceLabelSelector(cmd *cobra.Command) (string, error) {
slice, err := getStringSliceFromFlags(cmd, "resource-label-selector")
if err != nil {
logrus.Fatal(err)
}
for i, kv := range slice {
// Legacy support for ":" as a delimiter and "*" for wildcard.
if strings.Contains(kv, ":") {
split := strings.Split(kv, ":")
if split[1] == "*" {
slice[i] = split[0]
} else {
slice[i] = split[0] + "=" + split[1]
}
}
// Convert wildcard to valid apimachinery operator
if strings.Contains(kv, "=") {
split := strings.Split(kv, "=")
if split[1] == "*" {
slice[i] = split[0]
}
}
}
resourceLabelSelector := strings.Join(slice[:], ",")
_, err = labels.Parse(resourceLabelSelector)
if err != nil {
logrus.Fatal(err)
}
return resourceLabelSelector, nil
}
func getStringSliceFromFlags(cmd *cobra.Command, flag string) ([]string, error) {
slice, err := cmd.Flags().GetStringSlice(flag)
if err != nil {
return nil, err
}
return slice, nil
}
func getIgnoredResourcesList(cmd *cobra.Command) (util.List, error) {
ignoredResourcesList, err := getStringSliceFromFlags(cmd, "resources-to-ignore")
if err != nil {
return nil, err
}
for _, v := range ignoredResourcesList {
if v != "configMaps" && v != "secrets" {
return nil, fmt.Errorf("'resources-to-ignore' only accepts 'configMaps' or 'secrets', not '%s'", v)
}
}
if len(ignoredResourcesList) > 1 {
return nil, errors.New("'resources-to-ignore' only accepts 'configMaps' or 'secrets', not both")
}
return ignoredResourcesList, nil
}

View File

@@ -1,8 +0,0 @@
package constants
const (
// ConfigmapUpdateOnChangeAnnotation is an annotation to detect changes in configmaps
ConfigmapUpdateOnChangeAnnotation = "configmap.reloader.stakater.com/reload"
// SecretUpdateOnChangeAnnotation is an annotation to detect changes in secrets
SecretUpdateOnChangeAnnotation = "secret.reloader.stakater.com/reload"
)

View File

@@ -1,10 +1,32 @@
package constants
const (
// DefaultHttpListenAddr is the default listening address for global http server
DefaultHttpListenAddr = ":9090"
// ConfigmapEnvVarPostfix is a postfix for configmap envVar
ConfigmapEnvVarPostfix = "CONFIGMAP"
// SecretEnvVarPostfix is a postfix for secret envVar
SecretEnvVarPostfix = "SECRET"
// EnvVarPrefix is a Prefix for environment variable
EnvVarPrefix = "STAKATER_"
// ReloaderAnnotationPrefix is a Prefix for all reloader annotations
ReloaderAnnotationPrefix = "reloader.stakater.com"
// LastReloadedFromAnnotation is an annotation used to describe the last resource that triggered a reload
LastReloadedFromAnnotation = "last-reloaded-from"
// ReloadStrategyFlag The reload strategy flag name
ReloadStrategyFlag = "reload-strategy"
// EnvVarsReloadStrategy instructs Reloader to add container environment variables to facilitate a restart
EnvVarsReloadStrategy = "env-vars"
// AnnotationsReloadStrategy instructs Reloader to add pod template annotations to facilitate a restart
AnnotationsReloadStrategy = "annotations"
)
// Leadership election related consts
const (
LockName string = "stakater-reloader-lock"
PodNameEnv string = "POD_NAME"
PodNamespaceEnv string = "POD_NAMESPACE"
)

View File

@@ -0,0 +1,15 @@
package constants
// Result is a status for deployment update
type Result int
const (
// Updated is returned when environment variable is created/updated
Updated Result = 1 + iota
// NotUpdated is returned when environment variable is found but had value equals to the new value
NotUpdated
// NoEnvVarFound is returned when no environment variable is found
NoEnvVarFound
// NoContainerFound is returned when no environment variable is found
NoContainerFound
)

View File

@@ -6,35 +6,80 @@ import (
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/handler"
"github.com/stakater/Reloader/internal/pkg/metrics"
"github.com/stakater/Reloader/internal/pkg/options"
"github.com/stakater/Reloader/internal/pkg/util"
"github.com/stakater/Reloader/pkg/kube"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/utils/strings/slices"
)
// Controller for checking events
type Controller struct {
client kubernetes.Interface
indexer cache.Indexer
queue workqueue.RateLimitingInterface
informer cache.Controller
namespace string
client kubernetes.Interface
indexer cache.Indexer
queue workqueue.RateLimitingInterface
informer cache.Controller
namespace string
resource string
ignoredNamespaces util.List
collectors metrics.Collectors
recorder record.EventRecorder
namespaceSelector string
resourceSelector string
}
// controllerInitialized flag determines whether controlled is being initialized
var secretControllerInitialized bool = false
var configmapControllerInitialized bool = false
var selectedNamespacesCache []string
// NewController for initializing a Controller
func NewController(
client kubernetes.Interface, resource string, namespace string) (*Controller, error) {
client kubernetes.Interface, resource string, namespace string, ignoredNamespaces []string, namespaceLabelSelector string, resourceLabelSelector string, collectors metrics.Collectors) (*Controller, error) {
c := Controller{
client: client,
namespace: namespace,
if options.SyncAfterRestart {
secretControllerInitialized = true
configmapControllerInitialized = true
}
c := Controller{
client: client,
namespace: namespace,
ignoredNamespaces: ignoredNamespaces,
namespaceSelector: namespaceLabelSelector,
resourceSelector: resourceLabelSelector,
resource: resource,
}
eventBroadcaster := record.NewBroadcaster()
eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{
Interface: client.CoreV1().Events(""),
})
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: fmt.Sprintf("reloader-%s", resource)})
queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
listWatcher := cache.NewListWatchFromClient(client.CoreV1().RESTClient(), resource, namespace, fields.Everything())
optionsModifier := func(options *metav1.ListOptions) {
if resource == "namespaces" {
options.LabelSelector = c.namespaceSelector
} else if len(c.resourceSelector) > 0 {
options.LabelSelector = c.resourceSelector
} else {
options.FieldSelector = fields.Everything().String()
}
}
listWatcher := cache.NewFilteredListWatchFromClient(client.CoreV1().RESTClient(), resource, namespace, optionsModifier)
indexer, informer := cache.NewIndexerInformer(listWatcher, kube.ResourceMap[resource], 0, cache.ResourceEventHandlerFuncs{
AddFunc: c.Add,
@@ -44,33 +89,106 @@ func NewController(
c.indexer = indexer
c.informer = informer
c.queue = queue
c.collectors = collectors
c.recorder = recorder
logrus.Infof("created controller for: %s", resource)
return &c, nil
}
// Add function to add a new object to the queue in case of creating a resource
func (c *Controller) Add(obj interface{}) {
c.queue.Add(handler.ResourceCreatedHandler{
Resource: obj,
})
switch object := obj.(type) {
case *v1.Namespace:
c.addSelectedNamespaceToCache(*object)
return
}
if options.ReloadOnCreate == "true" {
if !c.resourceInIgnoredNamespace(obj) && c.resourceInSelectedNamespaces(obj) && secretControllerInitialized && configmapControllerInitialized {
c.queue.Add(handler.ResourceCreatedHandler{
Resource: obj,
Collectors: c.collectors,
Recorder: c.recorder,
})
}
}
}
func (c *Controller) resourceInIgnoredNamespace(raw interface{}) bool {
switch object := raw.(type) {
case *v1.ConfigMap:
return c.ignoredNamespaces.Contains(object.ObjectMeta.Namespace)
case *v1.Secret:
return c.ignoredNamespaces.Contains(object.ObjectMeta.Namespace)
}
return false
}
func (c *Controller) resourceInSelectedNamespaces(raw interface{}) bool {
if len(c.namespaceSelector) == 0 {
return true
}
switch object := raw.(type) {
case *v1.ConfigMap:
if slices.Contains(selectedNamespacesCache, object.GetNamespace()) {
return true
}
case *v1.Secret:
if slices.Contains(selectedNamespacesCache, object.GetNamespace()) {
return true
}
}
return false
}
func (c *Controller) addSelectedNamespaceToCache(namespace v1.Namespace) {
selectedNamespacesCache = append(selectedNamespacesCache, namespace.GetName())
logrus.Infof("added namespace to be watched: %s", namespace.GetName())
}
func (c *Controller) removeSelectedNamespaceFromCache(namespace v1.Namespace) {
for i, v := range selectedNamespacesCache {
if v == namespace.GetName() {
selectedNamespacesCache = append(selectedNamespacesCache[:i], selectedNamespacesCache[i+1:]...)
logrus.Infof("removed namespace from watch: %s", namespace.GetName())
return
}
}
}
// Update function to add an old object and a new object to the queue in case of updating a resource
func (c *Controller) Update(old interface{}, new interface{}) {
c.queue.Add(handler.ResourceUpdatedHandler{
Resource: new,
OldResource: old,
})
switch new.(type) {
case *v1.Namespace:
return
}
if !c.resourceInIgnoredNamespace(new) && c.resourceInSelectedNamespaces(new) {
c.queue.Add(handler.ResourceUpdatedHandler{
Resource: new,
OldResource: old,
Collectors: c.collectors,
Recorder: c.recorder,
})
}
}
// Delete function to add an object to the queue in case of deleting a resource
func (c *Controller) Delete(old interface{}) {
logrus.Infof("Resource deletion has been detected but no further implementation found to take action")
switch object := old.(type) {
case *v1.Namespace:
c.removeSelectedNamespaceFromCache(*object)
return
}
// Todo: Any future delete event can be handled here
}
//Run function for controller which handles the queue
// Run function for controller which handles the queue
func (c *Controller) Run(threadiness int, stopCh chan struct{}) {
logrus.Infof("Starting Controller")
defer runtime.HandleCrash()
// Let the workers stop when we are done
@@ -93,6 +211,13 @@ func (c *Controller) Run(threadiness int, stopCh chan struct{}) {
}
func (c *Controller) runWorker() {
// At this point the controller is fully initialized and we can start processing the resources
if c.resource == "secrets" {
secretControllerInitialized = true
} else if c.resource == "configMaps" {
configmapControllerInitialized = true
}
for c.processNextItem() {
}
}
@@ -127,7 +252,7 @@ func (c *Controller) handleErr(err error, key interface{}) {
// This controller retries 5 times if something goes wrong. After that, it stops trying.
if c.queue.NumRequeues(key) < 5 {
logrus.Errorf("Error syncing events %v: %v", key, err)
logrus.Errorf("Error syncing events: %v", err)
// Re-enqueue the key rate limited. Based on the rate limiter on the
// queue and the re-enqueue history, the key will be processed later again.
@@ -138,5 +263,6 @@ func (c *Controller) handleErr(err error, key interface{}) {
c.queue.Forget(key)
// Report to an external entity that, even after several retries, we could not successfully process this key
runtime.HandleError(err)
logrus.Infof("Dropping the key %q out of the queue: %v", key, err)
logrus.Errorf("Dropping key out of the queue: %v", err)
logrus.Debugf("Dropping the key %q out of the queue: %v", key, err)
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,17 +2,41 @@ package handler
import (
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/metrics"
"github.com/stakater/Reloader/internal/pkg/util"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/tools/record"
)
// ResourceCreatedHandler contains new objects
type ResourceCreatedHandler struct {
Resource interface{}
Resource interface{}
Collectors metrics.Collectors
Recorder record.EventRecorder
}
// Handle processes the newly created resource
func (r ResourceCreatedHandler) Handle() error {
if r.Resource == nil {
logrus.Errorf("Resource creation handler received nil resource")
} else {
config, _ := r.GetConfig()
// process resource based on its type
return doRollingUpgrade(config, r.Collectors, r.Recorder)
}
return nil
}
// GetConfig gets configurations containing SHA, annotations, namespace and resource name
func (r ResourceCreatedHandler) GetConfig() (util.Config, string) {
var oldSHAData string
var config util.Config
if _, ok := r.Resource.(*v1.ConfigMap); ok {
config = util.GetConfigmapConfig(r.Resource.(*v1.ConfigMap))
} else if _, ok := r.Resource.(*v1.Secret); ok {
config = util.GetSecretConfig(r.Resource.(*v1.Secret))
} else {
logrus.Warnf("Invalid resource: Resource should be 'Secret' or 'Configmap' but found, %v", r.Resource)
}
return config, oldSHAData
}

View File

@@ -1,6 +1,11 @@
package handler
import (
"github.com/stakater/Reloader/internal/pkg/util"
)
// ResourceHandler handles the creation and update of resources
type ResourceHandler interface {
Handle() error
GetConfig() (util.Config, string)
}

View File

@@ -1,23 +1,19 @@
package handler
import (
"sort"
"strings"
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/callbacks"
"github.com/stakater/Reloader/internal/pkg/constants"
"github.com/stakater/Reloader/internal/pkg/crypto"
"github.com/stakater/Reloader/internal/pkg/metrics"
"github.com/stakater/Reloader/internal/pkg/util"
"github.com/stakater/Reloader/pkg/kube"
"k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/tools/record"
)
// ResourceUpdatedHandler contains updated objects
type ResourceUpdatedHandler struct {
Resource interface{}
OldResource interface{}
Collectors metrics.Collectors
Recorder record.EventRecorder
}
// Handle processes the updated resource
@@ -25,162 +21,27 @@ func (r ResourceUpdatedHandler) Handle() error {
if r.Resource == nil || r.OldResource == nil {
logrus.Errorf("Resource update handler received nil resource")
} else {
config, envVarPostfix, oldSHAData := getConfig(r)
config, oldSHAData := r.GetConfig()
if config.SHAValue != oldSHAData {
logrus.Infof("Changes detected in %s of type '%s' in namespace: %s", config.ResourceName, envVarPostfix, config.Namespace)
// process resource based on its type
rollingUpgrade(r, config, envVarPostfix, callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetDeploymentItems,
ContainersFunc: callbacks.GetDeploymentContainers,
UpdateFunc: callbacks.UpdateDeployment,
ResourceType: "Deployment",
})
rollingUpgrade(r, config, envVarPostfix, callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetDaemonSetItems,
ContainersFunc: callbacks.GetDaemonSetContainers,
UpdateFunc: callbacks.UpdateDaemonSet,
ResourceType: "DaemonSet",
})
rollingUpgrade(r, config, envVarPostfix, callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetStatefulSetItems,
ContainersFunc: callbacks.GetStatefulsetContainers,
UpdateFunc: callbacks.UpdateStatefulset,
ResourceType: "StatefulSet",
})
return doRollingUpgrade(config, r.Collectors, r.Recorder)
}
}
return nil
}
func rollingUpgrade(r ResourceUpdatedHandler, config util.Config, envarPostfix string, upgradeFuncs callbacks.RollingUpgradeFuncs) {
client, err := kube.GetClient()
if err != nil {
logrus.Fatalf("Unable to create Kubernetes client error = %v", err)
}
err = PerformRollingUpgrade(client, config, envarPostfix, upgradeFuncs)
if err != nil {
logrus.Errorf("Rolling upgrade for %s failed with error = %v", config.ResourceName, err)
}
}
func getConfig(r ResourceUpdatedHandler) (util.Config, string, string) {
var oldSHAData, envVarPostfix string
// GetConfig gets configurations containing SHA, annotations, namespace and resource name
func (r ResourceUpdatedHandler) GetConfig() (util.Config, string) {
var oldSHAData string
var config util.Config
if _, ok := r.Resource.(*v1.ConfigMap); ok {
oldSHAData = getSHAfromConfigmap(r.OldResource.(*v1.ConfigMap).Data)
config = getConfigmapConfig(r)
envVarPostfix = constants.ConfigmapEnvVarPostfix
oldSHAData = util.GetSHAfromConfigmap(r.OldResource.(*v1.ConfigMap))
config = util.GetConfigmapConfig(r.Resource.(*v1.ConfigMap))
} else if _, ok := r.Resource.(*v1.Secret); ok {
oldSHAData = getSHAfromSecret(r.OldResource.(*v1.Secret).Data)
config = getSecretConfig(r)
envVarPostfix = constants.SecretEnvVarPostfix
oldSHAData = util.GetSHAfromSecret(r.OldResource.(*v1.Secret).Data)
config = util.GetSecretConfig(r.Resource.(*v1.Secret))
} else {
logrus.Warnf("Invalid resource: Resource should be 'Secret' or 'Configmap' but found, %v", r.Resource)
}
return config, envVarPostfix, oldSHAData
}
func getConfigmapConfig(r ResourceUpdatedHandler) util.Config {
configmap := r.Resource.(*v1.ConfigMap)
return util.Config{
Namespace: configmap.Namespace,
ResourceName: configmap.Name,
Annotation: constants.ConfigmapUpdateOnChangeAnnotation,
SHAValue: getSHAfromConfigmap(configmap.Data),
}
}
func getSecretConfig(r ResourceUpdatedHandler) util.Config {
secret := r.Resource.(*v1.Secret)
return util.Config{
Namespace: secret.Namespace,
ResourceName: secret.Name,
Annotation: constants.SecretUpdateOnChangeAnnotation,
SHAValue: getSHAfromSecret(secret.Data),
}
}
// PerformRollingUpgrade upgrades the deployment if there is any change in configmap or secret data
func PerformRollingUpgrade(client kubernetes.Interface, config util.Config, envarPostfix string, upgradeFuncs callbacks.RollingUpgradeFuncs) error {
items := upgradeFuncs.ItemsFunc(client, config.Namespace)
var err error
for _, i := range items {
containers := upgradeFuncs.ContainersFunc(i)
resourceName := util.ToObjectMeta(i).Name
// find correct annotation and update the resource
annotationValue := util.ToObjectMeta(i).Annotations[config.Annotation]
if annotationValue != "" {
values := strings.Split(annotationValue, ",")
for _, value := range values {
if value == config.ResourceName {
updated := updateContainers(containers, value, config.SHAValue, envarPostfix)
if !updated {
logrus.Warnf("Rolling upgrade failed because no container found to add environment variable in %s of type %s in namespace: %s", resourceName, upgradeFuncs.ResourceType, config.Namespace)
} else {
err = upgradeFuncs.UpdateFunc(client, config.Namespace, i)
if err != nil {
logrus.Errorf("Update for %s of type %s in namespace %s failed with error %v", resourceName, upgradeFuncs.ResourceType, config.Namespace, err)
} else {
logrus.Infof("Updated %s of type %s in namespace: %s ", resourceName, upgradeFuncs.ResourceType, config.Namespace)
}
break
}
}
}
}
}
return err
}
func updateContainers(containers []v1.Container, annotationValue string, shaData string, envarPostfix string) bool {
updated := false
envar := constants.EnvVarPrefix + util.ConvertToEnvVarName(annotationValue)+ "_" + envarPostfix
for i := range containers {
envs := containers[i].Env
//update if env var exists
updated = updateEnvVar(envs, envar, shaData)
// if no existing env var exists lets create one
if !updated {
e := v1.EnvVar{
Name: envar,
Value: shaData,
}
containers[i].Env = append(containers[i].Env, e)
updated = true
}
}
return updated
}
func updateEnvVar(envs []v1.EnvVar, envar string, shaData string) bool {
for j := range envs {
if envs[j].Name == envar {
if envs[j].Value != shaData {
envs[j].Value = shaData
return true
}
}
}
return false
}
func getSHAfromConfigmap(data map[string]string) string {
values := []string{}
for k, v := range data {
values = append(values, k+"="+v)
}
sort.Strings(values)
return crypto.GenerateSHA(strings.Join(values, ";"))
}
func getSHAfromSecret(data map[string][]byte) string {
values := []string{}
for k, v := range data {
values = append(values, k+"="+string(v[:]))
}
sort.Strings(values)
return crypto.GenerateSHA(strings.Join(values, ";"))
return config, oldSHAData
}

View File

@@ -1,315 +0,0 @@
package handler
import (
"os"
"testing"
"time"
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/callbacks"
"github.com/stakater/Reloader/internal/pkg/constants"
"github.com/stakater/Reloader/internal/pkg/testutil"
"github.com/stakater/Reloader/internal/pkg/util"
testclient "k8s.io/client-go/kubernetes/fake"
)
var (
client = testclient.NewSimpleClientset()
namespace = "test-handler-" + testutil.RandSeq(5)
configmapName = "testconfigmap-handler-" + testutil.RandSeq(5)
secretName = "testsecret-handler-" + testutil.RandSeq(5)
)
func TestMain(m *testing.M) {
// Creating namespace
testutil.CreateNamespace(namespace, client)
logrus.Infof("Setting up the test resources")
setup()
logrus.Infof("Running Testcases")
retCode := m.Run()
logrus.Infof("tearing down the test resources")
teardown()
os.Exit(retCode)
}
func setup() {
// Creating configmap
_, err := testutil.CreateConfigMap(client, namespace, configmapName, "www.google.com")
if err != nil {
logrus.Errorf("Error in configmap creation: %v", err)
}
// Creating secret
data := "dGVzdFNlY3JldEVuY29kaW5nRm9yUmVsb2FkZXI="
_, err = testutil.CreateSecret(client, namespace, secretName, data)
if err != nil {
logrus.Errorf("Error in secret creation: %v", err)
}
// Creating Deployment with configmap
_, err = testutil.CreateDeployment(client, configmapName, namespace)
if err != nil {
logrus.Errorf("Error in Deployment with configmap creation: %v", err)
}
// Creating Deployment with secret
_, err = testutil.CreateDeployment(client, secretName, namespace)
if err != nil {
logrus.Errorf("Error in Deployment with secret creation: %v", err)
}
// Creating DaemonSet with configmap
_, err = testutil.CreateDaemonSet(client, configmapName, namespace)
if err != nil {
logrus.Errorf("Error in DaemonSet with configmap creation: %v", err)
}
// Creating DaemonSet with secret
_, err = testutil.CreateDaemonSet(client, secretName, namespace)
if err != nil {
logrus.Errorf("Error in DaemonSet with secret creation: %v", err)
}
// Creating StatefulSet with configmap
_, err = testutil.CreateStatefulSet(client, configmapName, namespace)
if err != nil {
logrus.Errorf("Error in StatefulSet with configmap creation: %v", err)
}
// Creating StatefulSet with secret
_, err = testutil.CreateStatefulSet(client, secretName, namespace)
if err != nil {
logrus.Errorf("Error in StatefulSet with secret creation: %v", err)
}
}
func teardown() {
// Deleting Deployment with configmap
deploymentError := testutil.DeleteDeployment(client, namespace, configmapName)
if deploymentError != nil {
logrus.Errorf("Error while deleting deployment with configmap %v", deploymentError)
}
// Deleting Deployment with secret
deploymentError = testutil.DeleteDeployment(client, namespace, secretName)
if deploymentError != nil {
logrus.Errorf("Error while deleting deployment with secret %v", deploymentError)
}
// Deleting DaemonSet with configmap
daemonSetError := testutil.DeleteDaemonSet(client, namespace, configmapName)
if daemonSetError != nil {
logrus.Errorf("Error while deleting daemonSet with configmap %v", daemonSetError)
}
// Deleting Deployment with secret
daemonSetError = testutil.DeleteDaemonSet(client, namespace, secretName)
if daemonSetError != nil {
logrus.Errorf("Error while deleting daemonSet with secret %v", daemonSetError)
}
// Deleting StatefulSet with configmap
statefulSetError := testutil.DeleteStatefulSet(client, namespace, configmapName)
if statefulSetError != nil {
logrus.Errorf("Error while deleting statefulSet with configmap %v", statefulSetError)
}
// Deleting Deployment with secret
statefulSetError = testutil.DeleteStatefulSet(client, namespace, secretName)
if statefulSetError != nil {
logrus.Errorf("Error while deleting statefulSet with secret %v", statefulSetError)
}
// Deleting Configmap
err := testutil.DeleteConfigMap(client, namespace, configmapName)
if err != nil {
logrus.Errorf("Error while deleting the configmap %v", err)
}
// Deleting Secret
err = testutil.DeleteSecret(client, namespace, secretName)
if err != nil {
logrus.Errorf("Error while deleting the secret %v", err)
}
// Deleting namespace
testutil.DeleteNamespace(namespace, client)
}
func TestRollingUpgradeForDeploymentWithConfigmap(t *testing.T) {
shaData := testutil.ConvertResourceToSHA(testutil.SecretResourceType, namespace, configmapName, "www.stakater.com")
config := util.Config{
Namespace: namespace,
ResourceName: configmapName,
SHAValue: shaData,
Annotation: constants.ConfigmapUpdateOnChangeAnnotation,
}
deploymentFuncs := callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetDeploymentItems,
ContainersFunc: callbacks.GetDeploymentContainers,
UpdateFunc: callbacks.UpdateDeployment,
ResourceType: "Deployment",
}
err := PerformRollingUpgrade(client, config, constants.ConfigmapEnvVarPostfix, deploymentFuncs)
time.Sleep(5 * time.Second)
if err != nil {
t.Errorf("Rolling upgrade failed for Deployment with Configmap")
}
logrus.Infof("Verifying deployment update")
updated := testutil.VerifyResourceUpdate(client, config, constants.ConfigmapEnvVarPostfix, deploymentFuncs)
if !updated {
t.Errorf("Deployment was not updated")
}
}
func TestRollingUpgradeForDeploymentWithSecret(t *testing.T) {
shaData := testutil.ConvertResourceToSHA(testutil.SecretResourceType, namespace, secretName, "dGVzdFVwZGF0ZWRTZWNyZXRFbmNvZGluZ0ZvclJlbG9hZGVy")
config := util.Config{
Namespace: namespace,
ResourceName: secretName,
SHAValue: shaData,
Annotation: constants.SecretUpdateOnChangeAnnotation,
}
deploymentFuncs := callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetDeploymentItems,
ContainersFunc: callbacks.GetDeploymentContainers,
UpdateFunc: callbacks.UpdateDeployment,
ResourceType: "Deployment",
}
err := PerformRollingUpgrade(client, config, constants.SecretEnvVarPostfix, deploymentFuncs)
time.Sleep(5 * time.Second)
if err != nil {
t.Errorf("Rolling upgrade failed for Deployment with Secret")
}
logrus.Infof("Verifying deployment update")
updated := testutil.VerifyResourceUpdate(client, config, constants.SecretEnvVarPostfix, deploymentFuncs)
if !updated {
t.Errorf("Deployment was not updated")
}
}
func TestRollingUpgradeForDaemonSetWithConfigmap(t *testing.T) {
shaData := testutil.ConvertResourceToSHA(testutil.ConfigmapResourceType, namespace, configmapName, "www.facebook.com")
config := util.Config{
Namespace: namespace,
ResourceName: configmapName,
SHAValue: shaData,
Annotation: constants.ConfigmapUpdateOnChangeAnnotation,
}
daemonSetFuncs := callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetDaemonSetItems,
ContainersFunc: callbacks.GetDaemonSetContainers,
UpdateFunc: callbacks.UpdateDaemonSet,
ResourceType: "DaemonSet",
}
err := PerformRollingUpgrade(client, config, constants.ConfigmapEnvVarPostfix, daemonSetFuncs)
time.Sleep(5 * time.Second)
if err != nil {
t.Errorf("Rolling upgrade failed for DaemonSet with configmap")
}
logrus.Infof("Verifying daemonSet update")
updated := testutil.VerifyResourceUpdate(client, config, constants.ConfigmapEnvVarPostfix, daemonSetFuncs)
if !updated {
t.Errorf("DaemonSet was not updated")
}
}
func TestRollingUpgradeForDaemonSetWithSecret(t *testing.T) {
shaData := testutil.ConvertResourceToSHA(testutil.SecretResourceType, namespace, secretName, "d3d3LmZhY2Vib29rLmNvbQ==")
config := util.Config{
Namespace: namespace,
ResourceName: secretName,
SHAValue: shaData,
Annotation: constants.SecretUpdateOnChangeAnnotation,
}
daemonSetFuncs := callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetDaemonSetItems,
ContainersFunc: callbacks.GetDaemonSetContainers,
UpdateFunc: callbacks.UpdateDaemonSet,
ResourceType: "DaemonSet",
}
err := PerformRollingUpgrade(client, config, constants.SecretEnvVarPostfix, daemonSetFuncs)
time.Sleep(5 * time.Second)
if err != nil {
t.Errorf("Rolling upgrade failed for DaemonSet with secret")
}
logrus.Infof("Verifying daemonSet update")
updated := testutil.VerifyResourceUpdate(client, config, constants.SecretEnvVarPostfix, daemonSetFuncs)
if !updated {
t.Errorf("DaemonSet was not updated")
}
}
func TestRollingUpgradeForStatefulSetWithConfigmap(t *testing.T) {
shaData := testutil.ConvertResourceToSHA(testutil.ConfigmapResourceType, namespace, configmapName, "www.twitter.com")
config := util.Config{
Namespace: namespace,
ResourceName: configmapName,
SHAValue: shaData,
Annotation: constants.ConfigmapUpdateOnChangeAnnotation,
}
statefulSetFuncs := callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetStatefulSetItems,
ContainersFunc: callbacks.GetStatefulsetContainers,
UpdateFunc: callbacks.UpdateStatefulset,
ResourceType: "StatefulSet",
}
err := PerformRollingUpgrade(client, config, constants.ConfigmapEnvVarPostfix, statefulSetFuncs)
time.Sleep(5 * time.Second)
if err != nil {
t.Errorf("Rolling upgrade failed for StatefulSet with configmap")
}
logrus.Infof("Verifying statefulSet update")
updated := testutil.VerifyResourceUpdate(client, config, constants.ConfigmapEnvVarPostfix, statefulSetFuncs)
if !updated {
t.Errorf("StatefulSet was not updated")
}
}
func TestRollingUpgradeForStatefulSetWithSecret(t *testing.T) {
shaData := testutil.ConvertResourceToSHA(testutil.SecretResourceType, namespace, secretName, "d3d3LnR3aXR0ZXIuY29t")
config := util.Config{
Namespace: namespace,
ResourceName: secretName,
SHAValue: shaData,
Annotation: constants.SecretUpdateOnChangeAnnotation,
}
statefulSetFuncs := callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetStatefulSetItems,
ContainersFunc: callbacks.GetStatefulsetContainers,
UpdateFunc: callbacks.UpdateStatefulset,
ResourceType: "StatefulSet",
}
err := PerformRollingUpgrade(client, config, constants.SecretEnvVarPostfix, statefulSetFuncs)
time.Sleep(5 * time.Second)
if err != nil {
t.Errorf("Rolling upgrade failed for StatefulSet with secret")
}
logrus.Infof("Verifying statefulSet update")
updated := testutil.VerifyResourceUpdate(client, config, constants.SecretEnvVarPostfix, statefulSetFuncs)
if !updated {
t.Errorf("StatefulSet was not updated")
}
}

View File

@@ -0,0 +1,426 @@
package handler
import (
"encoding/json"
"errors"
"fmt"
"os"
"regexp"
"strconv"
"strings"
"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
alert "github.com/stakater/Reloader/internal/pkg/alerts"
"github.com/stakater/Reloader/internal/pkg/callbacks"
"github.com/stakater/Reloader/internal/pkg/constants"
"github.com/stakater/Reloader/internal/pkg/metrics"
"github.com/stakater/Reloader/internal/pkg/options"
"github.com/stakater/Reloader/internal/pkg/util"
"github.com/stakater/Reloader/pkg/kube"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/record"
)
// GetDeploymentRollingUpgradeFuncs returns all callback funcs for a deployment
func GetDeploymentRollingUpgradeFuncs() callbacks.RollingUpgradeFuncs {
return callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetDeploymentItems,
AnnotationsFunc: callbacks.GetDeploymentAnnotations,
PodAnnotationsFunc: callbacks.GetDeploymentPodAnnotations,
ContainersFunc: callbacks.GetDeploymentContainers,
InitContainersFunc: callbacks.GetDeploymentInitContainers,
UpdateFunc: callbacks.UpdateDeployment,
VolumesFunc: callbacks.GetDeploymentVolumes,
ResourceType: "Deployment",
}
}
// GetDaemonSetRollingUpgradeFuncs returns all callback funcs for a daemonset
func GetDaemonSetRollingUpgradeFuncs() callbacks.RollingUpgradeFuncs {
return callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetDaemonSetItems,
AnnotationsFunc: callbacks.GetDaemonSetAnnotations,
PodAnnotationsFunc: callbacks.GetDaemonSetPodAnnotations,
ContainersFunc: callbacks.GetDaemonSetContainers,
InitContainersFunc: callbacks.GetDaemonSetInitContainers,
UpdateFunc: callbacks.UpdateDaemonSet,
VolumesFunc: callbacks.GetDaemonSetVolumes,
ResourceType: "DaemonSet",
}
}
// GetStatefulSetRollingUpgradeFuncs returns all callback funcs for a statefulSet
func GetStatefulSetRollingUpgradeFuncs() callbacks.RollingUpgradeFuncs {
return callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetStatefulSetItems,
AnnotationsFunc: callbacks.GetStatefulSetAnnotations,
PodAnnotationsFunc: callbacks.GetStatefulSetPodAnnotations,
ContainersFunc: callbacks.GetStatefulSetContainers,
InitContainersFunc: callbacks.GetStatefulSetInitContainers,
UpdateFunc: callbacks.UpdateStatefulSet,
VolumesFunc: callbacks.GetStatefulSetVolumes,
ResourceType: "StatefulSet",
}
}
// GetDeploymentConfigRollingUpgradeFuncs returns all callback funcs for a deploymentConfig
func GetDeploymentConfigRollingUpgradeFuncs() callbacks.RollingUpgradeFuncs {
return callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetDeploymentConfigItems,
AnnotationsFunc: callbacks.GetDeploymentConfigAnnotations,
PodAnnotationsFunc: callbacks.GetDeploymentConfigPodAnnotations,
ContainersFunc: callbacks.GetDeploymentConfigContainers,
InitContainersFunc: callbacks.GetDeploymentConfigInitContainers,
UpdateFunc: callbacks.UpdateDeploymentConfig,
VolumesFunc: callbacks.GetDeploymentConfigVolumes,
ResourceType: "DeploymentConfig",
}
}
// GetArgoRolloutRollingUpgradeFuncs returns all callback funcs for a rollout
func GetArgoRolloutRollingUpgradeFuncs() callbacks.RollingUpgradeFuncs {
return callbacks.RollingUpgradeFuncs{
ItemsFunc: callbacks.GetRolloutItems,
AnnotationsFunc: callbacks.GetRolloutAnnotations,
PodAnnotationsFunc: callbacks.GetRolloutPodAnnotations,
ContainersFunc: callbacks.GetRolloutContainers,
InitContainersFunc: callbacks.GetRolloutInitContainers,
UpdateFunc: callbacks.UpdateRollout,
VolumesFunc: callbacks.GetRolloutVolumes,
ResourceType: "Rollout",
}
}
func doRollingUpgrade(config util.Config, collectors metrics.Collectors, recorder record.EventRecorder) error {
clients := kube.GetClients()
err := rollingUpgrade(clients, config, GetDeploymentRollingUpgradeFuncs(), collectors, recorder)
if err != nil {
return err
}
err = rollingUpgrade(clients, config, GetDaemonSetRollingUpgradeFuncs(), collectors, recorder)
if err != nil {
return err
}
err = rollingUpgrade(clients, config, GetStatefulSetRollingUpgradeFuncs(), collectors, recorder)
if err != nil {
return err
}
if kube.IsOpenshift {
err = rollingUpgrade(clients, config, GetDeploymentConfigRollingUpgradeFuncs(), collectors, recorder)
if err != nil {
return err
}
}
if options.IsArgoRollouts == "true" {
err = rollingUpgrade(clients, config, GetArgoRolloutRollingUpgradeFuncs(), collectors, recorder)
if err != nil {
return err
}
}
return nil
}
func rollingUpgrade(clients kube.Clients, config util.Config, upgradeFuncs callbacks.RollingUpgradeFuncs, collectors metrics.Collectors, recorder record.EventRecorder) error {
err := PerformRollingUpgrade(clients, config, upgradeFuncs, collectors, recorder)
if err != nil {
logrus.Errorf("Rolling upgrade for '%s' failed with error = %v", config.ResourceName, err)
}
return err
}
// PerformRollingUpgrade upgrades the deployment if there is any change in configmap or secret data
func PerformRollingUpgrade(clients kube.Clients, config util.Config, upgradeFuncs callbacks.RollingUpgradeFuncs, collectors metrics.Collectors, recorder record.EventRecorder) error {
items := upgradeFuncs.ItemsFunc(clients, config.Namespace)
for _, i := range items {
// find correct annotation and update the resource
annotations := upgradeFuncs.AnnotationsFunc(i)
annotationValue, found := annotations[config.Annotation]
searchAnnotationValue, foundSearchAnn := annotations[options.AutoSearchAnnotation]
reloaderEnabledValue, foundAuto := annotations[options.ReloaderAutoAnnotation]
if !found && !foundAuto && !foundSearchAnn {
annotations = upgradeFuncs.PodAnnotationsFunc(i)
annotationValue = annotations[config.Annotation]
searchAnnotationValue = annotations[options.AutoSearchAnnotation]
reloaderEnabledValue = annotations[options.ReloaderAutoAnnotation]
}
result := constants.NotUpdated
reloaderEnabled, err := strconv.ParseBool(reloaderEnabledValue)
if err == nil && reloaderEnabled {
result = invokeReloadStrategy(upgradeFuncs, i, config, true)
}
if result != constants.Updated && annotationValue != "" {
values := strings.Split(annotationValue, ",")
for _, value := range values {
value = strings.TrimSpace(value)
re := regexp.MustCompile("^" + value + "$")
if re.Match([]byte(config.ResourceName)) {
result = invokeReloadStrategy(upgradeFuncs, i, config, false)
if result == constants.Updated {
break
}
}
}
}
if result != constants.Updated && searchAnnotationValue == "true" {
matchAnnotationValue := config.ResourceAnnotations[options.SearchMatchAnnotation]
if matchAnnotationValue == "true" {
result = invokeReloadStrategy(upgradeFuncs, i, config, true)
}
}
if result == constants.Updated {
accessor, err := meta.Accessor(i)
if err != nil {
return err
}
resourceName := accessor.GetName()
err = upgradeFuncs.UpdateFunc(clients, config.Namespace, i)
if err != nil {
message := fmt.Sprintf("Update for '%s' of type '%s' in namespace '%s' failed with error %v", resourceName, upgradeFuncs.ResourceType, config.Namespace, err)
logrus.Errorf(message)
collectors.Reloaded.With(prometheus.Labels{"success": "false"}).Inc()
if recorder != nil {
recorder.Event(i, v1.EventTypeWarning, "ReloadFail", message)
}
return err
} else {
message := fmt.Sprintf("Changes detected in '%s' of type '%s' in namespace '%s'", config.ResourceName, config.Type, config.Namespace)
message += fmt.Sprintf(", Updated '%s' of type '%s' in namespace '%s'", resourceName, upgradeFuncs.ResourceType, config.Namespace)
logrus.Infof(message)
collectors.Reloaded.With(prometheus.Labels{"success": "true"}).Inc()
alert_on_reload, ok := os.LookupEnv("ALERT_ON_RELOAD")
if recorder != nil {
recorder.Event(i, v1.EventTypeNormal, "Reloaded", message)
}
if ok && alert_on_reload == "true" {
msg := fmt.Sprintf(
"Reloader detected changes in *%s* of type *%s* in namespace *%s*. Hence reloaded *%s* of type *%s* in namespace *%s*",
config.ResourceName, config.Type, config.Namespace, resourceName, upgradeFuncs.ResourceType, config.Namespace)
alert.SendWebhookAlert(msg)
}
}
}
}
return nil
}
func getVolumeMountName(volumes []v1.Volume, mountType string, volumeName string) string {
for i := range volumes {
if mountType == constants.ConfigmapEnvVarPostfix {
if volumes[i].ConfigMap != nil && volumes[i].ConfigMap.Name == volumeName {
return volumes[i].Name
}
if volumes[i].Projected != nil {
for j := range volumes[i].Projected.Sources {
if volumes[i].Projected.Sources[j].ConfigMap != nil && volumes[i].Projected.Sources[j].ConfigMap.Name == volumeName {
return volumes[i].Name
}
}
}
} else if mountType == constants.SecretEnvVarPostfix {
if volumes[i].Secret != nil && volumes[i].Secret.SecretName == volumeName {
return volumes[i].Name
}
if volumes[i].Projected != nil {
for j := range volumes[i].Projected.Sources {
if volumes[i].Projected.Sources[j].Secret != nil && volumes[i].Projected.Sources[j].Secret.Name == volumeName {
return volumes[i].Name
}
}
}
}
}
return ""
}
func getContainerWithVolumeMount(containers []v1.Container, volumeMountName string) *v1.Container {
for i := range containers {
volumeMounts := containers[i].VolumeMounts
for j := range volumeMounts {
if volumeMounts[j].Name == volumeMountName {
return &containers[i]
}
}
}
return nil
}
func getContainerWithEnvReference(containers []v1.Container, resourceName string, resourceType string) *v1.Container {
for i := range containers {
envs := containers[i].Env
for j := range envs {
envVarSource := envs[j].ValueFrom
if envVarSource != nil {
if resourceType == constants.SecretEnvVarPostfix && envVarSource.SecretKeyRef != nil && envVarSource.SecretKeyRef.LocalObjectReference.Name == resourceName {
return &containers[i]
} else if resourceType == constants.ConfigmapEnvVarPostfix && envVarSource.ConfigMapKeyRef != nil && envVarSource.ConfigMapKeyRef.LocalObjectReference.Name == resourceName {
return &containers[i]
}
}
}
envsFrom := containers[i].EnvFrom
for j := range envsFrom {
if resourceType == constants.SecretEnvVarPostfix && envsFrom[j].SecretRef != nil && envsFrom[j].SecretRef.LocalObjectReference.Name == resourceName {
return &containers[i]
} else if resourceType == constants.ConfigmapEnvVarPostfix && envsFrom[j].ConfigMapRef != nil && envsFrom[j].ConfigMapRef.LocalObjectReference.Name == resourceName {
return &containers[i]
}
}
}
return nil
}
func getContainerUsingResource(upgradeFuncs callbacks.RollingUpgradeFuncs, item runtime.Object, config util.Config, autoReload bool) *v1.Container {
volumes := upgradeFuncs.VolumesFunc(item)
containers := upgradeFuncs.ContainersFunc(item)
initContainers := upgradeFuncs.InitContainersFunc(item)
var container *v1.Container
// Get the volumeMountName to find volumeMount in container
volumeMountName := getVolumeMountName(volumes, config.Type, config.ResourceName)
// Get the container with mounted configmap/secret
if volumeMountName != "" {
container = getContainerWithVolumeMount(containers, volumeMountName)
if container == nil && len(initContainers) > 0 {
container = getContainerWithVolumeMount(initContainers, volumeMountName)
if container != nil {
// if configmap/secret is being used in init container then return the first Pod container to save reloader env
return &containers[0]
}
} else if container != nil {
return container
}
}
// Get the container with referenced secret or configmap as env var
container = getContainerWithEnvReference(containers, config.ResourceName, config.Type)
if container == nil && len(initContainers) > 0 {
container = getContainerWithEnvReference(initContainers, config.ResourceName, config.Type)
if container != nil {
// if configmap/secret is being used in init container then return the first Pod container to save reloader env
return &containers[0]
}
}
// Get the first container if the annotation is related to specified configmap or secret i.e. configmap.reloader.stakater.com/reload
if container == nil && !autoReload {
return &containers[0]
}
return container
}
func invokeReloadStrategy(upgradeFuncs callbacks.RollingUpgradeFuncs, item runtime.Object, config util.Config, autoReload bool) constants.Result {
if options.ReloadStrategy == constants.AnnotationsReloadStrategy {
return updatePodAnnotations(upgradeFuncs, item, config, autoReload)
}
return updateContainerEnvVars(upgradeFuncs, item, config, autoReload)
}
func updatePodAnnotations(upgradeFuncs callbacks.RollingUpgradeFuncs, item runtime.Object, config util.Config, autoReload bool) constants.Result {
container := getContainerUsingResource(upgradeFuncs, item, config, autoReload)
if container == nil {
return constants.NoContainerFound
}
// Generate reloaded annotations. Attaching this to the item's annotation will trigger a rollout
// Note: the data on this struct is purely informational and is not used for future updates
reloadSource := util.NewReloadSourceFromConfig(config, []string{container.Name})
annotations, err := createReloadedAnnotations(&reloadSource)
if err != nil {
logrus.Errorf("Failed to create reloaded annotations for %s! error = %v", config.ResourceName, err)
return constants.NotUpdated
}
// Copy the all annotations to the item's annotations
pa := upgradeFuncs.PodAnnotationsFunc(item)
if pa == nil {
return constants.NotUpdated
}
for k, v := range annotations {
pa[k] = v
}
return constants.Updated
}
func createReloadedAnnotations(target *util.ReloadSource) (map[string]string, error) {
if target == nil {
return nil, errors.New("target is required")
}
// Create a single "last-invokeReloadStrategy-from" annotation that stores metadata about the
// resource that caused the last invokeReloadStrategy.
// Intentionally only storing the last item in order to keep
// the generated annotations as small as possible.
annotations := make(map[string]string)
lastReloadedResourceName := fmt.Sprintf("%s/%s",
constants.ReloaderAnnotationPrefix,
constants.LastReloadedFromAnnotation,
)
lastReloadedResource, err := json.Marshal(target)
if err != nil {
return nil, err
}
annotations[lastReloadedResourceName] = string(lastReloadedResource)
return annotations, nil
}
func updateContainerEnvVars(upgradeFuncs callbacks.RollingUpgradeFuncs, item runtime.Object, config util.Config, autoReload bool) constants.Result {
var result constants.Result
envVar := constants.EnvVarPrefix + util.ConvertToEnvVarName(config.ResourceName) + "_" + config.Type
container := getContainerUsingResource(upgradeFuncs, item, config, autoReload)
if container == nil {
return constants.NoContainerFound
}
//update if env var exists
result = updateEnvVar(upgradeFuncs.ContainersFunc(item), envVar, config.SHAValue)
// if no existing env var exists lets create one
if result == constants.NoEnvVarFound {
e := v1.EnvVar{
Name: envVar,
Value: config.SHAValue,
}
container.Env = append(container.Env, e)
result = constants.Updated
}
return result
}
func updateEnvVar(containers []v1.Container, envVar string, shaData string) constants.Result {
for i := range containers {
envs := containers[i].Env
for j := range envs {
if envs[j].Name == envVar {
if envs[j].Value != shaData {
envs[j].Value = shaData
return constants.Updated
}
return constants.NotUpdated
}
}
}
return constants.NoEnvVarFound
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
package leadership
import (
"context"
"net/http"
"sync"
"time"
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/controller"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/leaderelection"
"k8s.io/client-go/tools/leaderelection/resourcelock"
coordinationv1 "k8s.io/client-go/kubernetes/typed/coordination/v1"
)
var (
// Used for liveness probe
m sync.Mutex
healthy bool = true
)
func GetNewLock(client coordinationv1.CoordinationV1Interface, lockName, podname, namespace string) *resourcelock.LeaseLock {
return &resourcelock.LeaseLock{
LeaseMeta: v1.ObjectMeta{
Name: lockName,
Namespace: namespace,
},
Client: client,
LockConfig: resourcelock.ResourceLockConfig{
Identity: podname,
},
}
}
// runLeaderElection runs leadership election. If an instance of the controller is the leader and stops leading it will shutdown.
func RunLeaderElection(lock *resourcelock.LeaseLock, ctx context.Context, cancel context.CancelFunc, id string, controllers []*controller.Controller) {
// Construct channels for the controllers to use
var stopChannels []chan struct{}
for i := 0; i < len(controllers); i++ {
stop := make(chan struct{})
stopChannels = append(stopChannels, stop)
}
leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{
Lock: lock,
ReleaseOnCancel: true,
LeaseDuration: 15 * time.Second,
RenewDeadline: 10 * time.Second,
RetryPeriod: 2 * time.Second,
Callbacks: leaderelection.LeaderCallbacks{
OnStartedLeading: func(c context.Context) {
logrus.Info("became leader, starting controllers")
runControllers(controllers, stopChannels)
},
OnStoppedLeading: func() {
logrus.Info("no longer leader, shutting down")
stopControllers(stopChannels)
cancel()
m.Lock()
defer m.Unlock()
healthy = false
},
OnNewLeader: func(current_id string) {
if current_id == id {
logrus.Info("still the leader!")
return
}
logrus.Infof("new leader is %s", current_id)
},
},
})
}
func runControllers(controllers []*controller.Controller, stopChannels []chan struct{}) {
for i, c := range controllers {
c := c
go c.Run(1, stopChannels[i])
}
}
func stopControllers(stopChannels []chan struct{}) {
for _, c := range stopChannels {
close(c)
}
}
// Healthz sets up the liveness probe endpoint. If leadership election is
// enabled and a replica stops leading the liveness probe will fail and the
// kubelet will restart the container.
func SetupLivenessEndpoint() {
http.HandleFunc("/live", healthz)
}
func healthz(w http.ResponseWriter, req *http.Request) {
m.Lock()
defer m.Unlock()
if healthy {
if i, err := w.Write([]byte("alive")); err != nil {
logrus.Infof("failed to write liveness response, wrote: %d bytes, got err: %s", i, err)
}
return
}
w.WriteHeader(http.StatusInternalServerError)
}

View File

@@ -0,0 +1,213 @@
package leadership
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/constants"
"github.com/stakater/Reloader/internal/pkg/controller"
"github.com/stakater/Reloader/internal/pkg/handler"
"github.com/stakater/Reloader/internal/pkg/metrics"
"github.com/stakater/Reloader/internal/pkg/options"
"github.com/stakater/Reloader/internal/pkg/testutil"
"github.com/stakater/Reloader/internal/pkg/util"
"github.com/stakater/Reloader/pkg/kube"
)
func TestMain(m *testing.M) {
testutil.CreateNamespace(testutil.Namespace, testutil.Clients.KubernetesClient)
logrus.Infof("Running Testcases")
retCode := m.Run()
testutil.DeleteNamespace(testutil.Namespace, testutil.Clients.KubernetesClient)
os.Exit(retCode)
}
func TestHealthz(t *testing.T) {
request, err := http.NewRequest(http.MethodGet, "/live", nil)
if err != nil {
t.Fatalf(("failed to create request"))
}
response := httptest.NewRecorder()
healthz(response, request)
got := response.Code
want := 200
if got != want {
t.Fatalf("got: %q, want: %q", got, want)
}
// Have the liveness probe serve a 500
healthy = false
request, err = http.NewRequest(http.MethodGet, "/live", nil)
if err != nil {
t.Fatalf(("failed to create request"))
}
response = httptest.NewRecorder()
healthz(response, request)
got = response.Code
want = 500
if got != want {
t.Fatalf("got: %q, want: %q", got, want)
}
}
// TestRunLeaderElection validates that the liveness endpoint serves 500 when
// leadership election fails
func TestRunLeaderElection(t *testing.T) {
ctx, cancel := context.WithCancel(context.TODO())
lock := GetNewLock(testutil.Clients.KubernetesClient.CoordinationV1(), constants.LockName, testutil.Pod, testutil.Namespace)
go RunLeaderElection(lock, ctx, cancel, testutil.Pod, []*controller.Controller{})
// Liveness probe should be serving OK
request, err := http.NewRequest(http.MethodGet, "/live", nil)
if err != nil {
t.Fatalf(("failed to create request"))
}
response := httptest.NewRecorder()
healthz(response, request)
got := response.Code
want := 500
if got != want {
t.Fatalf("got: %q, want: %q", got, want)
}
// Cancel the leader election context, so leadership is released and
// live endpoint serves 500
cancel()
request, err = http.NewRequest(http.MethodGet, "/live", nil)
if err != nil {
t.Fatalf(("failed to create request"))
}
response = httptest.NewRecorder()
healthz(response, request)
got = response.Code
want = 500
if got != want {
t.Fatalf("got: %q, want: %q", got, want)
}
}
// TestRunLeaderElectionWithControllers tests that leadership election works
// wiht real controllers and that on context cancellation the controllers stop
// running.
func TestRunLeaderElectionWithControllers(t *testing.T) {
t.Logf("Creating controller")
var controllers []*controller.Controller
for k := range kube.ResourceMap {
c, err := controller.NewController(testutil.Clients.KubernetesClient, k, testutil.Namespace, []string{}, "", "", metrics.NewCollectors())
if err != nil {
logrus.Fatalf("%s", err)
}
controllers = append(controllers, c)
}
time.Sleep(3 * time.Second)
lock := GetNewLock(testutil.Clients.KubernetesClient.CoordinationV1(), fmt.Sprintf("%s-%d", constants.LockName, 1), testutil.Pod, testutil.Namespace)
ctx, cancel := context.WithCancel(context.TODO())
// Start running leadership election, this also starts the controllers
go RunLeaderElection(lock, ctx, cancel, testutil.Pod, controllers)
time.Sleep(3 * time.Second)
// Create some stuff and do a thing
configmapName := testutil.ConfigmapNamePrefix + "-update-" + testutil.RandSeq(5)
configmapClient, err := testutil.CreateConfigMap(testutil.Clients.KubernetesClient, testutil.Namespace, configmapName, "www.google.com")
if err != nil {
t.Fatalf("Error while creating the configmap %v", err)
}
// Creating deployment
_, err = testutil.CreateDeployment(testutil.Clients.KubernetesClient, configmapName, testutil.Namespace, true)
if err != nil {
t.Fatalf("Error in deployment creation: %v", err)
}
// Updating configmap for first time
updateErr := testutil.UpdateConfigMap(configmapClient, testutil.Namespace, configmapName, "", "www.stakater.com")
if updateErr != nil {
t.Fatalf("Configmap was not updated")
}
time.Sleep(3 * time.Second)
// Verifying deployment update
logrus.Infof("Verifying pod envvars has been created")
shaData := testutil.ConvertResourceToSHA(testutil.ConfigmapResourceType, testutil.Namespace, configmapName, "www.stakater.com")
config := util.Config{
Namespace: testutil.Namespace,
ResourceName: configmapName,
SHAValue: shaData,
Annotation: options.ConfigmapUpdateOnChangeAnnotation,
}
deploymentFuncs := handler.GetDeploymentRollingUpgradeFuncs()
updated := testutil.VerifyResourceEnvVarUpdate(testutil.Clients, config, constants.ConfigmapEnvVarPostfix, deploymentFuncs)
if !updated {
t.Fatalf("Deployment was not updated")
}
time.Sleep(testutil.SleepDuration)
// Cancel the leader election context, so leadership is released
logrus.Info("shutting down controller from test")
cancel()
time.Sleep(5 * time.Second)
// Updating configmap again
updateErr = testutil.UpdateConfigMap(configmapClient, testutil.Namespace, configmapName, "", "www.stakater.com/new")
if updateErr != nil {
t.Fatalf("Configmap was not updated")
}
// Verifying that the deployment was not updated as leadership has been lost
logrus.Infof("Verifying pod envvars has not been updated")
shaData = testutil.ConvertResourceToSHA(testutil.ConfigmapResourceType, testutil.Namespace, configmapName, "www.stakater.com/new")
config = util.Config{
Namespace: testutil.Namespace,
ResourceName: configmapName,
SHAValue: shaData,
Annotation: options.ConfigmapUpdateOnChangeAnnotation,
}
deploymentFuncs = handler.GetDeploymentRollingUpgradeFuncs()
updated = testutil.VerifyResourceEnvVarUpdate(testutil.Clients, config, constants.ConfigmapEnvVarPostfix, deploymentFuncs)
if updated {
t.Fatalf("Deployment was updated")
}
// Deleting deployment
err = testutil.DeleteDeployment(testutil.Clients.KubernetesClient, testutil.Namespace, configmapName)
if err != nil {
logrus.Errorf("Error while deleting the deployment %v", err)
}
// Deleting configmap
err = testutil.DeleteConfigMap(testutil.Clients.KubernetesClient, testutil.Namespace, configmapName)
if err != nil {
logrus.Errorf("Error while deleting the configmap %v", err)
}
time.Sleep(testutil.SleepDuration)
}

View File

@@ -0,0 +1,38 @@
package metrics
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
)
type Collectors struct {
Reloaded *prometheus.CounterVec
}
func NewCollectors() Collectors {
reloaded := prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: "reloader",
Name: "reload_executed_total",
Help: "Counter of reloads executed by Reloader.",
},
[]string{"success"},
)
//set 0 as default value
reloaded.With(prometheus.Labels{"success": "true"}).Add(0)
reloaded.With(prometheus.Labels{"success": "false"}).Add(0)
return Collectors{
Reloaded: reloaded,
}
}
func SetupPrometheusEndpoint() Collectors {
collectors := NewCollectors()
prometheus.MustRegister(collectors.Reloaded)
http.Handle("/metrics", promhttp.Handler())
return collectors
}

View File

@@ -0,0 +1,31 @@
package options
import "github.com/stakater/Reloader/internal/pkg/constants"
var (
// ConfigmapUpdateOnChangeAnnotation is an annotation to detect changes in
// configmaps specified by name
ConfigmapUpdateOnChangeAnnotation = "configmap.reloader.stakater.com/reload"
// SecretUpdateOnChangeAnnotation is an annotation to detect changes in
// secrets specified by name
SecretUpdateOnChangeAnnotation = "secret.reloader.stakater.com/reload"
// ReloaderAutoAnnotation is an annotation to detect changes in secrets
ReloaderAutoAnnotation = "reloader.stakater.com/auto"
// AutoSearchAnnotation is an annotation to detect changes in
// configmaps or triggers with the SearchMatchAnnotation
AutoSearchAnnotation = "reloader.stakater.com/search"
// SearchMatchAnnotation is an annotation to tag secrets to be found with
// AutoSearchAnnotation
SearchMatchAnnotation = "reloader.stakater.com/match"
// LogFormat is the log format to use (json, or empty string for default)
LogFormat = ""
// IsArgoRollouts Adds support for argo rollouts
IsArgoRollouts = "false"
// ReloadStrategy Specify the update strategy
ReloadStrategy = constants.EnvVarsReloadStrategy
// ReloadOnCreate Adds support to watch create events
ReloadOnCreate = "false"
SyncAfterRestart = false
// EnableHA adds support for running multiple replicas via leadership election
EnableHA = false
)

View File

@@ -1,20 +1,28 @@
package testutil
import (
"context"
"encoding/json"
"fmt"
"math/rand"
"sort"
"strconv"
"strings"
"time"
openshiftv1 "github.com/openshift/api/apps/v1"
appsclient "github.com/openshift/client-go/apps/clientset/versioned"
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/callbacks"
"github.com/stakater/Reloader/internal/pkg/constants"
"github.com/stakater/Reloader/internal/pkg/crypto"
"github.com/stakater/Reloader/internal/pkg/metrics"
"github.com/stakater/Reloader/internal/pkg/options"
"github.com/stakater/Reloader/internal/pkg/util"
"github.com/stakater/Reloader/pkg/kube"
v1_beta1 "k8s.io/api/apps/v1beta1"
"k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
core_v1 "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -28,19 +36,24 @@ var (
SecretResourceType = "secrets"
)
func GetClient() *kubernetes.Clientset {
newClient, err := kube.GetClient()
if err != nil {
logrus.Fatalf("Unable to create Kubernetes client error = %v", err)
}
return newClient
}
var (
Clients = kube.GetClients()
Pod = "test-reloader-" + RandSeq(5)
Namespace = "test-reloader-" + RandSeq(5)
ConfigmapNamePrefix = "testconfigmap-reloader"
SecretNamePrefix = "testsecret-reloader"
Data = "dGVzdFNlY3JldEVuY29kaW5nRm9yUmVsb2FkZXI="
NewData = "dGVzdE5ld1NlY3JldEVuY29kaW5nRm9yUmVsb2FkZXI="
UpdatedData = "dGVzdFVwZGF0ZWRTZWNyZXRFbmNvZGluZ0ZvclJlbG9hZGVy"
Collectors = metrics.NewCollectors()
SleepDuration = 3 * time.Second
)
// CreateNamespace creates namespace for testing
func CreateNamespace(namespace string, client kubernetes.Interface) {
_, err := client.CoreV1().Namespaces().Create(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}})
_, err := client.CoreV1().Namespaces().Create(context.TODO(), &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}, metav1.CreateOptions{})
if err != nil {
logrus.Fatalf("Failed to create namespace for testing", err)
logrus.Fatalf("Failed to create namespace for testing %v", err)
} else {
logrus.Infof("Creating namespace for testing = %s", namespace)
}
@@ -48,44 +61,163 @@ func CreateNamespace(namespace string, client kubernetes.Interface) {
// DeleteNamespace deletes namespace for testing
func DeleteNamespace(namespace string, client kubernetes.Interface) {
err := client.CoreV1().Namespaces().Delete(namespace, &metav1.DeleteOptions{})
err := client.CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{})
if err != nil {
logrus.Fatalf("Failed to delete namespace that was created for testing", err)
logrus.Fatalf("Failed to delete namespace that was created for testing %v", err)
} else {
logrus.Infof("Deleting namespace for testing = %s", namespace)
}
}
// GetDeployment provides deployment for testing
func GetDeployment(namespace string, deploymentName string) *v1beta1.Deployment {
replicaset := int32(1)
return &v1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: deploymentName,
Namespace: namespace,
Labels: map[string]string{"firstLabel": "temp"},
Annotations: map[string]string{
constants.ConfigmapUpdateOnChangeAnnotation: deploymentName,
constants.SecretUpdateOnChangeAnnotation: deploymentName},
},
Spec: v1beta1.DeploymentSpec{
Replicas: &replicaset,
Strategy: v1beta1.DeploymentStrategy{
Type: v1beta1.RollingUpdateDeploymentStrategyType,
},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"secondLabel": "temp"},
func getObjectMeta(namespace string, name string, autoReload bool) metav1.ObjectMeta {
return metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: map[string]string{"firstLabel": "temp"},
Annotations: getAnnotations(name, autoReload),
}
}
func getAnnotations(name string, autoReload bool) map[string]string {
if autoReload {
return map[string]string{
options.ReloaderAutoAnnotation: "true"}
}
return map[string]string{
options.ConfigmapUpdateOnChangeAnnotation: name,
options.SecretUpdateOnChangeAnnotation: name}
}
func getEnvVarSources(name string) []v1.EnvFromSource {
return []v1.EnvFromSource{
{
ConfigMapRef: &v1.ConfigMapEnvSource{
LocalObjectReference: v1.LocalObjectReference{
Name: name,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
},
},
{
SecretRef: &v1.SecretEnvSource{
LocalObjectReference: v1.LocalObjectReference{
Name: name,
},
},
},
}
}
func getVolumes(name string) []v1.Volume {
return []v1.Volume{
{
Name: "projectedconfigmap",
VolumeSource: v1.VolumeSource{
Projected: &v1.ProjectedVolumeSource{
Sources: []v1.VolumeProjection{
{
Image: "tutum/hello-world",
Name: deploymentName,
Env: []v1.EnvVar{
{
Name: "BUCKET_NAME",
Value: "test",
ConfigMap: &v1.ConfigMapProjection{
LocalObjectReference: v1.LocalObjectReference{
Name: name,
},
},
},
},
},
},
},
{
Name: "projectedsecret",
VolumeSource: v1.VolumeSource{
Projected: &v1.ProjectedVolumeSource{
Sources: []v1.VolumeProjection{
{
Secret: &v1.SecretProjection{
LocalObjectReference: v1.LocalObjectReference{
Name: name,
},
},
},
},
},
},
},
{
Name: "configmap",
VolumeSource: v1.VolumeSource{
ConfigMap: &v1.ConfigMapVolumeSource{
LocalObjectReference: v1.LocalObjectReference{
Name: name,
},
},
},
},
{
Name: "secret",
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: name,
},
},
},
}
}
func getVolumeMounts(name string) []v1.VolumeMount {
return []v1.VolumeMount{
{
MountPath: "etc/config",
Name: "configmap",
},
{
MountPath: "etc/sec",
Name: "secret",
},
{
MountPath: "etc/projectedconfig",
Name: "projectedconfigmap",
},
{
MountPath: "etc/projectedsec",
Name: "projectedsecret",
},
}
}
func getPodTemplateSpecWithEnvVars(name string) v1.PodTemplateSpec {
return v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"secondLabel": "temp"},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Image: "tutum/hello-world",
Name: name,
Env: []v1.EnvVar{
{
Name: "BUCKET_NAME",
Value: "test",
},
{
Name: "CONFIGMAP_" + util.ConvertToEnvVarName(name),
ValueFrom: &v1.EnvVarSource{
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: name,
},
Key: "test.url",
},
},
},
{
Name: "SECRET_" + util.ConvertToEnvVarName(name),
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: name,
},
Key: "test.url",
},
},
},
@@ -96,78 +228,306 @@ func GetDeployment(namespace string, deploymentName string) *v1beta1.Deployment
}
}
// GetDaemonSet provides daemonset for testing
func GetDaemonSet(namespace string, daemonsetName string) *v1beta1.DaemonSet {
return &v1beta1.DaemonSet{
func getPodTemplateSpecWithEnvVarSources(name string) v1.PodTemplateSpec {
return v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Name: daemonsetName,
Namespace: namespace,
Labels: map[string]string{"firstLabel": "temp"},
Annotations: map[string]string{
constants.ConfigmapUpdateOnChangeAnnotation: daemonsetName,
constants.SecretUpdateOnChangeAnnotation: daemonsetName},
Labels: map[string]string{"secondLabel": "temp"},
},
Spec: v1beta1.DaemonSetSpec{
UpdateStrategy: v1beta1.DaemonSetUpdateStrategy{
Type: v1beta1.RollingUpdateDaemonSetStrategyType,
},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"secondLabel": "temp"},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Image: "tutum/hello-world",
Name: name,
EnvFrom: getEnvVarSources(name),
},
Spec: v1.PodSpec{
Containers: []v1.Container{
},
},
}
}
func getPodTemplateSpecWithVolumes(name string) v1.PodTemplateSpec {
return v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"secondLabel": "temp"},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Image: "tutum/hello-world",
Name: name,
Env: []v1.EnvVar{
{
Image: "tutum/hello-world",
Name: daemonsetName,
Env: []v1.EnvVar{
{
Name: "BUCKET_NAME",
Value: "test",
},
},
Name: "BUCKET_NAME",
Value: "test",
},
},
VolumeMounts: getVolumeMounts(name),
},
},
Volumes: getVolumes(name),
},
}
}
func getPodTemplateSpecWithInitContainer(name string) v1.PodTemplateSpec {
return v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"secondLabel": "temp"},
},
Spec: v1.PodSpec{
InitContainers: []v1.Container{
{
Image: "busybox",
Name: "busyBox",
VolumeMounts: getVolumeMounts(name),
},
},
Containers: []v1.Container{
{
Image: "tutum/hello-world",
Name: name,
Env: []v1.EnvVar{
{
Name: "BUCKET_NAME",
Value: "test",
},
},
},
},
Volumes: getVolumes(name),
},
}
}
func getPodTemplateSpecWithInitContainerAndEnv(name string) v1.PodTemplateSpec {
return v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"secondLabel": "temp"},
},
Spec: v1.PodSpec{
InitContainers: []v1.Container{
{
Image: "busybox",
Name: "busyBox",
EnvFrom: getEnvVarSources(name),
},
},
Containers: []v1.Container{
{
Image: "tutum/hello-world",
Name: name,
Env: []v1.EnvVar{
{
Name: "BUCKET_NAME",
Value: "test",
},
},
},
},
},
}
}
// GetDeployment provides deployment for testing
func GetDeployment(namespace string, deploymentName string) *appsv1.Deployment {
replicaset := int32(1)
return &appsv1.Deployment{
ObjectMeta: getObjectMeta(namespace, deploymentName, false),
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
Replicas: &replicaset,
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
},
Template: getPodTemplateSpecWithVolumes(deploymentName),
},
}
}
// GetDeploymentConfig provides deployment for testing
func GetDeploymentConfig(namespace string, deploymentConfigName string) *openshiftv1.DeploymentConfig {
replicaset := int32(1)
podTemplateSpecWithVolume := getPodTemplateSpecWithVolumes(deploymentConfigName)
return &openshiftv1.DeploymentConfig{
ObjectMeta: getObjectMeta(namespace, deploymentConfigName, false),
Spec: openshiftv1.DeploymentConfigSpec{
Replicas: replicaset,
Strategy: openshiftv1.DeploymentStrategy{
Type: openshiftv1.DeploymentStrategyTypeRolling,
},
Template: &podTemplateSpecWithVolume,
},
}
}
// GetDeploymentWithInitContainer provides deployment with init container and volumeMounts
func GetDeploymentWithInitContainer(namespace string, deploymentName string) *appsv1.Deployment {
replicaset := int32(1)
return &appsv1.Deployment{
ObjectMeta: getObjectMeta(namespace, deploymentName, false),
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
Replicas: &replicaset,
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
},
Template: getPodTemplateSpecWithInitContainer(deploymentName),
},
}
}
// GetDeploymentWithInitContainerAndEnv provides deployment with init container and EnvSource
func GetDeploymentWithInitContainerAndEnv(namespace string, deploymentName string) *appsv1.Deployment {
replicaset := int32(1)
return &appsv1.Deployment{
ObjectMeta: getObjectMeta(namespace, deploymentName, true),
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
Replicas: &replicaset,
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
},
Template: getPodTemplateSpecWithInitContainerAndEnv(deploymentName),
},
}
}
func GetDeploymentWithEnvVars(namespace string, deploymentName string) *appsv1.Deployment {
replicaset := int32(1)
return &appsv1.Deployment{
ObjectMeta: getObjectMeta(namespace, deploymentName, true),
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
Replicas: &replicaset,
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
},
Template: getPodTemplateSpecWithEnvVars(deploymentName),
},
}
}
func GetDeploymentConfigWithEnvVars(namespace string, deploymentConfigName string) *openshiftv1.DeploymentConfig {
replicaset := int32(1)
podTemplateSpecWithEnvVars := getPodTemplateSpecWithEnvVars(deploymentConfigName)
return &openshiftv1.DeploymentConfig{
ObjectMeta: getObjectMeta(namespace, deploymentConfigName, false),
Spec: openshiftv1.DeploymentConfigSpec{
Replicas: replicaset,
Strategy: openshiftv1.DeploymentStrategy{
Type: openshiftv1.DeploymentStrategyTypeRolling,
},
Template: &podTemplateSpecWithEnvVars,
},
}
}
func GetDeploymentWithEnvVarSources(namespace string, deploymentName string) *appsv1.Deployment {
replicaset := int32(1)
return &appsv1.Deployment{
ObjectMeta: getObjectMeta(namespace, deploymentName, true),
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
Replicas: &replicaset,
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
},
Template: getPodTemplateSpecWithEnvVarSources(deploymentName),
},
}
}
func GetDeploymentWithPodAnnotations(namespace string, deploymentName string, both bool) *appsv1.Deployment {
replicaset := int32(1)
deployment := &appsv1.Deployment{
ObjectMeta: getObjectMeta(namespace, deploymentName, false),
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
Replicas: &replicaset,
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
},
Template: getPodTemplateSpecWithEnvVarSources(deploymentName),
},
}
if !both {
deployment.ObjectMeta.Annotations = nil
}
deployment.Spec.Template.ObjectMeta.Annotations = getAnnotations(deploymentName, true)
return deployment
}
// GetDaemonSet provides daemonset for testing
func GetDaemonSet(namespace string, daemonsetName string) *appsv1.DaemonSet {
return &appsv1.DaemonSet{
ObjectMeta: getObjectMeta(namespace, daemonsetName, false),
Spec: appsv1.DaemonSetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
UpdateStrategy: appsv1.DaemonSetUpdateStrategy{
Type: appsv1.RollingUpdateDaemonSetStrategyType,
},
Template: getPodTemplateSpecWithVolumes(daemonsetName),
},
}
}
func GetDaemonSetWithEnvVars(namespace string, daemonSetName string) *appsv1.DaemonSet {
return &appsv1.DaemonSet{
ObjectMeta: getObjectMeta(namespace, daemonSetName, true),
Spec: appsv1.DaemonSetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
UpdateStrategy: appsv1.DaemonSetUpdateStrategy{
Type: appsv1.RollingUpdateDaemonSetStrategyType,
},
Template: getPodTemplateSpecWithEnvVars(daemonSetName),
},
}
}
// GetStatefulSet provides statefulset for testing
func GetStatefulSet(namespace string, statefulsetName string) *v1_beta1.StatefulSet {
return &v1_beta1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: statefulsetName,
Namespace: namespace,
Labels: map[string]string{"firstLabel": "temp"},
Annotations: map[string]string{
constants.ConfigmapUpdateOnChangeAnnotation: statefulsetName,
constants.SecretUpdateOnChangeAnnotation: statefulsetName},
func GetStatefulSet(namespace string, statefulsetName string) *appsv1.StatefulSet {
return &appsv1.StatefulSet{
ObjectMeta: getObjectMeta(namespace, statefulsetName, false),
Spec: appsv1.StatefulSetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
Type: appsv1.RollingUpdateStatefulSetStrategyType,
},
Template: getPodTemplateSpecWithVolumes(statefulsetName),
},
Spec: v1_beta1.StatefulSetSpec{
UpdateStrategy: v1_beta1.StatefulSetUpdateStrategy{
Type: v1_beta1.RollingUpdateStatefulSetStrategyType,
}
}
// GetStatefulSet provides statefulset for testing
func GetStatefulSetWithEnvVar(namespace string, statefulsetName string) *appsv1.StatefulSet {
return &appsv1.StatefulSet{
ObjectMeta: getObjectMeta(namespace, statefulsetName, true),
Spec: appsv1.StatefulSetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"secondLabel": "temp"},
},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"secondLabel": "temp"},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Image: "tutum/hello-world",
Name: statefulsetName,
Env: []v1.EnvVar{
{
Name: "BUCKET_NAME",
Value: "test",
},
},
},
},
},
UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
Type: appsv1.RollingUpdateStatefulSetStrategyType,
},
Template: getPodTemplateSpecWithEnvVars(statefulsetName),
},
}
}
@@ -220,12 +580,12 @@ func GetSecretWithUpdatedLabel(namespace string, secretName string, label string
}
}
// GetResourceSHA returns the SHA value of given environment variable
func GetResourceSHA(containers []v1.Container, envar string) string {
// GetResourceSHAFromEnvVar returns the SHA value of given environment variable
func GetResourceSHAFromEnvVar(containers []v1.Container, envVar string) string {
for i := range containers {
envs := containers[i].Env
for j := range envs {
if envs[j].Name == envar {
if envs[j].Name == envVar {
return envs[j].Value
}
}
@@ -233,7 +593,29 @@ func GetResourceSHA(containers []v1.Container, envar string) string {
return ""
}
//ConvertResourceToSHA generates SHA from secret or configmap data
// GetResourceSHAFromAnnotation returns the SHA value of given environment variable
func GetResourceSHAFromAnnotation(podAnnotations map[string]string) string {
lastReloadedResourceName := fmt.Sprintf("%s/%s",
constants.ReloaderAnnotationPrefix,
constants.LastReloadedFromAnnotation,
)
annotationJson, ok := podAnnotations[lastReloadedResourceName]
if !ok {
return ""
}
var last util.ReloadSource
bytes := []byte(annotationJson)
err := json.Unmarshal(bytes, &last)
if err != nil {
return ""
}
return last.Hash
}
// ConvertResourceToSHA generates SHA from secret or configmap data
func ConvertResourceToSHA(resourceType string, namespace string, resourceName string, data string) string {
values := []string{}
if resourceType == SecretResourceType {
@@ -255,8 +637,8 @@ func ConvertResourceToSHA(resourceType string, namespace string, resourceName st
func CreateConfigMap(client kubernetes.Interface, namespace string, configmapName string, data string) (core_v1.ConfigMapInterface, error) {
logrus.Infof("Creating configmap")
configmapClient := client.CoreV1().ConfigMaps(namespace)
_, err := configmapClient.Create(GetConfigmap(namespace, configmapName, data))
time.Sleep(10 * time.Second)
_, err := configmapClient.Create(context.TODO(), GetConfigmap(namespace, configmapName, data), metav1.CreateOptions{})
time.Sleep(3 * time.Second)
return configmapClient, err
}
@@ -264,59 +646,148 @@ func CreateConfigMap(client kubernetes.Interface, namespace string, configmapNam
func CreateSecret(client kubernetes.Interface, namespace string, secretName string, data string) (core_v1.SecretInterface, error) {
logrus.Infof("Creating secret")
secretClient := client.CoreV1().Secrets(namespace)
_, err := secretClient.Create(GetSecret(namespace, secretName, data))
time.Sleep(10 * time.Second)
_, err := secretClient.Create(context.TODO(), GetSecret(namespace, secretName, data), metav1.CreateOptions{})
time.Sleep(3 * time.Second)
return secretClient, err
}
// CreateDeployment creates a deployment in given namespace and returns the Deployment
func CreateDeployment(client kubernetes.Interface, deploymentName string, namespace string) (*v1beta1.Deployment, error) {
func CreateDeployment(client kubernetes.Interface, deploymentName string, namespace string, volumeMount bool) (*appsv1.Deployment, error) {
logrus.Infof("Creating Deployment")
deploymentClient := client.ExtensionsV1beta1().Deployments(namespace)
deployment, err := deploymentClient.Create(GetDeployment(namespace, deploymentName))
time.Sleep(10 * time.Second)
deploymentClient := client.AppsV1().Deployments(namespace)
var deploymentObj *appsv1.Deployment
if volumeMount {
deploymentObj = GetDeployment(namespace, deploymentName)
} else {
deploymentObj = GetDeploymentWithEnvVars(namespace, deploymentName)
}
deployment, err := deploymentClient.Create(context.TODO(), deploymentObj, metav1.CreateOptions{})
time.Sleep(3 * time.Second)
return deployment, err
}
// CreateDeploymentConfig creates a deploymentConfig in given namespace and returns the DeploymentConfig
func CreateDeploymentConfig(client appsclient.Interface, deploymentName string, namespace string, volumeMount bool) (*openshiftv1.DeploymentConfig, error) {
logrus.Infof("Creating DeploymentConfig")
deploymentConfigsClient := client.AppsV1().DeploymentConfigs(namespace)
var deploymentConfigObj *openshiftv1.DeploymentConfig
if volumeMount {
deploymentConfigObj = GetDeploymentConfig(namespace, deploymentName)
} else {
deploymentConfigObj = GetDeploymentConfigWithEnvVars(namespace, deploymentName)
}
deploymentConfig, err := deploymentConfigsClient.Create(context.TODO(), deploymentConfigObj, metav1.CreateOptions{})
time.Sleep(5 * time.Second)
return deploymentConfig, err
}
// CreateDeploymentWithInitContainer creates a deployment in given namespace with init container and returns the Deployment
func CreateDeploymentWithInitContainer(client kubernetes.Interface, deploymentName string, namespace string, volumeMount bool) (*appsv1.Deployment, error) {
logrus.Infof("Creating Deployment")
deploymentClient := client.AppsV1().Deployments(namespace)
var deploymentObj *appsv1.Deployment
if volumeMount {
deploymentObj = GetDeploymentWithInitContainer(namespace, deploymentName)
} else {
deploymentObj = GetDeploymentWithInitContainerAndEnv(namespace, deploymentName)
}
deployment, err := deploymentClient.Create(context.TODO(), deploymentObj, metav1.CreateOptions{})
time.Sleep(3 * time.Second)
return deployment, err
}
// CreateDeploymentWithEnvVarSource creates a deployment in given namespace and returns the Deployment
func CreateDeploymentWithEnvVarSource(client kubernetes.Interface, deploymentName string, namespace string) (*appsv1.Deployment, error) {
logrus.Infof("Creating Deployment")
deploymentClient := client.AppsV1().Deployments(namespace)
deploymentObj := GetDeploymentWithEnvVarSources(namespace, deploymentName)
deployment, err := deploymentClient.Create(context.TODO(), deploymentObj, metav1.CreateOptions{})
time.Sleep(3 * time.Second)
return deployment, err
}
// CreateDeploymentWithPodAnnotations creates a deployment in given namespace and returns the Deployment
func CreateDeploymentWithPodAnnotations(client kubernetes.Interface, deploymentName string, namespace string, both bool) (*appsv1.Deployment, error) {
logrus.Infof("Creating Deployment")
deploymentClient := client.AppsV1().Deployments(namespace)
deploymentObj := GetDeploymentWithPodAnnotations(namespace, deploymentName, both)
deployment, err := deploymentClient.Create(context.TODO(), deploymentObj, metav1.CreateOptions{})
time.Sleep(3 * time.Second)
return deployment, err
}
// CreateDeploymentWithEnvVarSourceAndAnnotations returns a deployment in given
// namespace with given annotations.
func CreateDeploymentWithEnvVarSourceAndAnnotations(client kubernetes.Interface, deploymentName string, namespace string, annotations map[string]string) (*appsv1.Deployment, error) {
logrus.Infof("Creating Deployment")
deploymentClient := client.AppsV1().Deployments(namespace)
deploymentObj := GetDeploymentWithEnvVarSources(namespace, deploymentName)
deploymentObj.Annotations = annotations
deployment, err := deploymentClient.Create(context.TODO(), deploymentObj, metav1.CreateOptions{})
time.Sleep(3 * time.Second)
return deployment, err
}
// CreateDaemonSet creates a deployment in given namespace and returns the DaemonSet
func CreateDaemonSet(client kubernetes.Interface, daemonsetName string, namespace string) (*v1beta1.DaemonSet, error) {
func CreateDaemonSet(client kubernetes.Interface, daemonsetName string, namespace string, volumeMount bool) (*appsv1.DaemonSet, error) {
logrus.Infof("Creating DaemonSet")
daemonsetClient := client.ExtensionsV1beta1().DaemonSets(namespace)
daemonset, err := daemonsetClient.Create(GetDaemonSet(namespace, daemonsetName))
time.Sleep(10 * time.Second)
daemonsetClient := client.AppsV1().DaemonSets(namespace)
var daemonsetObj *appsv1.DaemonSet
if volumeMount {
daemonsetObj = GetDaemonSet(namespace, daemonsetName)
} else {
daemonsetObj = GetDaemonSetWithEnvVars(namespace, daemonsetName)
}
daemonset, err := daemonsetClient.Create(context.TODO(), daemonsetObj, metav1.CreateOptions{})
time.Sleep(3 * time.Second)
return daemonset, err
}
// CreateStatefulSet creates a deployment in given namespace and returns the StatefulSet
func CreateStatefulSet(client kubernetes.Interface, statefulsetName string, namespace string) (*v1_beta1.StatefulSet, error) {
func CreateStatefulSet(client kubernetes.Interface, statefulsetName string, namespace string, volumeMount bool) (*appsv1.StatefulSet, error) {
logrus.Infof("Creating StatefulSet")
statefulsetClient := client.AppsV1beta1().StatefulSets(namespace)
statefulset, err := statefulsetClient.Create(GetStatefulSet(namespace, statefulsetName))
time.Sleep(10 * time.Second)
statefulsetClient := client.AppsV1().StatefulSets(namespace)
var statefulsetObj *appsv1.StatefulSet
if volumeMount {
statefulsetObj = GetStatefulSet(namespace, statefulsetName)
} else {
statefulsetObj = GetStatefulSetWithEnvVar(namespace, statefulsetName)
}
statefulset, err := statefulsetClient.Create(context.TODO(), statefulsetObj, metav1.CreateOptions{})
time.Sleep(3 * time.Second)
return statefulset, err
}
// DeleteDeployment creates a deployment in given namespace and returns the error if any
func DeleteDeployment(client kubernetes.Interface, namespace string, deploymentName string) error {
logrus.Infof("Deleting Deployment")
deploymentError := client.ExtensionsV1beta1().Deployments(namespace).Delete(deploymentName, &metav1.DeleteOptions{})
time.Sleep(10 * time.Second)
deploymentError := client.AppsV1().Deployments(namespace).Delete(context.TODO(), deploymentName, metav1.DeleteOptions{})
time.Sleep(3 * time.Second)
return deploymentError
}
// DeleteDeploymentConfig deletes a deploymentConfig in given namespace and returns the error if any
func DeleteDeploymentConfig(client appsclient.Interface, namespace string, deploymentConfigName string) error {
logrus.Infof("Deleting DeploymentConfig")
deploymentConfigError := client.AppsV1().DeploymentConfigs(namespace).Delete(context.TODO(), deploymentConfigName, metav1.DeleteOptions{})
time.Sleep(3 * time.Second)
return deploymentConfigError
}
// DeleteDaemonSet creates a daemonset in given namespace and returns the error if any
func DeleteDaemonSet(client kubernetes.Interface, namespace string, daemonsetName string) error {
logrus.Infof("Deleting DaemonSet %s", daemonsetName)
daemonsetError := client.ExtensionsV1beta1().DaemonSets(namespace).Delete(daemonsetName, &metav1.DeleteOptions{})
time.Sleep(10 * time.Second)
daemonsetError := client.AppsV1().DaemonSets(namespace).Delete(context.TODO(), daemonsetName, metav1.DeleteOptions{})
time.Sleep(3 * time.Second)
return daemonsetError
}
// DeleteStatefulSet creates a statefulset in given namespace and returns the error if any
func DeleteStatefulSet(client kubernetes.Interface, namespace string, statefulsetName string) error {
logrus.Infof("Deleting StatefulSet %s", statefulsetName)
statefulsetError := client.AppsV1beta1().StatefulSets(namespace).Delete(statefulsetName, &metav1.DeleteOptions{})
time.Sleep(10 * time.Second)
statefulsetError := client.AppsV1().StatefulSets(namespace).Delete(context.TODO(), statefulsetName, metav1.DeleteOptions{})
time.Sleep(3 * time.Second)
return statefulsetError
}
@@ -329,8 +800,8 @@ func UpdateConfigMap(configmapClient core_v1.ConfigMapInterface, namespace strin
} else {
configmap = GetConfigmap(namespace, configmapName, data)
}
_, updateErr := configmapClient.Update(configmap)
time.Sleep(10 * time.Second)
_, updateErr := configmapClient.Update(context.TODO(), configmap, metav1.UpdateOptions{})
time.Sleep(3 * time.Second)
return updateErr
}
@@ -343,30 +814,29 @@ func UpdateSecret(secretClient core_v1.SecretInterface, namespace string, secret
} else {
secret = GetSecret(namespace, secretName, data)
}
_, updateErr := secretClient.Update(secret)
time.Sleep(10 * time.Second)
_, updateErr := secretClient.Update(context.TODO(), secret, metav1.UpdateOptions{})
time.Sleep(3 * time.Second)
return updateErr
}
// DeleteConfigMap deletes a configmap in given namespace and returns the error if any
func DeleteConfigMap(client kubernetes.Interface, namespace string, configmapName string) error {
logrus.Infof("Deleting configmap %q.\n", configmapName)
err := client.CoreV1().ConfigMaps(namespace).Delete(configmapName, &metav1.DeleteOptions{})
time.Sleep(10 * time.Second)
err := client.CoreV1().ConfigMaps(namespace).Delete(context.TODO(), configmapName, metav1.DeleteOptions{})
time.Sleep(3 * time.Second)
return err
}
// DeleteSecret deletes a secret in given namespace and returns the error if any
func DeleteSecret(client kubernetes.Interface, namespace string, secretName string) error {
logrus.Infof("Deleting secret %q.\n", secretName)
err := client.CoreV1().Secrets(namespace).Delete(secretName, &metav1.DeleteOptions{})
time.Sleep(10 * time.Second)
err := client.CoreV1().Secrets(namespace).Delete(context.TODO(), secretName, metav1.DeleteOptions{})
time.Sleep(3 * time.Second)
return err
}
// RandSeq generates a random sequence
func RandSeq(n int) string {
rand.Seed(time.Now().UnixNano())
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
@@ -374,28 +844,87 @@ func RandSeq(n int) string {
return string(b)
}
func VerifyResourceUpdate(client kubernetes.Interface, config util.Config, envVarPostfix string, upgradeFuncs callbacks.RollingUpgradeFuncs) bool {
items := upgradeFuncs.ItemsFunc(client, config.Namespace)
// VerifyResourceEnvVarUpdate verifies whether the rolling upgrade happened or not
func VerifyResourceEnvVarUpdate(clients kube.Clients, config util.Config, envVarPostfix string, upgradeFuncs callbacks.RollingUpgradeFuncs) bool {
items := upgradeFuncs.ItemsFunc(clients, config.Namespace)
for _, i := range items {
containers := upgradeFuncs.ContainersFunc(i)
accessor, err := meta.Accessor(i)
if err != nil {
return false
}
annotations := accessor.GetAnnotations()
// match statefulsets with the correct annotation
annotationValue := util.ToObjectMeta(i).Annotations[config.Annotation]
if annotationValue != "" {
annotationValue := annotations[config.Annotation]
searchAnnotationValue := annotations[options.AutoSearchAnnotation]
reloaderEnabledValue := annotations[options.ReloaderAutoAnnotation]
reloaderEnabled, err := strconv.ParseBool(reloaderEnabledValue)
matches := false
if err == nil && reloaderEnabled {
matches = true
} else if annotationValue != "" {
values := strings.Split(annotationValue, ",")
matches := false
for _, value := range values {
value = strings.Trim(value, " ")
if value == config.ResourceName {
matches = true
break
}
}
if matches {
envName := constants.EnvVarPrefix + util.ConvertToEnvVarName(annotationValue) + "_" + envVarPostfix
updated := GetResourceSHA(containers, envName)
} else if searchAnnotationValue == "true" {
if config.ResourceAnnotations[options.SearchMatchAnnotation] == "true" {
matches = true
}
}
if updated == config.SHAValue {
return true
}
if matches {
envName := constants.EnvVarPrefix + util.ConvertToEnvVarName(config.ResourceName) + "_" + envVarPostfix
updated := GetResourceSHAFromEnvVar(containers, envName)
if updated == config.SHAValue {
return true
}
}
}
return false
}
// VerifyResourceAnnotationUpdate verifies whether the rolling upgrade happened or not
func VerifyResourceAnnotationUpdate(clients kube.Clients, config util.Config, upgradeFuncs callbacks.RollingUpgradeFuncs) bool {
items := upgradeFuncs.ItemsFunc(clients, config.Namespace)
for _, i := range items {
podAnnotations := upgradeFuncs.PodAnnotationsFunc(i)
accessor, err := meta.Accessor(i)
if err != nil {
return false
}
annotations := accessor.GetAnnotations()
// match statefulsets with the correct annotation
annotationValue := annotations[config.Annotation]
searchAnnotationValue := annotations[options.AutoSearchAnnotation]
reloaderEnabledValue := annotations[options.ReloaderAutoAnnotation]
reloaderEnabled, err := strconv.ParseBool(reloaderEnabledValue)
matches := false
if err == nil && reloaderEnabled {
matches = true
} else if annotationValue != "" {
values := strings.Split(annotationValue, ",")
for _, value := range values {
value = strings.Trim(value, " ")
if value == config.ResourceName {
matches = true
break
}
}
} else if searchAnnotationValue == "true" {
if config.ResourceAnnotations[options.SearchMatchAnnotation] == "true" {
matches = true
}
}
if matches {
updated := GetResourceSHAFromAnnotation(podAnnotations)
if updated == config.SHAValue {
return true
}
}
}

View File

@@ -1,9 +1,41 @@
package util
import (
"github.com/stakater/Reloader/internal/pkg/constants"
"github.com/stakater/Reloader/internal/pkg/options"
v1 "k8s.io/api/core/v1"
)
//Config contains rolling upgrade configuration parameters
type Config struct {
Namespace string
ResourceName string
Annotation string
SHAValue string
Namespace string
ResourceName string
ResourceAnnotations map[string]string
Annotation string
SHAValue string
Type string
}
// GetConfigmapConfig provides utility config for configmap
func GetConfigmapConfig(configmap *v1.ConfigMap) Config {
return Config{
Namespace: configmap.Namespace,
ResourceName: configmap.Name,
ResourceAnnotations: configmap.Annotations,
Annotation: options.ConfigmapUpdateOnChangeAnnotation,
SHAValue: GetSHAfromConfigmap(configmap),
Type: constants.ConfigmapEnvVarPostfix,
}
}
// GetSecretConfig provides utility config for secret
func GetSecretConfig(secret *v1.Secret) Config {
return Config{
Namespace: secret.Namespace,
ResourceName: secret.Name,
ResourceAnnotations: secret.Annotations,
Annotation: options.SecretUpdateOnChangeAnnotation,
SHAValue: GetSHAfromSecret(secret.Data),
Type: constants.SecretEnvVarPostfix,
}
}

View File

@@ -2,6 +2,7 @@ package util
import (
"reflect"
"strconv"
"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -36,3 +37,14 @@ func ToObjectMeta(kubernetesObject interface{}) ObjectMeta {
ObjectMeta: field,
}
}
// ParseBool returns result in bool format after parsing
func ParseBool(value interface{}) bool {
if reflect.Bool == reflect.TypeOf(value).Kind() {
return value.(bool)
} else if reflect.String == reflect.TypeOf(value).Kind() {
result, _ := strconv.ParseBool(value.(string))
return result
}
return false
}

View File

@@ -0,0 +1,39 @@
package util
import "time"
type ReloadSource struct {
Type string `json:"type"`
Name string `json:"name"`
Namespace string `json:"namespace"`
Hash string `json:"hash"`
ContainerRefs []string `json:"containerRefs"`
ObservedAt int64 `json:"observedAt"`
}
func NewReloadSource(
resourceName string,
resourceNamespace string,
resourceType string,
resourceHash string,
containerRefs []string,
) ReloadSource {
return ReloadSource{
ObservedAt: time.Now().Unix(),
Name: resourceName,
Namespace: resourceNamespace,
Type: resourceType,
Hash: resourceHash,
ContainerRefs: containerRefs,
}
}
func NewReloadSourceFromConfig(config Config, containerRefs []string) ReloadSource {
return NewReloadSource(
config.ResourceName,
config.Namespace,
config.Type,
config.SHAValue,
containerRefs,
)
}

View File

@@ -2,7 +2,12 @@ package util
import (
"bytes"
"encoding/base64"
"sort"
"strings"
"github.com/stakater/Reloader/internal/pkg/crypto"
v1 "k8s.io/api/core/v1"
)
// ConvertToEnvVarName converts the given text into a usable env var
@@ -25,3 +30,37 @@ func ConvertToEnvVarName(text string) string {
}
return buffer.String()
}
func GetSHAfromConfigmap(configmap *v1.ConfigMap) string {
values := []string{}
for k, v := range configmap.Data {
values = append(values, k+"="+v)
}
for k, v := range configmap.BinaryData {
values = append(values, k+"="+base64.StdEncoding.EncodeToString(v))
}
sort.Strings(values)
return crypto.GenerateSHA(strings.Join(values, ";"))
}
func GetSHAfromSecret(data map[string][]byte) string {
values := []string{}
for k, v := range data {
values = append(values, k+"="+string(v[:]))
}
sort.Strings(values)
return crypto.GenerateSHA(strings.Join(values, ";"))
}
type List []string
type Map map[string]string
func (l *List) Contains(s string) bool {
for _, v := range *l {
if v == s {
return true
}
}
return false
}

View File

@@ -2,6 +2,8 @@ package util
import (
"testing"
v1 "k8s.io/api/core/v1"
)
func TestConvertToEnvVarName(t *testing.T) {
@@ -11,3 +13,35 @@ func TestConvertToEnvVarName(t *testing.T) {
t.Errorf("Failed to convert data into environment variable")
}
}
func TestGetHashFromConfigMap(t *testing.T) {
data := map[*v1.ConfigMap]string{
{
Data: map[string]string{"test": "test"},
}: "Only Data",
{
Data: map[string]string{"test": "test"},
BinaryData: map[string][]byte{"bintest": []byte("test")},
}: "Both Data and BinaryData",
{
BinaryData: map[string][]byte{"bintest": []byte("test")},
}: "Only BinaryData",
}
converted := map[string]string{}
for cm, cmName := range data {
converted[cmName] = GetSHAfromConfigmap(cm)
}
// Test that the has for each configmap is really unique
for cmName, cmHash := range converted {
count := 0
for _, cmHash2 := range converted {
if cmHash == cmHash2 {
count++
}
}
if count > 1 {
t.Errorf("Found duplicate hashes for %v", cmName)
}
}
}

17
okteto.yml Normal file
View File

@@ -0,0 +1,17 @@
dev:
reloader-reloader:
image: okteto/golang:1
command: bash
volumes:
- /go/pkg/
- /root/.cache/go-build/
sync:
- .:/app
forward:
- 2345:2345
workdir: /app
autocreate: true
securityContext:
capabilities:
add:
- SYS_PTRACE

View File

@@ -1,17 +1,102 @@
package kube
import (
"context"
"os"
"k8s.io/client-go/tools/clientcmd"
argorollout "github.com/argoproj/argo-rollouts/pkg/client/clientset/versioned"
appsclient "github.com/openshift/client-go/apps/clientset/versioned"
"github.com/sirupsen/logrus"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
// GetClient gets the client for k8s, if ~/.kube/config exists so get that config else incluster config
func GetClient() (*kubernetes.Clientset, error) {
// Clients struct exposes interfaces for kubernetes as well as openshift if available
type Clients struct {
KubernetesClient kubernetes.Interface
OpenshiftAppsClient appsclient.Interface
ArgoRolloutClient argorollout.Interface
}
var (
// IsOpenshift is true if environment is Openshift, it is false if environment is Kubernetes
IsOpenshift = isOpenshift()
)
// GetClients returns a `Clients` object containing both openshift and kubernetes clients with an openshift identifier
func GetClients() Clients {
client, err := GetKubernetesClient()
if err != nil {
logrus.Fatalf("Unable to create Kubernetes client error = %v", err)
}
var appsClient *appsclient.Clientset
if IsOpenshift {
appsClient, err = GetOpenshiftAppsClient()
if err != nil {
logrus.Warnf("Unable to create Openshift Apps client error = %v", err)
}
}
var rolloutClient *argorollout.Clientset
rolloutClient, err = GetArgoRolloutClient()
if err != nil {
logrus.Warnf("Unable to create ArgoRollout client error = %v", err)
}
return Clients{
KubernetesClient: client,
OpenshiftAppsClient: appsClient,
ArgoRolloutClient: rolloutClient,
}
}
func GetArgoRolloutClient() (*argorollout.Clientset, error) {
config, err := getConfig()
if err != nil {
return nil, err
}
return argorollout.NewForConfig(config)
}
func isOpenshift() bool {
client, err := GetKubernetesClient()
if err != nil {
logrus.Fatalf("Unable to create Kubernetes client error = %v", err)
}
_, err = client.RESTClient().Get().AbsPath("/apis/project.openshift.io").Do(context.TODO()).Raw()
if err == nil {
logrus.Info("Environment: Openshift")
return true
}
logrus.Info("Environment: Kubernetes")
return false
}
// GetOpenshiftAppsClient returns an Openshift Client that can query on Apps
func GetOpenshiftAppsClient() (*appsclient.Clientset, error) {
config, err := getConfig()
if err != nil {
return nil, err
}
return appsclient.NewForConfig(config)
}
// GetKubernetesClient gets the client for k8s, if ~/.kube/config exists so get that config else incluster config
func GetKubernetesClient() (*kubernetes.Clientset, error) {
config, err := getConfig()
if err != nil {
return nil, err
}
return kubernetes.NewForConfig(config)
}
func getConfig() (*rest.Config, error) {
var config *rest.Config
var err error
kubeconfigPath := os.Getenv("KUBECONFIG")
if kubeconfigPath == "" {
kubeconfigPath = os.Getenv("HOME") + "/.kube/config"
@@ -28,8 +113,6 @@ func GetClient() (*kubernetes.Clientset, error) {
return nil, err
}
}
if err != nil {
return nil, err
}
return kubernetes.NewForConfig(config)
return config, nil
}

View File

@@ -1,7 +1,7 @@
package kube
import (
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
)
@@ -9,4 +9,5 @@ import (
var ResourceMap = map[string]runtime.Object{
"configMaps": &v1.ConfigMap{},
"secrets": &v1.Secret{},
"namespaces": &v1.Namespace{},
}

6
renovate.json Normal file
View File

@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
}

View File

@@ -1,4 +0,0 @@
issues:
kind: 1
url: https://aurorasolutions.atlassian.net
project: STK

1
vocabulary Submodule

Submodule vocabulary added at 899bf2db35