Compare commits

...

48 Commits

Author SHA1 Message Date
Daniel Holbach
ca56c02e2e Merge pull request #646 from evrardjp/clarify_for_redirected_users
Display new URL for redirected users
2022-09-20 15:01:59 +02:00
Jean-Philippe Evrard
c0092171f4 Display new URL for redirected users
To add clarity, we should publish, on our old page, the
information about how to use the new helm charts.

Signed-off-by: Jean-Philippe Evrard <open-source@a.spamming.party>
2022-09-20 14:59:34 +02:00
dholbach
9f0583ba71 Publish kured-3.0.1.tgz 2022-08-20 09:11:27 +00:00
ckotzbauer
c3cca29970 Publish kured-3.0.0.tgz 2022-07-31 13:51:38 +00:00
ckotzbauer
08ba855e41 Publish kured-2.17.0.tgz 2022-07-01 15:44:53 +00:00
jackfrancis
c5d21d4e03 Publish kured-2.16.0.tgz 2022-06-29 12:50:23 +00:00
ckotzbauer
f0815759b2 Publish kured-2.15.0.tgz 2022-06-08 17:32:33 +00:00
ckotzbauer
8b983e2507 Publish kured-2.14.2.tgz 2022-05-25 04:51:50 +00:00
ckotzbauer
090b33b726 Publish kured-2.14.1.tgz 2022-05-12 06:57:59 +00:00
jackfrancis
1bc4d46483 Publish kured-2.14.0.tgz 2022-05-06 19:42:06 +00:00
ckotzbauer
14636ee333 Publish kured-2.13.0.tgz 2022-04-02 15:26:54 +00:00
ckotzbauer
aba74cb73b Publish kured-2.12.1.tgz 2022-03-29 10:07:10 +00:00
ckotzbauer
40c99fbd76 Publish kured-2.12.0.tgz 2022-03-16 10:49:00 +00:00
ckotzbauer
18e4566504 Publish kured-2.11.2.tgz 2022-01-12 06:25:36 +00:00
ckotzbauer
55c66a4751 Publish kured-2.11.1.tgz 2022-01-06 18:13:28 +00:00
ckotzbauer
fdcc8438ac Publish kured-2.11.0.tgz 2021-12-17 13:15:05 +00:00
dholbach
09c6ac3a13 Publish kured-2.10.2.tgz 2021-12-06 14:04:27 +00:00
evrardjp
bd5fd3312a Publish kured-2.10.1.tgz 2021-11-27 10:19:18 +00:00
ckotzbauer
20f61e3a13 Publish kured-2.10.0.tgz 2021-10-08 14:02:19 +00:00
ckotzbauer
dc746f5f88 Publish kured-2.9.1.tgz 2021-09-15 16:46:01 +00:00
ckotzbauer
ec79ea66d9 Publish kured-2.9.0.tgz 2021-08-06 07:39:04 +00:00
ckotzbauer
72913ee233 Publish kured-2.8.0.tgz 2021-07-26 11:19:41 +00:00
dholbach
4b1506e15d Publish kured-2.7.1.tgz 2021-07-16 07:55:58 +00:00
ckotzbauer
6f7abae29b Publish kured-2.7.0.tgz 2021-06-17 16:14:33 +00:00
ckotzbauer
9db0ef7a38 Publish kured-2.6.0.tgz 2021-05-20 11:56:16 +00:00
ckotzbauer
f13943b929 Publish kured-2.5.0.tgz 2021-05-19 17:10:18 +00:00
dholbach
db4510d21a Publish kured-2.4.3.tgz 2021-04-14 08:11:51 +00:00
dholbach
cccf89601c Publish kured-2.4.2.tgz 2021-04-06 13:01:16 +00:00
evrardjp
606cc3b935 Publish kured-2.4.1.tgz 2021-04-02 08:06:31 +00:00
dholbach
491b55acb1 Publish kured-2.4.0.tgz 2021-03-11 11:05:05 +00:00
dholbach
091028f331 Publish kured-2.3.2.tgz 2021-02-08 15:05:49 +00:00
dholbach
df0d58e3ae Publish kured-2.3.1.tgz 2021-01-11 15:39:49 +00:00
dholbach
54dfa59722 Publish kured-2.3.0.tgz 2021-01-11 14:19:17 +00:00
dholbach
5fae235d6a Publish kured-2.2.4.tgz 2021-01-11 13:54:21 +00:00
Daniel Holbach
20bc76497d Merge pull request #265 from evrardjp/remove-circle-ci
Remove circle ci configuration from gh pages
2020-12-07 16:41:41 +01:00
Jean-Philippe Evrard
ed9e8f2b35 Remove circle ci configuration from gh pages
We removed Circle CI from this repo, as we can do everything
from github actions. There is no point in keeping this
configuration here. Removing.
2020-12-07 16:37:43 +01:00
dholbach
a59b47e75f Publish kured-2.2.1.tgz 2020-11-24 14:40:37 +00:00
dholbach
feaf366ac0 Publish kured-2.2.0.tgz 2020-09-01 13:54:50 +00:00
dholbach
972bab5e60 Publish kured-2.1.1.tgz 2020-08-05 09:35:40 +00:00
dholbach
2575ab4bed Publish kured-2.0.3.tgz 2020-07-01 09:30:45 +00:00
dholbach
250e1f0f58 Publish kured-2.0.1.tgz 2020-06-30 16:32:52 +00:00
Daniel Holbach
554cf53b7b Merge pull request #160 from dholbach/add-gh-page-readme
add README explaining how to install kured from chart
2020-06-30 17:37:43 +02:00
Daniel Holbach
a415ae856f add README explaining how to install kured from chart 2020-06-30 17:37:09 +02:00
Daniel Holbach
622c1c6082 Merge pull request #159 from dholbach/filter-out-gh-pages
Don't run Circle CI on gh-pages branch
2020-06-30 13:27:17 +02:00
Daniel Holbach
8ed3e7991d Don't run Circle CI on gh-pages branch
Follow the lead of
	https://github.com/weaveworks/flagger/blob/gh-pages/.circleci/config.yml
2020-06-30 11:28:14 +02:00
Daniel Holbach
18e1a4537d add a README.md file 2020-06-30 11:17:11 +02:00
dholbach
c4287dc22b Publish kured-2.0.0.tgz 2020-06-30 08:48:58 +00:00
Daniel Holbach
bc43dacf4a Create empty gh-pages branch
We will use Github pages for publishing our helm chart via
	https://github.com/stefanprodan/helm-gh-pages
2020-06-17 12:11:14 +02:00
64 changed files with 699 additions and 1980 deletions

View File

@@ -1,26 +0,0 @@
version: 2
jobs:
build:
docker:
- image: cimg/go:1.13
steps:
- checkout
- setup_remote_docker
- deploy:
name: Build and push image
command: |
echo "$DOCKER_PASS" | docker login --username "$DOCKER_USER" --password-stdin
if [ -z "${CIRCLE_TAG}" ]; then
make publish-image
else
make VERSION="${CIRCLE_TAG}" publish-image
fi
workflows:
version: 2
build:
jobs:
- build:
filters:
tags:
only: /.*/

View File

@@ -1,16 +0,0 @@
name: "Check links"
on: [pull_request, push]
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Link Checker
id: lc
uses: peter-evans/link-checker@v1
with:
args: -r *.md *.yaml */*/*.go -x .cluster.local
- name: Fail if there were link errors
run: exit ${{ steps.lc.outputs.exit_code }}

4
.gitignore vendored
View File

@@ -1,4 +0,0 @@
cmd/kured/kured
cmd/prom-active-alerts/prom-active-alerts
vendor
build

View File

@@ -1,106 +0,0 @@
# Developing `kured`
We love contributions to `kured`, no matter if you are [helping out on
Slack][slack], reporting or triaging [issues][issues] or contributing code
to `kured`.
In any case, it will make sense to familiarise yourself with the main
[README][readme] to understand the different features and options, which is
helpful for testing. The "building" section in particular makes sense if
you are planning to contribute code.
[slack]: README.md#getting-help
[issues]: https://github.com/weaveworks/kured/issues
[readme]: README.md
## Updating k8s support
Whenever we want to update e.g. [`kubectl` in the
image](cmd/kured/Dockerfile), we need to consider if we update `client-go`
as well, some RBAC changes might be necessary too.
This is what it took to support Kubernetes 1.14:
<https://github.com/weaveworks/kured/pull/75>
That the process can be more involved that that can be seen in
<https://github.com/weaveworks/kured/commits/support-k8s-1.10>
Once you updated everything, make sure you update the support matrix on
the main [README][readme] as well.
## Release testing
Before `kured` is released, we want to make sure it still works fine on the
previous, current and next minor version of Kubernetes (with respect to the
embedded `client-go` & `kubectl`). For local testing e.g. `minikube` can be
sufficient.
Deploy kured in your test scenario, make sure you pass the right `image`,
update the e.g. `period` and `reboot-days` options, so you get immediate
results, if you login to a node and run:
```console
sudo touch /var/run/reboot-required
```
### Testing with `minikube`
A test-run with `minikube` could look like this:
```console
minikube start --vm-driver kvm2 --kubernetes-version <k8s-release>
# edit kured-ds.yaml to
# - point to new image
# - change e.g. period and reboot-days option for immediate results
minikube kubectl -- apply -f kured-rbac.yaml
minikube kubectl -- apply -f kured-ds.yaml
minikube kubectl -- logs daemonset.apps/kured -n kube-system -f
# In separate terminal
minikube ssh
sudo touch /var/run/reboot-required
minikube logs -f
```
Now check for the 'Commanding reboot' message and minikube going down.
Unfortunately as of today, you are going to run into
<https://github.com/kubernetes/minikube/issues/2874>. This means that
minikube won't come back easily. You will need to start minikube again.
Then you can check for the lock release.
If all the tests ran well, kured maintainers can reach out to the Weaveworks
team to get an upcoming `kured` release tested in the Dev environment for
real life testing.
## Publishing a new kured release
Check that `README.md` has an updated compatibility matrix and that the
url in the `kubectl` incantation (under "Installation") is updated to the
new version you want to release.
Now create the `kured-<release>-dockerhub.yaml` for e.g. `1.3.0`:
```sh
VERSION=1.3.0
MANIFEST="kured-$VERSION-dockerhub.yaml"
cat kured-rbac.yaml > "$MANIFEST"
cat kured-ds.yaml >> "$MANIFEST"
sed -i "s#docker.io/weaveworks/kured#docker.io/weaveworks/kured:$VERSION#g" "$MANIFEST"
```
The last thing you need to do is update the `image:` to point to the release
tag, e.g. `docker.io/weaveworks/kured:1.3.0`.
Now you can head to the Github UI, use the version number as tag and upload the
`kured-<release>-dockerhub.yaml` file.
### Release notes
Please describe what's new and noteworthy in the release notes, list the PRs
that landed and give a shout-out to everyone who contributed.
Please also note down on which releases the upcoming `kured` release was
tested on. (Check old release notes if you're unsure.)

191
LICENSE
View File

@@ -1,191 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2017 Weaveworks Ltd.
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 +0,0 @@
.DEFAULT: all
.PHONY: all clean image publish-image minikube-publish
DH_ORG=weaveworks
VERSION=$(shell git symbolic-ref --short HEAD)-$(shell git rev-parse --short HEAD)
SUDO=$(shell docker info >/dev/null 2>&1 || echo "sudo -E")
all: image
clean:
rm -f cmd/kured/kured
rm -rf ./build
godeps=$(shell go list -f '{{join .Deps "\n"}}' $1 | grep -v /vendor/ | xargs go list -f '{{if not .Standard}}{{ $$dep := . }}{{range .GoFiles}}{{$$dep.Dir}}/{{.}} {{end}}{{end}}')
DEPS=$(call godeps,./cmd/kured)
cmd/kured/kured: $(DEPS)
cmd/kured/kured: cmd/kured/*.go
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-X main.version=$(VERSION)" -o $@ cmd/kured/*.go
build/.image.done: cmd/kured/Dockerfile cmd/kured/kured
mkdir -p build
cp $^ build
$(SUDO) docker build -t docker.io/$(DH_ORG)/kured -f build/Dockerfile ./build
$(SUDO) docker tag docker.io/$(DH_ORG)/kured docker.io/$(DH_ORG)/kured:$(VERSION)
touch $@
image: build/.image.done
publish-image: image
$(SUDO) docker push docker.io/$(DH_ORG)/kured:$(VERSION)
minikube-publish: image
$(SUDO) docker save docker.io/$(DH_ORG)/kured | (eval $$(minikube docker-env) && docker load)

309
README.md
View File

@@ -1,307 +1,20 @@
# Kured Helm Repository
<img src="https://github.com/weaveworks/kured/raw/master/img/logo.png" align="right"/>
![Kured](https://raw.githubusercontent.com/kubereboot/kured/main/img/logo.png)
* [Introduction](#introduction)
* [Kubernetes & OS Compatibility](#kubernetes-&-os-compatibility)
* [Installation](#installation)
* [Configuration](#configuration)
* [Reboot Sentinel File & Period](#reboot-sentinel-file-&-period)
* [Setting a schedule](#setting-a-schedule)
* [Blocking Reboots via Alerts](#blocking-reboots-via-alerts)
* [Blocking Reboots via Pods](#blocking-reboots-via-pods)
* [Prometheus Metrics](#prometheus-metrics)
* [Slack Notifications](#slack-notifications)
* [Overriding Lock Configuration](#overriding-lock-configuration)
* [Operation](#operation)
* [Testing](#testing)
* [Disabling Reboots](#disabling-reboots)
* [Manual Unlock](#manual-unlock)
* [Building](#building)
* [Frequently Asked/Anticipated Questions](#frequently-askedanticipated-questions)
* [Getting Help](#getting-help)
Caution! We are currently in the middle of the move to a different github organisation.
Here is the info for the new organisation.
## Introduction
Add Kured repository to Helm repos:
Kured (KUbernetes REboot Daemon) is a Kubernetes daemonset that
performs safe automatic node reboots when the need to do so is
indicated by the package management system of the underlying OS.
* Watches for the presence of a reboot sentinel e.g. `/var/run/reboot-required`
* Utilises a lock in the API server to ensure only one node reboots at
a time
* Optionally defers reboots in the presence of active Prometheus alerts or selected pods
* Cordons & drains worker nodes before reboot, uncordoning them after
## Kubernetes & OS Compatibility
The daemon image contains versions of `k8s.io/client-go` and the
`kubectl` binary for the purposes of maintaining the lock and draining
worker nodes. Kubernetes aims to provide forwards & backwards
compatibility of one minor version between client and server:
| kured | kubectl | k8s.io/client-go | k8s.io/apimachinery | expected kubernetes compatibility |
|--------|---------|------------------|---------------------|-----------------------------------|
| master | 1.18.2 | v0.18.2 | v0.18.2 | 1.17.x, 1.18.x, 1.19.x |
| 1.4.0 | 1.17.5 | v0.17.0 | v0.17.0 | 1.16.x, 1.17.x, 1.18.x |
| 1.3.0 | 1.15.10 | v12.0.0 | release-1.15 | 1.15.x, 1.16.x, 1.17.x |
| 1.2.0 | 1.13.6 | v10.0.0 | release-1.13 | 1.12.x, 1.13.x, 1.14.x |
| 1.1.0 | 1.12.1 | v9.0.0 | release-1.12 | 1.11.x, 1.12.x, 1.13.x |
| 1.0.0 | 1.7.6 | v4.0.0 | release-1.7 | 1.6.x, 1.7.x, 1.8.x |
See the [release notes](https://github.com/weaveworks/kured/releases)
for specific version compatibility information, including which
combination have been formally tested.
Versions >=1.1.0 enter the host mount namespace to invoke
`systemctl reboot`, so should work on any systemd distribution.
## Installation
To obtain a default installation without Prometheus alerting interlock
or Slack notifications:
```
kubectl apply -f https://github.com/weaveworks/kured/releases/download/1.3.0/kured-1.3.0-dockerhub.yaml
```console
helm repo add kubereboot https://kubereboot.github.io/charts/
```
If you want to customise the installation, download the manifest and
edit it in accordance with the following section before application.
## Install Kured
## Configuration
The following arguments can be passed to kured via the daemonset pod template:
```
Flags:
--alert-filter-regexp regexp.Regexp alert names to ignore when checking for active alerts
--blocking-pod-selector stringArray label selector identifying pods whose presence should prevent reboots
--ds-name string name of daemonset on which to place lock (default "kured")
--ds-namespace string namespace containing daemonset on which to place lock (default "kube-system")
--end-time string only reboot before this time of day (default "23:59")
-h, --help help for kured
--lock-annotation string annotation in which to record locking node (default "weave.works/kured-node-lock")
--period duration reboot check period (default 1h0m0s)
--prometheus-url string Prometheus instance to probe for active alerts
--reboot-days strings only reboot on these days (default [su,mo,tu,we,th,fr,sa])
--reboot-sentinel string path to file whose existence signals need to reboot (default "/var/run/reboot-required")
--slack-channel string slack channel for reboot notfications
--slack-hook-url string slack hook URL for reboot notfications
--slack-username string slack username for reboot notfications (default "kured")
--start-time string only reboot after this time of day (default "0:00")
--time-zone string use this timezone to calculate allowed reboot time (default "UTC")
```console
helm install my-release kubereboot/kured
```
### Reboot Sentinel File & Period
By default kured checks for the existence of
`/var/run/reboot-required` every sixty minutes; you can override these
values with `--reboot-sentinel` and `--period`. Each replica of the
daemon uses a random offset derived from the period on startup so that
nodes don't all contend for the lock simultaneously.
### Setting a schedule
By default, kured will reboot any time it detects the sentinel, but this
may cause reboots during odd hours. While service disruption does not
normally occur, anything is possible and operators may want to restrict
reboots to predictable schedules. Use `--reboot-days`, `--start-time`,
`--end-time`, and `--time-zone` to set a schedule. For example, business
hours on the west coast USA can be specified with:
```
--reboot-days mon,tue,wed,thu,fri
--start-time 9am
--end-time 5pm
--time-zone America/Los_Angeles
```
Times can be formatted in numerous ways, including `5pm`, `5:00pm` `17:00`,
and `17`. `--time-zone` represents a Go `time.Location`, and can be `UTC`,
`Local`, or any entry in the standard Linux tz database.
Note that when using smaller time windows, you should consider shortening
the sentinel check period (`--period`).
### Blocking Reboots via Alerts
You may find it desirable to block automatic node reboots when there
are active alerts - you can do so by providing the URL of your
Prometheus server:
```
--prometheus-url=http://prometheus.monitoring.svc.cluster.local
```
By default the presence of *any* active (pending or firing) alerts
will block reboots, however you can ignore specific alerts:
```
--alert-filter-regexp=^(RebootRequired|AnotherBenignAlert|...$
```
See the section on Prometheus metrics for an important application of this
filter.
### Blocking Reboots via Pods
You can also block reboots of an _individual node_ when specific pods
are scheduled on it:
```
--blocking-pod-selector=runtime=long,cost=expensive
```
Since label selector strings use commas to express logical 'and', you can
specify this parameter multiple times for 'or':
```
--blocking-pod-selector=runtime=long,cost=expensive
--blocking-pod-selector=name=temperamental
```
In this case, the presence of either an (appropriately labelled) expensive long
running job or a known temperamental pod on a node will stop it rebooting.
> Try not to abuse this mechanism - it's better to strive for
> restartability where possible. If you do use it, make sure you set
> up a RebootRequired alert as described in the next section so that
> you can intervene manually if reboots are blocked for too long.
### Prometheus Metrics
Each kured pod exposes a single gauge metric (`:8080/metrics`) that
indicates the presence of the sentinel file:
```
# HELP kured_reboot_required OS requires reboot due to software updates.
# TYPE kured_reboot_required gauge
kured_reboot_required{node="ip-xxx-xxx-xxx-xxx.ec2.internal"} 0
```
The purpose of this metric is to power an alert which will summon an
operator if the cluster cannot reboot itself automatically for a
prolonged period:
```
# Alert if a reboot is required for any machines. Acts as a failsafe for the
# reboot daemon, which will not reboot nodes if there are pending alerts save
# this one.
ALERT RebootRequired
IF max(kured_reboot_required) != 0
FOR 24h
LABELS { severity="warning" }
ANNOTATIONS {
summary = "Machine(s) require being rebooted, and the reboot daemon has failed to do so for 24 hours",
impact = "Cluster nodes more vulnerable to security exploits. Eventually, no disk space left.",
description = "Machine(s) require being rebooted, probably due to kernel update.",
}
```
If you choose to employ such an alert and have configured kured to
probe for active alerts before rebooting, be sure to specify
`--alert-filter-regexp=^RebootRequired$` to avoid deadlock!
### Slack Notifications
If you specify a Slack hook via `--slack-hook-url`, kured will notify
you immediately prior to rebooting a node:
<img src="https://github.com/weaveworks/kured/raw/master/img/slack-notification.png"/>
We recommend setting `--slack-username` to be the name of the
environment, e.g. `dev` or `prod`.
### Overriding Lock Configuration
The `--ds-name` and `--ds-namespace` arguments should match the name and
namespace of the daemonset used to deploy the reboot daemon - the locking is
implemented by means of an annotation on this resource. The defaults match
the daemonset YAML provided in the repository.
Similarly `--lock-annotation` can be used to change the name of the
annotation kured will use to store the lock, but the default is almost
certainly safe.
## Operation
The example commands in this section assume that you have not
overriden the default lock annotation, daemonset name or namespace;
if you have, you will have to adjust the commands accordingly.
### Testing
You can test your configuration by provoking a reboot on a node:
```
sudo touch /var/run/reboot-required
```
### Disabling Reboots
If you need to temporarily stop kured from rebooting any nodes, you
can take the lock manually:
```
kubectl -n kube-system annotate ds kured weave.works/kured-node-lock='{"nodeID":"manual"}'
```
Don't forget to release it afterwards!
### Manual Unlock
In exceptional circumstances, such as a node experiencing a permanent
failure whilst rebooting, manual intervention may be required to
remove the cluster lock:
```
kubectl -n kube-system annotate ds kured weave.works/kured-node-lock-
```
> NB the `-` at the end of the command is important - it instructs
> `kubectl` to remove that annotation entirely.
## Building
See the [CircleCI config](.circleci/config.yml) for the preferred
version of Golang. Kured now uses [Go
Modules](https://github.com/golang/go/wiki/Modules), so build
instructions vary depending on where you have checked out the
repository:
**Building outside $GOPATH:**
```
make
```
**Building inside $GOPATH:**
```
GO111MODULE=on make
```
If you are interested in contributing code to kured, please take a look at
our [development][development] docs.
[development]: DEVELOPMENT.md
## Frequently Asked/Anticipated Questions
### Why is there no `latest` tag on Docker Hub?
Use of `latest` for production deployments is bad practice - see
[here](https://kubernetes.io/docs/concepts/configuration/overview) for
details. The manifest on `master` refers to `latest` for local
development testing with minikube only; for production use choose a
versioned manifest from the [release page](https://github.com/weaveworks/kured/releases/).
## Getting Help
If you have any questions about, feedback for or problems with `kured`:
- Invite yourself to the <a href="https://slack.weave.works/" target="_blank">Weave Users Slack</a>.
- Ask a question on the [#kured](https://weave-community.slack.com/messages/kured/) slack channel.
- [File an issue](https://github.com/weaveworks/kured/issues/new).
- Join us in [our monthly meeting](https://docs.google.com/document/d/1bsHTjHhqaaZ7yJnXF6W8c89UB_yn-OoSZEmDnIP34n8/edit#),
every fourth Wednesday of the month at 16:00 UTC.
Your feedback is always welcome!
For more details on installing Kured please see the [chart readme](https://github.com/kubereboot/charts/tree/main/charts/kured).

View File

@@ -1,7 +0,0 @@
FROM alpine:3.11
RUN apk update && apk add ca-certificates tzdata && rm -rf /var/cache/apk/*
# NB: you may need to update RBAC permissions when upgrading kubectl - see kured-rbac.yaml for details
ADD https://storage.googleapis.com/kubernetes-release/release/v1.18.2/bin/linux/amd64/kubectl /usr/bin/kubectl
RUN chmod 0755 /usr/bin/kubectl
COPY ./kured /usr/bin/kured
ENTRYPOINT ["/usr/bin/kured"]

View File

@@ -1,356 +0,0 @@
package main
import (
"context"
"fmt"
"math/rand"
"net/http"
"os"
"os/exec"
"regexp"
"time"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/weaveworks/kured/pkg/alerts"
"github.com/weaveworks/kured/pkg/daemonsetlock"
"github.com/weaveworks/kured/pkg/delaytick"
"github.com/weaveworks/kured/pkg/notifications/slack"
"github.com/weaveworks/kured/pkg/timewindow"
)
var (
version = "unreleased"
// Command line flags
period time.Duration
dsNamespace string
dsName string
lockAnnotation string
prometheusURL string
alertFilter *regexp.Regexp
rebootSentinel string
slackHookURL string
slackUsername string
slackChannel string
podSelectors []string
rebootDays []string
rebootStart string
rebootEnd string
timezone string
// Metrics
rebootRequiredGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Subsystem: "kured",
Name: "reboot_required",
Help: "OS requires reboot due to software updates.",
}, []string{"node"})
)
func init() {
prometheus.MustRegister(rebootRequiredGauge)
}
func main() {
rootCmd := &cobra.Command{
Use: "kured",
Short: "Kubernetes Reboot Daemon",
Run: root}
rootCmd.PersistentFlags().DurationVar(&period, "period", time.Minute*60,
"reboot check period")
rootCmd.PersistentFlags().StringVar(&dsNamespace, "ds-namespace", "kube-system",
"namespace containing daemonset on which to place lock")
rootCmd.PersistentFlags().StringVar(&dsName, "ds-name", "kured",
"name of daemonset on which to place lock")
rootCmd.PersistentFlags().StringVar(&lockAnnotation, "lock-annotation", "weave.works/kured-node-lock",
"annotation in which to record locking node")
rootCmd.PersistentFlags().StringVar(&prometheusURL, "prometheus-url", "",
"Prometheus instance to probe for active alerts")
rootCmd.PersistentFlags().Var(&regexpValue{&alertFilter}, "alert-filter-regexp",
"alert names to ignore when checking for active alerts")
rootCmd.PersistentFlags().StringVar(&rebootSentinel, "reboot-sentinel", "/var/run/reboot-required",
"path to file whose existence signals need to reboot")
rootCmd.PersistentFlags().StringVar(&slackHookURL, "slack-hook-url", "",
"slack hook URL for reboot notfications")
rootCmd.PersistentFlags().StringVar(&slackUsername, "slack-username", "kured",
"slack username for reboot notfications")
rootCmd.PersistentFlags().StringVar(&slackChannel, "slack-channel", "",
"slack channel for reboot notfications")
rootCmd.PersistentFlags().StringArrayVar(&podSelectors, "blocking-pod-selector", nil,
"label selector identifying pods whose presence should prevent reboots")
rootCmd.PersistentFlags().StringSliceVar(&rebootDays, "reboot-days", timewindow.EveryDay,
"schedule reboot on these days")
rootCmd.PersistentFlags().StringVar(&rebootStart, "start-time", "0:00",
"schedule reboot only after this time of day")
rootCmd.PersistentFlags().StringVar(&rebootEnd, "end-time", "23:59:59",
"schedule reboot only before this time of day")
rootCmd.PersistentFlags().StringVar(&timezone, "time-zone", "UTC",
"use this timezone for schedule inputs")
if err := rootCmd.Execute(); err != nil {
log.Fatal(err)
}
}
// newCommand creates a new Command with stdout/stderr wired to our standard logger
func newCommand(name string, arg ...string) *exec.Cmd {
cmd := exec.Command(name, arg...)
cmd.Stdout = log.NewEntry(log.StandardLogger()).
WithField("cmd", cmd.Args[0]).
WithField("std", "out").
WriterLevel(log.InfoLevel)
cmd.Stderr = log.NewEntry(log.StandardLogger()).
WithField("cmd", cmd.Args[0]).
WithField("std", "err").
WriterLevel(log.WarnLevel)
return cmd
}
func sentinelExists() bool {
// Relies on hostPID:true and privileged:true to enter host mount space
sentinelCmd := newCommand("/usr/bin/nsenter", "-m/proc/1/ns/mnt", "--", "/usr/bin/test", "-f", rebootSentinel)
if err := sentinelCmd.Run(); err != nil {
switch err := err.(type) {
case *exec.ExitError:
// We assume a non-zero exit code means 'reboot not required', but of course
// the user could have misconfigured the sentinel command or something else
// went wrong during its execution. In that case, not entering a reboot loop
// is the right thing to do, and we are logging stdout/stderr of the command
// so it should be obvious what is wrong.
return false
default:
// Something was grossly misconfigured, such as the command path being wrong.
log.Fatalf("Error invoking sentinel command: %v", err)
}
}
return true
}
func rebootRequired() bool {
if sentinelExists() {
log.Infof("Reboot required")
return true
} else {
log.Infof("Reboot not required")
return false
}
}
func rebootBlocked(client *kubernetes.Clientset, nodeID string) bool {
if prometheusURL != "" {
alertNames, err := alerts.PrometheusActiveAlerts(prometheusURL, alertFilter)
if err != nil {
log.Warnf("Reboot blocked: prometheus query error: %v", err)
return true
}
count := len(alertNames)
if count > 10 {
alertNames = append(alertNames[:10], "...")
}
if count > 0 {
log.Warnf("Reboot blocked: %d active alerts: %v", count, alertNames)
return true
}
}
fieldSelector := fmt.Sprintf("spec.nodeName=%s", nodeID)
for _, labelSelector := range podSelectors {
podList, err := client.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{
LabelSelector: labelSelector,
FieldSelector: fieldSelector,
Limit: 10})
if err != nil {
log.Warnf("Reboot blocked: pod query error: %v", err)
return true
}
if len(podList.Items) > 0 {
podNames := make([]string, 0, len(podList.Items))
for _, pod := range podList.Items {
podNames = append(podNames, pod.Name)
}
if len(podList.Continue) > 0 {
podNames = append(podNames, "...")
}
log.Warnf("Reboot blocked: matching pods: %v", podNames)
return true
}
}
return false
}
func holding(lock *daemonsetlock.DaemonSetLock, metadata interface{}) bool {
holding, err := lock.Test(metadata)
if err != nil {
log.Fatalf("Error testing lock: %v", err)
}
if holding {
log.Infof("Holding lock")
}
return holding
}
func acquire(lock *daemonsetlock.DaemonSetLock, metadata interface{}) bool {
holding, holder, err := lock.Acquire(metadata)
switch {
case err != nil:
log.Fatalf("Error acquiring lock: %v", err)
return false
case !holding:
log.Warnf("Lock already held: %v", holder)
return false
default:
log.Infof("Acquired reboot lock")
return true
}
}
func release(lock *daemonsetlock.DaemonSetLock) {
log.Infof("Releasing lock")
if err := lock.Release(); err != nil {
log.Fatalf("Error releasing lock: %v", err)
}
}
func drain(nodeID string) {
log.Infof("Draining node %s", nodeID)
if slackHookURL != "" {
if err := slack.NotifyDrain(slackHookURL, slackUsername, slackChannel, nodeID); err != nil {
log.Warnf("Error notifying slack: %v", err)
}
}
drainCmd := newCommand("/usr/bin/kubectl", "drain",
"--ignore-daemonsets", "--delete-local-data", "--force", nodeID)
if err := drainCmd.Run(); err != nil {
log.Fatalf("Error invoking drain command: %v", err)
}
}
func uncordon(nodeID string) {
log.Infof("Uncordoning node %s", nodeID)
uncordonCmd := newCommand("/usr/bin/kubectl", "uncordon", nodeID)
if err := uncordonCmd.Run(); err != nil {
log.Fatalf("Error invoking uncordon command: %v", err)
}
}
func commandReboot(nodeID string) {
log.Infof("Commanding reboot for node: %s", nodeID)
if slackHookURL != "" {
if err := slack.NotifyReboot(slackHookURL, slackUsername, slackChannel, nodeID); err != nil {
log.Warnf("Error notifying slack: %v", err)
}
}
// Relies on hostPID:true and privileged:true to enter host mount space
rebootCmd := newCommand("/usr/bin/nsenter", "-m/proc/1/ns/mnt", "/bin/systemctl", "reboot")
if err := rebootCmd.Run(); err != nil {
log.Fatalf("Error invoking reboot command: %v", err)
}
}
func maintainRebootRequiredMetric(nodeID string) {
for {
if sentinelExists() {
rebootRequiredGauge.WithLabelValues(nodeID).Set(1)
} else {
rebootRequiredGauge.WithLabelValues(nodeID).Set(0)
}
time.Sleep(time.Minute)
}
}
// nodeMeta is used to remember information across reboots
type nodeMeta struct {
Unschedulable bool `json:"unschedulable"`
}
func rebootAsRequired(nodeID string, window *timewindow.TimeWindow) {
config, err := rest.InClusterConfig()
if err != nil {
log.Fatal(err)
}
client, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal(err)
}
lock := daemonsetlock.New(client, nodeID, dsNamespace, dsName, lockAnnotation)
nodeMeta := nodeMeta{}
if holding(lock, &nodeMeta) {
if !nodeMeta.Unschedulable {
uncordon(nodeID)
}
release(lock)
}
source := rand.NewSource(time.Now().UnixNano())
tick := delaytick.New(source, period)
for _ = range tick {
if window.Contains(time.Now()) && rebootRequired() && !rebootBlocked(client, nodeID) {
node, err := client.CoreV1().Nodes().Get(context.TODO(), nodeID, metav1.GetOptions{})
if err != nil {
log.Fatal(err)
}
nodeMeta.Unschedulable = node.Spec.Unschedulable
if acquire(lock, &nodeMeta) {
if !nodeMeta.Unschedulable {
drain(nodeID)
}
commandReboot(nodeID)
for {
log.Infof("Waiting for reboot")
time.Sleep(time.Minute)
}
}
}
}
}
func root(cmd *cobra.Command, args []string) {
log.Infof("Kubernetes Reboot Daemon: %s", version)
nodeID := os.Getenv("KURED_NODE_ID")
if nodeID == "" {
log.Fatal("KURED_NODE_ID environment variable required")
}
window, err := timewindow.New(rebootDays, rebootStart, rebootEnd, timezone)
if err != nil {
log.Fatalf("Failed to build time window: %v", err)
}
log.Infof("Node ID: %s", nodeID)
log.Infof("Lock Annotation: %s/%s:%s", dsNamespace, dsName, lockAnnotation)
log.Infof("Reboot Sentinel: %s every %v", rebootSentinel, period)
log.Infof("Blocking Pod Selectors: %v", podSelectors)
log.Infof("Reboot on: %v", window)
go rebootAsRequired(nodeID, window)
go maintainRebootRequiredMetric(nodeID)
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(":8080", nil))
}

View File

@@ -1,31 +0,0 @@
package main
import (
"regexp"
)
type regexpValue struct {
value **regexp.Regexp
}
func (rev *regexpValue) String() string {
if *rev.value == nil {
return ""
}
return (*rev.value).String()
}
func (rev *regexpValue) Set(s string) error {
value, err := regexp.Compile(s)
if err != nil {
return err
}
*rev.value = value
return nil
}
func (rev *regexpValue) Type() string {
return "regexp.Regexp"
}

View File

@@ -1,23 +0,0 @@
package main
import (
"fmt"
"log"
"os"
"regexp"
"github.com/weaveworks/kured/pkg/alerts"
)
func main() {
if len(os.Args) != 3 {
log.Fatalf("USAGE: %s <prometheusURL> <filterRegexp>", os.Args[0])
}
count, err := alerts.PrometheusCountActive(os.Args[1], regexp.MustCompile(os.Args[2]))
if err != nil {
log.Fatal(err)
}
fmt.Println(count)
}

15
go.mod
View File

@@ -1,15 +0,0 @@
module github.com/weaveworks/kured
go 1.13
require (
github.com/googleapis/gnostic v0.2.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/prometheus/client_golang v0.0.0-20181230203121-fb3d5cb2ad57
github.com/prometheus/common v0.0.0-20181218105931-67670fe90761
github.com/prometheus/procfs v0.0.0-20190102135031-14fa7590c24d // indirect
github.com/sirupsen/logrus v1.2.0
github.com/spf13/cobra v0.0.0-20181127133106-d2d81d9a96e2
k8s.io/apimachinery v0.18.2
k8s.io/client-go v0.18.2
)

232
go.sum
View File

@@ -1,232 +0,0 @@
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=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
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/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/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/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
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/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.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/uuid v1.1.1/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/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
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/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
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 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
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/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/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
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 v0.0.0-20181230203121-fb3d5cb2ad57 h1:+cstagqzfjiYrs1QrmypZRndHJafhB9W3ab/zPiwl1Q=
github.com/prometheus/client_golang v0.0.0-20181230203121-fb3d5cb2ad57/go.mod h1:PS8H/EtMiYNSR3o4jWYMuyp9FkDf2ptwxn1kTerl5EM=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20181218105931-67670fe90761 h1:z6tvbDJ5OLJ48FFmnksv04a78maSTRBUIhkdHYV5Y98=
github.com/prometheus/common v0.0.0-20181218105931-67670fe90761/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190102135031-14fa7590c24d h1:iSxvUGRUGQTUgEo5+8TqMVQoH5AdaphEIjh8AnM7TPo=
github.com/prometheus/procfs v0.0.0-20190102135031-14fa7590c24d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cobra v0.0.0-20181127133106-d2d81d9a96e2 h1:gPjqutnNhLnq5t4hT2UfL06h/mvp4je4OY7Dk71vhuk=
github.com/spf13/cobra v0.0.0-20181127133106-d2d81d9a96e2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
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/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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-20181217023233-e147a9138326/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-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
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 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
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/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20190209173611-3b5209105503/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
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 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/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-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/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-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
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/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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=
k8s.io/api v0.18.0 h1:lwYk8Vt7rsVTwjRU6pzEsa9YNhThbmbocQlKvNBB4EQ=
k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8=
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
k8s.io/apimachinery v0.18.0 h1:fuPfYpk3cs1Okp/515pAf0dNhL66+8zk8RLbSX+EgAE=
k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA=
k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/client-go v0.18.0 h1:yqKw4cTUQraZK3fcVCMeSa+lqKwcjZ5wtcOIPnxQno4=
k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE=
k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

688
index.yaml Normal file
View File

@@ -0,0 +1,688 @@
apiVersion: v1
entries:
kured:
- apiVersion: v1
appVersion: 1.10.2
created: "2022-08-20T09:11:27.828539459Z"
description: A Helm chart for kured
digest: 0d69719fdec1e5c264cb0b04a849aca7452a016e85ea1caca64d3b57b402c75c
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-3.0.1.tgz
version: 3.0.1
- apiVersion: v1
appVersion: 1.10.1
created: "2022-07-31T13:51:38.928629992Z"
description: A Helm chart for kured
digest: 1b66b4183ca1d3ac66779cc5ff2e1276c2a2325c17875a85a19532e8a5022a10
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-3.0.0.tgz
version: 3.0.0
- apiVersion: v1
appVersion: 1.10.1
created: "2022-07-01T15:44:53.561402098Z"
description: A Helm chart for kured
digest: e2727a5db21ab73d8c57db5a2a3cd09793296408c0c494279f8e2afb5d52cf28
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.17.0.tgz
version: 2.17.0
- apiVersion: v1
appVersion: 1.10.0
created: "2022-06-29T12:50:23.453793995Z"
description: A Helm chart for kured
digest: 1e047a20c633e226d7f77fc4e85b33a5547ce3e2b44525b680cb3d0b89350cbd
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.16.0.tgz
version: 2.16.0
- apiVersion: v1
appVersion: 1.10.0
created: "2022-06-08T17:32:33.101479721Z"
description: A Helm chart for kured
digest: e168f38de6d44da877509c099fcad738e5fcc3b99240ded34221c7bfa7ed5d0a
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.15.0.tgz
version: 2.15.0
- apiVersion: v1
appVersion: 1.9.2
created: "2022-05-25T04:51:50.346850231Z"
description: A Helm chart for kured
digest: 48b267700a0d48ab73e4b6ace31c1c84c393959ed09c31a3ec03e170b6b4aacf
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.14.2.tgz
version: 2.14.2
- apiVersion: v1
appVersion: 1.9.2
created: "2022-05-12T06:57:59.679228473Z"
description: A Helm chart for kured
digest: 345949c01aecbc73312a8dbdd2b7b553ca1a80fc24744a17c92b3c3c990f36a2
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.14.1.tgz
version: 2.14.1
- apiVersion: v1
appVersion: 1.9.2
created: "2022-05-06T19:42:06.720738587Z"
description: A Helm chart for kured
digest: cddb002491f4d32fb418dadc3cb846b12885fa6cb8c32d0968021c11bb3b2733
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.14.0.tgz
version: 2.14.0
- apiVersion: v1
appVersion: 1.9.2
created: "2022-04-02T15:26:54.467410377Z"
description: A Helm chart for kured
digest: 76000a5c32552deab99bae1745fcb195f73f99bfcdb847a96cbcc4f833d4b641
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.13.0.tgz
version: 2.13.0
- apiVersion: v1
appVersion: 1.9.2
created: "2022-03-29T10:07:10.572530457Z"
description: A Helm chart for kured
digest: 7635175d009834464b53f92184066a2e17dffe5a9c9f7965c32ffaada570326e
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.12.1.tgz
version: 2.12.1
- apiVersion: v1
appVersion: 1.9.1
created: "2022-03-16T10:49:00.591818431Z"
description: A Helm chart for kured
digest: 5ef50be15401f068d6558e23f327333c960cd48b3d09431e56362f5da5aed84c
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.12.0.tgz
version: 2.12.0
- apiVersion: v1
appVersion: 1.9.1
created: "2022-01-12T06:25:36.587168836Z"
description: A Helm chart for kured
digest: 9f2991549faa094ffb8324abeec649d39f9d2dd915e0287e11642411a47a4c26
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.11.2.tgz
version: 2.11.2
- apiVersion: v1
appVersion: 1.9.1
created: "2022-01-06T18:13:28.526458698Z"
description: A Helm chart for kured
digest: cb9884e9968426177a39d78b437d02046bd61b019cb8f3165624560ba24a9907
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.11.1.tgz
version: 2.11.1
- apiVersion: v1
appVersion: 1.9.0
created: "2021-12-17T13:15:05.508704637Z"
description: A Helm chart for kured
digest: 125117291df9b58f7961de17d4d2d8d0b55267e2acc90ad76a2aab1fc9efea96
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.11.0.tgz
version: 2.11.0
- apiVersion: v1
appVersion: 1.8.2
created: "2021-12-06T14:04:27.615912334Z"
description: A Helm chart for kured
digest: 0527e881055b974e869e86d6bda1a5ac1a86f305dbf7f9d7ba8cc082a24f1e32
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.10.2.tgz
version: 2.10.2
- apiVersion: v1
appVersion: 1.8.1
created: "2021-11-27T10:19:18.570439253Z"
description: A Helm chart for kured
digest: 905576b23f8263dcf26da50da6c004cb266a143cca0567f0e5d5586569b8e367
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.10.1.tgz
version: 2.10.1
- apiVersion: v1
appVersion: 1.8.0
created: "2021-10-08T14:02:19.678658295Z"
description: A Helm chart for kured
digest: fff452ed6b03903cb4d5c2b7c865b7e199fc03f7ce6a5e9449115a1746c37f50
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.10.0.tgz
version: 2.10.0
- apiVersion: v1
appVersion: 1.7.0
created: "2021-09-15T16:46:01.039895438Z"
description: A Helm chart for kured
digest: 02fd3ce98b427b411bf425cbdd60567072596f3c1ca44ff3ecb17f4852cd0099
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.9.1.tgz
version: 2.9.1
- apiVersion: v1
appVersion: 1.7.0
created: "2021-08-06T07:39:04.864672062Z"
description: A Helm chart for kured
digest: ee06afc5ba1af0591ac29f1be1425517a855959112d2fa7bc185df905f793d90
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.9.0.tgz
version: 2.9.0
- apiVersion: v1
appVersion: 1.7.0
created: "2021-07-26T11:19:41.659147727Z"
description: A Helm chart for kured
digest: 68154ea2c074c0d331548b9e17f3c3246b283251eb1c5331eabb60dba168c1ed
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.8.0.tgz
version: 2.8.0
- apiVersion: v1
appVersion: 1.7.0
created: "2021-07-16T07:55:57.986831107Z"
description: A Helm chart for kured
digest: 2607eabd4c1fd308e9825f30148ee67bc066660f800c92eeaffb7a9678c5451f
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.7.1.tgz
version: 2.7.1
- apiVersion: v1
appVersion: 1.7.0
created: "2021-06-17T16:14:33.768706163Z"
description: A Helm chart for kured
digest: 85ab0f0d25a26a863bce43100dc3ad9584b6f11319ca6d320093ed33acf3bc6f
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.7.0.tgz
version: 2.7.0
- apiVersion: v1
appVersion: 1.7.0
created: "2021-05-20T11:56:16.670153606Z"
description: A Helm chart for kured
digest: b783d7acd1c19d3b12474a9e74d0bf396b5cb2c2b4984246cb1d1f8bc2c12d68
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.6.0.tgz
version: 2.6.0
- apiVersion: v1
appVersion: 1.7.0
created: "2021-05-19T17:10:18.386329817Z"
description: A Helm chart for kured
digest: d4815d495cc9476dcb6e8204e9a2791fac1f89f17a9136d3167d202be88f7000
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.5.0.tgz
version: 2.5.0
- apiVersion: v1
appVersion: 1.6.1
created: "2021-04-14T08:11:51.869402029Z"
description: A Helm chart for kured
digest: 1961e0937676e0bcb8ceb7a4973c61450d059e2d4beea78481a9323cf0b964a6
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.4.3.tgz
version: 2.4.3
- apiVersion: v1
appVersion: 1.6.1
created: "2021-04-06T13:01:16.715078451Z"
description: A Helm chart for kured
digest: 4f26e153bec10f32d120c9abb521262aba97d96fbb80b0e8829b41157b556c4b
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/main/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.4.2.tgz
version: 2.4.2
- apiVersion: v1
appVersion: 1.6.1
created: "2021-04-06T13:01:16.714161094Z"
description: A Helm chart for kured
digest: 4788a1d33a938b6c17a760d6602eb03d68c86eb6be46c50272d9ebeeee3941ae
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.4.1.tgz
version: 2.4.1
- apiVersion: v1
appVersion: 1.6.1
created: "2021-04-06T13:01:16.713214735Z"
description: A Helm chart for kured
digest: 5cb1837122133aa6022b56140fb04583f232b4199ed44fe3746a6240e9d116a2
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.4.0.tgz
version: 2.4.0
- apiVersion: v1
appVersion: 1.6.1
created: "2021-04-06T13:01:16.712224972Z"
description: A Helm chart for kured
digest: d6eed3eac12ea285716e46f8de0fc101692fc1827d6a56780976ef8f0c4d1cce
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.3.2.tgz
version: 2.3.2
- apiVersion: v1
appVersion: 1.6.1
created: "2021-04-06T13:01:16.711557431Z"
description: A Helm chart for kured
digest: 84a75e3967d13440e3a856ecfc5a2a845ce19089a8b8b8da30d3e6344d1f3c3b
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.3.1.tgz
version: 2.3.1
- apiVersion: v1
appVersion: 1.6.1
created: "2021-04-06T13:01:16.710894489Z"
description: A Helm chart for kured
digest: db5f718db2a38cc4c46b5afb41fbc4cb82ac5298388008589bb1fc321d233ca3
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.3.0.tgz
version: 2.3.0
- apiVersion: v1
appVersion: 1.5.1
created: "2021-04-06T13:01:16.709668812Z"
description: A Helm chart for kured
digest: b3a8b13a79efa56a0a94fa91976faa4916fbdab826d9f50ddf63f4d9179a36e4
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.2.4.tgz
version: 2.2.4
- apiVersion: v1
appVersion: 1.5.1
created: "2021-04-06T13:01:16.70899537Z"
description: A Helm chart for kured
digest: 47d881f78ce887567dd3513c5bf0a1c4532c34e05cd9697cc602ce9e461fd10a
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.2.1.tgz
version: 2.2.1
- apiVersion: v1
appVersion: 1.5.0
created: "2021-04-06T13:01:16.708325128Z"
description: A Helm chart for kured
digest: f1d8d83d9992346275d8ed5b4cdb84164cbeaada73b1ff11d802f0d7a38c1621
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
- email: david@davidkarlsen.com
name: davidkarlsen
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.2.0.tgz
version: 2.2.0
- apiVersion: v1
appVersion: 1.4.5
created: "2021-04-06T13:01:16.707676487Z"
description: A Helm chart for kured
digest: 5c63a1bf4aff4394afb703f44d6f20bcb0d9f79af4a89b7a1476148e5f8b0fd5
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: daniel@weave.works
name: dholbach
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.1.1.tgz
version: 2.1.1
- apiVersion: v1
appVersion: 1.4.4
created: "2021-04-06T13:01:16.707031347Z"
description: A Helm chart for kured
digest: 8ae0a2884d185ac6311d9333ba7b29c8815a2b433892bc073922c9ad5c0771bc
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: daniel@weave.works
name: dholbach
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.0.3.tgz
version: 2.0.3
- apiVersion: v1
appVersion: 1.4.3
created: "2021-04-06T13:01:16.706360205Z"
description: A Helm chart for kured
digest: 6b8057d3f8f5774ae75a57e38e63fe73ac7230871082177bd219543e03bc3981
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: daniel@weave.works
name: dholbach
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.0.1.tgz
version: 2.0.1
- apiVersion: v1
appVersion: 1.4.2
created: "2021-04-06T13:01:16.705726665Z"
description: A Helm chart for kured
digest: 3a97561f4b5ad420a9e73ca88bcfdc29f25d722195614fc797b770ff053df672
home: https://github.com/weaveworks/kured
icon: https://raw.githubusercontent.com/weaveworks/kured/master/img/logo.png
maintainers:
- email: daniel@weave.works
name: dholbach
- email: christian.kotzbauer@gmail.com
name: ckotzbauer
name: kured
sources:
- https://github.com/weaveworks/kured
urls:
- https://weaveworks.github.io/kured/kured-2.0.0.tgz
version: 2.0.0
generated: "2022-08-20T09:11:27.825605805Z"

BIN
kured-2.0.0.tgz Normal file

Binary file not shown.

BIN
kured-2.0.1.tgz Normal file

Binary file not shown.

BIN
kured-2.0.3.tgz Normal file

Binary file not shown.

BIN
kured-2.1.1.tgz Normal file

Binary file not shown.

BIN
kured-2.10.0.tgz Normal file

Binary file not shown.

BIN
kured-2.10.1.tgz Normal file

Binary file not shown.

BIN
kured-2.10.2.tgz Normal file

Binary file not shown.

BIN
kured-2.11.0.tgz Normal file

Binary file not shown.

BIN
kured-2.11.1.tgz Normal file

Binary file not shown.

BIN
kured-2.11.2.tgz Normal file

Binary file not shown.

BIN
kured-2.12.0.tgz Normal file

Binary file not shown.

BIN
kured-2.12.1.tgz Normal file

Binary file not shown.

BIN
kured-2.13.0.tgz Normal file

Binary file not shown.

BIN
kured-2.14.0.tgz Normal file

Binary file not shown.

BIN
kured-2.14.1.tgz Normal file

Binary file not shown.

BIN
kured-2.14.2.tgz Normal file

Binary file not shown.

BIN
kured-2.15.0.tgz Normal file

Binary file not shown.

BIN
kured-2.16.0.tgz Normal file

Binary file not shown.

BIN
kured-2.17.0.tgz Normal file

Binary file not shown.

BIN
kured-2.2.0.tgz Normal file

Binary file not shown.

BIN
kured-2.2.1.tgz Normal file

Binary file not shown.

BIN
kured-2.2.4.tgz Normal file

Binary file not shown.

BIN
kured-2.3.0.tgz Normal file

Binary file not shown.

BIN
kured-2.3.1.tgz Normal file

Binary file not shown.

BIN
kured-2.3.2.tgz Normal file

Binary file not shown.

BIN
kured-2.4.0.tgz Normal file

Binary file not shown.

BIN
kured-2.4.1.tgz Normal file

Binary file not shown.

BIN
kured-2.4.2.tgz Normal file

Binary file not shown.

BIN
kured-2.4.3.tgz Normal file

Binary file not shown.

BIN
kured-2.5.0.tgz Normal file

Binary file not shown.

BIN
kured-2.6.0.tgz Normal file

Binary file not shown.

BIN
kured-2.7.0.tgz Normal file

Binary file not shown.

BIN
kured-2.7.1.tgz Normal file

Binary file not shown.

BIN
kured-2.8.0.tgz Normal file

Binary file not shown.

BIN
kured-2.9.0.tgz Normal file

Binary file not shown.

BIN
kured-2.9.1.tgz Normal file

Binary file not shown.

BIN
kured-3.0.0.tgz Normal file

Binary file not shown.

BIN
kured-3.0.1.tgz Normal file

Binary file not shown.

View File

@@ -1,63 +0,0 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kured
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kured # Must match `--ds-name`
namespace: kube-system # Must match `--ds-namespace`
spec:
selector:
matchLabels:
name: kured
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
name: kured
spec:
serviceAccountName: kured
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
hostPID: true # Facilitate entering the host mount namespace via init
restartPolicy: Always
containers:
- name: kured
image: docker.io/weaveworks/kured
# If you find yourself here wondering why there is no
# :latest tag on Docker Hub,see the FAQ in the README
imagePullPolicy: IfNotPresent
securityContext:
privileged: true # Give permission to nsenter /proc/1/ns/mnt
env:
# Pass in the name of the node on which this pod is scheduled
# for use with drain/uncordon operations and lock acquisition
- name: KURED_NODE_ID
valueFrom:
fieldRef:
fieldPath: spec.nodeName
command:
- /usr/bin/kured
# - --alert-filter-regexp=^RebootRequired$
# - --blocking-pod-selector=runtime=long,cost=expensive
# - --blocking-pod-selector=name=temperamental
# - --blocking-pod-selector=...
# - --ds-name=kured
# - --ds-namespace=kube-system
# - --end-time=23:59:59
# - --lock-annotation=weave.works/kured-node-lock
# - --period=1h
# - --prometheus-url=http://prometheus.monitoring.svc.cluster.local
# - --reboot-days=sun,mon,tue,wed,thu,fri,sat
# - --reboot-sentinel=/var/run/reboot-required
# - --slack-hook-url=https://hooks.slack.com/...
# - --slack-username=prod
# - --slack-channel=alerting
# - --start-time=0:00
# - --time-zone=UTC

View File

@@ -1,63 +0,0 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kured
rules:
# Allow kured to read spec.unschedulable
# Allow kubectl to drain/uncordon
#
# NB: These permissions are tightly coupled to the bundled version of kubectl; the ones below
# match https://github.com/kubernetes/kubernetes/blob/v1.18.2/staging/src/k8s.io/kubectl/pkg/cmd/drain/drain.go
#
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["list","delete","get"]
- apiGroups: ["apps"]
resources: ["daemonsets"]
verbs: ["get"]
- apiGroups: [""]
resources: ["pods/eviction"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kured
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kured
subjects:
- kind: ServiceAccount
name: kured
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: kube-system
name: kured
rules:
# Allow kured to lock/unlock itself
- apiGroups: ["apps"]
resources: ["daemonsets"]
resourceNames: ["kured"]
verbs: ["update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: kube-system
name: kured
subjects:
- kind: ServiceAccount
namespace: kube-system
name: kured
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kured

View File

@@ -1,52 +0,0 @@
package alerts
import (
"context"
"fmt"
"regexp"
"sort"
"time"
"github.com/prometheus/client_golang/api"
"github.com/prometheus/client_golang/api/prometheus/v1"
"github.com/prometheus/common/model"
)
// Returns a list of names of active (e.g. pending or firing) alerts, filtered
// by the supplied regexp.
func PrometheusActiveAlerts(prometheusURL string, filter *regexp.Regexp) ([]string, error) {
client, err := api.NewClient(api.Config{Address: prometheusURL})
if err != nil {
return nil, err
}
queryAPI := v1.NewAPI(client)
value, err := queryAPI.Query(context.Background(), "ALERTS", time.Now())
if err != nil {
return nil, err
}
if value.Type() == model.ValVector {
if vector, ok := value.(model.Vector); ok {
activeAlertSet := make(map[string]bool)
for _, sample := range vector {
if alertName, isAlert := sample.Metric[model.AlertNameLabel]; isAlert && sample.Value != 0 {
if filter == nil || !filter.MatchString(string(alertName)) {
activeAlertSet[string(alertName)] = true
}
}
}
var activeAlerts []string
for activeAlert, _ := range activeAlertSet {
activeAlerts = append(activeAlerts, activeAlert)
}
sort.Sort(sort.StringSlice(activeAlerts))
return activeAlerts, nil
}
}
return nil, fmt.Errorf("Unexpected value type: %v", value)
}

View File

@@ -1,123 +0,0 @@
package daemonsetlock
import (
"context"
"encoding/json"
"fmt"
"time"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
type DaemonSetLock struct {
client *kubernetes.Clientset
nodeID string
namespace string
name string
annotation string
}
type lockAnnotationValue struct {
NodeID string `json:"nodeID"`
Metadata interface{} `json:"metadata,omitempty"`
}
func New(client *kubernetes.Clientset, nodeID, namespace, name, annotation string) *DaemonSetLock {
return &DaemonSetLock{client, nodeID, namespace, name, annotation}
}
func (dsl *DaemonSetLock) Acquire(metadata interface{}) (acquired bool, owner string, err error) {
for {
ds, err := dsl.client.AppsV1().DaemonSets(dsl.namespace).Get(context.TODO(), dsl.name, metav1.GetOptions{})
if err != nil {
return false, "", err
}
valueString, exists := ds.ObjectMeta.Annotations[dsl.annotation]
if exists {
value := lockAnnotationValue{}
if err := json.Unmarshal([]byte(valueString), &value); err != nil {
return false, "", err
}
return value.NodeID == dsl.nodeID, value.NodeID, nil
}
if ds.ObjectMeta.Annotations == nil {
ds.ObjectMeta.Annotations = make(map[string]string)
}
value := lockAnnotationValue{NodeID: dsl.nodeID, Metadata: metadata}
valueBytes, err := json.Marshal(&value)
if err != nil {
return false, "", err
}
ds.ObjectMeta.Annotations[dsl.annotation] = string(valueBytes)
_, err = dsl.client.AppsV1().DaemonSets(dsl.namespace).Update(context.TODO(), ds, metav1.UpdateOptions{})
if err != nil {
if se, ok := err.(*errors.StatusError); ok && se.ErrStatus.Reason == metav1.StatusReasonConflict {
// Something else updated the resource between us reading and writing - try again soon
time.Sleep(time.Second)
continue
} else {
return false, "", err
}
}
return true, dsl.nodeID, nil
}
}
func (dsl *DaemonSetLock) Test(metadata interface{}) (holding bool, err error) {
ds, err := dsl.client.AppsV1().DaemonSets(dsl.namespace).Get(context.TODO(), dsl.name, metav1.GetOptions{})
if err != nil {
return false, err
}
valueString, exists := ds.ObjectMeta.Annotations[dsl.annotation]
if exists {
value := lockAnnotationValue{Metadata: metadata}
if err := json.Unmarshal([]byte(valueString), &value); err != nil {
return false, err
}
return value.NodeID == dsl.nodeID, nil
}
return false, nil
}
func (dsl *DaemonSetLock) Release() error {
for {
ds, err := dsl.client.AppsV1().DaemonSets(dsl.namespace).Get(context.TODO(), dsl.name, metav1.GetOptions{})
if err != nil {
return err
}
valueString, exists := ds.ObjectMeta.Annotations[dsl.annotation]
if exists {
value := lockAnnotationValue{}
if err := json.Unmarshal([]byte(valueString), &value); err != nil {
return err
}
if value.NodeID != dsl.nodeID {
return fmt.Errorf("Not lock holder: %v", value.NodeID)
}
} else {
return fmt.Errorf("Lock not held")
}
delete(ds.ObjectMeta.Annotations, dsl.annotation)
_, err = dsl.client.AppsV1().DaemonSets(dsl.namespace).Update(context.TODO(), ds, metav1.UpdateOptions{})
if err != nil {
if se, ok := err.(*errors.StatusError); ok && se.ErrStatus.Reason == metav1.StatusReasonConflict {
// Something else updated the resource between us reading and writing - try again soon
time.Sleep(time.Second)
continue
} else {
return err
}
}
return nil
}
}

View File

@@ -1,22 +0,0 @@
package delaytick
import (
"math/rand"
"time"
)
// Tick regularly after an initial delay randomly distributed between d/2 and d + d/2
func New(s rand.Source, d time.Duration) <-chan time.Time {
c := make(chan time.Time)
go func() {
random := rand.New(s)
time.Sleep(time.Duration(float64(d)/2 + float64(d)*random.Float64()))
c <- time.Now()
for t := range time.Tick(d) {
c <- t
}
}()
return c
}

View File

@@ -1,52 +0,0 @@
package slack
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
var (
httpClient = &http.Client{Timeout: 5 * time.Second}
)
type body struct {
Text string `json:"text,omitempty"`
Username string `json:"username,omitempty"`
Channel string `json:"channel,omitempty"`
}
func notify(hookURL, username, channel, message string) error {
msg := body{
Text: message,
Username: username,
Channel: channel,
}
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(&msg); err != nil {
return err
}
resp, err := httpClient.Post(hookURL, "application/json", &buf)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf(resp.Status)
}
return nil
}
func NotifyDrain(hookURL, username, channel, nodeID string) error {
return notify(hookURL, username, channel, fmt.Sprintf("Draining node %s", nodeID))
}
func NotifyReboot(hookURL, username, channel, nodeID string) error {
return notify(hookURL, username, channel, fmt.Sprintf("Rebooting node %s", nodeID))
}

View File

@@ -1,91 +0,0 @@
package timewindow
import (
"fmt"
"strconv"
"strings"
"time"
)
var EveryDay = []string{"su", "mo", "tu", "we", "th", "fr", "sa"}
// dayStrings maps day strings to time.Weekdays
var dayStrings = map[string]time.Weekday{
"su": time.Sunday,
"sun": time.Sunday,
"sunday": time.Sunday,
"mo": time.Monday,
"mon": time.Monday,
"monday": time.Monday,
"tu": time.Tuesday,
"tue": time.Tuesday,
"tuesday": time.Tuesday,
"we": time.Wednesday,
"wed": time.Wednesday,
"wednesday": time.Wednesday,
"th": time.Thursday,
"thu": time.Thursday,
"thursday": time.Thursday,
"fr": time.Friday,
"fri": time.Friday,
"friday": time.Friday,
"sa": time.Saturday,
"sat": time.Saturday,
"saturday": time.Saturday,
}
type weekdays uint32
// parseWeekdays creates a set of weekdays from a string slice
func parseWeekdays(days []string) (weekdays, error) {
var result uint32
for _, day := range days {
if len(day) == 0 {
continue
}
weekday, err := parseWeekday(day)
if err != nil {
return weekdays(0), err
}
result |= 1 << uint32(weekday)
}
return weekdays(result), nil
}
// Contains returns true if the specified weekday is a member of this set.
func (w weekdays) Contains(day time.Weekday) bool {
return uint32(w)&(1<<uint32(day)) != 0
}
// String returns a string representation of the set of weekdays.
func (w weekdays) String() string {
var b strings.Builder
for i := uint32(0); i < 7; i++ {
if uint32(w)&(1<<i) != 0 {
b.WriteString(time.Weekday(i).String()[0:3])
} else {
b.WriteString("---")
}
}
return b.String()
}
func parseWeekday(day string) (time.Weekday, error) {
if n, err := strconv.Atoi(day); err == nil {
if n >= 0 && n < 7 {
return time.Weekday(n), nil
} else {
return time.Sunday, fmt.Errorf("Invalid weekday, number out of range: %s", day)
}
}
if weekday, ok := dayStrings[strings.ToLower(day)]; ok {
return weekday, nil
} else {
return time.Sunday, fmt.Errorf("Invalid weekday: %s", day)
}
}

View File

@@ -1,46 +0,0 @@
package timewindow
import (
"strings"
"testing"
)
func TestParseWeekdays(t *testing.T) {
tests := []struct {
input string
result string
}{
{"0,4", "Sun---------Thu------"},
{"su,mo,tu", "SunMonTue------------"},
{"sunday,tu,thu", "Sun---Tue---Thu------"},
{"THURSDAY", "------------Thu------"},
{"we,WED,WeDnEsDaY", "---------Wed---------"},
{"", "---------------------"},
{",,,", "---------------------"},
}
for _, tst := range tests {
res, err := parseWeekdays(strings.Split(tst.input, ","))
if err != nil {
t.Errorf("Received error for input %s: %v", tst.input, err)
} else if res.String() != tst.result {
t.Errorf("Test %s: Expected %s got %s", tst.input, tst.result, res.String())
}
}
}
func TestParseWeekdaysErrors(t *testing.T) {
tests := []string{
"15",
"-8",
"8",
"mon,tue,wed,fridayyyy",
}
for _, tst := range tests {
_, err := parseWeekdays(strings.Split(tst, ","))
if err == nil {
t.Errorf("Expected to receive error for input %s", tst)
}
}
}

View File

@@ -1,68 +0,0 @@
package timewindow
import (
"fmt"
"time"
)
// TimeWindow specifies a schedule of days and times.
type TimeWindow struct {
days weekdays
location *time.Location
startTime time.Time
endTime time.Time
}
// New creates a TimeWindow instance based on string inputs specifying a schedule.
func New(days []string, startTime, endTime, location string) (*TimeWindow, error) {
tw := &TimeWindow{}
var err error
if tw.days, err = parseWeekdays(days); err != nil {
return nil, err
}
if tw.location, err = time.LoadLocation(location); err != nil {
return nil, err
}
if tw.startTime, err = parseTime(startTime, tw.location); err != nil {
return nil, err
}
if tw.endTime, err = parseTime(endTime, tw.location); err != nil {
return nil, err
}
return tw, nil
}
// Contains determines whether the specified time is within this time window.
func (tw *TimeWindow) Contains(t time.Time) bool {
loctime := t.In(tw.location)
if !tw.days.Contains(loctime.Weekday()) {
return false
}
start := time.Date(loctime.Year(), loctime.Month(), loctime.Day(), tw.startTime.Hour(), tw.startTime.Minute(), tw.startTime.Second(), 0, tw.location)
end := time.Date(loctime.Year(), loctime.Month(), loctime.Day(), tw.endTime.Hour(), tw.endTime.Minute(), tw.endTime.Second(), 1e9-1, tw.location)
return (loctime.After(start) || loctime.Equal(start)) && (loctime.Before(end) || loctime.Equal(end))
}
// String returns a string representation of this time window.
func (tw *TimeWindow) String() string {
return fmt.Sprintf("%s between %02d:%02d and %02d:%02d %s", tw.days.String(), tw.startTime.Hour(), tw.startTime.Minute(), tw.endTime.Hour(), tw.endTime.Minute(), tw.location.String())
}
// parseTime tries to parse a time with several formats.
func parseTime(s string, loc *time.Location) (time.Time, error) {
fmts := []string{"15:04", "15:04:05", "03:04pm", "15", "03pm", "3pm"}
for _, f := range fmts {
if t, err := time.ParseInLocation(f, s, loc); err == nil {
return t, nil
}
}
return time.Now(), fmt.Errorf("Invalid time format: %s", s)
}

View File

@@ -1,60 +0,0 @@
package timewindow
import (
"strings"
"testing"
"time"
)
func TestTimeWindows(t *testing.T) {
type testcase struct {
time string
result bool
}
tests := []struct {
days string
start string
end string
loc string
cases []testcase
}{
{"mon,tue,wed,thu,fri", "9am", "5pm", "America/Los_Angeles", []testcase{
{"2019/04/04 00:49 PDT", false},
{"2019/04/05 08:59 PDT", false},
{"2019/04/05 9:01 PDT", true},
{"2019/03/31 10:00 PDT", false},
{"2019/04/04 12:00 PDT", true},
{"2019/04/04 11:59 UTC", false},
}},
{"mon,we,fri", "10:01", "11:30am", "America/Los_Angeles", []testcase{
{"2019/04/05 10:30 PDT", true},
{"2019/04/06 10:30 PDT", false},
{"2019/04/07 10:30 PDT", false},
{"2019/04/08 10:30 PDT", true},
{"2019/04/09 10:30 PDT", false},
{"2019/04/10 10:30 PDT", true},
{"2019/04/11 10:30 PDT", false},
}},
{"mo,tu,we,th,fr", "00:00", "23:59:59", "UTC", []testcase{
{"2019/04/18 00:00 UTC", true},
{"2019/04/18 23:59 UTC", true},
}},
}
for i, tst := range tests {
tw, err := New(strings.Split(tst.days, ","), tst.start, tst.end, tst.loc)
if err != nil {
t.Errorf("Test [%d] failed to create TimeWindow: %v", i, err)
}
for _, cas := range tst.cases {
tm, err := time.ParseInLocation("2006/01/02 15:04 MST", cas.time, tw.location)
if err != nil {
t.Errorf("Failed to parse time \"%s\": %v", cas.time, err)
} else if cas.result != tw.Contains(tm) {
t.Errorf("(%s) contains (%s) didn't match expected result of %v", tw.String(), cas.time, cas.result)
}
}
}
}