Skip to content

Commit e19e2a5

Browse files
committed
Call an optional webhook before killing a pod
1 parent bd9b6e8 commit e19e2a5

File tree

5 files changed

+94
-15
lines changed

5 files changed

+94
-15
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ spec:
9090
- --timezone=Europe/Berlin
9191
# exclude all pods that haven't been running for at least one hour
9292
- --minimum-age=1h
93+
# check with a webhook before killing a pod
94+
- --webhook=https://httpbin.org/post
9395
# terminate pods for real: this disables dry-run mode which is on by default
9496
# - --no-dry-run
9597
```
@@ -234,6 +236,7 @@ Use `UTC`, `Local` or pick a timezone name from the [(IANA) tz database](https:/
234236
| `--dry-run` | don't kill pods, only log what would have been done | true |
235237
| `--log-format` | specify the format of the log messages. Options are text and json | text |
236238
| `--log-caller` | include the calling function name and location in the log messages | false |
239+
| `--webhook` | filter pods by a POST webhook, if non HTTP 200 returned, exclude pod | no webhook calls |
237240

238241
## Related work
239242

chaoskube/chaoskube.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package chaoskube
22

33
import (
4+
"bytes"
45
"context"
6+
"encoding/json"
57
"errors"
68
"fmt"
79
"math/rand"
10+
"net/http"
11+
"net/url"
812
"regexp"
913
"time"
1014

@@ -63,6 +67,8 @@ type Chaoskube struct {
6367
EventRecorder record.EventRecorder
6468
// a function to retrieve the current time
6569
Now func() time.Time
70+
// Webhook
71+
Webhook url.URL
6672
}
6773

6874
var (
@@ -86,7 +92,7 @@ var (
8692
// * a logger implementing logrus.FieldLogger to send log output to
8793
// * what specific terminator to use to imbue chaos on victim pods
8894
// * whether to enable/disable dry-run mode
89-
func New(client kubernetes.Interface, labels, annotations, namespaces, namespaceLabels labels.Selector, includedPodNames, excludedPodNames *regexp.Regexp, excludedWeekdays []time.Weekday, excludedTimesOfDay []util.TimePeriod, excludedDaysOfYear []time.Time, timezone *time.Location, minimumAge time.Duration, logger log.FieldLogger, dryRun bool, terminator terminator.Terminator) *Chaoskube {
95+
func New(client kubernetes.Interface, labels, annotations, namespaces, namespaceLabels labels.Selector, includedPodNames, excludedPodNames *regexp.Regexp, excludedWeekdays []time.Weekday, excludedTimesOfDay []util.TimePeriod, excludedDaysOfYear []time.Time, timezone *time.Location, minimumAge time.Duration, logger log.FieldLogger, dryRun bool, terminator terminator.Terminator, Webhook url.URL) *Chaoskube {
9096
broadcaster := record.NewBroadcaster()
9197
broadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: client.CoreV1().Events(v1.NamespaceAll)})
9298
recorder := broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "chaoskube"})
@@ -109,6 +115,7 @@ func New(client kubernetes.Interface, labels, annotations, namespaces, namespace
109115
Terminator: terminator,
110116
EventRecorder: recorder,
111117
Now: time.Now,
118+
Webhook: Webhook,
112119
}
113120
}
114121

@@ -212,6 +219,7 @@ func (c *Chaoskube) Candidates() ([]v1.Pod, error) {
212219
pods = filterByPhase(pods, v1.PodRunning)
213220
pods = filterByMinimumAge(pods, c.MinimumAge, c.Now())
214221
pods = filterByPodName(pods, c.IncludedPodNames, c.ExcludedPodNames)
222+
pods = filterByWebhook(pods, c.Webhook)
215223

216224
return pods, nil
217225
}
@@ -409,3 +417,32 @@ func filterByPodName(pods []v1.Pod, includedPodNames, excludedPodNames *regexp.R
409417

410418
return filteredList
411419
}
420+
421+
// filterByWebhook filters pods by a POST webhook. Only pods where the webhooks returns an
422+
// HTTP 200 are returned
423+
func filterByWebhook(pods []v1.Pod, url url.URL) []v1.Pod {
424+
// return early if url is not given
425+
if url.String() == "" {
426+
return pods
427+
}
428+
429+
filteredList := []v1.Pod{}
430+
431+
for _, pod := range pods {
432+
postData := new(bytes.Buffer)
433+
err := json.NewEncoder(postData).Encode(pod)
434+
if err != nil {
435+
continue
436+
}
437+
resp, err := http.Post(url.String(), "application/json", postData)
438+
if err != nil {
439+
continue
440+
}
441+
442+
if resp.StatusCode == http.StatusOK {
443+
filteredList = append(filteredList, pod)
444+
}
445+
}
446+
447+
return filteredList
448+
}

chaoskube/chaoskube_test.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package chaoskube
33
import (
44
"context"
55
"math/rand"
6+
"net/url"
67
"regexp"
78
"testing"
89
"time"
@@ -46,13 +47,14 @@ func (suite *Suite) TestNew() {
4647
includedPodNames = regexp.MustCompile("foo")
4748
excludedPodNames = regexp.MustCompile("bar")
4849
excludedWeekdays = []time.Weekday{time.Friday}
49-
excludedTimesOfDay = []util.TimePeriod{util.TimePeriod{}}
50+
excludedTimesOfDay = []util.TimePeriod{{}}
5051
excludedDaysOfYear = []time.Time{time.Now()}
5152
minimumAge = time.Duration(42)
5253
dryRun = true
5354
terminator = terminator.NewDeletePodTerminator(client, logger, 10*time.Second)
5455
)
5556

57+
webhook, _ := url.Parse("")
5658
chaoskube := New(
5759
client,
5860
labelSelector,
@@ -69,6 +71,7 @@ func (suite *Suite) TestNew() {
6971
logger,
7072
dryRun,
7173
terminator,
74+
*webhook,
7275
)
7376
suite.Require().NotNil(chaoskube)
7477

@@ -105,6 +108,7 @@ func (suite *Suite) TestRunContextCanceled() {
105108
time.Duration(0),
106109
false,
107110
10,
111+
url.URL{},
108112
)
109113

110114
ctx, cancel := context.WithCancel(context.Background())
@@ -122,19 +126,20 @@ func (suite *Suite) TestCandidates() {
122126
labelSelector string
123127
annotationSelector string
124128
namespaceSelector string
129+
webhook string
125130
pods []map[string]string
126131
}{
127-
{"", "", "", []map[string]string{foo, bar}},
128-
{"app=foo", "", "", []map[string]string{foo}},
129-
{"app!=foo", "", "", []map[string]string{bar}},
130-
{"", "chaos=foo", "", []map[string]string{foo}},
131-
{"", "chaos!=foo", "", []map[string]string{bar}},
132-
{"", "", "default", []map[string]string{foo}},
133-
{"", "", "default,testing", []map[string]string{foo, bar}},
134-
{"", "", "!testing", []map[string]string{foo}},
135-
{"", "", "!default,!testing", []map[string]string{}},
136-
{"", "", "default,!testing", []map[string]string{foo}},
137-
{"", "", "default,!default", []map[string]string{}},
132+
{"", "", "", "", []map[string]string{foo, bar}},
133+
{"app=foo", "", "", "", []map[string]string{foo}},
134+
{"app!=foo", "", "", "", []map[string]string{bar}},
135+
{"", "chaos=foo", "", "", []map[string]string{foo}},
136+
{"", "chaos!=foo", "", "", []map[string]string{bar}},
137+
{"", "", "default", "", []map[string]string{foo}},
138+
{"", "", "default,testing", "", []map[string]string{foo, bar}},
139+
{"", "", "!testing", "", []map[string]string{foo}},
140+
{"", "", "!default,!testing", "", []map[string]string{}},
141+
{"", "", "default,!testing", "", []map[string]string{foo}},
142+
{"", "", "default,!default", "", []map[string]string{}},
138143
} {
139144
labelSelector, err := labels.Parse(tt.labelSelector)
140145
suite.Require().NoError(err)
@@ -159,6 +164,7 @@ func (suite *Suite) TestCandidates() {
159164
time.Duration(0),
160165
false,
161166
10,
167+
url.URL{},
162168
)
163169

164170
suite.assertCandidates(chaoskube, tt.pods)
@@ -203,6 +209,7 @@ func (suite *Suite) TestCandidatesNamespaceLabels() {
203209
time.Duration(0),
204210
false,
205211
10,
212+
url.URL{},
206213
)
207214

208215
suite.assertCandidates(chaoskube, tt.pods)
@@ -245,6 +252,7 @@ func (suite *Suite) TestCandidatesPodNameRegexp() {
245252
time.Duration(0),
246253
false,
247254
10,
255+
url.URL{},
248256
)
249257

250258
suite.assertCandidates(chaoskube, tt.pods)
@@ -284,6 +292,7 @@ func (suite *Suite) TestVictim() {
284292
time.Duration(0),
285293
false,
286294
10,
295+
url.URL{},
287296
)
288297

289298
suite.assertVictim(chaoskube, tt.victim)
@@ -306,6 +315,7 @@ func (suite *Suite) TestNoVictimReturnsError() {
306315
time.Duration(0),
307316
false,
308317
10,
318+
url.URL{},
309319
)
310320

311321
_, err := chaoskube.Victim()
@@ -339,6 +349,7 @@ func (suite *Suite) TestDeletePod() {
339349
time.Duration(0),
340350
tt.dryRun,
341351
10,
352+
url.URL{},
342353
)
343354

344355
victim := util.NewPod("default", "foo", v1.PodRunning)
@@ -367,6 +378,7 @@ func (suite *Suite) TestDeletePodNotFound() {
367378
time.Duration(0),
368379
false,
369380
10,
381+
url.URL{},
370382
)
371383

372384
victim := util.NewPod("default", "foo", v1.PodRunning)
@@ -597,6 +609,7 @@ func (suite *Suite) TestTerminateVictim() {
597609
time.Duration(0),
598610
false,
599611
10,
612+
url.URL{},
600613
)
601614
chaoskube.Now = tt.now
602615

@@ -626,6 +639,7 @@ func (suite *Suite) TestTerminateNoVictimLogsInfo() {
626639
time.Duration(0),
627640
false,
628641
10,
642+
url.URL{},
629643
)
630644

631645
err := chaoskube.TerminateVictim()
@@ -650,7 +664,7 @@ func (suite *Suite) assertVictim(chaoskube *Chaoskube, expected map[string]strin
650664
suite.AssertPod(victim, expected)
651665
}
652666

653-
func (suite *Suite) setupWithPods(labelSelector labels.Selector, annotations labels.Selector, namespaces labels.Selector, namespaceLabels labels.Selector, includedPodNames *regexp.Regexp, excludedPodNames *regexp.Regexp, excludedWeekdays []time.Weekday, excludedTimesOfDay []util.TimePeriod, excludedDaysOfYear []time.Time, timezone *time.Location, minimumAge time.Duration, dryRun bool, gracePeriod time.Duration) *Chaoskube {
667+
func (suite *Suite) setupWithPods(labelSelector labels.Selector, annotations labels.Selector, namespaces labels.Selector, namespaceLabels labels.Selector, includedPodNames *regexp.Regexp, excludedPodNames *regexp.Regexp, excludedWeekdays []time.Weekday, excludedTimesOfDay []util.TimePeriod, excludedDaysOfYear []time.Time, timezone *time.Location, minimumAge time.Duration, dryRun bool, gracePeriod time.Duration, webhook url.URL) *Chaoskube {
654668
chaoskube := suite.setup(
655669
labelSelector,
656670
annotations,
@@ -665,6 +679,7 @@ func (suite *Suite) setupWithPods(labelSelector labels.Selector, annotations lab
665679
minimumAge,
666680
dryRun,
667681
gracePeriod,
682+
webhook,
668683
)
669684

670685
for _, namespace := range []v1.Namespace{
@@ -689,7 +704,7 @@ func (suite *Suite) setupWithPods(labelSelector labels.Selector, annotations lab
689704
return chaoskube
690705
}
691706

692-
func (suite *Suite) setup(labelSelector labels.Selector, annotations labels.Selector, namespaces labels.Selector, namespaceLabels labels.Selector, includedPodNames *regexp.Regexp, excludedPodNames *regexp.Regexp, excludedWeekdays []time.Weekday, excludedTimesOfDay []util.TimePeriod, excludedDaysOfYear []time.Time, timezone *time.Location, minimumAge time.Duration, dryRun bool, gracePeriod time.Duration) *Chaoskube {
707+
func (suite *Suite) setup(labelSelector labels.Selector, annotations labels.Selector, namespaces labels.Selector, namespaceLabels labels.Selector, includedPodNames *regexp.Regexp, excludedPodNames *regexp.Regexp, excludedWeekdays []time.Weekday, excludedTimesOfDay []util.TimePeriod, excludedDaysOfYear []time.Time, timezone *time.Location, minimumAge time.Duration, dryRun bool, gracePeriod time.Duration, webhook url.URL) *Chaoskube {
693708
logOutput.Reset()
694709

695710
client := fake.NewSimpleClientset()
@@ -711,6 +726,7 @@ func (suite *Suite) setup(labelSelector labels.Selector, annotations labels.Sele
711726
logger,
712727
dryRun,
713728
terminator.NewDeletePodTerminator(client, nullLogger, gracePeriod),
729+
url.URL{},
714730
)
715731
}
716732

@@ -814,6 +830,7 @@ func (suite *Suite) TestMinimumAge() {
814830
tt.minimumAge,
815831
false,
816832
10,
833+
url.URL{},
817834
)
818835
chaoskube.Now = tt.now
819836

go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
1111
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
1212
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
1313
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
14+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
1415
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
1516
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1617
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -37,12 +38,14 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
3738
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
3839
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
3940
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
41+
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
4042
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
4143
github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
4244
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
4345
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
4446
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
4547
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
48+
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
4649
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
4750
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
4851
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
@@ -60,6 +63,7 @@ github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
6063
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
6164
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
6265
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
66+
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
6367
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
6468
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
6569
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
@@ -93,10 +97,12 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx
9397
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
9498
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
9599
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
100+
github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
96101
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
97102
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
98103
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
99104
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
105+
github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
100106
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
101107
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
102108
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
@@ -116,13 +122,15 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
116122
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
117123
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE=
118124
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
125+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
119126
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
120127
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
121128
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
122129
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
123130
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
124131
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006 h1:bfLnR+k0tq5Lqt6dflRLcZiz6UaXCMt3vhYJ1l4FQ80=
125132
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
133+
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
126134
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
127135
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
128136
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
@@ -138,6 +146,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
138146
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
139147
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
140148
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
149+
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
141150
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
142151
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
143152
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU=

0 commit comments

Comments
 (0)