From 78c48af7e418a54d69b5babca3100ffd4941eb71 Mon Sep 17 00:00:00 2001 From: Adrian Pascu <1521321+adipascu@users.noreply.github.com> Date: Fri, 23 Aug 2019 16:45:14 +0300 Subject: [PATCH 01/79] Fix confusing arrow direction --- docs/tutorials/azure.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/azure.md b/docs/tutorials/azure.md index 51f6d77fcf..27d8f9edd0 100644 --- a/docs/tutorials/azure.md +++ b/docs/tutorials/azure.md @@ -94,10 +94,10 @@ Create the service principal ``` bash > az ad sp create-for-rbac -n ExternalDnsServicePrincipal { - "appId": "appId GUID", <-- aadClientId value + "appId": "appId GUID", --> aadClientId value ... - "password": "password", <-- aadClientSecret value - "tenant": "AzureAD Tenant Id" <-- tenantId value + "password": "password", --> aadClientSecret value + "tenant": "AzureAD Tenant Id" --> tenantId value } ``` From 6681a3a3585ffe404a2147d4ec6a2d7ebcd2d822 Mon Sep 17 00:00:00 2001 From: Alfred Krohmer Date: Sun, 28 Apr 2019 18:03:49 +0200 Subject: [PATCH 02/79] Add support for all AWS Route53 routing policies; add additional SetIdentifier abstraction layer This adds support for all AWS Route53 routing policies, namely: * simple (default) * weighted * latency * failover * geolocation * multi value answer These routing policies allow to create multiple records with the same name, but different "SetIdentifiers". Therefor, as a prerequisite for implementing support for above routing policies, there is a new "abstraction layer" added that handles this SetIdentifier by adding a new attribute in the Endpoint struct and adding another level in the plan table. --- endpoint/endpoint.go | 9 ++- internal/testutils/endpoint.go | 8 +-- internal/testutils/endpoint_test.go | 21 +++---- plan/plan.go | 77 +++++++++++-------------- plan/plan_test.go | 66 +++++++++++++++++++++- provider/aws.go | 88 ++++++++++++++++++++++++++++- provider/aws_test.go | 22 +++++++- provider/inmemory.go | 48 +++++++++------- provider/inmemory_test.go | 35 ++++++++++-- registry/txt.go | 18 +++--- registry/txt_test.go | 38 +++++++++++++ 11 files changed, 332 insertions(+), 98 deletions(-) diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 2d292fb0d5..3c01879354 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -126,6 +126,8 @@ type Endpoint struct { Targets Targets `json:"targets,omitempty"` // RecordType type of record, e.g. CNAME, A, SRV, TXT etc RecordType string `json:"recordType,omitempty"` + // Identifier to distinguish multiple records with the same name and type (e.g. Route53 records with routing policies other than 'simple') + SetIdentifier string `json:"setIdentifier,omitempty"` // TTL for the record RecordTTL TTL `json:"recordTTL,omitempty"` // Labels stores labels defined for the Endpoint @@ -157,6 +159,11 @@ func NewEndpointWithTTL(dnsName, recordType string, ttl TTL, targets ...string) } } +func (e *Endpoint) WithSetIdentifier(setIdentifier string) *Endpoint { + e.SetIdentifier = setIdentifier + return e +} + // WithProviderSpecific attaches a key/value pair to the Endpoint and returns the Endpoint. // This can be used to pass additional data through the stages of ExternalDNS's Endpoint processing. // The assumption is that most of the time this will be provider specific metadata that doesn't @@ -182,7 +189,7 @@ func (e *Endpoint) GetProviderSpecificProperty(key string) (ProviderSpecificProp } func (e *Endpoint) String() string { - return fmt.Sprintf("%s %d IN %s %s %s", e.DNSName, e.RecordTTL, e.RecordType, e.Targets, e.ProviderSpecific) + return fmt.Sprintf("%s %d IN %s %s %s %s", e.DNSName, e.RecordTTL, e.RecordType, e.SetIdentifier, e.Targets, e.ProviderSpecific) } // DNSEndpointSpec defines the desired state of DNSEndpoint diff --git a/internal/testutils/endpoint.go b/internal/testutils/endpoint.go index b4dfa43760..98df7d2524 100644 --- a/internal/testutils/endpoint.go +++ b/internal/testutils/endpoint.go @@ -47,10 +47,10 @@ func (b byAllFields) Less(i, j int) bool { // SameEndpoint returns true if two endpoints are same // considers example.org. and example.org DNSName/Target as different endpoints func SameEndpoint(a, b *endpoint.Endpoint) bool { - return a.DNSName == b.DNSName && a.Targets.Same(b.Targets) && a.RecordType == b.RecordType && + return a.DNSName == b.DNSName && a.Targets.Same(b.Targets) && a.RecordType == b.RecordType && a.SetIdentifier == b.SetIdentifier && a.Labels[endpoint.OwnerLabelKey] == b.Labels[endpoint.OwnerLabelKey] && a.RecordTTL == b.RecordTTL && a.Labels[endpoint.ResourceLabelKey] == b.Labels[endpoint.ResourceLabelKey] && - SameProverSpecific(a.ProviderSpecific, b.ProviderSpecific) + SameProviderSpecific(a.ProviderSpecific, b.ProviderSpecific) } // SameEndpoints compares two slices of endpoints regardless of order @@ -100,7 +100,7 @@ func SamePlanChanges(a, b map[string][]*endpoint.Endpoint) bool { SameEndpoints(a["UpdateOld"], b["UpdateOld"]) && SameEndpoints(a["UpdateNew"], b["UpdateNew"]) } -// SameProverSpecific verifies that two maps contain the same string/string key/value pairs -func SameProverSpecific(a, b endpoint.ProviderSpecific) bool { +// SameProviderSpecific verifies that two maps contain the same string/string key/value pairs +func SameProviderSpecific(a, b endpoint.ProviderSpecific) bool { return reflect.DeepEqual(a, b) } diff --git a/internal/testutils/endpoint_test.go b/internal/testutils/endpoint_test.go index 2f1204fd68..3f3a2bbce1 100644 --- a/internal/testutils/endpoint_test.go +++ b/internal/testutils/endpoint_test.go @@ -40,9 +40,10 @@ func ExampleSameEndpoints() { RecordType: endpoint.RecordTypeTXT, }, { - DNSName: "abc.com", - Targets: endpoint.Targets{"1.2.3.4"}, - RecordType: endpoint.RecordTypeA, + DNSName: "abc.com", + Targets: endpoint.Targets{"1.2.3.4"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "test-set-1", }, { DNSName: "bbc.com", @@ -68,11 +69,11 @@ func ExampleSameEndpoints() { fmt.Println(ep) } // Output: - // abc.com 0 IN A 1.2.3.4 [] - // abc.com 0 IN TXT something [] - // bbc.com 0 IN CNAME foo.com [] - // cbc.com 60 IN CNAME foo.com [] - // example.org 0 IN load-balancer.org [] - // example.org 0 IN load-balancer.org [{foo bar}] - // example.org 0 IN TXT load-balancer.org [] + // abc.com 0 IN A test-set-1 1.2.3.4 [] + // abc.com 0 IN TXT something [] + // bbc.com 0 IN CNAME foo.com [] + // cbc.com 60 IN CNAME foo.com [] + // example.org 0 IN load-balancer.org [] + // example.org 0 IN load-balancer.org [{foo bar}] + // example.org 0 IN TXT load-balancer.org [] } diff --git a/plan/plan.go b/plan/plan.go index efe949be6b..7b805bc762 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -63,12 +63,12 @@ bar.com | | [->191.1.1.1, ->190.1.1.1] | = create (bar.com -> 1 "=", i.e. result of calculation relies on supplied ConflictResolver */ type planTable struct { - rows map[string]*planTableRow + rows map[string]map[string]*planTableRow resolver ConflictResolver } func newPlanTable() planTable { //TODO: make resolver configurable - return planTable{map[string]*planTableRow{}, PerResource{}} + return planTable{map[string]map[string]*planTableRow{}, PerResource{}} } // planTableRow @@ -86,52 +86,23 @@ func (t planTableRow) String() string { func (t planTable) addCurrent(e *endpoint.Endpoint) { dnsName := normalizeDNSName(e.DNSName) if _, ok := t.rows[dnsName]; !ok { - t.rows[dnsName] = &planTableRow{} + t.rows[dnsName] = make(map[string]*planTableRow) } - t.rows[dnsName].current = e + if _, ok := t.rows[dnsName][e.SetIdentifier]; !ok { + t.rows[dnsName][e.SetIdentifier] = &planTableRow{} + } + t.rows[dnsName][e.SetIdentifier].current = e } func (t planTable) addCandidate(e *endpoint.Endpoint) { dnsName := normalizeDNSName(e.DNSName) if _, ok := t.rows[dnsName]; !ok { - t.rows[dnsName] = &planTableRow{} + t.rows[dnsName] = make(map[string]*planTableRow) } - t.rows[dnsName].candidates = append(t.rows[dnsName].candidates, e) -} - -// TODO: allows record type change, which might not be supported by all dns providers -func (t planTable) getUpdates() (updateNew []*endpoint.Endpoint, updateOld []*endpoint.Endpoint) { - for _, row := range t.rows { - if row.current != nil && len(row.candidates) > 0 { //dns name is taken - update := t.resolver.ResolveUpdate(row.current, row.candidates) - // compare "update" to "current" to figure out if actual update is required - if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) || shouldUpdateProviderSpecific(update, row.current) { - inheritOwner(row.current, update) - updateNew = append(updateNew, update) - updateOld = append(updateOld, row.current) - } - continue - } + if _, ok := t.rows[dnsName][e.SetIdentifier]; !ok { + t.rows[dnsName][e.SetIdentifier] = &planTableRow{} } - return -} - -func (t planTable) getCreates() (createList []*endpoint.Endpoint) { - for _, row := range t.rows { - if row.current == nil { //dns name not taken - createList = append(createList, t.resolver.ResolveCreate(row.candidates)) - } - } - return -} - -func (t planTable) getDeletes() (deleteList []*endpoint.Endpoint) { - for _, row := range t.rows { - if row.current != nil && len(row.candidates) == 0 { - deleteList = append(deleteList, row.current) - } - } - return + t.rows[dnsName][e.SetIdentifier].candidates = append(t.rows[dnsName][e.SetIdentifier].candidates, e) } // Calculate computes the actions needed to move current state towards desired @@ -148,9 +119,29 @@ func (p *Plan) Calculate() *Plan { } changes := &Changes{} - changes.Create = t.getCreates() - changes.Delete = t.getDeletes() - changes.UpdateNew, changes.UpdateOld = t.getUpdates() + + for _, topRow := range t.rows { + for _, row := range topRow { + if row.current == nil { //dns name not taken + changes.Create = append(changes.Create, t.resolver.ResolveCreate(row.candidates)) + } + if row.current != nil && len(row.candidates) == 0 { + changes.Delete = append(changes.Delete, row.current) + } + + // TODO: allows record type change, which might not be supported by all dns providers + if row.current != nil && len(row.candidates) > 0 { //dns name is taken + update := t.resolver.ResolveUpdate(row.current, row.candidates) + // compare "update" to "current" to figure out if actual update is required + if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) || shouldUpdateProviderSpecific(update, row.current) { + inheritOwner(row.current, update) + changes.UpdateNew = append(changes.UpdateNew, update) + changes.UpdateOld = append(changes.UpdateOld, row.current) + } + continue + } + } + } for _, pol := range p.Policies { changes = pol.Apply(changes) } diff --git a/plan/plan_test.go b/plan/plan_test.go index eb742e11ab..f217768f93 100644 --- a/plan/plan_test.go +++ b/plan/plan_test.go @@ -38,6 +38,9 @@ type PlanTestSuite struct { bar127AWithProviderSpecificTrue *endpoint.Endpoint bar127AWithProviderSpecificFalse *endpoint.Endpoint bar192A *endpoint.Endpoint + multiple1 *endpoint.Endpoint + multiple2 *endpoint.Endpoint + multiple3 *endpoint.Endpoint } func (suite *PlanTestSuite) SetupTest() { @@ -138,7 +141,24 @@ func (suite *PlanTestSuite) SetupTest() { endpoint.ResourceLabelKey: "ingress/default/bar-192", }, } - + suite.multiple1 = &endpoint.Endpoint{ + DNSName: "multiple", + Targets: endpoint.Targets{"192.168.0.1"}, + RecordType: "A", + SetIdentifier: "test-set-1", + } + suite.multiple2 = &endpoint.Endpoint{ + DNSName: "multiple", + Targets: endpoint.Targets{"192.168.0.2"}, + RecordType: "A", + SetIdentifier: "test-set-1", + } + suite.multiple3 = &endpoint.Endpoint{ + DNSName: "multiple", + Targets: endpoint.Targets{"192.168.0.2"}, + RecordType: "A", + SetIdentifier: "test-set-2", + } } func (suite *PlanTestSuite) TestSyncFirstRound() { @@ -427,6 +447,50 @@ func (suite *PlanTestSuite) TestDuplicatedEndpointsForSameResourceRetain() { validateEntries(suite.T(), changes.Delete, expectedDelete) } +func (suite *PlanTestSuite) TestMultipleRecordsSameNameDifferentSetIdentifier() { + + current := []*endpoint.Endpoint{suite.multiple1} + desired := []*endpoint.Endpoint{suite.multiple2, suite.multiple3} + expectedCreate := []*endpoint.Endpoint{suite.multiple3} + expectedUpdateOld := []*endpoint.Endpoint{suite.multiple1} + expectedUpdateNew := []*endpoint.Endpoint{suite.multiple2} + expectedDelete := []*endpoint.Endpoint{} + + p := &Plan{ + Policies: []Policy{&SyncPolicy{}}, + Current: current, + Desired: desired, + } + + changes := p.Calculate().Changes + validateEntries(suite.T(), changes.Create, expectedCreate) + validateEntries(suite.T(), changes.UpdateNew, expectedUpdateNew) + validateEntries(suite.T(), changes.UpdateOld, expectedUpdateOld) + validateEntries(suite.T(), changes.Delete, expectedDelete) +} + +func (suite *PlanTestSuite) TestSetIdentifierUpdateCreatesAndDeletes() { + + current := []*endpoint.Endpoint{suite.multiple2} + desired := []*endpoint.Endpoint{suite.multiple3} + expectedCreate := []*endpoint.Endpoint{suite.multiple3} + expectedUpdateOld := []*endpoint.Endpoint{} + expectedUpdateNew := []*endpoint.Endpoint{} + expectedDelete := []*endpoint.Endpoint{suite.multiple2} + + p := &Plan{ + Policies: []Policy{&SyncPolicy{}}, + Current: current, + Desired: desired, + } + + changes := p.Calculate().Changes + validateEntries(suite.T(), changes.Create, expectedCreate) + validateEntries(suite.T(), changes.UpdateNew, expectedUpdateNew) + validateEntries(suite.T(), changes.UpdateOld, expectedUpdateOld) + validateEntries(suite.T(), changes.Delete, expectedDelete) +} + func TestPlan(t *testing.T) { suite.Run(t, new(PlanTestSuite)) } diff --git a/provider/aws.go b/provider/aws.go index 819cad6369..2ca25d648b 100644 --- a/provider/aws.go +++ b/provider/aws.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "sort" + "strconv" "strings" "time" @@ -37,7 +38,16 @@ const ( recordTTL = 300 // provider specific key that designates whether an AWS ALIAS record has the EvaluateTargetHealth // field set to true. - providerSpecificEvaluateTargetHealth = "aws/evaluate-target-health" + providerSpecificEvaluateTargetHealth = "aws/evaluate-target-health" + providerSpecificSetIdentifier = "aws/set-identifier" + providerSpecificWeight = "aws/weight" + providerSpecificRegion = "aws/region" + providerSpecificFailover = "aws/failover" + providerSpecificGeolocation = "aws/geolocation" + providerSpecificGeolocationContinentCode = "aws/geolocation-continent-code" + providerSpecificGeolocationCountryCode = "aws/geolocation-country-code" + providerSpecificGeolocationSubdivisionCode = "aws/geolocation-subdivision-code" + providerSpecificMultiValueAnswer = "aws/multi-value-answer" ) var ( @@ -245,6 +255,8 @@ func (p *AWSProvider) records(zones map[string]*route53.HostedZone) ([]*endpoint endpoints := make([]*endpoint.Endpoint, 0) f := func(resp *route53.ListResourceRecordSetsOutput, lastPage bool) (shouldContinue bool) { for _, r := range resp.ResourceRecordSets { + newEndpoints := make([]*endpoint.Endpoint, 0) + // TODO(linki, ownership): Remove once ownership system is in place. // See: https://github.com/kubernetes-incubator/external-dns/pull/122/files/74e2c3d3e237411e619aefc5aab694742001cdec#r109863370 @@ -263,7 +275,7 @@ func (p *AWSProvider) records(zones map[string]*route53.HostedZone) ([]*endpoint targets[idx] = aws.StringValue(rr.Value) } - endpoints = append(endpoints, endpoint.NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), aws.StringValue(r.Type), ttl, targets...)) + newEndpoints = append(newEndpoints, endpoint.NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), aws.StringValue(r.Type), ttl, targets...)) } if r.AliasTarget != nil { @@ -274,6 +286,37 @@ func (p *AWSProvider) records(zones map[string]*route53.HostedZone) ([]*endpoint ep := endpoint. NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), endpoint.RecordTypeCNAME, ttl, aws.StringValue(r.AliasTarget.DNSName)). WithProviderSpecific(providerSpecificEvaluateTargetHealth, fmt.Sprintf("%t", aws.BoolValue(r.AliasTarget.EvaluateTargetHealth))) + newEndpoints = append(newEndpoints, ep) + } + + for _, ep := range newEndpoints { + if r.SetIdentifier != nil { + ep.SetIdentifier = aws.StringValue(r.SetIdentifier) + if r.Weight != nil { + ep.WithProviderSpecific(providerSpecificWeight, fmt.Sprintf("%d", aws.Int64Value(r.Weight))) + } + if r.Region != nil { + ep.WithProviderSpecific(providerSpecificRegion, aws.StringValue(r.Region)) + } + if r.Failover != nil { + ep.WithProviderSpecific(providerSpecificFailover, aws.StringValue(r.Failover)) + } + if r.MultiValueAnswer != nil && aws.BoolValue(r.MultiValueAnswer) { + ep.WithProviderSpecific(providerSpecificMultiValueAnswer, "") + } + if r.GeoLocation != nil { + if r.GeoLocation.ContinentCode != nil { + ep.WithProviderSpecific(providerSpecificGeolocationContinentCode, aws.StringValue(r.GeoLocation.ContinentCode)) + } else { + if r.GeoLocation.CountryCode != nil { + ep.WithProviderSpecific(providerSpecificGeolocationCountryCode, aws.StringValue(r.GeoLocation.CountryCode)) + } + if r.GeoLocation.SubdivisionCode != nil { + ep.WithProviderSpecific(providerSpecificGeolocationSubdivisionCode, aws.StringValue(r.GeoLocation.SubdivisionCode)) + } + } + } + } endpoints = append(endpoints, ep) } } @@ -479,6 +522,47 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint, recordsCac } } + setIdentifier := endpoint.SetIdentifier + if setIdentifier != "" { + change.ResourceRecordSet.SetIdentifier = aws.String(setIdentifier) + if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificWeight); ok { + weight, err := strconv.ParseInt(prop.Value, 10, 64) + if err != nil { + log.Errorf("Failed parsing value of %s: %s: %v; using weight of 0", providerSpecificWeight, prop.Value, err) + weight = 0 + } + change.ResourceRecordSet.Weight = aws.Int64(weight) + } + if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificRegion); ok { + change.ResourceRecordSet.Region = aws.String(prop.Value) + } + if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificFailover); ok { + change.ResourceRecordSet.Failover = aws.String(prop.Value) + } + if _, ok := endpoint.GetProviderSpecificProperty(providerSpecificMultiValueAnswer); ok { + change.ResourceRecordSet.MultiValueAnswer = aws.Bool(true) + } + + var geolocation = &route53.GeoLocation{} + useGeolocation := false + if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificGeolocationContinentCode); ok { + geolocation.ContinentCode = aws.String(prop.Value) + useGeolocation = true + } else { + if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificGeolocationCountryCode); ok { + geolocation.CountryCode = aws.String(prop.Value) + useGeolocation = true + } + if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificGeolocationSubdivisionCode); ok { + geolocation.SubdivisionCode = aws.String(prop.Value) + useGeolocation = true + } + } + if useGeolocation { + change.ResourceRecordSet.GeoLocation = geolocation + } + } + return change, dualstack } diff --git a/provider/aws_test.go b/provider/aws_test.go index 898f0b2eb5..2405934022 100644 --- a/provider/aws_test.go +++ b/provider/aws_test.go @@ -184,7 +184,11 @@ func (r *Route53APIStub) ChangeResourceRecordSets(input *route53.ChangeResourceR change.ResourceRecordSet.AliasTarget.DNSName = aws.String(wildcardEscape(ensureTrailingDot(aws.StringValue(change.ResourceRecordSet.AliasTarget.DNSName)))) } - key := aws.StringValue(change.ResourceRecordSet.Name) + "::" + aws.StringValue(change.ResourceRecordSet.Type) + setId := "" + if change.ResourceRecordSet.SetIdentifier != nil { + setId = aws.StringValue(change.ResourceRecordSet.SetIdentifier) + } + key := aws.StringValue(change.ResourceRecordSet.Name) + "::" + aws.StringValue(change.ResourceRecordSet.Type) + "::" + setId switch aws.StringValue(change.Action) { case route53.ChangeActionCreate: if _, found := recordSets[key]; found { @@ -314,6 +318,13 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpoint("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpointWithTTL("list-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), endpoint.NewEndpointWithTTL("prefix-*.wildcard.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "random"), + endpoint.NewEndpointWithTTL("weight-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10"), + endpoint.NewEndpointWithTTL("weight-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20"), + endpoint.NewEndpointWithTTL("latency-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificRegion, "us-east-1"), + endpoint.NewEndpointWithTTL("failover-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificFailover, "PRIMARY"), + endpoint.NewEndpointWithTTL("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificMultiValueAnswer, ""), + endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationContinentCode, "EU"), + endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificGeolocationCountryCode, "DE"), }) records, err := provider.Records() @@ -328,6 +339,13 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpointWithTTL("list-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), endpoint.NewEndpointWithTTL("prefix-*.wildcard.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "random"), + endpoint.NewEndpointWithTTL("weight-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10"), + endpoint.NewEndpointWithTTL("weight-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20"), + endpoint.NewEndpointWithTTL("latency-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificRegion, "us-east-1"), + endpoint.NewEndpointWithTTL("failover-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificFailover, "PRIMARY"), + endpoint.NewEndpointWithTTL("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificMultiValueAnswer, ""), + endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationContinentCode, "EU"), + endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificGeolocationCountryCode, "DE"), }) } @@ -797,7 +815,7 @@ func TestAWSBatchChangeSetExceedingNameChange(t *testing.T) { } func validateEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expected []*endpoint.Endpoint) { - assert.True(t, testutils.SameEndpoints(endpoints, expected), "expected and actual endpoints don't match. %s:%s", endpoints, expected) + assert.True(t, testutils.SameEndpoints(endpoints, expected), "actual and expected endpoints don't match. %s:%s", endpoints, expected) } func validateAWSZones(t *testing.T, zones map[string]*route53.HostedZone, expected map[string]*route53.HostedZone) { diff --git a/provider/inmemory.go b/provider/inmemory.go index d480fe160c..0a16d2be02 100644 --- a/provider/inmemory.go +++ b/provider/inmemory.go @@ -131,7 +131,7 @@ func (im *InMemoryProvider) Records() ([]*endpoint.Endpoint, error) { } for _, record := range records { - ep := endpoint.NewEndpoint(record.Name, record.Type, record.Target) + ep := endpoint.NewEndpoint(record.Name, record.Type, record.Target).WithSetIdentifier(record.SetIdentifier) ep.Labels = record.Labels endpoints = append(endpoints, ep) } @@ -204,10 +204,11 @@ func convertToInMemoryRecord(endpoints []*endpoint.Endpoint) []*inMemoryRecord { records := []*inMemoryRecord{} for _, ep := range endpoints { records = append(records, &inMemoryRecord{ - Type: ep.RecordType, - Name: ep.DNSName, - Target: ep.Targets[0], - Labels: ep.Labels, + Type: ep.RecordType, + Name: ep.DNSName, + Target: ep.Targets[0], + SetIdentifier: ep.SetIdentifier, + Labels: ep.Labels, }) } return records @@ -246,10 +247,11 @@ func (f *filter) EndpointZoneID(endpoint *endpoint.Endpoint, zones map[string]st // Name - DNS name assigned to the record // Target - target of the record type inMemoryRecord struct { - Type string - Name string - Target string - Labels endpoint.Labels + Type string + SetIdentifier string + Name string + Target string + Labels endpoint.Labels } type zone map[string][]*inMemoryRecord @@ -328,15 +330,19 @@ func (c *inMemoryClient) ApplyChanges(ctx context.Context, zoneID string, change return nil } -func (c *inMemoryClient) updateMesh(mesh map[string]map[string]bool, record *inMemoryRecord) error { +func (c *inMemoryClient) updateMesh(mesh map[string]map[string]map[string]bool, record *inMemoryRecord) error { if _, exists := mesh[record.Name]; exists { - if mesh[record.Name][record.Type] { - return ErrDuplicateRecordFound + if _, exists := mesh[record.Name][record.Type]; exists { + if mesh[record.Name][record.Type][record.SetIdentifier] { + return ErrDuplicateRecordFound + } + mesh[record.Name][record.Type][record.SetIdentifier] = true + return nil } - mesh[record.Name][record.Type] = true + mesh[record.Name][record.Type] = map[string]bool{record.SetIdentifier: true} return nil } - mesh[record.Name] = map[string]bool{record.Type: true} + mesh[record.Name] = map[string]map[string]bool{record.Type: {record.SetIdentifier: true}} return nil } @@ -346,9 +352,9 @@ func (c *inMemoryClient) validateChangeBatch(zone string, changes *inMemoryChang if !ok { return ErrZoneNotFound } - mesh := map[string]map[string]bool{} + mesh := map[string]map[string]map[string]bool{} for _, newEndpoint := range changes.Create { - if c.findByType(newEndpoint.Type, curZone[newEndpoint.Name]) != nil { + if c.findByTypeAndSetIdentifier(newEndpoint.Type, newEndpoint.SetIdentifier, curZone[newEndpoint.Name]) != nil { return ErrRecordAlreadyExists } if err := c.updateMesh(mesh, newEndpoint); err != nil { @@ -356,7 +362,7 @@ func (c *inMemoryClient) validateChangeBatch(zone string, changes *inMemoryChang } } for _, updateEndpoint := range changes.UpdateNew { - if c.findByType(updateEndpoint.Type, curZone[updateEndpoint.Name]) == nil { + if c.findByTypeAndSetIdentifier(updateEndpoint.Type, updateEndpoint.SetIdentifier, curZone[updateEndpoint.Name]) == nil { return ErrRecordNotFound } if err := c.updateMesh(mesh, updateEndpoint); err != nil { @@ -364,12 +370,12 @@ func (c *inMemoryClient) validateChangeBatch(zone string, changes *inMemoryChang } } for _, updateOldEndpoint := range changes.UpdateOld { - if rec := c.findByType(updateOldEndpoint.Type, curZone[updateOldEndpoint.Name]); rec == nil || rec.Target != updateOldEndpoint.Target { + if rec := c.findByTypeAndSetIdentifier(updateOldEndpoint.Type, updateOldEndpoint.SetIdentifier, curZone[updateOldEndpoint.Name]); rec == nil || rec.Target != updateOldEndpoint.Target { return ErrRecordNotFound } } for _, deleteEndpoint := range changes.Delete { - if rec := c.findByType(deleteEndpoint.Type, curZone[deleteEndpoint.Name]); rec == nil || rec.Target != deleteEndpoint.Target { + if rec := c.findByTypeAndSetIdentifier(deleteEndpoint.Type, deleteEndpoint.SetIdentifier, curZone[deleteEndpoint.Name]); rec == nil || rec.Target != deleteEndpoint.Target { return ErrRecordNotFound } if err := c.updateMesh(mesh, deleteEndpoint); err != nil { @@ -379,9 +385,9 @@ func (c *inMemoryClient) validateChangeBatch(zone string, changes *inMemoryChang return nil } -func (c *inMemoryClient) findByType(recordType string, records []*inMemoryRecord) *inMemoryRecord { +func (c *inMemoryClient) findByTypeAndSetIdentifier(recordType, setIdentifier string, records []*inMemoryRecord) *inMemoryRecord { for _, record := range records { - if record.Type == recordType { + if record.Type == recordType && record.SetIdentifier == setIdentifier { return record } } diff --git a/provider/inmemory_test.go b/provider/inmemory_test.go index 0d61a94807..b4297dd6df 100644 --- a/provider/inmemory_test.go +++ b/provider/inmemory_test.go @@ -43,11 +43,12 @@ func TestInMemoryProvider(t *testing.T) { func testInMemoryFindByType(t *testing.T) { for _, ti := range []struct { - title string - findType string - records []*inMemoryRecord - expected *inMemoryRecord - expectedEmpty bool + title string + findType string + findSetIdentifier string + records []*inMemoryRecord + expected *inMemoryRecord + expectedEmpty bool }{ { title: "no records, empty type", @@ -112,10 +113,32 @@ func testInMemoryFindByType(t *testing.T) { Type: endpoint.RecordTypeA, }, }, + { + title: "multiple records, right type and set identifier", + findType: endpoint.RecordTypeA, + findSetIdentifier: "test-set-1", + records: []*inMemoryRecord{ + { + Type: endpoint.RecordTypeA, + SetIdentifier: "test-set-1", + }, + { + Type: endpoint.RecordTypeA, + SetIdentifier: "test-set-2", + }, + { + Type: endpoint.RecordTypeTXT, + }, + }, + expected: &inMemoryRecord{ + Type: endpoint.RecordTypeA, + SetIdentifier: "test-set-1", + }, + }, } { t.Run(ti.title, func(t *testing.T) { c := newInMemoryClient() - record := c.findByType(ti.findType, ti.records) + record := c.findByTypeAndSetIdentifier(ti.findType, ti.findSetIdentifier, ti.records) if ti.expectedEmpty { assert.Nil(t, record) } else { diff --git a/registry/txt.go b/registry/txt.go index 3305568f07..84a15040a3 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -21,6 +21,7 @@ import ( "errors" "time" + "fmt" "strings" "github.com/kubernetes-incubator/external-dns/endpoint" @@ -94,15 +95,16 @@ func (im *TXTRegistry) Records() ([]*endpoint.Endpoint, error) { if err != nil { return nil, err } - endpointDNSName := im.mapper.toEndpointName(record.DNSName) - labelMap[endpointDNSName] = labels + key := fmt.Sprintf("%s::%s", im.mapper.toEndpointName(record.DNSName), record.SetIdentifier) + labelMap[key] = labels } for _, ep := range endpoints { if ep.Labels == nil { ep.Labels = endpoint.NewLabels() } - if labels, ok := labelMap[ep.DNSName]; ok { + key := fmt.Sprintf("%s::%s", ep.DNSName, ep.SetIdentifier) + if labels, ok := labelMap[key]; ok { for k, v := range labels { ep.Labels[k] = v } @@ -132,7 +134,7 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) r.Labels = make(map[string]string) } r.Labels[endpoint.OwnerLabelKey] = im.ownerID - txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)) + txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)).WithSetIdentifier(r.SetIdentifier) filteredChanges.Create = append(filteredChanges.Create, txt) if im.cacheInterval > 0 { @@ -141,7 +143,7 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) } for _, r := range filteredChanges.Delete { - txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)) + txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)).WithSetIdentifier(r.SetIdentifier) // when we delete TXT records for which value has changed (due to new label) this would still work because // !!! TXT record value is uniquely generated from the Labels of the endpoint. Hence old TXT record can be uniquely reconstructed @@ -154,7 +156,7 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) // make sure TXT records are consistently updated as well for _, r := range filteredChanges.UpdateOld { - txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)) + txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)).WithSetIdentifier(r.SetIdentifier) // when we updateOld TXT records for which value has changed (due to new label) this would still work because // !!! TXT record value is uniquely generated from the Labels of the endpoint. Hence old TXT record can be uniquely reconstructed filteredChanges.UpdateOld = append(filteredChanges.UpdateOld, txt) @@ -166,7 +168,7 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) // make sure TXT records are consistently updated as well for _, r := range filteredChanges.UpdateNew { - txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)) + txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)).WithSetIdentifier(r.SetIdentifier) filteredChanges.UpdateNew = append(filteredChanges.UpdateNew, txt) // add new version of record to cache if im.cacheInterval > 0 { @@ -230,7 +232,7 @@ func (im *TXTRegistry) removeFromCache(ep *endpoint.Endpoint) { } for i, e := range im.recordsCache { - if e.DNSName == ep.DNSName && e.RecordType == ep.RecordType && e.Targets.Same(ep.Targets) { + if e.DNSName == ep.DNSName && e.RecordType == ep.RecordType && e.SetIdentifier == ep.SetIdentifier && e.Targets.Same(ep.Targets) { // We found a match delete the endpoint from the cache. im.recordsCache = append(im.recordsCache[:i], im.recordsCache[i+1:]...) return diff --git a/registry/txt_test.go b/registry/txt_test.go index 6f7cf7db78..e11378c958 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -80,6 +80,10 @@ func testTXTRegistryRecordsPrefixed(t *testing.T) { newEndpointWithOwner("TxT.tar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner-2\"", endpoint.RecordTypeTXT, ""), // case-insensitive TXT prefix newEndpointWithOwner("foobar.test-zone.example.org", "foobar.loadbalancer.com", endpoint.RecordTypeCNAME, ""), newEndpointWithOwner("foobar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newEndpointWithOwner("multiple.test-zone.example.org", "lb1.loadbalancer.com", endpoint.RecordTypeCNAME, "").WithSetIdentifier("test-set-1"), + newEndpointWithOwner("multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-1"), + newEndpointWithOwner("multiple.test-zone.example.org", "lb2.loadbalancer.com", endpoint.RecordTypeCNAME, "").WithSetIdentifier("test-set-2"), + newEndpointWithOwner("multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"), }, }) expectedRecords := []*endpoint.Endpoint{ @@ -134,6 +138,24 @@ func testTXTRegistryRecordsPrefixed(t *testing.T) { endpoint.OwnerLabelKey: "", }, }, + { + DNSName: "multiple.test-zone.example.org", + Targets: endpoint.Targets{"lb1.loadbalancer.com"}, + SetIdentifier: "test-set-1", + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "multiple.test-zone.example.org", + Targets: endpoint.Targets{"lb2.loadbalancer.com"}, + SetIdentifier: "test-set-2", + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, } r, _ := NewTXTRegistry(p, "txt.", "owner", time.Hour) @@ -246,6 +268,10 @@ func testTXTRegistryApplyChangesWithPrefix(t *testing.T) { newEndpointWithOwner("txt.tar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), newEndpointWithOwner("foobar.test-zone.example.org", "foobar.loadbalancer.com", endpoint.RecordTypeCNAME, ""), newEndpointWithOwner("txt.foobar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newEndpointWithOwner("multiple.test-zone.example.org", "lb1.loadbalancer.com", endpoint.RecordTypeCNAME, "").WithSetIdentifier("test-set-1"), + newEndpointWithOwner("txt.multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-1"), + newEndpointWithOwner("multiple.test-zone.example.org", "lb2.loadbalancer.com", endpoint.RecordTypeCNAME, "").WithSetIdentifier("test-set-2"), + newEndpointWithOwner("txt.multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"), }, }) r, _ := NewTXTRegistry(p, "txt.", "owner", time.Hour) @@ -253,33 +279,45 @@ func testTXTRegistryApplyChangesWithPrefix(t *testing.T) { changes := &plan.Changes{ Create: []*endpoint.Endpoint{ newEndpointWithOwnerResource("new-record-1.test-zone.example.org", "new-loadbalancer-1.lb.com", "", "", "ingress/default/my-ingress"), + newEndpointWithOwnerResource("multiple.test-zone.example.org", "lb3.loadbalancer.com", "", "", "ingress/default/my-ingress").WithSetIdentifier("test-set-3"), }, Delete: []*endpoint.Endpoint{ newEndpointWithOwner("foobar.test-zone.example.org", "foobar.loadbalancer.com", endpoint.RecordTypeCNAME, "owner"), + newEndpointWithOwner("multiple.test-zone.example.org", "lb1.loadbalancer.com", endpoint.RecordTypeCNAME, "owner").WithSetIdentifier("test-set-1"), }, UpdateNew: []*endpoint.Endpoint{ newEndpointWithOwnerResource("tar.test-zone.example.org", "new-tar.loadbalancer.com", endpoint.RecordTypeCNAME, "owner", "ingress/default/my-ingress-2"), + newEndpointWithOwnerResource("multiple.test-zone.example.org", "new.loadbalancer.com", endpoint.RecordTypeCNAME, "owner", "ingress/default/my-ingress-2").WithSetIdentifier("test-set-2"), }, UpdateOld: []*endpoint.Endpoint{ newEndpointWithOwner("tar.test-zone.example.org", "tar.loadbalancer.com", endpoint.RecordTypeCNAME, "owner"), + newEndpointWithOwner("multiple.test-zone.example.org", "lb2.loadbalancer.com", endpoint.RecordTypeCNAME, "owner").WithSetIdentifier("test-set-2"), }, } expected := &plan.Changes{ Create: []*endpoint.Endpoint{ newEndpointWithOwnerResource("new-record-1.test-zone.example.org", "new-loadbalancer-1.lb.com", "", "owner", "ingress/default/my-ingress"), newEndpointWithOwner("txt.new-record-1.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner,external-dns/resource=ingress/default/my-ingress\"", endpoint.RecordTypeTXT, ""), + newEndpointWithOwnerResource("multiple.test-zone.example.org", "lb3.loadbalancer.com", "", "owner", "ingress/default/my-ingress").WithSetIdentifier("test-set-3"), + newEndpointWithOwner("txt.multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner,external-dns/resource=ingress/default/my-ingress\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-3"), }, Delete: []*endpoint.Endpoint{ newEndpointWithOwner("foobar.test-zone.example.org", "foobar.loadbalancer.com", endpoint.RecordTypeCNAME, "owner"), newEndpointWithOwner("txt.foobar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newEndpointWithOwner("multiple.test-zone.example.org", "lb1.loadbalancer.com", endpoint.RecordTypeCNAME, "owner").WithSetIdentifier("test-set-1"), + newEndpointWithOwner("txt.multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-1"), }, UpdateNew: []*endpoint.Endpoint{ newEndpointWithOwnerResource("tar.test-zone.example.org", "new-tar.loadbalancer.com", endpoint.RecordTypeCNAME, "owner", "ingress/default/my-ingress-2"), newEndpointWithOwner("txt.tar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner,external-dns/resource=ingress/default/my-ingress-2\"", endpoint.RecordTypeTXT, ""), + newEndpointWithOwnerResource("multiple.test-zone.example.org", "new.loadbalancer.com", endpoint.RecordTypeCNAME, "owner", "ingress/default/my-ingress-2").WithSetIdentifier("test-set-2"), + newEndpointWithOwner("txt.multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner,external-dns/resource=ingress/default/my-ingress-2\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"), }, UpdateOld: []*endpoint.Endpoint{ newEndpointWithOwner("tar.test-zone.example.org", "tar.loadbalancer.com", endpoint.RecordTypeCNAME, "owner"), newEndpointWithOwner("txt.tar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newEndpointWithOwner("multiple.test-zone.example.org", "lb2.loadbalancer.com", endpoint.RecordTypeCNAME, "owner").WithSetIdentifier("test-set-2"), + newEndpointWithOwner("txt.multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"), }, } p.OnApplyChanges = func(ctx context.Context, got *plan.Changes) { From b2a3e88303d2901b08a84a7962c4e58a8b08aec6 Mon Sep 17 00:00:00 2001 From: Alfred Krohmer Date: Sat, 8 Jun 2019 21:53:13 +0200 Subject: [PATCH 03/79] Fixes and cleanup --- plan/plan.go | 27 +++++++++++++++++++++++++-- provider/aws.go | 2 -- registry/txt.go | 4 ++++ source/dedup_source.go | 2 +- source/gateway.go | 10 +++++----- source/ingress.go | 12 ++++++------ source/service.go | 36 +++++++++++++++++++----------------- source/source.go | 22 +++++++++++++++++++--- 8 files changed, 79 insertions(+), 36 deletions(-) diff --git a/plan/plan.go b/plan/plan.go index 7b805bc762..cdecda4f55 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -187,11 +187,34 @@ func shouldUpdateProviderSpecific(desired, current *endpoint.Endpoint) bool { continue } + found := false for _, d := range desired.ProviderSpecific { - if d.Name == c.Name && d.Value != c.Value { - return true + if d.Name == c.Name { + if d.Value != c.Value { + // provider-specific attribute updated + return true + } + found = true + break + } + } + if !found { + // provider-specific attribute deleted + return true + } + } + for _, d := range desired.ProviderSpecific { + found := false + for _, c := range current.ProviderSpecific { + if d.Name == c.Name { + found = true + break } } + if !found { + // provider-specific attribute added + return true + } } return false diff --git a/provider/aws.go b/provider/aws.go index 2ca25d648b..febcc82f4f 100644 --- a/provider/aws.go +++ b/provider/aws.go @@ -39,11 +39,9 @@ const ( // provider specific key that designates whether an AWS ALIAS record has the EvaluateTargetHealth // field set to true. providerSpecificEvaluateTargetHealth = "aws/evaluate-target-health" - providerSpecificSetIdentifier = "aws/set-identifier" providerSpecificWeight = "aws/weight" providerSpecificRegion = "aws/region" providerSpecificFailover = "aws/failover" - providerSpecificGeolocation = "aws/geolocation" providerSpecificGeolocationContinentCode = "aws/geolocation-continent-code" providerSpecificGeolocationCountryCode = "aws/geolocation-country-code" providerSpecificGeolocationSubdivisionCode = "aws/geolocation-subdivision-code" diff --git a/registry/txt.go b/registry/txt.go index 84a15040a3..da574532a1 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -135,6 +135,7 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) } r.Labels[endpoint.OwnerLabelKey] = im.ownerID txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)).WithSetIdentifier(r.SetIdentifier) + txt.ProviderSpecific = r.ProviderSpecific filteredChanges.Create = append(filteredChanges.Create, txt) if im.cacheInterval > 0 { @@ -144,6 +145,7 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) for _, r := range filteredChanges.Delete { txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)).WithSetIdentifier(r.SetIdentifier) + txt.ProviderSpecific = r.ProviderSpecific // when we delete TXT records for which value has changed (due to new label) this would still work because // !!! TXT record value is uniquely generated from the Labels of the endpoint. Hence old TXT record can be uniquely reconstructed @@ -157,6 +159,7 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) // make sure TXT records are consistently updated as well for _, r := range filteredChanges.UpdateOld { txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)).WithSetIdentifier(r.SetIdentifier) + txt.ProviderSpecific = r.ProviderSpecific // when we updateOld TXT records for which value has changed (due to new label) this would still work because // !!! TXT record value is uniquely generated from the Labels of the endpoint. Hence old TXT record can be uniquely reconstructed filteredChanges.UpdateOld = append(filteredChanges.UpdateOld, txt) @@ -169,6 +172,7 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) // make sure TXT records are consistently updated as well for _, r := range filteredChanges.UpdateNew { txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)).WithSetIdentifier(r.SetIdentifier) + txt.ProviderSpecific = r.ProviderSpecific filteredChanges.UpdateNew = append(filteredChanges.UpdateNew, txt) // add new version of record to cache if im.cacheInterval > 0 { diff --git a/source/dedup_source.go b/source/dedup_source.go index de26388fb1..01d0df8936 100644 --- a/source/dedup_source.go +++ b/source/dedup_source.go @@ -43,7 +43,7 @@ func (ms *dedupSource) Endpoints() ([]*endpoint.Endpoint, error) { } for _, ep := range endpoints { - identifier := ep.DNSName + " / " + ep.Targets.String() + identifier := ep.DNSName + " / " + ep.SetIdentifier + " / " + ep.Targets.String() if _, ok := collected[identifier]; ok { log.Debugf("Removing duplicate endpoint %s", ep) diff --git a/source/gateway.go b/source/gateway.go index 85d58d5823..8349a71217 100644 --- a/source/gateway.go +++ b/source/gateway.go @@ -174,14 +174,14 @@ func (sc *gatewaySource) endpointsFromTemplate(config *istiomodel.Config) ([]*en } } - providerSpecific := getProviderSpecificAnnotations(config.Annotations) + providerSpecific, setIdentifier := getProviderSpecificAnnotations(config.Annotations) var endpoints []*endpoint.Endpoint // splits the FQDN template and removes the trailing periods hostnameList := strings.Split(strings.Replace(hostnames, " ", "", -1), ",") for _, hostname := range hostnameList { hostname = strings.TrimSuffix(hostname, ".") - endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) } return endpoints, nil } @@ -266,7 +266,7 @@ func (sc *gatewaySource) endpointsFromGatewayConfig(config istiomodel.Config) ([ gateway := config.Spec.(*istionetworking.Gateway) - providerSpecific := getProviderSpecificAnnotations(config.Annotations) + providerSpecific, setIdentifier := getProviderSpecificAnnotations(config.Annotations) for _, server := range gateway.Servers { for _, host := range server.Hosts { @@ -282,7 +282,7 @@ func (sc *gatewaySource) endpointsFromGatewayConfig(config istiomodel.Config) ([ host = parts[1] } - endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier)...) } } @@ -290,7 +290,7 @@ func (sc *gatewaySource) endpointsFromGatewayConfig(config istiomodel.Config) ([ if !sc.ignoreHostnameAnnotation { hostnameList := getHostnamesFromAnnotations(config.Annotations) for _, hostname := range hostnameList { - endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) } } diff --git a/source/ingress.go b/source/ingress.go index 3eed665493..03a45c19f9 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -187,14 +187,14 @@ func (sc *ingressSource) endpointsFromTemplate(ing *v1beta1.Ingress) ([]*endpoin targets = targetsFromIngressStatus(ing.Status) } - providerSpecific := getProviderSpecificAnnotations(ing.Annotations) + providerSpecific, setIdentifier := getProviderSpecificAnnotations(ing.Annotations) var endpoints []*endpoint.Endpoint // splits the FQDN template and removes the trailing periods hostnameList := strings.Split(strings.Replace(hostnames, " ", "", -1), ",") for _, hostname := range hostnameList { hostname = strings.TrimSuffix(hostname, ".") - endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) } return endpoints, nil } @@ -261,13 +261,13 @@ func endpointsFromIngress(ing *v1beta1.Ingress, ignoreHostnameAnnotation bool) [ targets = targetsFromIngressStatus(ing.Status) } - providerSpecific := getProviderSpecificAnnotations(ing.Annotations) + providerSpecific, setIdentifier := getProviderSpecificAnnotations(ing.Annotations) for _, rule := range ing.Spec.Rules { if rule.Host == "" { continue } - endpoints = append(endpoints, endpointsForHostname(rule.Host, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(rule.Host, targets, ttl, providerSpecific, setIdentifier)...) } for _, tls := range ing.Spec.TLS { @@ -275,7 +275,7 @@ func endpointsFromIngress(ing *v1beta1.Ingress, ignoreHostnameAnnotation bool) [ if host == "" { continue } - endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier)...) } } @@ -283,7 +283,7 @@ func endpointsFromIngress(ing *v1beta1.Ingress, ignoreHostnameAnnotation bool) [ if !ignoreHostnameAnnotation { hostnameList := getHostnamesFromAnnotations(ing.Annotations) for _, hostname := range hostnameList { - endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) } } return endpoints diff --git a/source/service.go b/source/service.go index 1fba3d624b..11ab0c3bbc 100644 --- a/source/service.go +++ b/source/service.go @@ -285,10 +285,10 @@ func (sc *serviceSource) endpointsFromTemplate(svc *v1.Service) ([]*endpoint.End return nil, fmt.Errorf("failed to apply template on service %s: %v", svc.String(), err) } - providerSpecific := getProviderSpecificAnnotations(svc.Annotations) + providerSpecific, setIdentifier := getProviderSpecificAnnotations(svc.Annotations) hostnameList := strings.Split(strings.Replace(buf.String(), " ", "", -1), ",") for _, hostname := range hostnameList { - endpoints = append(endpoints, sc.generateEndpoints(svc, hostname, providerSpecific)...) + endpoints = append(endpoints, sc.generateEndpoints(svc, hostname, providerSpecific, setIdentifier)...) } return endpoints, nil @@ -299,10 +299,10 @@ func (sc *serviceSource) endpoints(svc *v1.Service) []*endpoint.Endpoint { var endpoints []*endpoint.Endpoint // Skip endpoints if we do not want entries from annotations if !sc.ignoreHostnameAnnotation { - providerSpecific := getProviderSpecificAnnotations(svc.Annotations) + providerSpecific, setIdentifier := getProviderSpecificAnnotations(svc.Annotations) hostnameList := getHostnamesFromAnnotations(svc.Annotations) for _, hostname := range hostnameList { - endpoints = append(endpoints, sc.generateEndpoints(svc, hostname, providerSpecific)...) + endpoints = append(endpoints, sc.generateEndpoints(svc, hostname, providerSpecific, setIdentifier)...) } } return endpoints @@ -358,7 +358,7 @@ func (sc *serviceSource) setResourceLabel(service *v1.Service, endpoints []*endp } } -func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, providerSpecific endpoint.ProviderSpecific) []*endpoint.Endpoint { +func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, providerSpecific endpoint.ProviderSpecific, setIdentifier string) []*endpoint.Endpoint { hostname = strings.TrimSuffix(hostname, ".") ttl, err := getTTLFromAnnotations(svc.Annotations) if err != nil { @@ -366,21 +366,19 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, pro } epA := &endpoint.Endpoint{ - RecordTTL: ttl, - RecordType: endpoint.RecordTypeA, - Labels: endpoint.NewLabels(), - Targets: make(endpoint.Targets, 0, defaultTargetsCapacity), - DNSName: hostname, - ProviderSpecific: providerSpecific, + RecordTTL: ttl, + RecordType: endpoint.RecordTypeA, + Labels: endpoint.NewLabels(), + Targets: make(endpoint.Targets, 0, defaultTargetsCapacity), + DNSName: hostname, } epCNAME := &endpoint.Endpoint{ - RecordTTL: ttl, - RecordType: endpoint.RecordTypeCNAME, - Labels: endpoint.NewLabels(), - Targets: make(endpoint.Targets, 0, defaultTargetsCapacity), - DNSName: hostname, - ProviderSpecific: providerSpecific, + RecordTTL: ttl, + RecordType: endpoint.RecordTypeCNAME, + Labels: endpoint.NewLabels(), + Targets: make(endpoint.Targets, 0, defaultTargetsCapacity), + DNSName: hostname, } var endpoints []*endpoint.Endpoint @@ -423,6 +421,10 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, pro if len(epCNAME.Targets) > 0 { endpoints = append(endpoints, epCNAME) } + for _, endpoint := range endpoints { + endpoint.ProviderSpecific = providerSpecific + endpoint.SetIdentifier = setIdentifier + } return endpoints } diff --git a/source/source.go b/source/source.go index 83fc846917..9dc599ac32 100644 --- a/source/source.go +++ b/source/source.go @@ -45,6 +45,8 @@ const ( const ( // The annotation used for determining if traffic will go through Cloudflare CloudflareProxiedKey = "external-dns.alpha.kubernetes.io/cloudflare-proxied" + + SetIdentifierKey = "external-dns.alpha.kubernetes.io/set-identifier" ) const ( @@ -86,7 +88,7 @@ func getAliasFromAnnotations(annotations map[string]string) bool { return exists && aliasAnnotation == "true" } -func getProviderSpecificAnnotations(annotations map[string]string) endpoint.ProviderSpecific { +func getProviderSpecificAnnotations(annotations map[string]string) (endpoint.ProviderSpecific, string) { providerSpecificAnnotations := endpoint.ProviderSpecific{} v, exists := annotations[CloudflareProxiedKey] @@ -102,7 +104,19 @@ func getProviderSpecificAnnotations(annotations map[string]string) endpoint.Prov Value: "true", }) } - return providerSpecificAnnotations + setIdentifier := "" + for k, v := range annotations { + if k == SetIdentifierKey { + setIdentifier = v + } else if strings.HasPrefix(k, "external-dns.alpha.kubernetes.io/aws-") { + attr := strings.TrimPrefix(k, "external-dns.alpha.kubernetes.io/aws-") + providerSpecificAnnotations = append(providerSpecificAnnotations, endpoint.ProviderSpecificProperty{ + Name: fmt.Sprintf("aws/%s", attr), + Value: v, + }) + } + } + return providerSpecificAnnotations, setIdentifier } // getTargetsFromTargetAnnotation gets endpoints from optional "target" annotation. @@ -133,7 +147,7 @@ func suitableType(target string) string { } // endpointsForHostname returns the endpoint objects for each host-target combination. -func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoint.TTL, providerSpecific endpoint.ProviderSpecific) []*endpoint.Endpoint { +func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoint.TTL, providerSpecific endpoint.ProviderSpecific, setIdentifier string) []*endpoint.Endpoint { var endpoints []*endpoint.Endpoint var aTargets endpoint.Targets @@ -156,6 +170,7 @@ func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoin RecordType: endpoint.RecordTypeA, Labels: endpoint.NewLabels(), ProviderSpecific: providerSpecific, + SetIdentifier: setIdentifier, } endpoints = append(endpoints, epA) } @@ -168,6 +183,7 @@ func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoin RecordType: endpoint.RecordTypeCNAME, Labels: endpoint.NewLabels(), ProviderSpecific: providerSpecific, + SetIdentifier: setIdentifier, } endpoints = append(endpoints, epCNAME) } From a1738f982818b61b28da30530f2a8b2927f74ddb Mon Sep 17 00:00:00 2001 From: Alfred Krohmer Date: Sat, 8 Jun 2019 22:00:40 +0200 Subject: [PATCH 04/79] Add documentation for routing policies --- docs/tutorials/aws.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index 88a7a75a28..53395a74a1 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -320,6 +320,23 @@ spec: This will set the DNS record's TTL to 60 seconds. +## Routing policies + +Route53 offers [different routing policies](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html). The routing policy for a record can be controlled with the following annotations: + +* `external-dns.alpha.kubernetes.io/set-identifier`: this **needs** to be set to use any of the following routing policies + +For any given DNS name, only **one** of the following routing policies can be used: + +* Weighted records: `external-dns.alpha.kubernetes.io/aws-weight` +* Latency-based routing: `external-dns.alpha.kubernetes.io/aws-region` +* Failover:`external-dns.alpha.kubernetes.io/aws-failover` +* Geolocation-based routing: + * `external-dns.alpha.kubernetes.io/aws-geolocation-continent-code` + * `external-dns.alpha.kubernetes.io/aws-geolocation-country-code` + * `external-dns.alpha.kubernetes.io/aws-geolocation-subdivision-code` +* Multi-value answer:`external-dns.alpha.kubernetes.io/aws-multi-value-answer` + ## Clean up Make sure to delete all Service objects before terminating the cluster so all load balancers get cleaned up correctly. From 2d02bb374e0a8459e97e6b69bc2aa025c689a894 Mon Sep 17 00:00:00 2001 From: Alfred Krohmer Date: Fri, 23 Aug 2019 12:26:34 +0200 Subject: [PATCH 05/79] Use switch case instead of many ifs --- provider/aws.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/provider/aws.go b/provider/aws.go index febcc82f4f..88dd2db36b 100644 --- a/provider/aws.go +++ b/provider/aws.go @@ -290,19 +290,16 @@ func (p *AWSProvider) records(zones map[string]*route53.HostedZone) ([]*endpoint for _, ep := range newEndpoints { if r.SetIdentifier != nil { ep.SetIdentifier = aws.StringValue(r.SetIdentifier) - if r.Weight != nil { + switch { + case r.Weight != nil: ep.WithProviderSpecific(providerSpecificWeight, fmt.Sprintf("%d", aws.Int64Value(r.Weight))) - } - if r.Region != nil { + case r.Region != nil: ep.WithProviderSpecific(providerSpecificRegion, aws.StringValue(r.Region)) - } - if r.Failover != nil { + case r.Failover != nil: ep.WithProviderSpecific(providerSpecificFailover, aws.StringValue(r.Failover)) - } - if r.MultiValueAnswer != nil && aws.BoolValue(r.MultiValueAnswer) { + case r.MultiValueAnswer != nil && aws.BoolValue(r.MultiValueAnswer): ep.WithProviderSpecific(providerSpecificMultiValueAnswer, "") - } - if r.GeoLocation != nil { + case r.GeoLocation != nil: if r.GeoLocation.ContinentCode != nil { ep.WithProviderSpecific(providerSpecificGeolocationContinentCode, aws.StringValue(r.GeoLocation.ContinentCode)) } else { @@ -313,6 +310,8 @@ func (p *AWSProvider) records(zones map[string]*route53.HostedZone) ([]*endpoint ep.WithProviderSpecific(providerSpecificGeolocationSubdivisionCode, aws.StringValue(r.GeoLocation.SubdivisionCode)) } } + default: + // one of the above needs to be set, otherwise SetIdentifier doesn't make sense } } endpoints = append(endpoints, ep) From 2bfa8d95d982b0f6133e2e68e9e8d6e021af6694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20S=C3=B8rensen?= Date: Fri, 6 Sep 2019 16:11:30 +0200 Subject: [PATCH 06/79] Fix build errors --- provider/aws.go | 16 ++++++++-------- source/ingressroute.go | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/provider/aws.go b/provider/aws.go index 88dd2db36b..9f0b711fd8 100644 --- a/provider/aws.go +++ b/provider/aws.go @@ -519,10 +519,10 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint, recordsCac } } - setIdentifier := endpoint.SetIdentifier + setIdentifier := ep.SetIdentifier if setIdentifier != "" { change.ResourceRecordSet.SetIdentifier = aws.String(setIdentifier) - if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificWeight); ok { + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificWeight); ok { weight, err := strconv.ParseInt(prop.Value, 10, 64) if err != nil { log.Errorf("Failed parsing value of %s: %s: %v; using weight of 0", providerSpecificWeight, prop.Value, err) @@ -530,27 +530,27 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint, recordsCac } change.ResourceRecordSet.Weight = aws.Int64(weight) } - if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificRegion); ok { + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificRegion); ok { change.ResourceRecordSet.Region = aws.String(prop.Value) } - if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificFailover); ok { + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificFailover); ok { change.ResourceRecordSet.Failover = aws.String(prop.Value) } - if _, ok := endpoint.GetProviderSpecificProperty(providerSpecificMultiValueAnswer); ok { + if _, ok := ep.GetProviderSpecificProperty(providerSpecificMultiValueAnswer); ok { change.ResourceRecordSet.MultiValueAnswer = aws.Bool(true) } var geolocation = &route53.GeoLocation{} useGeolocation := false - if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificGeolocationContinentCode); ok { + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificGeolocationContinentCode); ok { geolocation.ContinentCode = aws.String(prop.Value) useGeolocation = true } else { - if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificGeolocationCountryCode); ok { + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificGeolocationCountryCode); ok { geolocation.CountryCode = aws.String(prop.Value) useGeolocation = true } - if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificGeolocationSubdivisionCode); ok { + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificGeolocationSubdivisionCode); ok { geolocation.SubdivisionCode = aws.String(prop.Value) useGeolocation = true } diff --git a/source/ingressroute.go b/source/ingressroute.go index cf4504446c..1f40967906 100644 --- a/source/ingressroute.go +++ b/source/ingressroute.go @@ -209,14 +209,14 @@ func (sc *ingressRouteSource) endpointsFromTemplate(ingressRoute *contourapi.Ing } } - providerSpecific := getProviderSpecificAnnotations(ingressRoute.Annotations) + providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations) var endpoints []*endpoint.Endpoint // splits the FQDN template and removes the trailing periods hostnameList := strings.Split(strings.Replace(hostnames, " ", "", -1), ",") for _, hostname := range hostnameList { hostname = strings.TrimSuffix(hostname, ".") - endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) } return endpoints, nil } @@ -302,11 +302,11 @@ func (sc *ingressRouteSource) endpointsFromIngressRoute(ingressRoute *contourapi } } - providerSpecific := getProviderSpecificAnnotations(ingressRoute.Annotations) + providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations) if virtualHost := ingressRoute.Spec.VirtualHost; virtualHost != nil { if fqdn := virtualHost.Fqdn; fqdn != "" { - endpoints = append(endpoints, endpointsForHostname(fqdn, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(fqdn, targets, ttl, providerSpecific, setIdentifier)...) } } @@ -314,7 +314,7 @@ func (sc *ingressRouteSource) endpointsFromIngressRoute(ingressRoute *contourapi if !sc.ignoreHostnameAnnotation { hostnameList := getHostnamesFromAnnotations(ingressRoute.Annotations) for _, hostname := range hostnameList { - endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific)...) + endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) } } From a491d8f6a2f2e279cf6052d25c8fe1e2e3a1f060 Mon Sep 17 00:00:00 2001 From: Reinier Schoof Date: Tue, 1 Oct 2019 09:27:06 +0200 Subject: [PATCH 07/79] added support for using nodes as source --- pkg/apis/externaldns/types.go | 2 +- source/node.go | 151 +++++++++++++++++++++++++++ source/node_test.go | 189 ++++++++++++++++++++++++++++++++++ source/store.go | 6 ++ 4 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 source/node.go create mode 100644 source/node_test.go diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 480593f14a..5f58eb5556 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -270,7 +270,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("contour-load-balancer", "The fully-qualified name of the Contour load balancer service. (default: heptio-contour/contour)").Default("heptio-contour/contour").StringVar(&cfg.ContourLoadBalancerService) // Flags related to processing sources - app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, fake, connector, istio-gateway, cloudfoundry, contour-ingressroute, crd, empty").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "istio-gateway", "cloudfoundry", "contour-ingressroute", "fake", "connector", "crd", "empty") + app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, istio-gateway, cloudfoundry, contour-ingressroute, crd, empty").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "istio-gateway", "cloudfoundry", "contour-ingressroute", "fake", "connector", "crd", "empty") app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate) diff --git a/source/node.go b/source/node.go new file mode 100644 index 0000000000..0818c51066 --- /dev/null +++ b/source/node.go @@ -0,0 +1,151 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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. +*/ + +package source + +import ( + "bytes" + "fmt" + "strings" + "text/template" + "time" + + log "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" + kubeinformers "k8s.io/client-go/informers" + coreinformers "k8s.io/client-go/informers/core/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + + "github.com/kubernetes-incubator/external-dns/endpoint" +) + +type nodeSource struct { + client kubernetes.Interface + fqdnTemplate *template.Template + nodeInformer coreinformers.NodeInformer +} + +func NewNodeSource(kubeClient kubernetes.Interface, fqdnTemplate string) (Source, error) { + var ( + tmpl *template.Template + err error + ) + + if fqdnTemplate != "" { + tmpl, err = template.New("endpoint").Funcs(template.FuncMap{ + "trimPrefix": strings.TrimPrefix, + }).Parse(fqdnTemplate) + if err != nil { + return nil, err + } + } + + // Use shared informers to listen for add/update/delete of services/pods/nodes in the specified namespace. + // Set resync period to 0, to prevent processing when nothing has changed + informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0) + nodeInformer := informerFactory.Core().V1().Nodes() + + // Add default resource event handler to properly initialize informer. + nodeInformer.Informer().AddEventHandler( + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + log.Debug("node added") + }, + }, + ) + + // TODO informer is not explicitly stopped since controller is not passing in its channel. + informerFactory.Start(wait.NeverStop) + + // wait for the local cache to be populated. + err = wait.Poll(time.Second, 60*time.Second, func() (bool, error) { + return nodeInformer.Informer().HasSynced() == true, nil + }) + if err != nil { + return nil, fmt.Errorf("failed to sync cache: %v", err) + } + + return &nodeSource{ + client: kubeClient, + fqdnTemplate: tmpl, + nodeInformer: nodeInformer, + }, nil +} + +// Endpoints returns endpoint objects for each service that should be processed. +func (ns *nodeSource) Endpoints() ([]*endpoint.Endpoint, error) { + nodes, err := ns.nodeInformer.Lister().List(labels.Everything()) + if err != nil { + return nil, err + } + + endpoints := []*endpoint.Endpoint{} + + // create endpoints for all nodes + for _, node := range nodes { + log.Debugf("creating endpoint for node %s", node.Name) + + // create new endpoint with the information we already have + ep := &endpoint.Endpoint{ + RecordType: "A", // hardcoded DNS record type + } + + if ns.fqdnTemplate != nil { + // Process the whole template string + var buf bytes.Buffer + err := ns.fqdnTemplate.Execute(&buf, node) + if err != nil { + return nil, fmt.Errorf("failed to apply template on node %s: %v", node.Name, err) + } + + ep.DNSName = buf.String() + log.Debugf("applied template for %s, converting to %s", node.Name, ep.DNSName) + } else { + ep.DNSName = node.Name + log.Debugf("not applying template for %s", node.Name) + } + + addr, err := ns.nodeAddress(node) + if err != nil { + log.Error(err) + continue + } + + ep.Targets = endpoint.Targets([]string{addr}) + + log.Debugf("adding endpoint %s", ep) + endpoints = append(endpoints, ep) + } + + return endpoints, nil +} + +// nodeAddress returns node's externalIP and if that's not found, node's internalIP +// basically what k8s.io/kubernetes/pkg/util/node.GetPreferredNodeAddress does +func (ns *nodeSource) nodeAddress(node *v1.Node) (string, error) { + for _, t := range []v1.NodeAddressType{v1.NodeExternalIP, v1.NodeInternalIP} { + for _, addr := range node.Status.Addresses { + if addr.Type == t { + return addr.Address, nil + } + } + } + + return "", fmt.Errorf("could not find node address for %s", node.Name) +} diff --git a/source/node_test.go b/source/node_test.go new file mode 100644 index 0000000000..aea8d66c70 --- /dev/null +++ b/source/node_test.go @@ -0,0 +1,189 @@ +package source + +import ( + "testing" + + "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" +) + +func TestNodeSource(t *testing.T) { + //suite.Run(t, new(ServiceSuite)) + //t.Run("Interface", testServiceSourceImplementsSource) + //t.Run("NewNodeSource", testNodeSourceNewNodeSource) + t.Run("Endpoints", testNodeSourceEndpoints) +} + +// testNodeSourceNewNodeSource tests that NewNodeService doesn't return an error. +func testNodeSourceNewNodeSource(t *testing.T) { + for _, ti := range []struct { + title string + fqdnTemplate string + expectError bool + }{ + { + title: "invalid template", + expectError: true, + fqdnTemplate: "{{.Name", + }, + { + title: "valid empty template", + expectError: false, + }, + { + title: "valid template", + expectError: false, + fqdnTemplate: "{{.Name}}-{{.Namespace}}.ext-dns.test.com", + }, + } { + t.Run(ti.title, func(t *testing.T) { + _, err := NewNodeSource( + fake.NewSimpleClientset(), + ti.fqdnTemplate, + ) + + if ti.expectError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +// testNodeSourceEndpoints tests that various node generate the correct endpoints. +func testNodeSourceEndpoints(t *testing.T) { + for _, tc := range []struct { + title string + fqdnTemplate string + nodeName string + nodeAddresses []v1.NodeAddress + labels map[string]string + annotations map[string]string + expected []*endpoint.Endpoint + expectError bool + }{ + { + "node with short hostname returns one endpoint", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}}, + }, + false, + }, + { + "node with fqdn returns one endpoint", + "", + "node1.example.org", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, + }, + false, + }, + { + "node with fqdn template returns endpoint with expanded hostname", + "{{.Name}}.example.org", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, + }, + false, + }, + { + "node with fqdn and fqdn template returns one endpoint", + "{{.Name}}.example.org", + "node1.example.org", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1.example.org.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, + }, + false, + }, + { + "node with both external and internal IP returns an endpoint with external IP", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}, {v1.NodeInternalIP, "2.3.4.5"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}}, + }, + false, + }, + { + "node with only internal IP returns an endpoint with internal IP", + "", + "node1", + []v1.NodeAddress{{v1.NodeInternalIP, "2.3.4.5"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"2.3.4.5"}}, + }, + false, + }, + { + "node with neither external nor internal IP returns no endpoints", + "", + "node1", + []v1.NodeAddress{}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{}, + false, + }, + } { + t.Run(tc.title, func(t *testing.T) { + // Create a Kubernetes testing client + kubernetes := fake.NewSimpleClientset() + + node := &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: tc.nodeName, + Labels: tc.labels, + Annotations: tc.annotations, + }, + Status: v1.NodeStatus{ + Addresses: tc.nodeAddresses, + }, + } + + _, err := kubernetes.CoreV1().Nodes().Create(node) + require.NoError(t, err) + + // Create our object under test and get the endpoints. + client, err := NewNodeSource( + kubernetes, + tc.fqdnTemplate, + ) + require.NoError(t, err) + + endpoints, err := client.Endpoints() + if tc.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + + // Validate returned endpoints against desired endpoints. + validateEndpoints(t, endpoints, tc.expected) + }) + } +} diff --git a/source/store.go b/source/store.go index d48a639866..c09a438df0 100644 --- a/source/store.go +++ b/source/store.go @@ -153,6 +153,12 @@ func ByNames(p ClientGenerator, names []string, cfg *Config) ([]Source, error) { // BuildWithConfig allows to generate a Source implementation from the shared config func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, error) { switch source { + case "node": + client, err := p.KubeClient() + if err != nil { + return nil, err + } + return NewNodeSource(client, cfg.FQDNTemplate) case "service": client, err := p.KubeClient() if err != nil { From 16194ca9cfe2bf43730f15b7d0ecf48816633ebc Mon Sep 17 00:00:00 2001 From: Reinier Schoof Date: Tue, 1 Oct 2019 11:26:47 +0200 Subject: [PATCH 08/79] implemented annotationFilter for node source --- source/node.go | 53 +++++++++++++++++++--- source/node_test.go | 107 ++++++++++++++++++++++++++++++++++---------- source/store.go | 2 +- 3 files changed, 130 insertions(+), 32 deletions(-) diff --git a/source/node.go b/source/node.go index 0818c51066..ff3df47aae 100644 --- a/source/node.go +++ b/source/node.go @@ -25,6 +25,7 @@ import ( log "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/wait" kubeinformers "k8s.io/client-go/informers" @@ -36,12 +37,13 @@ import ( ) type nodeSource struct { - client kubernetes.Interface - fqdnTemplate *template.Template - nodeInformer coreinformers.NodeInformer + client kubernetes.Interface + annotationFilter string + fqdnTemplate *template.Template + nodeInformer coreinformers.NodeInformer } -func NewNodeSource(kubeClient kubernetes.Interface, fqdnTemplate string) (Source, error) { +func NewNodeSource(kubeClient kubernetes.Interface, annotationFilter, fqdnTemplate string) (Source, error) { var ( tmpl *template.Template err error @@ -82,9 +84,10 @@ func NewNodeSource(kubeClient kubernetes.Interface, fqdnTemplate string) (Source } return &nodeSource{ - client: kubeClient, - fqdnTemplate: tmpl, - nodeInformer: nodeInformer, + client: kubeClient, + annotationFilter: annotationFilter, + fqdnTemplate: tmpl, + nodeInformer: nodeInformer, }, nil } @@ -95,6 +98,11 @@ func (ns *nodeSource) Endpoints() ([]*endpoint.Endpoint, error) { return nil, err } + nodes, err = ns.filterByAnnotations(nodes) + if err != nil { + return nil, err + } + endpoints := []*endpoint.Endpoint{} // create endpoints for all nodes @@ -149,3 +157,34 @@ func (ns *nodeSource) nodeAddress(node *v1.Node) (string, error) { return "", fmt.Errorf("could not find node address for %s", node.Name) } + +// filterByAnnotations filters a list of nodes by a given annotation selector. +func (ns *nodeSource) filterByAnnotations(nodes []*v1.Node) ([]*v1.Node, error) { + labelSelector, err := metav1.ParseToLabelSelector(ns.annotationFilter) + if err != nil { + return nil, err + } + selector, err := metav1.LabelSelectorAsSelector(labelSelector) + if err != nil { + return nil, err + } + + // empty filter returns original list + if selector.Empty() { + return nodes, nil + } + + filteredList := []*v1.Node{} + + for _, node := range nodes { + // convert the node's annotations to an equivalent label selector + annotations := labels.Set(node.Annotations) + + // include node if its annotations match the selector + if selector.Matches(annotations) { + filteredList = append(filteredList, node) + } + } + + return filteredList, nil +} diff --git a/source/node_test.go b/source/node_test.go index aea8d66c70..f20bd4b45d 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -14,16 +14,17 @@ import ( func TestNodeSource(t *testing.T) { //suite.Run(t, new(ServiceSuite)) //t.Run("Interface", testServiceSourceImplementsSource) - //t.Run("NewNodeSource", testNodeSourceNewNodeSource) + t.Run("NewNodeSource", testNodeSourceNewNodeSource) t.Run("Endpoints", testNodeSourceEndpoints) } // testNodeSourceNewNodeSource tests that NewNodeService doesn't return an error. func testNodeSourceNewNodeSource(t *testing.T) { for _, ti := range []struct { - title string - fqdnTemplate string - expectError bool + title string + annotationFilter string + fqdnTemplate string + expectError bool }{ { title: "invalid template", @@ -39,10 +40,16 @@ func testNodeSourceNewNodeSource(t *testing.T) { expectError: false, fqdnTemplate: "{{.Name}}-{{.Namespace}}.ext-dns.test.com", }, + { + title: "non-empty annotation filter label", + expectError: false, + annotationFilter: "kubernetes.io/ingress.class=nginx", + }, } { t.Run(ti.title, func(t *testing.T) { _, err := NewNodeSource( fake.NewSimpleClientset(), + ti.annotationFilter, ti.fqdnTemplate, ) @@ -58,66 +65,72 @@ func testNodeSourceNewNodeSource(t *testing.T) { // testNodeSourceEndpoints tests that various node generate the correct endpoints. func testNodeSourceEndpoints(t *testing.T) { for _, tc := range []struct { - title string - fqdnTemplate string - nodeName string - nodeAddresses []v1.NodeAddress - labels map[string]string - annotations map[string]string - expected []*endpoint.Endpoint - expectError bool + title string + annotationFilter string + fqdnTemplate string + nodeName string + nodeAddresses []v1.NodeAddress + labels map[string]string + annotations map[string]string + expected []*endpoint.Endpoint + expectError bool }{ { "node with short hostname returns one endpoint", "", + "", "node1", []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ - {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}}, - }, + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}}, + }, false, }, - { + { "node with fqdn returns one endpoint", "", + "", "node1.example.org", []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ - {RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, - }, + {RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, + }, false, }, { "node with fqdn template returns endpoint with expanded hostname", + "", "{{.Name}}.example.org", "node1", []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ - {RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, - }, + {RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, + }, false, }, - { + { "node with fqdn and fqdn template returns one endpoint", + "", "{{.Name}}.example.org", "node1.example.org", []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ - {RecordType: "A", DNSName: "node1.example.org.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, - }, + {RecordType: "A", DNSName: "node1.example.org.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, + }, false, }, { "node with both external and internal IP returns an endpoint with external IP", "", + "", "node1", []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}, {v1.NodeInternalIP, "2.3.4.5"}}, map[string]string{}, @@ -127,9 +140,10 @@ func testNodeSourceEndpoints(t *testing.T) { }, false, }, - { + { "node with only internal IP returns an endpoint with internal IP", "", + "", "node1", []v1.NodeAddress{{v1.NodeInternalIP, "2.3.4.5"}}, map[string]string{}, @@ -139,9 +153,10 @@ func testNodeSourceEndpoints(t *testing.T) { }, false, }, - { + { "node with neither external nor internal IP returns no endpoints", "", + "", "node1", []v1.NodeAddress{}, map[string]string{}, @@ -149,6 +164,49 @@ func testNodeSourceEndpoints(t *testing.T) { []*endpoint.Endpoint{}, false, }, + { + "annotated node without annotation filter returns endpoint", + "", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{ + "service.beta.kubernetes.io/external-traffic": "OnlyLocal", + }, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}}, + }, + false, + }, + { + "annotated node with matching annotation filter returns endpoint", + "service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{ + "service.beta.kubernetes.io/external-traffic": "OnlyLocal", + }, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}}, + }, + false, + }, + { + "annotated node with non-matching annotation filter returns endpoint", + "service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{ + "service.beta.kubernetes.io/external-traffic": "SomethingElse", + }, + []*endpoint.Endpoint{}, + false, + }, } { t.Run(tc.title, func(t *testing.T) { // Create a Kubernetes testing client @@ -171,6 +229,7 @@ func testNodeSourceEndpoints(t *testing.T) { // Create our object under test and get the endpoints. client, err := NewNodeSource( kubernetes, + tc.annotationFilter, tc.fqdnTemplate, ) require.NoError(t, err) diff --git a/source/store.go b/source/store.go index c09a438df0..14e32b7360 100644 --- a/source/store.go +++ b/source/store.go @@ -158,7 +158,7 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err if err != nil { return nil, err } - return NewNodeSource(client, cfg.FQDNTemplate) + return NewNodeSource(client, cfg.AnnotationFilter, cfg.FQDNTemplate) case "service": client, err := p.KubeClient() if err != nil { From 4325d7368bc9eaf69cebc062eff594c16981a098 Mon Sep 17 00:00:00 2001 From: Reinier Schoof Date: Tue, 1 Oct 2019 11:39:09 +0200 Subject: [PATCH 09/79] respect controller annotation for node source --- source/node.go | 8 ++++++++ source/node_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/source/node.go b/source/node.go index ff3df47aae..3b844b9fcf 100644 --- a/source/node.go +++ b/source/node.go @@ -107,6 +107,14 @@ func (ns *nodeSource) Endpoints() ([]*endpoint.Endpoint, error) { // create endpoints for all nodes for _, node := range nodes { + // Check controller annotation to see if we are responsible. + controller, ok := node.Annotations[controllerAnnotationKey] + if ok && controller != controllerAnnotationValue { + log.Debugf("Skipping node %s because controller value does not match, found: %s, required: %s", + node.Name, controller, controllerAnnotationValue) + continue + } + log.Debugf("creating endpoint for node %s", node.Name) // create new endpoint with the information we already have diff --git a/source/node_test.go b/source/node_test.go index f20bd4b45d..e40ae5d9ee 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -207,6 +207,34 @@ func testNodeSourceEndpoints(t *testing.T) { []*endpoint.Endpoint{}, false, }, + { + "our controller type is dns-controller", + "", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{ + controllerAnnotationKey: controllerAnnotationValue, + }, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}}, + }, + false, + }, + { + "different controller types are ignored", + "", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{ + controllerAnnotationKey: "not-dns-controller", + }, + []*endpoint.Endpoint{}, + false, + }, } { t.Run(tc.title, func(t *testing.T) { // Create a Kubernetes testing client From 36a8ec987af663a9eac7049e7d82fda5b65ea1bd Mon Sep 17 00:00:00 2001 From: Piotr Jander Date: Fri, 18 Oct 2019 13:51:27 +0200 Subject: [PATCH 10/79] Update aws.md --- docs/tutorials/aws.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index 67a7b37172..82d7228a06 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -178,7 +178,7 @@ Annotations which are specific to AWS. ### alias -`external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create an ALIAS record when the target is an ALIAS as well. To make the target an alias, the ingress needs to be configured correctly as described in [the docs](./nginx-ingress.md#with-a-separate-tcp-load-balancer). +`external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create an ALIAS record when the target is an ALIAS as well. To make the target an alias, the ingress needs to be configured correctly as described in [the docs](./nginx-ingress.md#with-a-separate-tcp-load-balancer). In particular, the argument `--publish-service=default/nginx-ingress-controller` has to be set on the `nginx-ingress-controller` container. If one uses the `nginx-ingress` Helm chart, this flag can be set with the `controller.publishService.enabled` configuration option. ## Verify ExternalDNS works (Ingress example) From 02f40d787a57c55a616f8e9ef5c3403a290bbce6 Mon Sep 17 00:00:00 2001 From: Martin Linkhorst Date: Thu, 24 Oct 2019 11:21:06 +0200 Subject: [PATCH 11/79] source: group equal DNS names into same endpoint --- source/node.go | 44 +++++++++++++++++++++++++++++++------------- source/node_test.go | 13 +++++++++++++ 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/source/node.go b/source/node.go index 3b844b9fcf..52d7baddee 100644 --- a/source/node.go +++ b/source/node.go @@ -103,7 +103,7 @@ func (ns *nodeSource) Endpoints() ([]*endpoint.Endpoint, error) { return nil, err } - endpoints := []*endpoint.Endpoint{} + endpoints := map[string]*endpoint.Endpoint{} // create endpoints for all nodes for _, node := range nodes { @@ -137,33 +137,51 @@ func (ns *nodeSource) Endpoints() ([]*endpoint.Endpoint, error) { log.Debugf("not applying template for %s", node.Name) } - addr, err := ns.nodeAddress(node) + addrs, err := ns.nodeAddresses(node) if err != nil { log.Error(err) continue } - ep.Targets = endpoint.Targets([]string{addr}) + ep.Targets = endpoint.Targets(addrs) log.Debugf("adding endpoint %s", ep) - endpoints = append(endpoints, ep) + if _, ok := endpoints[ep.DNSName]; ok { + endpoints[ep.DNSName].Targets = append(endpoints[ep.DNSName].Targets, ep.Targets...) + } else { + endpoints[ep.DNSName] = ep + } + } + + endpointsSlice := []*endpoint.Endpoint{} + for _, ep := range endpoints { + endpointsSlice = append(endpointsSlice, ep) } - return endpoints, nil + return endpointsSlice, nil } // nodeAddress returns node's externalIP and if that's not found, node's internalIP // basically what k8s.io/kubernetes/pkg/util/node.GetPreferredNodeAddress does -func (ns *nodeSource) nodeAddress(node *v1.Node) (string, error) { - for _, t := range []v1.NodeAddressType{v1.NodeExternalIP, v1.NodeInternalIP} { - for _, addr := range node.Status.Addresses { - if addr.Type == t { - return addr.Address, nil - } - } +func (ns *nodeSource) nodeAddresses(node *v1.Node) ([]string, error) { + addresses := map[v1.NodeAddressType][]string{ + v1.NodeExternalIP: []string{}, + v1.NodeInternalIP: []string{}, + } + + for _, addr := range node.Status.Addresses { + addresses[addr.Type] = append(addresses[addr.Type], addr.Address) + } + + if len(addresses[v1.NodeExternalIP]) > 0 { + return addresses[v1.NodeExternalIP], nil + } + + if len(addresses[v1.NodeInternalIP]) > 0 { + return addresses[v1.NodeInternalIP], nil } - return "", fmt.Errorf("could not find node address for %s", node.Name) + return nil, fmt.Errorf("could not find node address for %s", node.Name) } // filterByAnnotations filters a list of nodes by a given annotation selector. diff --git a/source/node_test.go b/source/node_test.go index e40ae5d9ee..009c159127 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -127,6 +127,19 @@ func testNodeSourceEndpoints(t *testing.T) { }, false, }, + { + "node with fqdn template returns two endpoints with multiple IP addresses and expanded hostname", + "", + "{{.Name}}.example.org", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}, {v1.NodeExternalIP, "5.6.7.8"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4", "5.6.7.8"}}, + }, + false, + }, { "node with both external and internal IP returns an endpoint with external IP", "", From fee7046e72191172d06e000707466cf59d7cb6cc Mon Sep 17 00:00:00 2001 From: Reinier Schoof Date: Thu, 24 Oct 2019 16:22:31 +0200 Subject: [PATCH 12/79] error when no node address could be found --- source/node.go | 3 +-- source/node_test.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/source/node.go b/source/node.go index 52d7baddee..36fc56e7fd 100644 --- a/source/node.go +++ b/source/node.go @@ -139,8 +139,7 @@ func (ns *nodeSource) Endpoints() ([]*endpoint.Endpoint, error) { addrs, err := ns.nodeAddresses(node) if err != nil { - log.Error(err) - continue + return nil, fmt.Errorf("failed to get node address from %s: %s", node.Name, err.Error()) } ep.Targets = endpoint.Targets(addrs) diff --git a/source/node_test.go b/source/node_test.go index 009c159127..1b3a7458e8 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -175,7 +175,7 @@ func testNodeSourceEndpoints(t *testing.T) { map[string]string{}, map[string]string{}, []*endpoint.Endpoint{}, - false, + true, }, { "annotated node without annotation filter returns endpoint", From b6ec8557ae356d1673e98a213cd4771032d53f18 Mon Sep 17 00:00:00 2001 From: Reinier Schoof Date: Thu, 24 Oct 2019 17:02:29 +0200 Subject: [PATCH 13/79] honor ttlAnnotationKey for node endpoints --- source/node.go | 8 +++++++- source/node_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/source/node.go b/source/node.go index 36fc56e7fd..8a976a3cdf 100644 --- a/source/node.go +++ b/source/node.go @@ -58,7 +58,7 @@ func NewNodeSource(kubeClient kubernetes.Interface, annotationFilter, fqdnTempla } } - // Use shared informers to listen for add/update/delete of services/pods/nodes in the specified namespace. + // Use shared informers to listen for add/update/delete of nodes. // Set resync period to 0, to prevent processing when nothing has changed informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0) nodeInformer := informerFactory.Core().V1().Nodes() @@ -117,9 +117,15 @@ func (ns *nodeSource) Endpoints() ([]*endpoint.Endpoint, error) { log.Debugf("creating endpoint for node %s", node.Name) + ttl, err := getTTLFromAnnotations(node.Annotations) + if err != nil { + log.Warn(err) + } + // create new endpoint with the information we already have ep := &endpoint.Endpoint{ RecordType: "A", // hardcoded DNS record type + RecordTTL: ttl, } if ns.fqdnTemplate != nil { diff --git a/source/node_test.go b/source/node_test.go index 1b3a7458e8..bce87a278a 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -248,6 +248,49 @@ func testNodeSourceEndpoints(t *testing.T) { []*endpoint.Endpoint{}, false, }, + { + "ttl not annotated should have RecordTTL.IsConfigured set to false", + "", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)}, + }, + false, + }, + { + "ttl annotated but invalid should have RecordTTL.IsConfigured set to false", + "", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{ + ttlAnnotationKey: "foo", + }, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)}, + }, + false, + }, + { + "ttl annotated and is valid should set Record.TTL", + "", + "", + "node1", + []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + map[string]string{}, + map[string]string{ + ttlAnnotationKey: "10", + }, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(10)}, + }, + false, + }, } { t.Run(tc.title, func(t *testing.T) { // Create a Kubernetes testing client From 5667d0b14e2bd194e5fded33ae67c4b965e56b4b Mon Sep 17 00:00:00 2001 From: Reinier Schoof Date: Fri, 25 Oct 2019 16:00:38 +0200 Subject: [PATCH 14/79] remove obsolete comment --- source/node_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/node_test.go b/source/node_test.go index bce87a278a..9e44718511 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -12,8 +12,6 @@ import ( ) func TestNodeSource(t *testing.T) { - //suite.Run(t, new(ServiceSuite)) - //t.Run("Interface", testServiceSourceImplementsSource) t.Run("NewNodeSource", testNodeSourceNewNodeSource) t.Run("Endpoints", testNodeSourceEndpoints) } From 0c547a9809efc3eef2c7b68bff0a971bb1ce7b16 Mon Sep 17 00:00:00 2001 From: Reinier Schoof Date: Fri, 25 Oct 2019 16:25:02 +0200 Subject: [PATCH 15/79] added description to exported function --- source/node.go | 1 + 1 file changed, 1 insertion(+) diff --git a/source/node.go b/source/node.go index 8a976a3cdf..46de331514 100644 --- a/source/node.go +++ b/source/node.go @@ -43,6 +43,7 @@ type nodeSource struct { nodeInformer coreinformers.NodeInformer } +// NewNodeSource creates a new nodeSource with the given config. func NewNodeSource(kubeClient kubernetes.Interface, annotationFilter, fqdnTemplate string) (Source, error) { var ( tmpl *template.Template From ad17f21a1fa7768bd77dbaaa1dd2ad4bd7de837a Mon Sep 17 00:00:00 2001 From: njuettner Date: Tue, 29 Oct 2019 16:40:37 +0100 Subject: [PATCH 16/79] Adding labels on PR --- .github/labeler.yml | 62 +++++++++++++++++++++++++++++++++++ .github/workflows/labeler.yml | 11 +++++++ 2 files changed, 73 insertions(+) create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/labeler.yml diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000000..2881bd2caa --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,62 @@ +# Add 'docs' to any changes within 'docs' folder or any subfolders +docs: + - docs/**/* + +# Add 'provider/alibaba' in file which starts with alibaba +provider/alibaba: provider/alibaba* + +# Add 'provider/aws' in file which starts with aws +provider/aws: provider/aws* + +# Add 'provider/azure' in file which starts with azure +provider/azure: provider/azure* + +# Add 'provider/cloudflare' in file which starts with cloudflare +provider/cloudflare: provider/cloudflare* + +# Add 'provider/coredns' in file which starts with coredns +provider/coredns: provider/coredns* + +# Add 'provider/designate' in file which starts with designate +provider/designate: provider/designate* + +# Add 'provider/digitalocean' in file which starts with digitalocean +provider/digitalocean: provider/digital_ocean* + +# Add 'provider/dnssimple' in file which starts with dnssimple +provider/dnssimple: provider/dnssimple* + +# Add 'provider/dyn' in file which starts with dyn +provider/dyn: provider/dyn* + +# Add 'provider/exoscale' in file which starts with exoscale +provider/exoscale: provider/exoscale* + +# Add 'provider/transip' in file which starts with transip +provider/transip: provider/transip* + +# Add 'provider/rfc2136' in file which starts with rfc2136 +provider/rfc2136: provider/rfc2136* + +# Add 'provider/rdns' in file which starts with rdns +provider/rdns: provider/rdns* + +# Add 'provider/powerdns' in file which starts with pdns +provider/powerdns: provider/pdns* + +# Add 'provider/google' in file which starts with google +provider/google: provider/google* + +# Add 'provider/infoblox' in file which starts with infoblox +provider/infoblox: provider/infoblox* + +# Add 'provider/linode' in file which starts with linode +provider/linode: provider/linode* +# Add 'provider/ns1' in file which starts with ns1 + +provider/ns1: provider/ns1* +# Add 'provider/oci' in file which starts with oci +provider/oci: provider/oci* + +# Add 'provider/vinyldns' in file which starts with vinyldns +provider/vinyldns: provider/vinyldns* diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 0000000000..dcafb97dc9 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,11 @@ +name: "Pull Request Labeler" +on: +- pull_request + +jobs: + triage: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v2 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" From 235edcbebd7d093513193f62c216e69fe1422aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nick=20J=C3=BCttner?= Date: Tue, 29 Oct 2019 17:25:34 +0100 Subject: [PATCH 17/79] Update labeler.yml --- .github/labeler.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 2881bd2caa..2ed29809ea 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -52,9 +52,10 @@ provider/infoblox: provider/infoblox* # Add 'provider/linode' in file which starts with linode provider/linode: provider/linode* -# Add 'provider/ns1' in file which starts with ns1 +# Add 'provider/ns1' in file which starts with ns1 provider/ns1: provider/ns1* + # Add 'provider/oci' in file which starts with oci provider/oci: provider/oci* From ce2eadcd665d0d4a5c6ed43335364e40376938f8 Mon Sep 17 00:00:00 2001 From: Vincent Desjardins Date: Thu, 31 Oct 2019 13:41:02 -0400 Subject: [PATCH 18/79] Google Provider: add support for batching updates The parameter is google-batch-change-size. Default value is 1000. --- main.go | 2 +- pkg/apis/externaldns/types.go | 3 + pkg/apis/externaldns/types_test.go | 5 ++ provider/google.go | 103 +++++++++++++++++++++++++---- provider/google_test.go | 94 +++++++++++++++++++++++++- 5 files changed, 191 insertions(+), 16 deletions(-) diff --git a/main.go b/main.go index 057034e594..1f08a82c11 100644 --- a/main.go +++ b/main.go @@ -142,7 +142,7 @@ func main() { case "rcodezero": p, err = provider.NewRcodeZeroProvider(domainFilter, cfg.DryRun, cfg.RcodezeroTXTEncrypt) case "google": - p, err = provider.NewGoogleProvider(cfg.GoogleProject, domainFilter, zoneIDFilter, cfg.DryRun) + p, err = provider.NewGoogleProvider(cfg.GoogleProject, domainFilter, zoneIDFilter, cfg.GoogleBatchChangeSize, cfg.DryRun) case "digitalocean": p, err = provider.NewDigitalOceanProvider(domainFilter, cfg.DryRun) case "linode": diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 5f58eb5556..0f976aa9d1 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -54,6 +54,7 @@ type Config struct { ConnectorSourceServer string Provider string GoogleProject string + GoogleBatchChangeSize int DomainFilter []string ExcludeDomains []string ZoneIDFilter []string @@ -145,6 +146,7 @@ var defaultConfig = &Config{ ConnectorSourceServer: "localhost:8080", Provider: "", GoogleProject: "", + GoogleBatchChangeSize: 1000, DomainFilter: []string{}, ExcludeDomains: []string{}, AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json", @@ -290,6 +292,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("exclude-domains", "Exclude subdomains (optional)").Default("").StringsVar(&cfg.ExcludeDomains) app.Flag("zone-id-filter", "Filter target zones by hosted zone id; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.ZoneIDFilter) app.Flag("google-project", "When using the Google provider, current project is auto-detected, when running on GCP. Specify other project with this. Must be specified when running outside GCP.").Default(defaultConfig.GoogleProject).StringVar(&cfg.GoogleProject) + app.Flag("google-batch-change-size", "When using the Google provider, set the maximum number of changes that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.GoogleBatchChangeSize)).IntVar(&cfg.GoogleBatchChangeSize) app.Flag("alibaba-cloud-config-file", "When using the Alibaba Cloud provider, specify the Alibaba Cloud configuration file (required when --provider=alibabacloud").Default(defaultConfig.AlibabaCloudConfigFile).StringVar(&cfg.AlibabaCloudConfigFile) app.Flag("alibaba-cloud-zone-type", "When using the Alibaba Cloud provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AlibabaCloudZoneType).EnumVar(&cfg.AlibabaCloudZoneType, "", "public", "private") app.Flag("aws-zone-type", "When using the AWS provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AWSZoneType).EnumVar(&cfg.AWSZoneType, "", "public", "private") diff --git a/pkg/apis/externaldns/types_test.go b/pkg/apis/externaldns/types_test.go index 584e166be4..19d9f45091 100644 --- a/pkg/apis/externaldns/types_test.go +++ b/pkg/apis/externaldns/types_test.go @@ -40,6 +40,7 @@ var ( Compatibility: "", Provider: "google", GoogleProject: "", + GoogleBatchChangeSize: 1000, DomainFilter: []string{""}, ExcludeDomains: []string{""}, ZoneIDFilter: []string{""}, @@ -104,6 +105,7 @@ var ( Compatibility: "mate", Provider: "google", GoogleProject: "project", + GoogleBatchChangeSize: 100, DomainFilter: []string{"example.org", "company.com"}, ExcludeDomains: []string{"xapi.example.org", "xapi.company.com"}, ZoneIDFilter: []string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"}, @@ -174,6 +176,7 @@ var ( Compatibility: "", Provider: "google", GoogleProject: "", + GoogleBatchChangeSize: 1000, DomainFilter: []string{""}, ExcludeDomains: []string{""}, ZoneIDFilter: []string{""}, @@ -256,6 +259,7 @@ func TestParseFlags(t *testing.T) { "--compatibility=mate", "--provider=google", "--google-project=project", + "--google-batch-change-size=100", "--azure-config-file=azure.json", "--azure-resource-group=arg", "--cloudflare-proxied", @@ -334,6 +338,7 @@ func TestParseFlags(t *testing.T) { "EXTERNAL_DNS_COMPATIBILITY": "mate", "EXTERNAL_DNS_PROVIDER": "google", "EXTERNAL_DNS_GOOGLE_PROJECT": "project", + "EXTERNAL_DNS_GOOGLE_BATCH_CHANGE_SIZE": "100", "EXTERNAL_DNS_AZURE_CONFIG_FILE": "azure.json", "EXTERNAL_DNS_AZURE_RESOURCE_GROUP": "arg", "EXTERNAL_DNS_CLOUDFLARE_PROXIED": "1", diff --git a/provider/google.go b/provider/google.go index 3ba73354ff..85c3a9084e 100644 --- a/provider/google.go +++ b/provider/google.go @@ -19,6 +19,7 @@ package provider import ( goctx "context" "fmt" + "sort" "strings" "cloud.google.com/go/compute/metadata" @@ -103,6 +104,8 @@ type GoogleProvider struct { project string // Enabled dry-run will print any modifying actions rather than execute them. dryRun bool + // Max batch size to submit to Google Cloud DNS per transaction. + batchChangeSize int // only consider hosted zones managing domains ending in this suffix domainFilter DomainFilter // only consider hosted zones ending with this zone id @@ -116,7 +119,7 @@ type GoogleProvider struct { } // NewGoogleProvider initializes a new Google CloudDNS based Provider. -func NewGoogleProvider(project string, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool) (*GoogleProvider, error) { +func NewGoogleProvider(project string, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, batchChangeSize int, dryRun bool) (*GoogleProvider, error) { gcloud, err := google.DefaultClient(context.TODO(), dns.NdevClouddnsReadwriteScope) if err != nil { return nil, err @@ -145,6 +148,7 @@ func NewGoogleProvider(project string, domainFilter DomainFilter, zoneIDFilter Z provider := &GoogleProvider{ project: project, dryRun: dryRun, + batchChangeSize: batchChangeSize, domainFilter: domainFilter, zoneIDFilter: zoneIDFilter, resourceRecordSetsClient: resourceRecordSetsService{dnsClient.ResourceRecordSets}, @@ -289,27 +293,100 @@ func (p *GoogleProvider) submitChange(change *dns.Change) error { // separate into per-zone change sets to be passed to the API. changes := separateChange(zones, change) - for z, c := range changes { - log.Infof("Change zone: %v", z) - for _, del := range c.Deletions { - log.Infof("Del records: %s %s %s %d", del.Name, del.Type, del.Rrdatas, del.Ttl) + for zone, change := range changes { + for batch, c := range batchChange(change, p.batchChangeSize) { + log.Infof("Change zone: %v batch #%d", zone, batch) + for _, del := range c.Deletions { + log.Infof("Del records: %s %s %s %d", del.Name, del.Type, del.Rrdatas, del.Ttl) + } + for _, add := range c.Additions { + log.Infof("Add records: %s %s %s %d", add.Name, add.Type, add.Rrdatas, add.Ttl) + } + + if p.dryRun { + continue + } + + if _, err := p.changesClient.Create(p.project, zone, c).Do(); err != nil { + return err + } + } + } + + return nil +} + +// batchChange seperates a zone in multiple transaction. +func batchChange(change *dns.Change, batchSize int) []*dns.Change { + changes := []*dns.Change{} + + if batchSize == 0 { + return append(changes, change) + } + + type dnsChange struct { + additions []*dns.ResourceRecordSet + deletions []*dns.ResourceRecordSet + } + + changesByName := map[string]*dnsChange{} + + for _, a := range change.Additions { + change, ok := changesByName[a.Name] + if !ok { + change = &dnsChange{} + changesByName[a.Name] = change } - for _, add := range c.Additions { - log.Infof("Add records: %s %s %s %d", add.Name, add.Type, add.Rrdatas, add.Ttl) + + change.additions = append(change.additions, a) + } + + for _, a := range change.Deletions { + change, ok := changesByName[a.Name] + if !ok { + change = &dnsChange{} + changesByName[a.Name] = change } + + change.deletions = append(change.deletions, a) } - if p.dryRun { - return nil + names := make([]string, 0) + for v := range changesByName { + names = append(names, v) } + sort.Strings(names) + + currentChange := &dns.Change{} + var totalChanges int + for _, name := range names { + c := changesByName[name] - for z, c := range changes { - if _, err := p.changesClient.Create(p.project, z, c).Do(); err != nil { - return err + totalChangesByName := len(c.additions) + len(c.deletions) + + if totalChangesByName > batchSize { + log.Warnf("Total changes for %s exceeds max batch size of %d, total changes: %d", name, + batchSize, totalChangesByName) + continue + } + + if totalChanges+totalChangesByName > batchSize { + totalChanges = 0 + changes = append(changes, currentChange) + currentChange = &dns.Change{} } + + currentChange.Additions = append(currentChange.Additions, c.additions...) + currentChange.Deletions = append(currentChange.Deletions, c.deletions...) + + totalChanges += totalChangesByName } - return nil + if totalChanges > 0 { + changes = append(changes, currentChange) + } + + return changes } // separateChange separates a multi-zone change into a single change per zone. diff --git a/provider/google_test.go b/provider/google_test.go index a45d81cab3..afb4746008 100644 --- a/provider/google_test.go +++ b/provider/google_test.go @@ -19,6 +19,7 @@ package provider import ( "fmt" "net/http" + "sort" "strings" "testing" @@ -36,8 +37,9 @@ import ( ) var ( - testZones = map[string]*dns.ManagedZone{} - testRecords = map[string]map[string]*dns.ResourceRecordSet{} + testZones = map[string]*dns.ManagedZone{} + testRecords = map[string]map[string]*dns.ResourceRecordSet{} + googleDefaultBatchChangeSize = 4000 ) type mockManagedZonesCreateCall struct { @@ -551,6 +553,94 @@ func TestSeparateChanges(t *testing.T) { }) } +func TestGoogleBatchChangeSet(t *testing.T) { + cs := &dns.Change{} + + for i := 1; i <= googleDefaultBatchChangeSize; i += 2 { + cs.Additions = append(cs.Additions, &dns.ResourceRecordSet{ + Name: fmt.Sprintf("host-%d.example.org.", i), + Ttl: 2, + }) + cs.Deletions = append(cs.Deletions, &dns.ResourceRecordSet{ + Name: fmt.Sprintf("host-%d.example.org.", i), + Ttl: 20, + }) + } + + batchCs := batchChange(cs, googleDefaultBatchChangeSize) + + require.Equal(t, 1, len(batchCs)) + + sortChangesByName(cs) + validateChange(t, batchCs[0], cs) +} + +func TestGoogleBatchChangeSetExceeding(t *testing.T) { + cs := &dns.Change{} + const testCount = 50 + const testLimit = 11 + const expectedBatchCount = 5 + const expectedChangesCount = 10 + + for i := 1; i <= testCount; i += 2 { + cs.Additions = append(cs.Additions, &dns.ResourceRecordSet{ + Name: fmt.Sprintf("host-%d.example.org.", i), + Ttl: 2, + }) + cs.Deletions = append(cs.Deletions, &dns.ResourceRecordSet{ + Name: fmt.Sprintf("host-%d.example.org.", i), + Ttl: 20, + }) + } + + batchCs := batchChange(cs, testLimit) + + require.Equal(t, expectedBatchCount, len(batchCs)) + + dnsChange := &dns.Change{} + for _, c := range batchCs { + dnsChange.Additions = append(dnsChange.Additions, c.Additions...) + dnsChange.Deletions = append(dnsChange.Deletions, c.Deletions...) + } + + require.Equal(t, len(cs.Additions), len(dnsChange.Additions)) + require.Equal(t, len(cs.Deletions), len(dnsChange.Deletions)) + + sortChangesByName(cs) + sortChangesByName(dnsChange) + + validateChange(t, dnsChange, cs) +} + +func TestGoogleBatchChangeSetExceedingNameChange(t *testing.T) { + cs := &dns.Change{} + const testCount = 10 + const testLimit = 1 + + cs.Additions = append(cs.Additions, &dns.ResourceRecordSet{ + Name: "host-1.example.org.", + Ttl: 2, + }) + cs.Deletions = append(cs.Deletions, &dns.ResourceRecordSet{ + Name: "host-1.example.org.", + Ttl: 20, + }) + + batchCs := batchChange(cs, testLimit) + + require.Equal(t, 0, len(batchCs)) +} + +func sortChangesByName(cs *dns.Change) { + sort.SliceStable(cs.Additions, func(i, j int) bool { + return cs.Additions[i].Name < cs.Additions[j].Name + }) + + sort.SliceStable(cs.Deletions, func(i, j int) bool { + return cs.Deletions[i].Name < cs.Deletions[j].Name + }) +} + func validateZones(t *testing.T, zones map[string]*dns.ManagedZone, expected map[string]*dns.ManagedZone) { require.Len(t, zones, len(expected)) From f763d2a4139746abd775c61642cb9e776b387ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nick=20J=C3=BCttner?= Date: Fri, 1 Nov 2019 17:10:19 +0100 Subject: [PATCH 19/79] Move into kubernetes-sigs organization (#1245) * Move into kubernetes-sigs organization * Disable labeler action for forks --- .github/workflows/labeler.yml | 1 + Dockerfile | 4 +- Dockerfile.mini | 4 +- Makefile | 2 +- README.md | 16 ++-- controller/controller.go | 8 +- controller/controller_test.go | 10 +-- docs/20190708-external-dns-incubator.md | 8 +- docs/contributing/crd-source.md | 4 +- docs/faq.md | 6 +- docs/proposal/multi-target.md | 16 ++-- docs/proposal/registry.md | 4 +- docs/tutorials/azure.md | 2 +- docs/tutorials/exoscale.md | 4 +- docs/tutorials/pdns.md | 2 +- docs/tutorials/rdns.md | 2 +- go.mod | 49 +----------- go.sum | 76 +------------------ internal/testutils/endpoint.go | 2 +- internal/testutils/endpoint_test.go | 2 +- internal/testutils/mock_source.go | 2 +- main.go | 14 ++-- pkg/apis/externaldns/validation/validation.go | 2 +- .../externaldns/validation/validation_test.go | 2 +- plan/conflict.go | 2 +- plan/conflict_test.go | 2 +- plan/plan.go | 4 +- plan/plan_test.go | 4 +- plan/policy_test.go | 2 +- provider/alibaba_cloud.go | 4 +- provider/alibaba_cloud_test.go | 4 +- provider/aws.go | 6 +- provider/aws_sd.go | 6 +- provider/aws_sd_test.go | 6 +- provider/aws_test.go | 8 +- provider/azure.go | 4 +- provider/azure_test.go | 6 +- provider/cloudflare.go | 6 +- provider/cloudflare_test.go | 4 +- provider/coredns.go | 4 +- provider/coredns_test.go | 4 +- provider/designate.go | 6 +- provider/designate_test.go | 4 +- provider/digital_ocean.go | 4 +- provider/digital_ocean_test.go | 4 +- provider/dnsimple.go | 4 +- provider/dnsimple_test.go | 4 +- provider/dyn.go | 4 +- provider/dyn_test.go | 2 +- provider/exoscale.go | 4 +- provider/exoscale_test.go | 4 +- provider/google.go | 4 +- provider/google_test.go | 4 +- provider/infoblox.go | 4 +- provider/infoblox_test.go | 4 +- provider/inmemory.go | 4 +- provider/inmemory_test.go | 6 +- provider/linode.go | 4 +- provider/linode_test.go | 4 +- provider/ns1.go | 4 +- provider/ns1_test.go | 4 +- provider/oci.go | 4 +- provider/oci_test.go | 4 +- provider/pdns.go | 6 +- provider/pdns_test.go | 2 +- provider/provider.go | 4 +- provider/rcode0.go | 4 +- provider/rcode0_test.go | 4 +- provider/rdns.go | 4 +- provider/rdns_test.go | 4 +- provider/rfc2136.go | 4 +- provider/rfc2136_test.go | 4 +- provider/transip.go | 4 +- provider/transip_test.go | 2 +- provider/vinyldns.go | 4 +- provider/vinyldns_test.go | 4 +- registry/aws_sd_registry.go | 6 +- registry/aws_sd_registry_test.go | 6 +- registry/noop.go | 6 +- registry/noop_test.go | 8 +- registry/registry.go | 4 +- registry/txt.go | 6 +- registry/txt_test.go | 8 +- source/cloudfoundry.go | 2 +- source/compatibility.go | 2 +- source/connector.go | 2 +- source/connector_test.go | 2 +- source/crd.go | 2 +- source/crd_test.go | 2 +- source/dedup_source.go | 2 +- source/dedup_source_test.go | 4 +- source/empty.go | 2 +- source/fake.go | 2 +- source/fake_test.go | 2 +- source/gateway.go | 2 +- source/gateway_test.go | 2 +- source/ingress.go | 2 +- source/ingress_test.go | 2 +- source/ingressroute.go | 2 +- source/ingressroute_test.go | 2 +- source/multi_source.go | 2 +- source/multi_source_test.go | 4 +- source/node.go | 2 +- source/node_test.go | 2 +- source/service.go | 2 +- source/service_test.go | 2 +- source/shared_test.go | 2 +- source/source.go | 2 +- source/source_test.go | 2 +- 109 files changed, 221 insertions(+), 337 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index dcafb97dc9..15e653f602 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -7,5 +7,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/labeler@v2 + if: github.repository == 'kubernetes-sigs/external-dns' with: repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/Dockerfile b/Dockerfile index 124987fa1a..07e2e61fc7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ # builder image FROM golang:1.13 as builder -WORKDIR /github.com/kubernetes-incubator/external-dns +WORKDIR /github.com/kubernetes-sigs/external-dns COPY . . RUN go mod vendor && \ @@ -29,7 +29,7 @@ LABEL maintainer="Team Teapot @ Zalando SE " RUN apk add --no-cache ca-certificates && \ update-ca-certificates -COPY --from=builder /github.com/kubernetes-incubator/external-dns/build/external-dns /bin/external-dns +COPY --from=builder /github.com/kubernetes-sigs/external-dns/build/external-dns /bin/external-dns # Run as UID for nobody since k8s pod securityContext runAsNonRoot can't resolve the user ID: # https://github.com/kubernetes/kubernetes/issues/40958 diff --git a/Dockerfile.mini b/Dockerfile.mini index 029409828c..1475c2416a 100644 --- a/Dockerfile.mini +++ b/Dockerfile.mini @@ -14,7 +14,7 @@ FROM golang:1.13 as builder -WORKDIR /github.com/kubernetes-incubator/external-dns +WORKDIR /github.com/kubernetes-sigs/external-dns COPY . . RUN apt-get update && \ @@ -27,7 +27,7 @@ RUN apt-get update && \ FROM gcr.io/distroless/static COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -COPY --from=builder /github.com/kubernetes-incubator/external-dns/build/external-dns /bin/external-dns +COPY --from=builder /github.com/kubernetes-sigs/external-dns/build/external-dns /bin/external-dns # Run as UID for nobody since k8s pod securityContext runAsNonRoot can't resolve the user ID: # https://github.com/kubernetes/kubernetes/issues/40958 diff --git a/Makefile b/Makefile index 15cfad027a..1230a1efcd 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ SOURCES = $(shell find . -name '*.go') IMAGE ?= registry.opensource.zalan.do/teapot/$(BINARY) VERSION ?= $(shell git describe --tags --always --dirty) BUILD_FLAGS ?= -v -LDFLAGS ?= -X github.com/kubernetes-incubator/external-dns/pkg/apis/externaldns.Version=$(VERSION) -w -s +LDFLAGS ?= -X github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns.Version=$(VERSION) -w -s build: build/$(BINARY) diff --git a/README.md b/README.md index 303ba66ed6..da755f2993 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@

# ExternalDNS -[![Build Status](https://travis-ci.org/kubernetes-incubator/external-dns.svg?branch=master)](https://travis-ci.org/kubernetes-incubator/external-dns) -[![Coverage Status](https://coveralls.io/repos/github/kubernetes-incubator/external-dns/badge.svg?branch=master)](https://coveralls.io/github/kubernetes-incubator/external-dns?branch=master) -[![GitHub release](https://img.shields.io/github/release/kubernetes-incubator/external-dns.svg)](https://github.com/kubernetes-incubator/external-dns/releases) -[![go-doc](https://godoc.org/github.com/kubernetes-incubator/external-dns?status.svg)](https://godoc.org/github.com/kubernetes-incubator/external-dns) -[![Go Report Card](https://goreportcard.com/badge/github.com/kubernetes-incubator/external-dns)](https://goreportcard.com/report/github.com/kubernetes-incubator/external-dns) +[![Build Status](https://travis-ci.org/kubernetes-sigs/external-dns.svg?branch=master)](https://travis-ci.org/kubernetes-sigs/external-dns) +[![Coverage Status](https://coveralls.io/repos/github/kubernetes-sigs/external-dns/badge.svg?branch=master)](https://coveralls.io/github/kubernetes-sigs/external-dns?branch=master) +[![GitHub release](https://img.shields.io/github/release/kubernetes-sigs/external-dns.svg)](https://github.com/kubernetes-sigs/external-dns/releases) +[![go-doc](https://godoc.org/github.com/kubernetes-sigs/external-dns?status.svg)](https://godoc.org/github.com/kubernetes-sigs/external-dns) +[![Go Report Card](https://goreportcard.com/badge/github.com/kubernetes-sigs/external-dns)](https://goreportcard.com/report/github.com/kubernetes-sigs/external-dns) ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers. @@ -53,7 +53,7 @@ Note that all flags can be replaced with environment variables; for instance, ## Status of providers -ExternalDNS supports multiple DNS providers which have been implemented by the [ExternalDNS contributors](https://github.com/kubernetes-incubator/external-dns/graphs/contributors). Maintaining all of those in a central repository is a challenge and we have limited resources to test changes. This means that it is very hard to test all providers for possible regressions and, as written in the [Contributing](#Contributing) section, we encourage contributors to step in as maintainers for the individual providers and help by testing the integrations. +ExternalDNS supports multiple DNS providers which have been implemented by the [ExternalDNS contributors](https://github.com/kubernetes-sigs/external-dns/graphs/contributors). Maintaining all of those in a central repository is a challenge and we have limited resources to test changes. This means that it is very hard to test all providers for possible regressions and, as written in the [Contributing](#Contributing) section, we encourage contributors to step in as maintainers for the individual providers and help by testing the integrations. End-to-end testing of ExternalDNS is currently [performed](https://github.com/zalando-incubator/kubernetes-on-aws/blob/dev/test/e2e/external_dns.go) @@ -151,7 +151,7 @@ Make sure you have the following prerequisites: First, get ExternalDNS: ```console -$ git clone https://github.com/kubernetes-incubator/external-dns.git && cd external-dns +$ git clone https://github.com/kubernetes-sigs/external-dns.git && cd external-dns ``` **This project uses [Go modules](https://github.com/golang/go/wiki/Modules) as @@ -281,7 +281,7 @@ Here's a rough outline on what is to come (subject to change): * Support for CRDs * Support for more advanced DNS record configurations -Have a look at [the milestones](https://github.com/kubernetes-incubator/external-dns/milestones) to get an idea of where we currently stand. +Have a look at [the milestones](https://github.com/kubernetes-sigs/external-dns/milestones) to get an idea of where we currently stand. ## Contributing diff --git a/controller/controller.go b/controller/controller.go index 0c546395c7..f6c88e9f40 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -23,10 +23,10 @@ import ( "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" - "github.com/kubernetes-incubator/external-dns/plan" - "github.com/kubernetes-incubator/external-dns/provider" - "github.com/kubernetes-incubator/external-dns/registry" - "github.com/kubernetes-incubator/external-dns/source" + "github.com/kubernetes-sigs/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/provider" + "github.com/kubernetes-sigs/external-dns/registry" + "github.com/kubernetes-sigs/external-dns/source" ) var ( diff --git a/controller/controller_test.go b/controller/controller_test.go index 1cf68bdfd1..3d0b0ecfa5 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -22,11 +22,11 @@ import ( "reflect" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" - "github.com/kubernetes-incubator/external-dns/plan" - "github.com/kubernetes-incubator/external-dns/provider" - "github.com/kubernetes-incubator/external-dns/registry" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/provider" + "github.com/kubernetes-sigs/external-dns/registry" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/docs/20190708-external-dns-incubator.md b/docs/20190708-external-dns-incubator.md index ba69197b7a..e3790ac26c 100644 --- a/docs/20190708-external-dns-incubator.md +++ b/docs/20190708-external-dns-incubator.md @@ -2,7 +2,7 @@ -- [Move ExternalDNS out of Kubernetes incubator](#move-externaldns-out-of-kubernetes-incubator) +- [Move ExternalDNS out of Kubernetes incubator](#move-externaldns-out-of-kubernetes-sigs) - [Summary](#summary) - [Motivation](#motivation) - [Goals](#goals) @@ -17,7 +17,7 @@ ## Summary -[ExternalDNS](https://github.com/kubernetes-incubator/external-dns) is a project that synchronizes Kubernetes’ Services, Ingresses and other Kubernetes resources to DNS backends for several DNS providers. +[ExternalDNS](https://github.com/kubernetes-sigs/external-dns) is a project that synchronizes Kubernetes’ Services, Ingresses and other Kubernetes resources to DNS backends for several DNS providers. The projects was started as a Kubernetes Incubator project in February 2017 and being the Kubernetes incubation initiative officially over, the maintainers want to propose the project to be moved to the kubernetes GitHub organization or to kubernetes-sigs, under the sponsorship of sig-network. @@ -35,7 +35,7 @@ When the project was proposed (see the [original discussion](https://github.com/ ExternalDNS’ goal from the beginning was to provide an officially supported solution to those problems. -After two years of development, the project is still in the kubernetes-incubator. +After two years of development, the project is still in the kubernetes-sigs. The incubation has been officially discontinued and to quote @thockin "Incubator projects should either become real projects in Kubernetes, shut themselves down, or move elsewhere" (see original thread [here](https://groups.google.com/forum/#!topic/kubernetes-sig-network/fvpDC_nxtEM)). @@ -57,7 +57,7 @@ External DNS... * Supports already 18 different DNS providers including all major public clouds (AWS, Azure, GCP). -Given that the kubernetes-incubator organization will eventually be shut down, the possible alternatives to moving to be an official Kubernetes project are the following: +Given that the kubernetes-sigs organization will eventually be shut down, the possible alternatives to moving to be an official Kubernetes project are the following: * Shut down the project diff --git a/docs/contributing/crd-source.md b/docs/contributing/crd-source.md index ca43503d31..e326d39356 100644 --- a/docs/contributing/crd-source.md +++ b/docs/contributing/crd-source.md @@ -4,12 +4,12 @@ CRD source provides a generic mechanism to manage DNS records in your favourite ### Details -CRD source watches for a user specified CRD to extract [Endpoints](https://github.com/kubernetes-incubator/external-dns/blob/master/endpoint/endpoint.go) from its `Spec`. +CRD source watches for a user specified CRD to extract [Endpoints](https://github.com/kubernetes-sigs/external-dns/blob/master/endpoint/endpoint.go) from its `Spec`. So users need to create such a CRD and register it to the kubernetes cluster and then create new object(s) of the CRD specifying the Endpoints. ### Registering CRD -Here is typical example of [CRD API type](https://github.com/kubernetes-incubator/external-dns/blob/master/endpoint/endpoint.go) which provides Endpoints to `CRD source`: +Here is typical example of [CRD API type](https://github.com/kubernetes-sigs/external-dns/blob/master/endpoint/endpoint.go) which provides Endpoints to `CRD source`: ```go type TTL int64 diff --git a/docs/faq.md b/docs/faq.md index 20f123a1a6..ca6b15c708 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -151,11 +151,11 @@ spec: ### I have a Service/Ingress but it's ignored by ExternalDNS. Why? -ExternalDNS can be configured to only use Services or Ingresses as source. In case Services or Ingresses seem to be ignored in your setup, consider checking how the flag `--source` was configured when deployed. For reference, see the issue https://github.com/kubernetes-incubator/external-dns/issues/267. +ExternalDNS can be configured to only use Services or Ingresses as source. In case Services or Ingresses seem to be ignored in your setup, consider checking how the flag `--source` was configured when deployed. For reference, see the issue https://github.com/kubernetes-sigs/external-dns/issues/267. ### I'm using an ELB with TXT registry but the CNAME record clashes with the TXT record. How to avoid this? -CNAMEs cannot co-exist with other records, therefore you can use the `--txt-prefix` flag which makes sure to create a TXT record with a name following the pattern `prefix.`. For reference, see the issue https://github.com/kubernetes-incubator/external-dns/issues/262. +CNAMEs cannot co-exist with other records, therefore you can use the `--txt-prefix` flag which makes sure to create a TXT record with a name following the pattern `prefix.`. For reference, see the issue https://github.com/kubernetes-sigs/external-dns/issues/262. ### Can I force ExternalDNS to create CNAME records for ELB/ALB? @@ -260,7 +260,7 @@ and one with `--annotation-filter=kubernetes.io/ingress.class=nginx-external`. ### Can external-dns manage(add/remove) records in a hosted zone which is setup in different AWS account? -Yes, give it the correct cross-account/assume-role permissions and use the `--aws-assume-role` flag https://github.com/kubernetes-incubator/external-dns/pull/524#issue-181256561 +Yes, give it the correct cross-account/assume-role permissions and use the `--aws-assume-role` flag https://github.com/kubernetes-sigs/external-dns/pull/524#issue-181256561 ### How do I provide multiple values to the annotation `external-dns.alpha.kubernetes.io/hostname`? diff --git a/docs/proposal/multi-target.md b/docs/proposal/multi-target.md index 42d2642820..2ed70ed794 100644 --- a/docs/proposal/multi-target.md +++ b/docs/proposal/multi-target.md @@ -10,7 +10,7 @@ ingress/service owns the record it can have multiple targets enable iff they are ## Use cases -See https://github.com/kubernetes-incubator/external-dns/issues/239 +See https://github.com/kubernetes-sigs/external-dns/issues/239 ## Current behaviour *(as of the moment of writing)* @@ -60,7 +60,7 @@ Once Create/Update/Delete lists are calculated correctly (this is where conflict `provider` specific implementation will decide how to convert the structures into required formats. If DNS provider does not (or partially) support multi targets then it is up to the provider to make sure that the change list of records passed to the DNS provider API is valid. **TODO**: explain best strategy. -Additionally see https://github.com/kubernetes-incubator/external-dns/issues/258 +Additionally see https://github.com/kubernetes-sigs/external-dns/issues/258 ## Implementation plan @@ -68,19 +68,19 @@ Brief summary of open PRs and what they are trying to address: ### PRs -1. https://github.com/kubernetes-incubator/external-dns/pull/243 - first attempt to add support for multiple targets. It is lagging far behind from master tip +1. https://github.com/kubernetes-sigs/external-dns/pull/243 - first attempt to add support for multiple targets. It is lagging far behind from master tip *what it does*: unfinished attempt to extend `Endpoint` struct, for it to allow multiple targets (essentially `target string -> targets []string`) *action*: evaluate if rebasing makes sense, or we can just close it. -2. https://github.com/kubernetes-incubator/external-dns/pull/261 - attempt to rework `plan` to make it work correctly with multiple targets. +2. https://github.com/kubernetes-sigs/external-dns/pull/261 - attempt to rework `plan` to make it work correctly with multiple targets. *what it does* : attempts to fix issues with `plan` described in `Current Behaviour` section above. Included tests reveal the current problem with `plan` *action*: rebase on master and make necessary changes to satisfy requirements listed in this document including back-reference to owning record -3. https://github.com/kubernetes-incubator/external-dns/pull/326 - attempt to add multiple target support. +3. https://github.com/kubernetes-sigs/external-dns/pull/326 - attempt to add multiple target support. *what it does*: for each pair `DNS Name` + `Record Type` it aggregates **all** targets from the cluster and passes them to Provider. It adds basic support for DO, Azura, Cloudflare, AWS, GCP, however those are not tested (?). (DNSSimple and Infoblox providers were not updated) @@ -88,8 +88,8 @@ Brief summary of open PRs and what they are trying to address: *action*: the `plan` logic will probably needs to be reworked, however the rest concerning support in Providers and extending `Endpoint` struct can be reused. Rebase on master and add missing pieces. Depends on `2`. - Related PRs: https://github.com/kubernetes-incubator/external-dns/pull/331/files, https://github.com/kubernetes-incubator/external-dns/pull/347/files - aiming at AWS Route53 weighted records. -These PRs should be considered after common agreement about the way to address multi-target support is achieved. Related discussion: https://github.com/kubernetes-incubator/external-dns/issues/196 + Related PRs: https://github.com/kubernetes-sigs/external-dns/pull/331/files, https://github.com/kubernetes-sigs/external-dns/pull/347/files - aiming at AWS Route53 weighted records. +These PRs should be considered after common agreement about the way to address multi-target support is achieved. Related discussion: https://github.com/kubernetes-sigs/external-dns/issues/196 ### How to proceed from here @@ -116,4 +116,4 @@ The following steps are needed: ## Open questions - Handling cases when ingress/service targets include both hostnames and IPs - postpone this until use cases occurs -- "Weighted records scope": https://github.com/kubernetes-incubator/external-dns/issues/196 - this should be considered once multi-target support is implemented +- "Weighted records scope": https://github.com/kubernetes-sigs/external-dns/issues/196 - this should be considered once multi-target support is implemented diff --git a/docs/proposal/registry.md b/docs/proposal/registry.md index 5dc293692b..a7f0a66116 100644 --- a/docs/proposal/registry.md +++ b/docs/proposal/registry.md @@ -1,7 +1,7 @@ # Registry #### [Old name: storage] -Initial discussion - https://github.com/kubernetes-incubator/external-dns/issues/44 +Initial discussion - https://github.com/kubernetes-sigs/external-dns/issues/44 ## Purpose @@ -102,7 +102,7 @@ It is possible that the configmap will go out of sync with the dns provider stat Components: * Source - all endpoints ( collection of ingress, service[type=LoadBalancer] etc.) -* [Plan](https://github.com/kubernetes-incubator/external-dns/issues/13) - object responsible for the create of change lists in external-dns +* [Plan](https://github.com/kubernetes-sigs/external-dns/issues/13) - object responsible for the create of change lists in external-dns * Provider - interface to access the DNS provider API Registry will serve as wrapper around `Provider` providing additional information regarding endpoint ownership. Ownership will further taken into account by `Plan` to filter out records to include only records managed by current ExternalDNS instance (having same `owner-id` value) diff --git a/docs/tutorials/azure.md b/docs/tutorials/azure.md index 51f6d77fcf..91351f2bff 100644 --- a/docs/tutorials/azure.md +++ b/docs/tutorials/azure.md @@ -167,7 +167,7 @@ Ensure that your nginx-ingress deployment has the following arg: added to it: - --publish-service=namespace/nginx-ingress-controller-svcname ``` -For more details see here: [nginx-ingress external-dns](https://github.com/kubernetes-incubator/external-dns/blob/master/docs/faq.md#why-is-externaldns-only-adding-a-single-ip-address-in-route-53-on-aws-when-using-the-nginx-ingress-controller-how-do-i-get-it-to-use-the-fqdn-of-the-elb-assigned-to-my-nginx-ingress-controller-service-instead) +For more details see here: [nginx-ingress external-dns](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/faq.md#why-is-externaldns-only-adding-a-single-ip-address-in-route-53-on-aws-when-using-the-nginx-ingress-controller-how-do-i-get-it-to-use-the-fqdn-of-the-elb-assigned-to-my-nginx-ingress-controller-service-instead) Connect your `kubectl` client to the cluster you want to test ExternalDNS with. Then apply one of the following manifests file to deploy ExternalDNS. diff --git a/docs/tutorials/exoscale.md b/docs/tutorials/exoscale.md index c05c7c639e..cc00178890 100644 --- a/docs/tutorials/exoscale.md +++ b/docs/tutorials/exoscale.md @@ -2,7 +2,7 @@ ## Prerequisites -Exoscale provider support was added via [this PR](https://github.com/kubernetes-incubator/external-dns/pull/625), thus you need to use external-dns v0.5.5. +Exoscale provider support was added via [this PR](https://github.com/kubernetes-sigs/external-dns/pull/625), thus you need to use external-dns v0.5.5. The Exoscale provider expects that your Exoscale zones, you wish to add records to, already exists and are configured correctly. It does not add, remove or configure new zones in anyway. @@ -155,4 +155,4 @@ spec: **Important!**: Don't run dig, nslookup or similar immediately (until you've confirmed the record exists). You'll get hit by [negative DNS caching](https://tools.ietf.org/html/rfc2308), which is hard to flush. -Wait about 30s-1m (interval for external-dns to kick in), then check Exoscales [portal](https://portal.exoscale.com/dns/example.com)... via-ingress.example.com should appear as a A and TXT record with your Elastic-IP-address. \ No newline at end of file +Wait about 30s-1m (interval for external-dns to kick in), then check Exoscales [portal](https://portal.exoscale.com/dns/example.com)... via-ingress.example.com should appear as a A and TXT record with your Elastic-IP-address. diff --git a/docs/tutorials/pdns.md b/docs/tutorials/pdns.md index b04ccfee0a..de632e0a69 100644 --- a/docs/tutorials/pdns.md +++ b/docs/tutorials/pdns.md @@ -4,7 +4,7 @@ The provider has been written for and tested against [PowerDNS](https://github.com/PowerDNS/pdns) v4.1.x and thus requires **PowerDNS Auth Server >= 4.1.x** -PowerDNS provider support was added via [this PR](https://github.com/kubernetes-incubator/external-dns/pull/373), thus you need to use external-dns version >= v0.5 +PowerDNS provider support was added via [this PR](https://github.com/kubernetes-sigs/external-dns/pull/373), thus you need to use external-dns version >= v0.5 The PDNS provider expects that your PowerDNS instance is already setup and functional. It expects that zones, you wish to add records to, already exist diff --git a/docs/tutorials/rdns.md b/docs/tutorials/rdns.md index 8738d023da..df44618909 100644 --- a/docs/tutorials/rdns.md +++ b/docs/tutorials/rdns.md @@ -171,4 +171,4 @@ If you don't see a command prompt, try pressing enter. dnstools# dig @172.31.35.77 nginx.lb.rancher.cloud +short 172.31.42.211 dnstools# -``` \ No newline at end of file +``` diff --git a/go.mod b/go.mod index b9cd90c012..321f36cf6f 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/kubernetes-incubator/external-dns +module github.com/kubernetes-sigs/external-dns go 1.13 @@ -6,89 +6,44 @@ require ( cloud.google.com/go v0.37.4 github.com/Azure/azure-sdk-for-go v10.0.4-beta+incompatible github.com/Azure/go-autorest v10.9.0+incompatible - github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 // indirect - github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 // indirect github.com/alecthomas/kingpin v2.2.5+incompatible - github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 // indirect github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f github.com/aws/aws-sdk-go v1.23.18 - github.com/cenkalti/backoff v2.1.1+incompatible // indirect github.com/cloudflare/cloudflare-go v0.10.1 github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 - github.com/coreos/bbolt v1.3.2 // indirect github.com/coreos/etcd v3.3.10+incompatible - github.com/coreos/go-semver v0.2.0 // indirect - github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect - github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/denverdino/aliyungo v0.0.0-20180815121905-69560d9530f5 - github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/digitalocean/godo v1.19.0 - github.com/dnaeon/go-vcr v1.0.1 // indirect github.com/dnsimple/dnsimple-go v0.14.0 github.com/exoscale/egoscale v0.18.1 github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 - github.com/go-resty/resty v1.8.0 // indirect - github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b // indirect github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8 - github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c // indirect - github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect - github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79 // indirect - github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.8.5 // indirect - github.com/hashicorp/go-multierror v1.0.0 // indirect github.com/heptio/contour v0.13.0 - github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65 - github.com/jonboulle/clockwork v0.1.0 // indirect - github.com/json-iterator/go v1.1.6 // indirect + github.com/kubernetes-incubator/external-dns v0.5.17 github.com/linki/instrumented_http v0.2.0 github.com/linode/linodego v0.3.0 - github.com/mattn/go-isatty v0.0.7 // indirect github.com/miekg/dns v1.0.8 - github.com/mitchellh/mapstructure v1.1.2 // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect - github.com/natefinch/lumberjack v2.0.0+incompatible // indirect github.com/nesv/go-dynect v0.6.0 github.com/nic-at/rc0go v1.1.0 - github.com/onsi/ginkgo v1.8.0 // indirect - github.com/onsi/gomega v1.5.0 // indirect github.com/oracle/oci-go-sdk v1.8.0 github.com/pkg/errors v0.8.1 github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0 - github.com/satori/go.uuid v1.2.0 // indirect - github.com/sergi/go-diff v1.0.0 // indirect github.com/sirupsen/logrus v1.4.1 - github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect - github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect - github.com/smartystreets/gunit v1.0.2 // indirect - github.com/soheilhy/cmux v0.1.3 // indirect - github.com/spf13/cobra v0.0.3 // indirect github.com/stretchr/testify v1.4.0 - github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 // indirect github.com/transip/gotransip v5.8.2+incompatible - github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 // indirect github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 - github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect - github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268 // indirect - go.etcd.io/bbolt v1.3.2 // indirect - go.uber.org/atomic v1.3.2 // indirect - go.uber.org/multierr v1.1.0 // indirect - go.uber.org/zap v1.9.1 // indirect golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a google.golang.org/api v0.3.1 - google.golang.org/appengine v1.5.0 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1 gopkg.in/yaml.v2 v2.2.2 istio.io/api v0.0.0-20190321180614-db16d82d3672 istio.io/istio v0.0.0-20190322063008-2b1331886076 k8s.io/api v0.0.0-20190503184017-f1b257a4ce96 - k8s.io/apiextensions-apiserver v0.0.0-20190503184539-c338b28ceaa1 // indirect k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841 k8s.io/client-go v8.0.0+incompatible - k8s.io/kube-openapi v0.0.0-20190401085232-94e1e7b7574c // indirect ) replace k8s.io/code-generator v0.0.0-20190409092313-b1289fc74931 => k8s.io/code-generator v0.0.0-20181128191024-b1289fc74931 diff --git a/go.sum b/go.sum index 4e1a3dc80f..8789be67a7 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,4 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= @@ -9,19 +8,15 @@ github.com/Azure/azure-sdk-for-go v10.0.4-beta+incompatible h1:FhnlL7/4O3gAB7EBg github.com/Azure/azure-sdk-for-go v10.0.4-beta+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest v10.9.0+incompatible h1:3ccqKLQg+scl0J6krcDgih2Rl+GC1eNuHZeRQYQxKkk= github.com/Azure/go-autorest v10.9.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= -github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= github.com/alecthomas/kingpin v2.2.5+incompatible h1:umWl1NNd72+ZvRti3T9C0SYean2hPZ7ZhxU8bsgc9BQ= github.com/alecthomas/kingpin v2.2.5+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= -github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAKQQZGOJ4knlw+7rfEQQcmwTbt4p5E= github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -34,24 +29,18 @@ github.com/aws/aws-sdk-go v1.23.18 h1:ADU/y1EO8yPzUJJYjcvJ0V9/suezxPh0u6hb5bSYIG github.com/aws/aws-sdk-go v1.23.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 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/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.10.1 h1:d2CL6F9k2O0Ux0w27LgogJ5UOzZRj6a/hDPFqPP68d8= github.com/cloudflare/cloudflare-go v0.10.1/go.mod h1:C0Y6eWnTJPMK2ceuOxx2pjh78UUHihcXeTTHb8r7QjU= github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 h1:rdRS5BT13Iae9ssvcslol66gfOOXjaLYwqerEn/cl9s= github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381/go.mod h1:e5+USP2j8Le2M0Jo3qKPFnNhuo1wueU4nWHCXBOfQ14= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 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= @@ -62,7 +51,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/digitalocean/godo v1.19.0 h1:9ApuchfzGD/XI8Zm0RRnZnytdfYHPjPTRKTnmzQNV7o= github.com/digitalocean/godo v1.19.0/go.mod h1:AAPQ+tiM4st79QHlEBTg8LM7JQNre4SAQCbn56wEyKY= -github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnsimple/dnsimple-go v0.14.0 h1:JGYtVVA/uHc91q0LjDWqR1oVj6EGu9Kn0lMRxjH/w30= github.com/dnsimple/dnsimple-go v0.14.0/go.mod h1:0FYu4qVNv/UcfZPNwa9zi68IkggJu3TIwM54D7rhmI4= @@ -78,29 +66,24 @@ github.com/exoscale/egoscale v0.18.1 h1:1FNZVk8jHUx0AvWhOZxLEDNlacTU0chMXUUNkm9E github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 h1:jmwW6QWvUO2OPe22YfgFvBaaZlSr8Rlrac5lZvG6IdM= github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99/go.mod h1:4mP9w9+vYGw2jUx2+2v03IA+phyQQjNRR4AL3uxlNrs= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-resty/resty v1.8.0 h1:vbNCxbHOWCototzwxf3L63PQCKx6xgT6v8SHfoqkp6U= github.com/go-resty/resty v1.8.0/go.mod h1:n37daLLGIHq2FFYHxg+FYQiwA95FpfNI+A9uxoIYGRk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/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= @@ -109,7 +92,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -123,74 +105,60 @@ github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8 h1:L9JPKrtsHMQ4VCRQfHvbbHBfB2Urn8xf6QZeXZ+OrN4= github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= -github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c h1:Lh2aW+HnU2Nbe1gqD9SOJLJxW1jBMmQOktN2acDyJk8= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79 h1:lR9ssWAqp9qL0bALxqEEkuudiP1eweOdv9jsRK3e7lE= github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/heptio/contour v0.13.0 h1:kiJ7qC439vFD21DTyQPNPzOGfDqkO/y//GrLYWJ5MdY= github.com/heptio/contour v0.13.0/go.mod h1:qYE0FAuA8W1NJEaHmyOoWkJZTRPL1x4GVO5BGZMG1Os= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= github.com/imdario/mergo v0.3.7/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/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65 h1:FP5rOFP4ifbtFIjFHJmwhFrsbDyONILK/FNntl/Pou8= github.com/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 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/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -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/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d h1:JV46OtdhH2vVt8mJ1EWUE94k99vbN9fZs1WQ8kcEapU= github.com/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d/go.mod h1:CHQ3o5KBH1PIS2Fb1mRLTIWO5YzP9kSUB3KoCICwlvA= +github.com/kubernetes-incubator/external-dns v0.5.17 h1:IppndULuSmCM7GUoylCVXHx9FK6d1tu2ftlimkAMaHQ= +github.com/kubernetes-incubator/external-dns v0.5.17/go.mod h1:6LFVqEVTlTlodv3qWMzMRPQFSPKEJ4gIANaKer3kiaY= github.com/linki/instrumented_http v0.2.0 h1:zLhcB3Q/McQQqml3qd5kzdZ0cGnL3vquPFIW2338f5Y= github.com/linki/instrumented_http v0.2.0/go.mod h1:pjYbItoegfuVi2GUOMhEqzvm/SJKuEL3H0tc8QRLRFk= github.com/linode/linodego v0.3.0 h1:I83pEPg4owSy5pCPaKix7xkGbWIjPxmAoc/Yu5OYDDY= github.com/linode/linodego v0.3.0/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= -github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 h1:YFh+sjyJTMQSYjKwM4dFKhJPJC/wfo98tPUc17HdoYw= github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= -github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= @@ -215,20 +183,16 @@ github.com/nic-at/rc0go v1.1.0/go.mod h1:KEa3H5fmDNXCaXSqOeAZxkKnG/8ggr1OHIG25Ve github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/oracle/oci-go-sdk v1.8.0 h1:4SO45bKV0I3/Mn1os3ANDZmV0eSE5z5CLdSUIkxtyzs= github.com/oracle/oci-go-sdk v1.8.0/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= -github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2 h1:CXwSGu/LYmbjEab5aMCs5usQRVBGThelUKBNnoSOuso= github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -238,14 +202,12 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872 h1:0aNv3xC7DmQoy1/x1sMh18g+fihWW68LL13i8ao9kl4= github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -256,25 +218,18 @@ github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0 h1:vOcHdR1nu7DO4B github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0/go.mod h1:FeplEtXXejBYC4NPAFTrs5L7KuK+5RL9bf5nB2vZe9o= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/smartystreets/assertions v0.0.0-20180725160413-e900ae048470/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 h1:hp2CYQUINdZMHdvTdXtPOY2ainKl4IoMcpAXEf2xj3Q= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/gunit v1.0.2 h1:nCXf7TXGchqk8zNVQFTtbeW6rGSrlp9ir9h8wmx0xws= github.com/smartystreets/gunit v1.0.2/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ= -github.com/soheilhy/cmux v0.1.3 h1:09wy7WZk4AqO03yH85Ex1X+Uo3vDsil3Fa9AgF8Emss= github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -283,28 +238,21 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= 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= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/transip/gotransip v5.8.2+incompatible h1:aNJhw/w/3QBqFcHAIPz1ytoK5FexeMzbUCGrrhWr3H0= github.com/transip/gotransip v5.8.2+incompatible/go.mod h1:uacMoJVmrfOcscM4Bi5NVg708b7c6rz2oDTWqa7i2Ic= -github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs= github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= -github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 h1:vG/gY/PxA3v3l04qxe3tDjXyu3bozii8ulSlIPOYKhI= github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA= github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 h1:Q76MzqJu++vAfhj0mVf7t0F4xHUbg+V/d/Uk5PBQjRU= github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92/go.mod h1:AZuEfReFWdvtU0LatbLpo70t3lqdLvph2D5mqFP0bkA= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268 h1:lkoOjizoHqOcEFsvYGE5c8Ykdijjnd0R3r1yDYHzLno= github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268/go.mod h1:mq0zhomp/G6rRTb0dvHWXRHr/2+Qgeq5hMXfJ670+i4= -go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.20.1 h1:pMEjRZ1M4ebWGikflH7nQpV6+Zr88KBMA2XJD3sbijw= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -315,14 +263,12 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5 h1:bselrhR0Or1vomJZC8ZIjWtbDmn9OYFLX5Ik9alpJpE= golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= 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 h1:hX65Cu3JDlGH3uEdK7I99Ii+9kjD6mvnnpfLdEAH0x4= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -333,23 +279,18 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/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 h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -358,17 +299,14 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/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-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c h1:hDn6jm7snBX2O7+EeTk6Q4WXJfKt7MWgtiCCRi1rBoY= golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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= @@ -381,40 +319,32 @@ golang.org/x/tools v0.0.0-20190213192042-740235f6c0d8/go.mod h1:n7NCudcB/nEzxVGm 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= golang.org/x/tools v0.0.0-20190325161752-5a8dccf5b48a/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0 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 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= 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/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1 h1:+fgY/3ngqdBW9oLQCMwL5g+QRkKFPJH05fx2/pipqRQ= gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1/go.mod h1:VV+3haRsgDiVLxyifmMBrBIuCWFBPYKbRssXB9z67Hw= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -429,13 +359,11 @@ istio.io/api v0.0.0-20190321180614-db16d82d3672/go.mod h1:hhLFQmpHia8zgaM37vb2ml istio.io/gogo-genproto v0.0.0-20190124151557-6d926a6e6feb/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI= istio.io/istio v0.0.0-20190322063008-2b1331886076 h1:gZhCrmVzfQJoDl4oav8i5+NF7p7v0M1Pou+2O+hZBtc= istio.io/istio v0.0.0-20190322063008-2b1331886076/go.mod h1:OWBySrQjjk549IhxWCt7DTl9ZSsXdvbgm+SmgGVRsGA= -k8s.io/api v0.0.0-20190226173710-145d52631d00 h1:xYfyMq0qxTGAg3O9GK23GMbNrBcpnFg9IeA6isDgIXk= k8s.io/api v0.0.0-20190226173710-145d52631d00/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/api v0.0.0-20190503184017-f1b257a4ce96 h1:zq/7PZXqJ6ZbPfLRbIm9Qs6gHMviY72SPk4ugPUPDvI= k8s.io/api v0.0.0-20190503184017-f1b257a4ce96/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/apiextensions-apiserver v0.0.0-20190503184539-c338b28ceaa1 h1:uNrdMFGXgDAaw+WyJSuRhnzW2eZkqZjc04SZOr4wky8= k8s.io/apiextensions-apiserver v0.0.0-20190503184539-c338b28ceaa1/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= -k8s.io/apimachinery v0.0.0-20190221084156-01f179d85dbc h1:7z9/6jKWBqkK9GI1RRB0B5fZcmkatLQ/nv8kysch24o= k8s.io/apimachinery v0.0.0-20190221084156-01f179d85dbc/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841 h1:Q4RZrHNtlC/mSdC1sTrcZ5RchC/9vxLVj57pWiCBKv4= k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= diff --git a/internal/testutils/endpoint.go b/internal/testutils/endpoint.go index b4dfa43760..f54fb9ced9 100644 --- a/internal/testutils/endpoint.go +++ b/internal/testutils/endpoint.go @@ -20,7 +20,7 @@ import ( "reflect" "sort" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) /** test utility functions for endpoints verifications */ diff --git a/internal/testutils/endpoint_test.go b/internal/testutils/endpoint_test.go index 2f1204fd68..91259a2126 100644 --- a/internal/testutils/endpoint_test.go +++ b/internal/testutils/endpoint_test.go @@ -20,7 +20,7 @@ import ( "fmt" "sort" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) func ExampleSameEndpoints() { diff --git a/internal/testutils/mock_source.go b/internal/testutils/mock_source.go index 30c5d871d2..6a9db805ff 100644 --- a/internal/testutils/mock_source.go +++ b/internal/testutils/mock_source.go @@ -19,7 +19,7 @@ package testutils import ( "github.com/stretchr/testify/mock" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) // MockSource returns mock endpoints. diff --git a/main.go b/main.go index 057034e594..d499af951f 100644 --- a/main.go +++ b/main.go @@ -27,13 +27,13 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth" - "github.com/kubernetes-incubator/external-dns/controller" - "github.com/kubernetes-incubator/external-dns/pkg/apis/externaldns" - "github.com/kubernetes-incubator/external-dns/pkg/apis/externaldns/validation" - "github.com/kubernetes-incubator/external-dns/plan" - "github.com/kubernetes-incubator/external-dns/provider" - "github.com/kubernetes-incubator/external-dns/registry" - "github.com/kubernetes-incubator/external-dns/source" + "github.com/kubernetes-sigs/external-dns/controller" + "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns" + "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns/validation" + "github.com/kubernetes-sigs/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/provider" + "github.com/kubernetes-sigs/external-dns/registry" + "github.com/kubernetes-sigs/external-dns/source" ) func main() { diff --git a/pkg/apis/externaldns/validation/validation.go b/pkg/apis/externaldns/validation/validation.go index 174550cb47..6ca2814284 100644 --- a/pkg/apis/externaldns/validation/validation.go +++ b/pkg/apis/externaldns/validation/validation.go @@ -20,7 +20,7 @@ import ( "errors" "fmt" - "github.com/kubernetes-incubator/external-dns/pkg/apis/externaldns" + "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns" ) // ValidateConfig performs validation on the Config object diff --git a/pkg/apis/externaldns/validation/validation_test.go b/pkg/apis/externaldns/validation/validation_test.go index da3d9e300c..5f7fe6e40c 100644 --- a/pkg/apis/externaldns/validation/validation_test.go +++ b/pkg/apis/externaldns/validation/validation_test.go @@ -19,7 +19,7 @@ package validation import ( "testing" - "github.com/kubernetes-incubator/external-dns/pkg/apis/externaldns" + "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/plan/conflict.go b/plan/conflict.go index 15c65169f3..f01a724bd3 100644 --- a/plan/conflict.go +++ b/plan/conflict.go @@ -19,7 +19,7 @@ package plan import ( "sort" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) // ConflictResolver is used to make a decision in case of two or more different kubernetes resources diff --git a/plan/conflict_test.go b/plan/conflict_test.go index f702f15901..14ae83cae0 100644 --- a/plan/conflict_test.go +++ b/plan/conflict_test.go @@ -19,7 +19,7 @@ package plan import ( "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/suite" ) diff --git a/plan/plan.go b/plan/plan.go index efe949be6b..bc6c519975 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) // Plan can convert a list of desired and current records to a series of create, @@ -191,7 +191,7 @@ func shouldUpdateProviderSpecific(desired, current *endpoint.Endpoint) bool { } for _, c := range current.ProviderSpecific { // don't consider target health when detecting changes - // see: https://github.com/kubernetes-incubator/external-dns/issues/869#issuecomment-458576954 + // see: https://github.com/kubernetes-sigs/external-dns/issues/869#issuecomment-458576954 if c.Name == "aws/evaluate-target-health" { continue } diff --git a/plan/plan_test.go b/plan/plan_test.go index eb742e11ab..0b54970b30 100644 --- a/plan/plan_test.go +++ b/plan/plan_test.go @@ -19,8 +19,8 @@ package plan import ( "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) diff --git a/plan/policy_test.go b/plan/policy_test.go index 4cffca4d70..c214526269 100644 --- a/plan/policy_test.go +++ b/plan/policy_test.go @@ -20,7 +20,7 @@ import ( "reflect" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) // TestApply tests that applying a policy results in the correct set of changes. diff --git a/provider/alibaba_cloud.go b/provider/alibaba_cloud.go index 6a06949ce7..97856f734c 100644 --- a/provider/alibaba_cloud.go +++ b/provider/alibaba_cloud.go @@ -28,8 +28,8 @@ import ( "github.com/aliyun/alibaba-cloud-sdk-go/services/alidns" "github.com/aliyun/alibaba-cloud-sdk-go/services/pvtz" "github.com/denverdino/aliyungo/metadata" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" yaml "gopkg.in/yaml.v2" ) diff --git a/provider/alibaba_cloud_test.go b/provider/alibaba_cloud_test.go index 4e86dc537d..55a57df5e4 100644 --- a/provider/alibaba_cloud_test.go +++ b/provider/alibaba_cloud_test.go @@ -22,9 +22,9 @@ import ( "github.com/aliyun/alibaba-cloud-sdk-go/services/alidns" "github.com/aliyun/alibaba-cloud-sdk-go/services/pvtz" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/plan" ) type MockAlibabaCloudDNSAPI struct { diff --git a/provider/aws.go b/provider/aws.go index 819cad6369..927a27536b 100644 --- a/provider/aws.go +++ b/provider/aws.go @@ -27,8 +27,8 @@ import ( "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/route53" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/linki/instrumented_http" log "github.com/sirupsen/logrus" ) @@ -246,7 +246,7 @@ func (p *AWSProvider) records(zones map[string]*route53.HostedZone) ([]*endpoint f := func(resp *route53.ListResourceRecordSetsOutput, lastPage bool) (shouldContinue bool) { for _, r := range resp.ResourceRecordSets { // TODO(linki, ownership): Remove once ownership system is in place. - // See: https://github.com/kubernetes-incubator/external-dns/pull/122/files/74e2c3d3e237411e619aefc5aab694742001cdec#r109863370 + // See: https://github.com/kubernetes-sigs/external-dns/pull/122/files/74e2c3d3e237411e619aefc5aab694742001cdec#r109863370 if !supportedRecordType(aws.StringValue(r.Type)) { continue diff --git a/provider/aws_sd.go b/provider/aws_sd.go index d5b0c83bd2..330db7528d 100644 --- a/provider/aws_sd.go +++ b/provider/aws_sd.go @@ -31,9 +31,9 @@ import ( "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" sd "github.com/aws/aws-sdk-go/service/servicediscovery" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/pkg/apis/externaldns" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/linki/instrumented_http" log "github.com/sirupsen/logrus" ) diff --git a/provider/aws_sd_test.go b/provider/aws_sd_test.go index 89605e1838..1f2d2ec83c 100644 --- a/provider/aws_sd_test.go +++ b/provider/aws_sd_test.go @@ -26,9 +26,9 @@ import ( "github.com/aws/aws-sdk-go/aws" sd "github.com/aws/aws-sdk-go/service/servicediscovery" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/provider/aws_test.go b/provider/aws_test.go index 898f0b2eb5..97575af3b5 100644 --- a/provider/aws_test.go +++ b/provider/aws_test.go @@ -27,9 +27,9 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -1049,7 +1049,7 @@ func TestAWSSuitableZones(t *testing.T) { {"foobar.example.org.", []*route53.HostedZone{zones["example-org-private"], zones["example-org"]}}, // all matching private zones are suitable - // https://github.com/kubernetes-incubator/external-dns/pull/356 + // https://github.com/kubernetes-sigs/external-dns/pull/356 {"bar.example.org.", []*route53.HostedZone{zones["example-org-private"], zones["bar-example-org-private"], zones["bar-example-org"]}}, {"foo.bar.example.org.", []*route53.HostedZone{zones["example-org-private"], zones["bar-example-org-private"], zones["bar-example-org"]}}, diff --git a/provider/azure.go b/provider/azure.go index 3f887e5552..a15369e582 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -32,8 +32,8 @@ import ( "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/to" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) const ( diff --git a/provider/azure_test.go b/provider/azure_test.go index 36d697661a..c1498658b9 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -25,9 +25,9 @@ import ( "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/to" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" ) diff --git a/provider/cloudflare.go b/provider/cloudflare.go index f7f5f6360f..893c757272 100644 --- a/provider/cloudflare.go +++ b/provider/cloudflare.go @@ -27,9 +27,9 @@ import ( cloudflare "github.com/cloudflare/cloudflare-go" log "github.com/sirupsen/logrus" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" - "github.com/kubernetes-incubator/external-dns/source" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/source" ) const ( diff --git a/provider/cloudflare_test.go b/provider/cloudflare_test.go index 7e24239786..c2cb67e660 100644 --- a/provider/cloudflare_test.go +++ b/provider/cloudflare_test.go @@ -23,8 +23,8 @@ import ( "testing" cloudflare "github.com/cloudflare/cloudflare-go" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/provider/coredns.go b/provider/coredns.go index 019003ceb1..a30541d454 100644 --- a/provider/coredns.go +++ b/provider/coredns.go @@ -33,8 +33,8 @@ import ( etcdcv3 "github.com/coreos/etcd/clientv3" log "github.com/sirupsen/logrus" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) func init() { diff --git a/provider/coredns_test.go b/provider/coredns_test.go index e86cc2fe51..2f4cc10ec1 100644 --- a/provider/coredns_test.go +++ b/provider/coredns_test.go @@ -21,8 +21,8 @@ import ( "strings" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) const defaultCoreDNSPrefix = "/skydns/" diff --git a/provider/designate.go b/provider/designate.go index 50ac157b7e..4cc1e55334 100644 --- a/provider/designate.go +++ b/provider/designate.go @@ -32,9 +32,9 @@ import ( "github.com/gophercloud/gophercloud/pagination" log "github.com/sirupsen/logrus" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/pkg/tlsutils" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/pkg/tlsutils" + "github.com/kubernetes-sigs/external-dns/plan" ) const ( diff --git a/provider/designate_test.go b/provider/designate_test.go index 3753ed3032..816be30cd5 100644 --- a/provider/designate_test.go +++ b/provider/designate_test.go @@ -31,8 +31,8 @@ import ( "github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets" "github.com/gophercloud/gophercloud/openstack/dns/v2/zones" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) var lastGeneratedDesignateID int32 diff --git a/provider/digital_ocean.go b/provider/digital_ocean.go index 87657a1e62..e6d5f65493 100644 --- a/provider/digital_ocean.go +++ b/provider/digital_ocean.go @@ -26,8 +26,8 @@ import ( log "github.com/sirupsen/logrus" "golang.org/x/oauth2" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) const ( diff --git a/provider/digital_ocean_test.go b/provider/digital_ocean_test.go index 596b16df37..40461ad692 100644 --- a/provider/digital_ocean_test.go +++ b/provider/digital_ocean_test.go @@ -24,8 +24,8 @@ import ( "github.com/digitalocean/godo" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/provider/dnsimple.go b/provider/dnsimple.go index 2bccfe435e..4d827d8cb7 100644 --- a/provider/dnsimple.go +++ b/provider/dnsimple.go @@ -24,8 +24,8 @@ import ( "strings" "github.com/dnsimple/dnsimple-go/dnsimple" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" ) diff --git a/provider/dnsimple_test.go b/provider/dnsimple_test.go index 1f30da0285..4838a0b940 100644 --- a/provider/dnsimple_test.go +++ b/provider/dnsimple_test.go @@ -25,8 +25,8 @@ import ( "strconv" "github.com/dnsimple/dnsimple-go/dnsimple" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/provider/dyn.go b/provider/dyn.go index 52f47ac343..a44e4cc91f 100644 --- a/provider/dyn.go +++ b/provider/dyn.go @@ -29,8 +29,8 @@ import ( "github.com/nesv/go-dynect/dynect" "github.com/sanyu/dynectsoap/dynectsoap" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) const ( diff --git a/provider/dyn_test.go b/provider/dyn_test.go index f2c2fa6d65..f748148c2b 100644 --- a/provider/dyn_test.go +++ b/provider/dyn_test.go @@ -24,7 +24,7 @@ import ( "github.com/nesv/go-dynect/dynect" "github.com/stretchr/testify/assert" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) func TestDynMerge_NoUpdateOnTTL0Changes(t *testing.T) { diff --git a/provider/exoscale.go b/provider/exoscale.go index 57906b199c..27c4dadb3d 100644 --- a/provider/exoscale.go +++ b/provider/exoscale.go @@ -21,8 +21,8 @@ import ( "strings" "github.com/exoscale/egoscale" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" ) diff --git a/provider/exoscale_test.go b/provider/exoscale_test.go index cc94965e2a..caae497ae1 100644 --- a/provider/exoscale_test.go +++ b/provider/exoscale_test.go @@ -22,8 +22,8 @@ import ( "testing" "github.com/exoscale/egoscale" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" ) diff --git a/provider/google.go b/provider/google.go index 3ba73354ff..a0696b2955 100644 --- a/provider/google.go +++ b/provider/google.go @@ -32,8 +32,8 @@ import ( googleapi "google.golang.org/api/googleapi" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) const ( diff --git a/provider/google_test.go b/provider/google_test.go index a45d81cab3..e749a42b2e 100644 --- a/provider/google_test.go +++ b/provider/google_test.go @@ -26,8 +26,8 @@ import ( "golang.org/x/net/context" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "google.golang.org/api/googleapi" diff --git a/provider/infoblox.go b/provider/infoblox.go index 108093e65e..8f9f1a6b92 100644 --- a/provider/infoblox.go +++ b/provider/infoblox.go @@ -25,8 +25,8 @@ import ( "strings" ibclient "github.com/infobloxopen/infoblox-go-client" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/sirupsen/logrus" ) diff --git a/provider/infoblox_test.go b/provider/infoblox_test.go index 6104fe8466..c4c821ba4c 100644 --- a/provider/infoblox_test.go +++ b/provider/infoblox_test.go @@ -25,8 +25,8 @@ import ( "testing" ibclient "github.com/infobloxopen/infoblox-go-client" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" ) diff --git a/provider/inmemory.go b/provider/inmemory.go index d480fe160c..fd08a0c08e 100644 --- a/provider/inmemory.go +++ b/provider/inmemory.go @@ -23,8 +23,8 @@ import ( log "github.com/sirupsen/logrus" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) var ( diff --git a/provider/inmemory_test.go b/provider/inmemory_test.go index 0d61a94807..96d5780f91 100644 --- a/provider/inmemory_test.go +++ b/provider/inmemory_test.go @@ -20,9 +20,9 @@ import ( "context" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/provider/linode.go b/provider/linode.go index 05076133e8..04f442c153 100644 --- a/provider/linode.go +++ b/provider/linode.go @@ -29,8 +29,8 @@ import ( "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) // LinodeDomainClient interface to ease testing diff --git a/provider/linode_test.go b/provider/linode_test.go index 9abf1950c8..32f255b87c 100644 --- a/provider/linode_test.go +++ b/provider/linode_test.go @@ -21,8 +21,8 @@ import ( "os" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/linode/linodego" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/provider/ns1.go b/provider/ns1.go index 988481d381..4540059235 100644 --- a/provider/ns1.go +++ b/provider/ns1.go @@ -29,8 +29,8 @@ import ( api "gopkg.in/ns1/ns1-go.v2/rest" "gopkg.in/ns1/ns1-go.v2/rest/model/dns" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) const ( diff --git a/provider/ns1_test.go b/provider/ns1_test.go index 6fc5ea8236..756fa2da73 100644 --- a/provider/ns1_test.go +++ b/provider/ns1_test.go @@ -23,8 +23,8 @@ import ( "os" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/provider/oci.go b/provider/oci.go index 6b5ae563a3..431a17a140 100644 --- a/provider/oci.go +++ b/provider/oci.go @@ -27,8 +27,8 @@ import ( log "github.com/sirupsen/logrus" yaml "gopkg.in/yaml.v2" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) const ociRecordTTL = 300 diff --git a/provider/oci_test.go b/provider/oci_test.go index fe7c80677e..985998bebc 100644 --- a/provider/oci_test.go +++ b/provider/oci_test.go @@ -26,8 +26,8 @@ import ( "github.com/pkg/errors" "github.com/stretchr/testify/require" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) type mockOCIDNSClient struct{} diff --git a/provider/pdns.go b/provider/pdns.go index 4622971f96..8553b021d5 100644 --- a/provider/pdns.go +++ b/provider/pdns.go @@ -33,9 +33,9 @@ import ( "net" pgo "github.com/ffledgling/pdns-go" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/pkg/tlsutils" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/pkg/tlsutils" + "github.com/kubernetes-sigs/external-dns/plan" ) type pdnsChangeType string diff --git a/provider/pdns_test.go b/provider/pdns_test.go index 7caf48a044..cd40dbc655 100644 --- a/provider/pdns_test.go +++ b/provider/pdns_test.go @@ -29,7 +29,7 @@ import ( "github.com/stretchr/testify/suite" pgo "github.com/ffledgling/pdns-go" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) // FIXME: What do we do about labels? diff --git a/provider/provider.go b/provider/provider.go index 7c6f1a61e1..1d55ec5927 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -21,8 +21,8 @@ import ( "net" "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) // Provider defines the interface DNS providers should implement. diff --git a/provider/rcode0.go b/provider/rcode0.go index d9a0adcdbc..5827b82ac3 100644 --- a/provider/rcode0.go +++ b/provider/rcode0.go @@ -23,8 +23,8 @@ import ( "os" "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" rc0 "github.com/nic-at/rc0go" log "github.com/sirupsen/logrus" ) diff --git a/provider/rcode0_test.go b/provider/rcode0_test.go index 904d2a8e60..dc5dc1a955 100644 --- a/provider/rcode0_test.go +++ b/provider/rcode0_test.go @@ -22,8 +22,8 @@ import ( "os" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" rc0 "github.com/nic-at/rc0go" "github.com/stretchr/testify/require" ) diff --git a/provider/rdns.go b/provider/rdns.go index a56563fe5d..459cf786c6 100644 --- a/provider/rdns.go +++ b/provider/rdns.go @@ -33,8 +33,8 @@ import ( "github.com/pkg/errors" "istio.io/istio/pkg/log" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) const ( diff --git a/provider/rdns_test.go b/provider/rdns_test.go index 084b1ff00b..57fe9f272b 100644 --- a/provider/rdns_test.go +++ b/provider/rdns_test.go @@ -27,8 +27,8 @@ import ( "github.com/coreos/etcd/mvcc/mvccpb" "github.com/stretchr/testify/assert" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) type fakeEtcdv3Client struct { diff --git a/provider/rfc2136.go b/provider/rfc2136.go index d6add81c11..ab33da1ffe 100644 --- a/provider/rfc2136.go +++ b/provider/rfc2136.go @@ -28,8 +28,8 @@ import ( "github.com/pkg/errors" log "github.com/sirupsen/logrus" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" ) // rfc2136 provider type diff --git a/provider/rfc2136_test.go b/provider/rfc2136_test.go index 8ce0f88ad8..6233891b20 100644 --- a/provider/rfc2136_test.go +++ b/provider/rfc2136_test.go @@ -21,8 +21,8 @@ import ( "strings" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/miekg/dns" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" diff --git a/provider/transip.go b/provider/transip.go index 1fff1daa2e..58192e79ab 100644 --- a/provider/transip.go +++ b/provider/transip.go @@ -6,8 +6,8 @@ import ( "fmt" "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" "github.com/transip/gotransip" transip "github.com/transip/gotransip/domain" diff --git a/provider/transip_test.go b/provider/transip_test.go index b195a246d1..5a4450dac6 100644 --- a/provider/transip_test.go +++ b/provider/transip_test.go @@ -3,7 +3,7 @@ package provider import ( "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" transip "github.com/transip/gotransip/domain" ) diff --git a/provider/vinyldns.go b/provider/vinyldns.go index cccfc6572e..dc485ab190 100644 --- a/provider/vinyldns.go +++ b/provider/vinyldns.go @@ -22,8 +22,8 @@ import ( "os" "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" "github.com/vinyldns/go-vinyldns/vinyldns" ) diff --git a/provider/vinyldns_test.go b/provider/vinyldns_test.go index 7bb9381e77..70eacc0385 100644 --- a/provider/vinyldns_test.go +++ b/provider/vinyldns_test.go @@ -22,8 +22,8 @@ import ( "os" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/vinyldns/go-vinyldns/vinyldns" diff --git a/registry/aws_sd_registry.go b/registry/aws_sd_registry.go index 64cd95b343..b73ed97726 100644 --- a/registry/aws_sd_registry.go +++ b/registry/aws_sd_registry.go @@ -20,9 +20,9 @@ import ( "context" "errors" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" - "github.com/kubernetes-incubator/external-dns/provider" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/provider" ) // AWSSDRegistry implements registry interface with ownership information associated via the Description field of SD Service diff --git a/registry/aws_sd_registry_test.go b/registry/aws_sd_registry_test.go index 6ebda2e011..953c2cc8bb 100644 --- a/registry/aws_sd_registry_test.go +++ b/registry/aws_sd_registry_test.go @@ -20,9 +20,9 @@ import ( "context" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/registry/noop.go b/registry/noop.go index 701f01c4ec..d6b04abcfa 100644 --- a/registry/noop.go +++ b/registry/noop.go @@ -19,9 +19,9 @@ package registry import ( "context" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" - "github.com/kubernetes-incubator/external-dns/provider" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/provider" ) // NoopRegistry implements registry interface without ownership directly propagating changes to dns provider diff --git a/registry/noop_test.go b/registry/noop_test.go index c1688503c8..01954576f3 100644 --- a/registry/noop_test.go +++ b/registry/noop_test.go @@ -20,10 +20,10 @@ import ( "context" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" - "github.com/kubernetes-incubator/external-dns/plan" - "github.com/kubernetes-incubator/external-dns/provider" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/provider" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/registry/registry.go b/registry/registry.go index 71e926341c..bf01dd8980 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -19,8 +19,8 @@ package registry import ( "context" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" ) diff --git a/registry/txt.go b/registry/txt.go index 3305568f07..2d56c72d9b 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -23,9 +23,9 @@ import ( "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/plan" - "github.com/kubernetes-incubator/external-dns/provider" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/provider" log "github.com/sirupsen/logrus" ) diff --git a/registry/txt_test.go b/registry/txt_test.go index 6f7cf7db78..bfa2485b2d 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -22,10 +22,10 @@ import ( "testing" "time" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" - "github.com/kubernetes-incubator/external-dns/plan" - "github.com/kubernetes-incubator/external-dns/provider" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/plan" + "github.com/kubernetes-sigs/external-dns/provider" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/source/cloudfoundry.go b/source/cloudfoundry.go index 8d8270c4ca..e136860055 100644 --- a/source/cloudfoundry.go +++ b/source/cloudfoundry.go @@ -20,7 +20,7 @@ import ( "net/url" cfclient "github.com/cloudfoundry-community/go-cfclient" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) type cloudfoundrySource struct { diff --git a/source/compatibility.go b/source/compatibility.go index e25184d040..069f699185 100644 --- a/source/compatibility.go +++ b/source/compatibility.go @@ -19,7 +19,7 @@ package source import ( "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" v1 "k8s.io/api/core/v1" ) diff --git a/source/connector.go b/source/connector.go index 6e4a1963d0..4adadea5ce 100644 --- a/source/connector.go +++ b/source/connector.go @@ -21,7 +21,7 @@ import ( "net" "time" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" log "github.com/sirupsen/logrus" ) diff --git a/source/connector_test.go b/source/connector_test.go index 63a29f084c..f4cd673f58 100644 --- a/source/connector_test.go +++ b/source/connector_test.go @@ -21,7 +21,7 @@ import ( "net" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) diff --git a/source/crd.go b/source/crd.go index 872eb4e08d..66c464c7bd 100644 --- a/source/crd.go +++ b/source/crd.go @@ -21,7 +21,7 @@ import ( "os" "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/source/crd_test.go b/source/crd_test.go index 863e6373fb..6f1ed19a5e 100644 --- a/source/crd_test.go +++ b/source/crd_test.go @@ -26,7 +26,7 @@ import ( "strings" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/source/dedup_source.go b/source/dedup_source.go index de26388fb1..756b21a399 100644 --- a/source/dedup_source.go +++ b/source/dedup_source.go @@ -19,7 +19,7 @@ package source import ( log "github.com/sirupsen/logrus" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) // dedupSource is a Source that removes duplicate endpoints from its wrapped source. diff --git a/source/dedup_source_test.go b/source/dedup_source_test.go index 04cd43598c..222b8f6f81 100644 --- a/source/dedup_source_test.go +++ b/source/dedup_source_test.go @@ -19,8 +19,8 @@ package source import ( "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" ) // Validates that dedupSource is a Source diff --git a/source/empty.go b/source/empty.go index c219581d3a..591a75c5dc 100644 --- a/source/empty.go +++ b/source/empty.go @@ -16,7 +16,7 @@ limitations under the License. package source -import "github.com/kubernetes-incubator/external-dns/endpoint" +import "github.com/kubernetes-sigs/external-dns/endpoint" // emptySource is a Source that returns no endpoints. type emptySource struct{} diff --git a/source/fake.go b/source/fake.go index 9a7637d265..be3f55af13 100644 --- a/source/fake.go +++ b/source/fake.go @@ -26,7 +26,7 @@ import ( "net" "time" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) // fakeSource is an implementation of Source that provides dummy endpoints for diff --git a/source/fake_test.go b/source/fake_test.go index 50052cc742..77a254ca6e 100644 --- a/source/fake_test.go +++ b/source/fake_test.go @@ -21,7 +21,7 @@ import ( "regexp" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) func generateTestEndpoints() []*endpoint.Endpoint { diff --git a/source/gateway.go b/source/gateway.go index 85d58d5823..f3040cefde 100644 --- a/source/gateway.go +++ b/source/gateway.go @@ -30,7 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "k8s.io/client-go/kubernetes" ) diff --git a/source/gateway_test.go b/source/gateway_test.go index e0598ed69b..2544160bb3 100644 --- a/source/gateway_test.go +++ b/source/gateway_test.go @@ -22,7 +22,7 @@ import ( istionetworking "istio.io/api/networking/v1alpha3" istiomodel "istio.io/istio/pilot/pkg/model" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "strconv" "sync" diff --git a/source/ingress.go b/source/ingress.go index 3eed665493..c841ca26d3 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -25,7 +25,7 @@ import ( "time" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" log "github.com/sirupsen/logrus" "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/source/ingress_test.go b/source/ingress_test.go index aff05ce6cc..ae2d560d73 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -26,7 +26,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes/fake" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/source/ingressroute.go b/source/ingressroute.go index cf4504446c..ad8df10c9c 100644 --- a/source/ingressroute.go +++ b/source/ingressroute.go @@ -28,7 +28,7 @@ import ( contour "github.com/heptio/contour/apis/generated/clientset/versioned" contourinformers "github.com/heptio/contour/apis/generated/informers/externalversions" extinformers "github.com/heptio/contour/apis/generated/informers/externalversions/contour/v1beta1" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/pkg/errors" log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/source/ingressroute_test.go b/source/ingressroute_test.go index e2ddbe5daf..6bf466e46a 100644 --- a/source/ingressroute_test.go +++ b/source/ingressroute_test.go @@ -29,7 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" fakeKube "k8s.io/client-go/kubernetes/fake" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) // This is a compile-time validation that ingressRouteSource is a Source. diff --git a/source/multi_source.go b/source/multi_source.go index 0ea81f126d..360c9c87ff 100644 --- a/source/multi_source.go +++ b/source/multi_source.go @@ -16,7 +16,7 @@ limitations under the License. package source -import "github.com/kubernetes-incubator/external-dns/endpoint" +import "github.com/kubernetes-sigs/external-dns/endpoint" // multiSource is a Source that merges the endpoints of its nested Sources. type multiSource struct { diff --git a/source/multi_source_test.go b/source/multi_source_test.go index b0241afe5f..2102c514a2 100644 --- a/source/multi_source_test.go +++ b/source/multi_source_test.go @@ -20,8 +20,8 @@ import ( "errors" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" - "github.com/kubernetes-incubator/external-dns/internal/testutils" + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/internal/testutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/source/node.go b/source/node.go index 46de331514..4364074f3b 100644 --- a/source/node.go +++ b/source/node.go @@ -33,7 +33,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) type nodeSource struct { diff --git a/source/node_test.go b/source/node_test.go index 9e44718511..d347945f5a 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -3,7 +3,7 @@ package source import ( "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" diff --git a/source/service.go b/source/service.go index 1fba3d624b..fa595fa027 100644 --- a/source/service.go +++ b/source/service.go @@ -37,7 +37,7 @@ import ( "time" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) const ( diff --git a/source/service_test.go b/source/service_test.go index b5265e339f..a83d1fd334 100644 --- a/source/service_test.go +++ b/source/service_test.go @@ -27,7 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/source/shared_test.go b/source/shared_test.go index 09645fcb4d..3118143329 100644 --- a/source/shared_test.go +++ b/source/shared_test.go @@ -21,7 +21,7 @@ import ( "strings" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) // test helper functions diff --git a/source/source.go b/source/source.go index 83fc846917..b4f96dd9de 100644 --- a/source/source.go +++ b/source/source.go @@ -23,7 +23,7 @@ import ( "strconv" "strings" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" ) const ( diff --git a/source/source_test.go b/source/source_test.go index f03b04e7c7..874336f249 100644 --- a/source/source_test.go +++ b/source/source_test.go @@ -20,7 +20,7 @@ import ( "fmt" "testing" - "github.com/kubernetes-incubator/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" ) From ce94d2f3285f90aefa8bf201bb1cd640699c8755 Mon Sep 17 00:00:00 2001 From: Vincent Desjardins Date: Fri, 1 Nov 2019 21:27:21 -0400 Subject: [PATCH 20/79] Google Provider: add support for batch interval. The parameter is google-batch-change-interval. Default value is 2s. --- main.go | 2 +- pkg/apis/externaldns/types.go | 3 + pkg/apis/externaldns/types_test.go | 141 +++++++++++++++-------------- provider/google.go | 8 +- 4 files changed, 84 insertions(+), 70 deletions(-) diff --git a/main.go b/main.go index 1f08a82c11..3bbb9ad343 100644 --- a/main.go +++ b/main.go @@ -142,7 +142,7 @@ func main() { case "rcodezero": p, err = provider.NewRcodeZeroProvider(domainFilter, cfg.DryRun, cfg.RcodezeroTXTEncrypt) case "google": - p, err = provider.NewGoogleProvider(cfg.GoogleProject, domainFilter, zoneIDFilter, cfg.GoogleBatchChangeSize, cfg.DryRun) + p, err = provider.NewGoogleProvider(cfg.GoogleProject, domainFilter, zoneIDFilter, cfg.GoogleBatchChangeSize, cfg.GoogleBatchChangeInterval, cfg.DryRun) case "digitalocean": p, err = provider.NewDigitalOceanProvider(domainFilter, cfg.DryRun) case "linode": diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 0f976aa9d1..e89bb40b3a 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -55,6 +55,7 @@ type Config struct { Provider string GoogleProject string GoogleBatchChangeSize int + GoogleBatchChangeInterval time.Duration DomainFilter []string ExcludeDomains []string ZoneIDFilter []string @@ -147,6 +148,7 @@ var defaultConfig = &Config{ Provider: "", GoogleProject: "", GoogleBatchChangeSize: 1000, + GoogleBatchChangeInterval: time.Second, DomainFilter: []string{}, ExcludeDomains: []string{}, AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json", @@ -293,6 +295,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("zone-id-filter", "Filter target zones by hosted zone id; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.ZoneIDFilter) app.Flag("google-project", "When using the Google provider, current project is auto-detected, when running on GCP. Specify other project with this. Must be specified when running outside GCP.").Default(defaultConfig.GoogleProject).StringVar(&cfg.GoogleProject) app.Flag("google-batch-change-size", "When using the Google provider, set the maximum number of changes that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.GoogleBatchChangeSize)).IntVar(&cfg.GoogleBatchChangeSize) + app.Flag("google-batch-change-interval", "When using the Google provider, set the interval between batch changes.").Default(defaultConfig.GoogleBatchChangeInterval.String()).DurationVar(&cfg.GoogleBatchChangeInterval) app.Flag("alibaba-cloud-config-file", "When using the Alibaba Cloud provider, specify the Alibaba Cloud configuration file (required when --provider=alibabacloud").Default(defaultConfig.AlibabaCloudConfigFile).StringVar(&cfg.AlibabaCloudConfigFile) app.Flag("alibaba-cloud-zone-type", "When using the Alibaba Cloud provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AlibabaCloudZoneType).EnumVar(&cfg.AlibabaCloudZoneType, "", "public", "private") app.Flag("aws-zone-type", "When using the AWS provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AWSZoneType).EnumVar(&cfg.AWSZoneType, "", "public", "private") diff --git a/pkg/apis/externaldns/types_test.go b/pkg/apis/externaldns/types_test.go index 19d9f45091..3134b51941 100644 --- a/pkg/apis/externaldns/types_test.go +++ b/pkg/apis/externaldns/types_test.go @@ -41,6 +41,7 @@ var ( Provider: "google", GoogleProject: "", GoogleBatchChangeSize: 1000, + GoogleBatchChangeInterval: time.Second, DomainFilter: []string{""}, ExcludeDomains: []string{""}, ZoneIDFilter: []string{""}, @@ -106,6 +107,7 @@ var ( Provider: "google", GoogleProject: "project", GoogleBatchChangeSize: 100, + GoogleBatchChangeInterval: time.Second * 2, DomainFilter: []string{"example.org", "company.com"}, ExcludeDomains: []string{"xapi.example.org", "xapi.company.com"}, ZoneIDFilter: []string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"}, @@ -177,6 +179,7 @@ var ( Provider: "google", GoogleProject: "", GoogleBatchChangeSize: 1000, + GoogleBatchChangeInterval: time.Second, DomainFilter: []string{""}, ExcludeDomains: []string{""}, ZoneIDFilter: []string{""}, @@ -260,6 +263,7 @@ func TestParseFlags(t *testing.T) { "--provider=google", "--google-project=project", "--google-batch-change-size=100", + "--google-batch-change-interval=2s", "--azure-config-file=azure.json", "--azure-resource-group=arg", "--cloudflare-proxied", @@ -326,74 +330,75 @@ func TestParseFlags(t *testing.T) { title: "override everything via environment variables", args: []string{}, envVars: map[string]string{ - "EXTERNAL_DNS_MASTER": "http://127.0.0.1:8080", - "EXTERNAL_DNS_KUBECONFIG": "/some/path", - "EXTERNAL_DNS_REQUEST_TIMEOUT": "77s", - "EXTERNAL_DNS_ISTIO_INGRESS_GATEWAY": "istio-other/istio-otheringressgateway", - "EXTERNAL_DNS_CONTOUR_LOAD_BALANCER": "heptio-contour-other/contour-other", - "EXTERNAL_DNS_SOURCE": "service\ningress\nconnector", - "EXTERNAL_DNS_NAMESPACE": "namespace", - "EXTERNAL_DNS_FQDN_TEMPLATE": "{{.Name}}.service.example.com", - "EXTERNAL_DNS_IGNORE_HOSTNAME_ANNOTATION": "1", - "EXTERNAL_DNS_COMPATIBILITY": "mate", - "EXTERNAL_DNS_PROVIDER": "google", - "EXTERNAL_DNS_GOOGLE_PROJECT": "project", - "EXTERNAL_DNS_GOOGLE_BATCH_CHANGE_SIZE": "100", - "EXTERNAL_DNS_AZURE_CONFIG_FILE": "azure.json", - "EXTERNAL_DNS_AZURE_RESOURCE_GROUP": "arg", - "EXTERNAL_DNS_CLOUDFLARE_PROXIED": "1", - "EXTERNAL_DNS_CLOUDFLARE_ZONES_PER_PAGE": "20", - "EXTERNAL_DNS_COREDNS_PREFIX": "/coredns/", - "EXTERNAL_DNS_INFOBLOX_GRID_HOST": "127.0.0.1", - "EXTERNAL_DNS_INFOBLOX_WAPI_PORT": "8443", - "EXTERNAL_DNS_INFOBLOX_WAPI_USERNAME": "infoblox", - "EXTERNAL_DNS_INFOBLOX_WAPI_PASSWORD": "infoblox", - "EXTERNAL_DNS_INFOBLOX_WAPI_VERSION": "2.6.1", - "EXTERNAL_DNS_INFOBLOX_VIEW": "internal", - "EXTERNAL_DNS_INFOBLOX_SSL_VERIFY": "0", - "EXTERNAL_DNS_INFOBLOX_MAX_RESULTS": "2000", - "EXTERNAL_DNS_OCI_CONFIG_FILE": "oci.yaml", - "EXTERNAL_DNS_INMEMORY_ZONE": "example.org\ncompany.com", - "EXTERNAL_DNS_DOMAIN_FILTER": "example.org\ncompany.com", - "EXTERNAL_DNS_EXCLUDE_DOMAINS": "xapi.example.org\nxapi.company.com", - "EXTERNAL_DNS_PDNS_SERVER": "http://ns.example.com:8081", - "EXTERNAL_DNS_PDNS_API_KEY": "some-secret-key", - "EXTERNAL_DNS_PDNS_TLS_ENABLED": "1", - "EXTERNAL_DNS_RDNS_ROOT_DOMAIN": "lb.rancher.cloud", - "EXTERNAL_DNS_TLS_CA": "/path/to/ca.crt", - "EXTERNAL_DNS_TLS_CLIENT_CERT": "/path/to/cert.pem", - "EXTERNAL_DNS_TLS_CLIENT_CERT_KEY": "/path/to/key.pem", - "EXTERNAL_DNS_ZONE_ID_FILTER": "/hostedzone/ZTST1\n/hostedzone/ZTST2", - "EXTERNAL_DNS_AWS_ZONE_TYPE": "private", - "EXTERNAL_DNS_AWS_ZONE_TAGS": "tag=foo", - "EXTERNAL_DNS_AWS_ASSUME_ROLE": "some-other-role", - "EXTERNAL_DNS_AWS_BATCH_CHANGE_SIZE": "100", - "EXTERNAL_DNS_AWS_BATCH_CHANGE_INTERVAL": "2s", - "EXTERNAL_DNS_AWS_EVALUATE_TARGET_HEALTH": "0", - "EXTERNAL_DNS_AWS_API_RETRIES": "13", - "EXTERNAL_DNS_AWS_PREFER_CNAME": "true", - "EXTERNAL_DNS_POLICY": "upsert-only", - "EXTERNAL_DNS_REGISTRY": "noop", - "EXTERNAL_DNS_TXT_OWNER_ID": "owner-1", - "EXTERNAL_DNS_TXT_PREFIX": "associated-txt-record", - "EXTERNAL_DNS_TXT_CACHE_INTERVAL": "12h", - "EXTERNAL_DNS_INTERVAL": "10m", - "EXTERNAL_DNS_ONCE": "1", - "EXTERNAL_DNS_DRY_RUN": "1", - "EXTERNAL_DNS_LOG_FORMAT": "json", - "EXTERNAL_DNS_METRICS_ADDRESS": "127.0.0.1:9099", - "EXTERNAL_DNS_LOG_LEVEL": "debug", - "EXTERNAL_DNS_CONNECTOR_SOURCE_SERVER": "localhost:8081", - "EXTERNAL_DNS_EXOSCALE_ENDPOINT": "https://api.foo.ch/dns", - "EXTERNAL_DNS_EXOSCALE_APIKEY": "1", - "EXTERNAL_DNS_EXOSCALE_APISECRET": "2", - "EXTERNAL_DNS_CRD_SOURCE_APIVERSION": "test.k8s.io/v1alpha1", - "EXTERNAL_DNS_CRD_SOURCE_KIND": "Endpoint", - "EXTERNAL_DNS_RCODEZERO_TXT_ENCRYPT": "1", - "EXTERNAL_DNS_NS1_ENDPOINT": "https://api.example.com/v1", - "EXTERNAL_DNS_NS1_IGNORESSL": "1", - "EXTERNAL_DNS_TRANSIP_ACCOUNT": "transip", - "EXTERNAL_DNS_TRANSIP_KEYFILE": "/path/to/transip.key", + "EXTERNAL_DNS_MASTER": "http://127.0.0.1:8080", + "EXTERNAL_DNS_KUBECONFIG": "/some/path", + "EXTERNAL_DNS_REQUEST_TIMEOUT": "77s", + "EXTERNAL_DNS_ISTIO_INGRESS_GATEWAY": "istio-other/istio-otheringressgateway", + "EXTERNAL_DNS_CONTOUR_LOAD_BALANCER": "heptio-contour-other/contour-other", + "EXTERNAL_DNS_SOURCE": "service\ningress\nconnector", + "EXTERNAL_DNS_NAMESPACE": "namespace", + "EXTERNAL_DNS_FQDN_TEMPLATE": "{{.Name}}.service.example.com", + "EXTERNAL_DNS_IGNORE_HOSTNAME_ANNOTATION": "1", + "EXTERNAL_DNS_COMPATIBILITY": "mate", + "EXTERNAL_DNS_PROVIDER": "google", + "EXTERNAL_DNS_GOOGLE_PROJECT": "project", + "EXTERNAL_DNS_GOOGLE_BATCH_CHANGE_SIZE": "100", + "EXTERNAL_DNS_GOOGLE_BATCH_CHANGE_INTERVAL": "2s", + "EXTERNAL_DNS_AZURE_CONFIG_FILE": "azure.json", + "EXTERNAL_DNS_AZURE_RESOURCE_GROUP": "arg", + "EXTERNAL_DNS_CLOUDFLARE_PROXIED": "1", + "EXTERNAL_DNS_CLOUDFLARE_ZONES_PER_PAGE": "20", + "EXTERNAL_DNS_COREDNS_PREFIX": "/coredns/", + "EXTERNAL_DNS_INFOBLOX_GRID_HOST": "127.0.0.1", + "EXTERNAL_DNS_INFOBLOX_WAPI_PORT": "8443", + "EXTERNAL_DNS_INFOBLOX_WAPI_USERNAME": "infoblox", + "EXTERNAL_DNS_INFOBLOX_WAPI_PASSWORD": "infoblox", + "EXTERNAL_DNS_INFOBLOX_WAPI_VERSION": "2.6.1", + "EXTERNAL_DNS_INFOBLOX_VIEW": "internal", + "EXTERNAL_DNS_INFOBLOX_SSL_VERIFY": "0", + "EXTERNAL_DNS_INFOBLOX_MAX_RESULTS": "2000", + "EXTERNAL_DNS_OCI_CONFIG_FILE": "oci.yaml", + "EXTERNAL_DNS_INMEMORY_ZONE": "example.org\ncompany.com", + "EXTERNAL_DNS_DOMAIN_FILTER": "example.org\ncompany.com", + "EXTERNAL_DNS_EXCLUDE_DOMAINS": "xapi.example.org\nxapi.company.com", + "EXTERNAL_DNS_PDNS_SERVER": "http://ns.example.com:8081", + "EXTERNAL_DNS_PDNS_API_KEY": "some-secret-key", + "EXTERNAL_DNS_PDNS_TLS_ENABLED": "1", + "EXTERNAL_DNS_RDNS_ROOT_DOMAIN": "lb.rancher.cloud", + "EXTERNAL_DNS_TLS_CA": "/path/to/ca.crt", + "EXTERNAL_DNS_TLS_CLIENT_CERT": "/path/to/cert.pem", + "EXTERNAL_DNS_TLS_CLIENT_CERT_KEY": "/path/to/key.pem", + "EXTERNAL_DNS_ZONE_ID_FILTER": "/hostedzone/ZTST1\n/hostedzone/ZTST2", + "EXTERNAL_DNS_AWS_ZONE_TYPE": "private", + "EXTERNAL_DNS_AWS_ZONE_TAGS": "tag=foo", + "EXTERNAL_DNS_AWS_ASSUME_ROLE": "some-other-role", + "EXTERNAL_DNS_AWS_BATCH_CHANGE_SIZE": "100", + "EXTERNAL_DNS_AWS_BATCH_CHANGE_INTERVAL": "2s", + "EXTERNAL_DNS_AWS_EVALUATE_TARGET_HEALTH": "0", + "EXTERNAL_DNS_AWS_API_RETRIES": "13", + "EXTERNAL_DNS_AWS_PREFER_CNAME": "true", + "EXTERNAL_DNS_POLICY": "upsert-only", + "EXTERNAL_DNS_REGISTRY": "noop", + "EXTERNAL_DNS_TXT_OWNER_ID": "owner-1", + "EXTERNAL_DNS_TXT_PREFIX": "associated-txt-record", + "EXTERNAL_DNS_TXT_CACHE_INTERVAL": "12h", + "EXTERNAL_DNS_INTERVAL": "10m", + "EXTERNAL_DNS_ONCE": "1", + "EXTERNAL_DNS_DRY_RUN": "1", + "EXTERNAL_DNS_LOG_FORMAT": "json", + "EXTERNAL_DNS_METRICS_ADDRESS": "127.0.0.1:9099", + "EXTERNAL_DNS_LOG_LEVEL": "debug", + "EXTERNAL_DNS_CONNECTOR_SOURCE_SERVER": "localhost:8081", + "EXTERNAL_DNS_EXOSCALE_ENDPOINT": "https://api.foo.ch/dns", + "EXTERNAL_DNS_EXOSCALE_APIKEY": "1", + "EXTERNAL_DNS_EXOSCALE_APISECRET": "2", + "EXTERNAL_DNS_CRD_SOURCE_APIVERSION": "test.k8s.io/v1alpha1", + "EXTERNAL_DNS_CRD_SOURCE_KIND": "Endpoint", + "EXTERNAL_DNS_RCODEZERO_TXT_ENCRYPT": "1", + "EXTERNAL_DNS_NS1_ENDPOINT": "https://api.example.com/v1", + "EXTERNAL_DNS_NS1_IGNORESSL": "1", + "EXTERNAL_DNS_TRANSIP_ACCOUNT": "transip", + "EXTERNAL_DNS_TRANSIP_KEYFILE": "/path/to/transip.key", }, expected: overriddenConfig, }, diff --git a/provider/google.go b/provider/google.go index 85c3a9084e..49ece4f0a6 100644 --- a/provider/google.go +++ b/provider/google.go @@ -21,6 +21,7 @@ import ( "fmt" "sort" "strings" + "time" "cloud.google.com/go/compute/metadata" "github.com/linki/instrumented_http" @@ -106,6 +107,8 @@ type GoogleProvider struct { dryRun bool // Max batch size to submit to Google Cloud DNS per transaction. batchChangeSize int + // Interval between batch updates. + batchChangeInterval time.Duration // only consider hosted zones managing domains ending in this suffix domainFilter DomainFilter // only consider hosted zones ending with this zone id @@ -119,7 +122,7 @@ type GoogleProvider struct { } // NewGoogleProvider initializes a new Google CloudDNS based Provider. -func NewGoogleProvider(project string, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, batchChangeSize int, dryRun bool) (*GoogleProvider, error) { +func NewGoogleProvider(project string, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, batchChangeSize int, batchChangeInterval time.Duration, dryRun bool) (*GoogleProvider, error) { gcloud, err := google.DefaultClient(context.TODO(), dns.NdevClouddnsReadwriteScope) if err != nil { return nil, err @@ -149,6 +152,7 @@ func NewGoogleProvider(project string, domainFilter DomainFilter, zoneIDFilter Z project: project, dryRun: dryRun, batchChangeSize: batchChangeSize, + batchChangeInterval: batchChangeInterval, domainFilter: domainFilter, zoneIDFilter: zoneIDFilter, resourceRecordSetsClient: resourceRecordSetsService{dnsClient.ResourceRecordSets}, @@ -310,6 +314,8 @@ func (p *GoogleProvider) submitChange(change *dns.Change) error { if _, err := p.changesClient.Create(p.project, zone, c).Do(); err != nil { return err } + + time.Sleep(p.batchChangeInterval) } } From 7be10ecbffd1d0f82638c08b3b50179f7fab1756 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Mon, 16 Sep 2019 21:37:53 +0100 Subject: [PATCH 21/79] WIP --- provider/azure.go | 45 +++++++++++++++++++++--------------------- provider/azure_test.go | 2 +- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index a15369e582..0a726e5bb8 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -26,7 +26,7 @@ import ( yaml "gopkg.in/yaml.v2" - "github.com/Azure/azure-sdk-for-go/arm/dns" + "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns" "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure" @@ -53,16 +53,16 @@ type config struct { // ZonesClient is an interface of dns.ZoneClient that can be stubbed for testing. type ZonesClient interface { - ListByResourceGroup(resourceGroupName string, top *int32) (result dns.ZoneListResult, err error) - ListByResourceGroupNextResults(lastResults dns.ZoneListResult) (result dns.ZoneListResult, err error) + ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResult, err error) + listByResourceGroupNextResults(ctx context.Context, lastResults dns.ZoneListResult) (result dns.ZoneListResult, err error) } // RecordsClient is an interface of dns.RecordClient that can be stubbed for testing. type RecordsClient interface { - ListByDNSZone(resourceGroupName string, zoneName string, top *int32) (result dns.RecordSetListResult, err error) - ListByDNSZoneNextResults(list dns.RecordSetListResult) (result dns.RecordSetListResult, err error) - Delete(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (result autorest.Response, err error) - CreateOrUpdate(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (result dns.RecordSet, err error) + ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result dns.RecordSetListResult, err error) + listByDNSZoneNextResults(ctx context.Context, lastResults dns.RecordSetListResult) (result dns.RecordSetListResult, err error) + Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (result autorest.Response, err error) + CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (result dns.RecordSet, err error) } // AzureProvider implements the DNS provider for Microsoft's Azure cloud platform. @@ -163,14 +163,14 @@ func getAccessToken(cfg config, environment azure.Environment) (*adal.ServicePri // Records gets the current records. // // Returns the current records or an error if the operation failed. -func (p *AzureProvider) Records() (endpoints []*endpoint.Endpoint, _ error) { - zones, err := p.zones() +func (p *AzureProvider) Records(ctx context.Context) (endpoints []*endpoint.Endpoint, _ error) { + zones, err := p.zones(ctx) if err != nil { return nil, err } for _, zone := range zones { - err := p.iterateRecords(*zone.Name, func(recordSet dns.RecordSet) bool { + err := p.iterateRecords(ctx, *zone.Name, func(recordSet dns.RecordSet) bool { if recordSet.Name == nil || recordSet.Type == nil { log.Error("Skipping invalid record set with nil name or type.") return true @@ -211,22 +211,22 @@ func (p *AzureProvider) Records() (endpoints []*endpoint.Endpoint, _ error) { // // Returns nil if the operation was successful or an error if the operation failed. func (p *AzureProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { - zones, err := p.zones() + zones, err := p.zones(ctx) if err != nil { return err } deleted, updated := p.mapChanges(zones, changes) - p.deleteRecords(deleted) - p.updateRecords(updated) + p.deleteRecords(ctx, deleted) + p.updateRecords(ctx, updated) return nil } -func (p *AzureProvider) zones() ([]dns.Zone, error) { +func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { log.Debug("Retrieving Azure DNS zones.") var zones []dns.Zone - list, err := p.zonesClient.ListByResourceGroup(p.resourceGroup, nil) + list, err := p.zonesClient.ListByResourceGroup(ctx, p.resourceGroup, nil) if err != nil { return nil, err } @@ -248,7 +248,7 @@ func (p *AzureProvider) zones() ([]dns.Zone, error) { zones = append(zones, zone) } - list, err = p.zonesClient.ListByResourceGroupNextResults(list) + list, err = p.zonesClient.listByResourceGroupNextResults(ctx, list) if err != nil { return nil, err } @@ -257,10 +257,10 @@ func (p *AzureProvider) zones() ([]dns.Zone, error) { return zones, nil } -func (p *AzureProvider) iterateRecords(zoneName string, callback func(dns.RecordSet) bool) error { +func (p *AzureProvider) iterateRecords(ctx context.Context, zoneName string, callback func(dns.RecordSet) bool) error { log.Debugf("Retrieving Azure DNS records for zone '%s'.", zoneName) - list, err := p.recordsClient.ListByDNSZone(p.resourceGroup, zoneName, nil) + list, err := p.recordsClient.ListByDNSZone(ctx, p.resourceGroup, zoneName, nil, "") // TODO if err != nil { return err } @@ -272,7 +272,7 @@ func (p *AzureProvider) iterateRecords(zoneName string, callback func(dns.Record } } - list, err = p.recordsClient.ListByDNSZoneNextResults(list) + list, err = p.recordsClient.listByDNSZoneNextResults(ctx, list) if err != nil { return err } @@ -323,7 +323,7 @@ func (p *AzureProvider) mapChanges(zones []dns.Zone, changes *plan.Changes) (azu return deleted, updated } -func (p *AzureProvider) deleteRecords(deleted azureChangeMap) { +func (p *AzureProvider) deleteRecords(ctx context.Context, deleted azureChangeMap) { // Delete records first for zone, endpoints := range deleted { for _, endpoint := range endpoints { @@ -332,7 +332,7 @@ func (p *AzureProvider) deleteRecords(deleted azureChangeMap) { log.Infof("Would delete %s record named '%s' for Azure DNS zone '%s'.", endpoint.RecordType, name, zone) } else { log.Infof("Deleting %s record named '%s' for Azure DNS zone '%s'.", endpoint.RecordType, name, zone) - if _, err := p.recordsClient.Delete(p.resourceGroup, zone, name, dns.RecordType(endpoint.RecordType), ""); err != nil { + if _, err := p.recordsClient.Delete(ctx, p.resourceGroup, zone, name, dns.RecordType(endpoint.RecordType), ""); err != nil { log.Errorf( "Failed to delete %s record named '%s' for Azure DNS zone '%s': %v", endpoint.RecordType, @@ -346,7 +346,7 @@ func (p *AzureProvider) deleteRecords(deleted azureChangeMap) { } } -func (p *AzureProvider) updateRecords(updated azureChangeMap) { +func (p *AzureProvider) updateRecords(ctx context.Context, updated azureChangeMap) { for zone, endpoints := range updated { for _, endpoint := range endpoints { name := p.recordSetNameForZone(zone, endpoint) @@ -372,6 +372,7 @@ func (p *AzureProvider) updateRecords(updated azureChangeMap) { recordSet, err := p.newRecordSet(endpoint) if err == nil { _, err = p.recordsClient.CreateOrUpdate( + ctx, p.resourceGroup, zone, name, diff --git a/provider/azure_test.go b/provider/azure_test.go index c1498658b9..92eff362ef 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -20,7 +20,7 @@ import ( "context" "testing" - "github.com/Azure/azure-sdk-for-go/arm/dns" + "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns" "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/to" From aafe52b7d6f8a4f93550d63f6a30f2190f31da51 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Tue, 17 Sep 2019 08:04:16 +0100 Subject: [PATCH 22/79] WIP Upgrade client-go + azure sdk --- provider/azure.go | 66 +++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index 0a726e5bb8..0202a115c0 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -53,13 +53,13 @@ type config struct { // ZonesClient is an interface of dns.ZoneClient that can be stubbed for testing. type ZonesClient interface { - ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResult, err error) + ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResultPage, err error) listByResourceGroupNextResults(ctx context.Context, lastResults dns.ZoneListResult) (result dns.ZoneListResult, err error) } -// RecordsClient is an interface of dns.RecordClient that can be stubbed for testing. -type RecordsClient interface { - ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result dns.RecordSetListResult, err error) +// RecordSetsClient is an interface of dns.RecordSetsClient that can be stubbed for testing. +type RecordSetsClient interface { + ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result dns.RecordSetListResultPage, err error) listByDNSZoneNextResults(ctx context.Context, lastResults dns.RecordSetListResult) (result dns.RecordSetListResult, err error) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (result autorest.Response, err error) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (result dns.RecordSet, err error) @@ -67,12 +67,12 @@ type RecordsClient interface { // AzureProvider implements the DNS provider for Microsoft's Azure cloud platform. type AzureProvider struct { - domainFilter DomainFilter - zoneIDFilter ZoneIDFilter - dryRun bool - resourceGroup string - zonesClient ZonesClient - recordsClient RecordsClient + domainFilter DomainFilter + zoneIDFilter ZoneIDFilter + dryRun bool + resourceGroup string + zonesClient dns.ZonesClient + recordSetsClient dns.RecordSetsClient } // NewAzureProvider creates a new Azure provider. @@ -111,16 +111,16 @@ func NewAzureProvider(configFile string, domainFilter DomainFilter, zoneIDFilter zonesClient := dns.NewZonesClientWithBaseURI(environment.ResourceManagerEndpoint, cfg.SubscriptionID) zonesClient.Authorizer = autorest.NewBearerAuthorizer(token) - recordsClient := dns.NewRecordSetsClientWithBaseURI(environment.ResourceManagerEndpoint, cfg.SubscriptionID) - recordsClient.Authorizer = autorest.NewBearerAuthorizer(token) + recordSetsClient := dns.NewRecordSetsClientWithBaseURI(environment.ResourceManagerEndpoint, cfg.SubscriptionID) + recordSetsClient.Authorizer = autorest.NewBearerAuthorizer(token) provider := &AzureProvider{ - domainFilter: domainFilter, - zoneIDFilter: zoneIDFilter, - dryRun: dryRun, - resourceGroup: cfg.ResourceGroup, - zonesClient: zonesClient, - recordsClient: recordsClient, + domainFilter: domainFilter, + zoneIDFilter: zoneIDFilter, + dryRun: dryRun, + resourceGroup: cfg.ResourceGroup, + zonesClient: zonesClient, + recordSetsClient: recordSetsClient, } return provider, nil } @@ -231,8 +231,8 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { return nil, err } - for list.Value != nil && len(*list.Value) > 0 { - for _, zone := range *list.Value { + for list.Values() != nil && len(list.Values()) > 0 { + for _, zone := range list.Values() { if zone.Name == nil { continue } @@ -248,10 +248,10 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { zones = append(zones, zone) } - list, err = p.zonesClient.listByResourceGroupNextResults(ctx, list) - if err != nil { - return nil, err - } + //list, err = p.zonesClient.listByResourceGroupNextResults(ctx, list) + //if err != nil { + // return nil, err + //} } log.Debugf("Found %d Azure DNS zone(s).", len(zones)) return zones, nil @@ -260,22 +260,22 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { func (p *AzureProvider) iterateRecords(ctx context.Context, zoneName string, callback func(dns.RecordSet) bool) error { log.Debugf("Retrieving Azure DNS records for zone '%s'.", zoneName) - list, err := p.recordsClient.ListByDNSZone(ctx, p.resourceGroup, zoneName, nil, "") // TODO + list, err := p.recordSetsClient.ListByDNSZone(ctx, p.resourceGroup, zoneName, nil, "") // TODO if err != nil { return err } - for list.Value != nil && len(*list.Value) > 0 { - for _, recordSet := range *list.Value { + for list.Values() != nil && len(list.Values()) > 0 { + for _, recordSet := range list.Values() { if !callback(recordSet) { return nil } } - list, err = p.recordsClient.listByDNSZoneNextResults(ctx, list) - if err != nil { - return err - } + //list, err = p.recordSetsClient.listByDNSZoneNextResults(ctx, list) + //if err != nil { + // return err + //} } return nil } @@ -332,7 +332,7 @@ func (p *AzureProvider) deleteRecords(ctx context.Context, deleted azureChangeMa log.Infof("Would delete %s record named '%s' for Azure DNS zone '%s'.", endpoint.RecordType, name, zone) } else { log.Infof("Deleting %s record named '%s' for Azure DNS zone '%s'.", endpoint.RecordType, name, zone) - if _, err := p.recordsClient.Delete(ctx, p.resourceGroup, zone, name, dns.RecordType(endpoint.RecordType), ""); err != nil { + if _, err := p.recordSetsClient.Delete(ctx, p.resourceGroup, zone, name, dns.RecordType(endpoint.RecordType), ""); err != nil { log.Errorf( "Failed to delete %s record named '%s' for Azure DNS zone '%s': %v", endpoint.RecordType, @@ -371,7 +371,7 @@ func (p *AzureProvider) updateRecords(ctx context.Context, updated azureChangeMa recordSet, err := p.newRecordSet(endpoint) if err == nil { - _, err = p.recordsClient.CreateOrUpdate( + _, err = p.recordSetsClient.CreateOrUpdate( ctx, p.resourceGroup, zone, From f170849b42517d676c15031379e636c98cf190b8 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Tue, 17 Sep 2019 22:30:34 +0100 Subject: [PATCH 23/79] It compiles! --- provider/azure.go | 3 ++- provider/rdns.go | 3 ++- source/store.go | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index 0202a115c0..a32e386863 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -163,7 +163,8 @@ func getAccessToken(cfg config, environment azure.Environment) (*adal.ServicePri // Records gets the current records. // // Returns the current records or an error if the operation failed. -func (p *AzureProvider) Records(ctx context.Context) (endpoints []*endpoint.Endpoint, _ error) { +func (p *AzureProvider) Records() (endpoints []*endpoint.Endpoint, _ error) { + ctx := context.Background() zones, err := p.zones(ctx) if err != nil { return nil, err diff --git a/provider/rdns.go b/provider/rdns.go index 459cf786c6..3e3216b7ae 100644 --- a/provider/rdns.go +++ b/provider/rdns.go @@ -29,9 +29,10 @@ import ( "strings" "time" + log "github.com/sirupsen/logrus" + "github.com/coreos/etcd/clientv3" "github.com/pkg/errors" - "istio.io/istio/pkg/log" "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/kubernetes-sigs/external-dns/plan" diff --git a/source/store.go b/source/store.go index 14e32b7360..f8ff6a54e6 100644 --- a/source/store.go +++ b/source/store.go @@ -25,11 +25,11 @@ import ( "sync" - cfclient "github.com/cloudfoundry-community/go-cfclient" + "github.com/cloudfoundry-community/go-cfclient" contour "github.com/heptio/contour/apis/generated/clientset/versioned" "github.com/linki/instrumented_http" log "github.com/sirupsen/logrus" - istiocrd "istio.io/istio/pilot/pkg/config/kube/crd" + istiocontroller "istio.io/istio/pilot/pkg/config/kube/crd/controller" istiomodel "istio.io/istio/pilot/pkg/model" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" @@ -259,14 +259,14 @@ func NewKubeClient(kubeConfig, kubeMaster string, requestTimeout time.Duration) // wrappers) to the client's config at this level. Furthermore, the Istio client // constructor does not expose the ability to override the Kubernetes master, // so the Master config attribute has no effect. -func NewIstioClient(kubeConfig string) (*istiocrd.Client, error) { +func NewIstioClient(kubeConfig string) (*istiocontroller.Client, error) { if kubeConfig == "" { if _, err := os.Stat(clientcmd.RecommendedHomeFile); err == nil { kubeConfig = clientcmd.RecommendedHomeFile } } - client, err := istiocrd.NewClient( + client, err := istiocontroller.NewClient( kubeConfig, "", istiomodel.ConfigDescriptor{istiomodel.Gateway}, From d333ecd508e203a971136df254850e543a627501 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Tue, 17 Sep 2019 22:37:44 +0100 Subject: [PATCH 24/79] Some test compilation fixes --- provider/azure_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/provider/azure_test.go b/provider/azure_test.go index 92eff362ef..6c7671c1f9 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -160,14 +160,14 @@ func (client *mockRecordsClient) CreateOrUpdate(resourceGroupName string, zoneNa return parameters, nil } -func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zonesClient ZonesClient, recordsClient RecordsClient) *AzureProvider { +func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zonesClient dns.ZonesClient, recordsClient dns.RecordSetsClient) *AzureProvider { return &AzureProvider{ domainFilter: domainFilter, zoneIDFilter: zoneIDFilter, dryRun: dryRun, resourceGroup: resourceGroup, zonesClient: zonesClient, - recordsClient: recordsClient, + recordSetsClient: recordsClient, } } @@ -291,7 +291,7 @@ func TestAzureApplyChangesDryRun(t *testing.T) { validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{}) } -func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordsClient) { +func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client dns.RecordSetsClient) { provider := newAzureProvider( NewDomainFilter([]string{""}), NewZoneIDFilter([]string{""}), From 8aa61d3ce3fe2be1ee972812c267cd121a054b33 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Thu, 19 Sep 2019 20:02:14 +0100 Subject: [PATCH 25/79] Update to new function names --- provider/azure_test.go | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/provider/azure_test.go b/provider/azure_test.go index 6c7671c1f9..6696e87fe8 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -32,10 +32,11 @@ import ( ) type mockZonesClient struct { - mockZoneListResult *dns.ZoneListResult + mockZoneListResult *dns.ZoneListResult + mockZoneListResultPage *dns.ZoneListResultPage } -type mockRecordsClient struct { +type mockRecordSetsClient struct { mockRecordSet *[]dns.RecordSet deletedEndpoints []*endpoint.Endpoint updatedEndpoints []*endpoint.Endpoint @@ -48,13 +49,13 @@ func createMockZone(zone string, id string) dns.Zone { } } -func (client *mockZonesClient) ListByResourceGroup(resourceGroupName string, top *int32) (dns.ZoneListResult, error) { +func (client *mockZonesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (dns.ZoneListResultPage, error) { // Don't bother filtering by resource group or implementing paging since that's the responsibility // of the Azure DNS service - return *client.mockZoneListResult, nil + return *client.mockZoneListResultPage, nil } -func (client *mockZonesClient) ListByResourceGroupNextResults(lastResults dns.ZoneListResult) (dns.ZoneListResult, error) { +func (client *mockZonesClient) listByResourceGroupNextResults(ctx context.Context, lastResults dns.ZoneListResult) (dns.ZoneListResult, error) { return dns.ZoneListResult{}, nil } @@ -123,15 +124,15 @@ func createMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values } -func (client *mockRecordsClient) ListByDNSZone(resourceGroupName string, zoneName string, top *int32) (dns.RecordSetListResult, error) { - return dns.RecordSetListResult{Value: client.mockRecordSet}, nil +func (client *mockRecordSetsClient) ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32) (dns.RecordSetListResultPage, error) { + return dns.RecordSetListResultPage{}, nil // todo add } -func (client *mockRecordsClient) ListByDNSZoneNextResults(list dns.RecordSetListResult) (dns.RecordSetListResult, error) { +func (client *mockRecordSetsClient) listByDNSZoneNextResults(ctx context.Context, list dns.RecordSetListResult) (dns.RecordSetListResult, error) { return dns.RecordSetListResult{}, nil } -func (client *mockRecordsClient) Delete(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (autorest.Response, error) { +func (client *mockRecordSetsClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (autorest.Response, error) { client.deletedEndpoints = append( client.deletedEndpoints, endpoint.NewEndpoint( @@ -143,7 +144,7 @@ func (client *mockRecordsClient) Delete(resourceGroupName string, zoneName strin return autorest.Response{}, nil } -func (client *mockRecordsClient) CreateOrUpdate(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (dns.RecordSet, error) { +func (client *mockRecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (dns.RecordSet, error) { var ttl endpoint.TTL if parameters.TTL != nil { ttl = endpoint.TTL(*parameters.TTL) @@ -182,9 +183,10 @@ func TestAzureRecord(t *testing.T) { createMockZone("example.com", "/dnszones/example.com"), }, }, + mockZoneListResultPage: &dns.ZoneListResultPage{}, } - recordsClient := mockRecordsClient{ + recordsClient := mockRecordSetsClient{ mockRecordSet: &[]dns.RecordSet{ createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), @@ -224,7 +226,7 @@ func TestAzureMultiRecord(t *testing.T) { }, } - recordsClient := mockRecordsClient{ + recordsClient := mockRecordSetsClient{ mockRecordSet: &[]dns.RecordSet{ createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), @@ -256,7 +258,7 @@ func TestAzureMultiRecord(t *testing.T) { } func TestAzureApplyChanges(t *testing.T) { - recordsClient := mockRecordsClient{} + recordsClient := mockRecordSetsClient{} testAzureApplyChangesInternal(t, false, &recordsClient) @@ -282,7 +284,7 @@ func TestAzureApplyChanges(t *testing.T) { } func TestAzureApplyChangesDryRun(t *testing.T) { - recordsClient := mockRecordsClient{} + recordsClient := mockRecordSetsClient{} testAzureApplyChangesInternal(t, true, &recordsClient) @@ -304,6 +306,8 @@ func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client dns.RecordS createMockZone("other.com", "/dnszones/other.com"), }, }, + mockZoneListResultPage: &dns.ZoneListResultPage{ + }, }, client, ) From b74b5ee5c4a3980e6f15b4acf90b5069c56c86e0 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Thu, 19 Sep 2019 20:04:06 +0100 Subject: [PATCH 26/79] Update value --- provider/azure_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/provider/azure_test.go b/provider/azure_test.go index 6696e87fe8..f456d6ca57 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -186,7 +186,7 @@ func TestAzureRecord(t *testing.T) { mockZoneListResultPage: &dns.ZoneListResultPage{}, } - recordsClient := mockRecordSetsClient{ + recordSetsClient := mockRecordSetsClient{ mockRecordSet: &[]dns.RecordSet{ createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), @@ -198,7 +198,7 @@ func TestAzureRecord(t *testing.T) { }, } - provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordsClient) + provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordSetsClient) actual, err := provider.Records() @@ -226,7 +226,7 @@ func TestAzureMultiRecord(t *testing.T) { }, } - recordsClient := mockRecordSetsClient{ + recordSetsClient := mockRecordSetsClient{ mockRecordSet: &[]dns.RecordSet{ createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), @@ -238,7 +238,7 @@ func TestAzureMultiRecord(t *testing.T) { }, } - provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordsClient) + provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordSetsClient) actual, err := provider.Records() From a00676c0329198c6754bab55d97223718d9d0db6 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Thu, 19 Sep 2019 20:45:38 +0100 Subject: [PATCH 27/79] Update function signatures to match SDK --- provider/azure_test.go | 43 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/provider/azure_test.go b/provider/azure_test.go index f456d6ca57..682e2d1da9 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -49,13 +49,13 @@ func createMockZone(zone string, id string) dns.Zone { } } -func (client *mockZonesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (dns.ZoneListResultPage, error) { +func (client *mockZonesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResultPage, err error) { // Don't bother filtering by resource group or implementing paging since that's the responsibility // of the Azure DNS service return *client.mockZoneListResultPage, nil } -func (client *mockZonesClient) listByResourceGroupNextResults(ctx context.Context, lastResults dns.ZoneListResult) (dns.ZoneListResult, error) { +func (client *mockZonesClient) listByResourceGroupNextResults(ctx context.Context, lastResults dns.ZoneListResult) (result dns.ZoneListResult, err error) { return dns.ZoneListResult{}, nil } @@ -124,15 +124,15 @@ func createMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values } -func (client *mockRecordSetsClient) ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32) (dns.RecordSetListResultPage, error) { +func (client *mockRecordSetsClient) ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result dns.RecordSetListResultPage, err error) { return dns.RecordSetListResultPage{}, nil // todo add } -func (client *mockRecordSetsClient) listByDNSZoneNextResults(ctx context.Context, list dns.RecordSetListResult) (dns.RecordSetListResult, error) { +func (client *mockRecordSetsClient) listByDNSZoneNextResults(ctx context.Context, lastResults dns.RecordSetListResult) (result dns.RecordSetListResult, err error) { return dns.RecordSetListResult{}, nil } -func (client *mockRecordSetsClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (autorest.Response, error) { +func (client *mockRecordSetsClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (result autorest.Response, err error) { client.deletedEndpoints = append( client.deletedEndpoints, endpoint.NewEndpoint( @@ -144,7 +144,7 @@ func (client *mockRecordSetsClient) Delete(ctx context.Context, resourceGroupNam return autorest.Response{}, nil } -func (client *mockRecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (dns.RecordSet, error) { +func (client *mockRecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (result dns.RecordSet, err error) { var ttl endpoint.TTL if parameters.TTL != nil { ttl = endpoint.TTL(*parameters.TTL) @@ -163,11 +163,11 @@ func (client *mockRecordSetsClient) CreateOrUpdate(ctx context.Context, resource func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zonesClient dns.ZonesClient, recordsClient dns.RecordSetsClient) *AzureProvider { return &AzureProvider{ - domainFilter: domainFilter, - zoneIDFilter: zoneIDFilter, - dryRun: dryRun, - resourceGroup: resourceGroup, - zonesClient: zonesClient, + domainFilter: domainFilter, + zoneIDFilter: zoneIDFilter, + dryRun: dryRun, + resourceGroup: resourceGroup, + zonesClient: zonesClient, recordSetsClient: recordsClient, } } @@ -294,21 +294,22 @@ func TestAzureApplyChangesDryRun(t *testing.T) { } func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client dns.RecordSetsClient) { + zonesClient := mockZonesClient{ + mockZoneListResult: &dns.ZoneListResult{ + Value: &[]dns.Zone{ + createMockZone("example.com", "/dnszones/example.com"), + createMockZone("other.com", "/dnszones/other.com"), + }, + }, + mockZoneListResultPage: &dns.ZoneListResultPage{}, + } + provider := newAzureProvider( NewDomainFilter([]string{""}), NewZoneIDFilter([]string{""}), dryRun, "group", - &mockZonesClient{ - mockZoneListResult: &dns.ZoneListResult{ - Value: &[]dns.Zone{ - createMockZone("example.com", "/dnszones/example.com"), - createMockZone("other.com", "/dnszones/other.com"), - }, - }, - mockZoneListResultPage: &dns.ZoneListResultPage{ - }, - }, + &zonesClient, client, ) From bb9edf79937d4277c0c403fa4ce21208ed20ffe3 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Thu, 19 Sep 2019 21:29:24 +0100 Subject: [PATCH 28/79] Use mocks properly --- provider/azure.go | 4 ++-- provider/azure_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index a32e386863..805bcd1e28 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -71,8 +71,8 @@ type AzureProvider struct { zoneIDFilter ZoneIDFilter dryRun bool resourceGroup string - zonesClient dns.ZonesClient - recordSetsClient dns.RecordSetsClient + zonesClient ZonesClient + recordSetsClient RecordSetsClient } // NewAzureProvider creates a new Azure provider. diff --git a/provider/azure_test.go b/provider/azure_test.go index 682e2d1da9..15031070e1 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -161,7 +161,7 @@ func (client *mockRecordSetsClient) CreateOrUpdate(ctx context.Context, resource return parameters, nil } -func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zonesClient dns.ZonesClient, recordsClient dns.RecordSetsClient) *AzureProvider { +func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zonesClient ZonesClient, recordsClient RecordSetsClient) *AzureProvider { return &AzureProvider{ domainFilter: domainFilter, zoneIDFilter: zoneIDFilter, @@ -293,7 +293,7 @@ func TestAzureApplyChangesDryRun(t *testing.T) { validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{}) } -func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client dns.RecordSetsClient) { +func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsClient) { zonesClient := mockZonesClient{ mockZoneListResult: &dns.ZoneListResult{ Value: &[]dns.Zone{ From 5d556868f1e752f4fbc69c106825dc02242dde0e Mon Sep 17 00:00:00 2001 From: stsaid Date: Sat, 28 Sep 2019 10:01:30 +0200 Subject: [PATCH 29/79] Reworked azuresdk usage (#1) --- provider/azure.go | 60 ++++++++++----------- provider/azure_test.go | 107 +++++++++++++++++++++++-------------- provider/designate_test.go | 2 +- 3 files changed, 95 insertions(+), 74 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index 805bcd1e28..09bcd35f6d 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -53,14 +53,12 @@ type config struct { // ZonesClient is an interface of dns.ZoneClient that can be stubbed for testing. type ZonesClient interface { - ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResultPage, err error) - listByResourceGroupNextResults(ctx context.Context, lastResults dns.ZoneListResult) (result dns.ZoneListResult, err error) + ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResultIterator, err error) } // RecordSetsClient is an interface of dns.RecordSetsClient that can be stubbed for testing. type RecordSetsClient interface { - ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result dns.RecordSetListResultPage, err error) - listByDNSZoneNextResults(ctx context.Context, lastResults dns.RecordSetListResult) (result dns.RecordSetListResult, err error) + ListAllByDNSZoneComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result dns.RecordSetListResultIterator, err error) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (result autorest.Response, err error) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (result dns.RecordSet, err error) } @@ -224,36 +222,37 @@ func (p *AzureProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) } func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { - log.Debug("Retrieving Azure DNS zones.") + log.Debugf("Retrieving Azure DNS zones for rg: %s.", p.resourceGroup) var zones []dns.Zone - list, err := p.zonesClient.ListByResourceGroup(ctx, p.resourceGroup, nil) + + i, err := p.zonesClient.ListByResourceGroupComplete(ctx, p.resourceGroup, nil) + if err != nil { return nil, err } - for list.Values() != nil && len(list.Values()) > 0 { - for _, zone := range list.Values() { - if zone.Name == nil { - continue - } + for i.NotDone() { + zone := i.Value() + log.Debugf("Validating Zone: %v", *zone.Name) - if !p.domainFilter.Match(*zone.Name) { - continue - } + if zone.Name == nil { + continue + } - if !p.zoneIDFilter.Match(*zone.ID) { - continue - } + if !p.domainFilter.Match(*zone.Name) { + continue + } - zones = append(zones, zone) + if !p.zoneIDFilter.Match(*zone.ID) { + continue } - //list, err = p.zonesClient.listByResourceGroupNextResults(ctx, list) - //if err != nil { - // return nil, err - //} + zones = append(zones, zone) + + i.NextWithContext(ctx) } + log.Debugf("Found %d Azure DNS zone(s).", len(zones)) return zones, nil } @@ -261,23 +260,20 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { func (p *AzureProvider) iterateRecords(ctx context.Context, zoneName string, callback func(dns.RecordSet) bool) error { log.Debugf("Retrieving Azure DNS records for zone '%s'.", zoneName) - list, err := p.recordSetsClient.ListByDNSZone(ctx, p.resourceGroup, zoneName, nil, "") // TODO + i, err := p.recordSetsClient.ListAllByDNSZoneComplete(ctx, p.resourceGroup, zoneName, nil, "") + if err != nil { return err } - for list.Values() != nil && len(list.Values()) > 0 { - for _, recordSet := range list.Values() { - if !callback(recordSet) { - return nil - } + for i.NotDone() { + if !callback(i.Value()) { + return nil } - //list, err = p.recordSetsClient.listByDNSZoneNextResults(ctx, list) - //if err != nil { - // return err - //} + i.NextWithContext(ctx) } + return nil } diff --git a/provider/azure_test.go b/provider/azure_test.go index 15031070e1..b9b93ac385 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -32,14 +32,13 @@ import ( ) type mockZonesClient struct { - mockZoneListResult *dns.ZoneListResult - mockZoneListResultPage *dns.ZoneListResultPage + mockZonesClientIterator *dns.ZoneListResultIterator } type mockRecordSetsClient struct { - mockRecordSet *[]dns.RecordSet - deletedEndpoints []*endpoint.Endpoint - updatedEndpoints []*endpoint.Endpoint + mockRecordSetListIterator *dns.RecordSetListResultIterator + deletedEndpoints []*endpoint.Endpoint + updatedEndpoints []*endpoint.Endpoint } func createMockZone(zone string, id string) dns.Zone { @@ -49,14 +48,8 @@ func createMockZone(zone string, id string) dns.Zone { } } -func (client *mockZonesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResultPage, err error) { - // Don't bother filtering by resource group or implementing paging since that's the responsibility - // of the Azure DNS service - return *client.mockZoneListResultPage, nil -} - -func (client *mockZonesClient) listByResourceGroupNextResults(ctx context.Context, lastResults dns.ZoneListResult) (result dns.ZoneListResult, err error) { - return dns.ZoneListResult{}, nil +func (client *mockZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResultIterator, err error) { + return *client.mockZonesClientIterator, nil } func aRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetProperties { @@ -124,12 +117,8 @@ func createMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values } -func (client *mockRecordSetsClient) ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result dns.RecordSetListResultPage, err error) { - return dns.RecordSetListResultPage{}, nil // todo add -} - -func (client *mockRecordSetsClient) listByDNSZoneNextResults(ctx context.Context, lastResults dns.RecordSetListResult) (result dns.RecordSetListResult, err error) { - return dns.RecordSetListResult{}, nil +func (client *mockRecordSetsClient) ListAllByDNSZoneComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result dns.RecordSetListResultIterator, err error) { + return *client.mockRecordSetListIterator, nil } func (client *mockRecordSetsClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (result autorest.Response, err error) { @@ -177,17 +166,22 @@ func validateAzureEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expect } func TestAzureRecord(t *testing.T) { - zonesClient := mockZonesClient{ - mockZoneListResult: &dns.ZoneListResult{ - Value: &[]dns.Zone{ - createMockZone("example.com", "/dnszones/example.com"), - }, + zlr := dns.ZoneListResult{ + Value: &[]dns.Zone{ + createMockZone("example.com", "/dnszones/example.com"), }, - mockZoneListResultPage: &dns.ZoneListResultPage{}, } + mockZoneListResultPage := dns.NewZoneListResultPage(func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) { + return zlr, nil + }) + mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) - recordSetsClient := mockRecordSetsClient{ - mockRecordSet: &[]dns.RecordSet{ + zonesClient := mockZonesClient{ + mockZonesClientIterator: &mockZoneClientIterator, + } + + rslr := dns.RecordSetListResult{ + Value: &[]dns.RecordSet{ createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), createMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122"), @@ -198,6 +192,16 @@ func TestAzureRecord(t *testing.T) { }, } + mockRecordSetListResultPage := dns.NewRecordSetListResultPage(func(ctxParam context.Context, rslrParam dns.RecordSetListResult) (dns.RecordSetListResult, error) { + return rslr, nil + }) + + mockRecordSetListIterator := dns.NewRecordSetListResultIterator(mockRecordSetListResultPage) + + recordSetsClient := mockRecordSetsClient{ + mockRecordSetListIterator: &mockRecordSetListIterator, + } + provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordSetsClient) actual, err := provider.Records() @@ -218,16 +222,22 @@ func TestAzureRecord(t *testing.T) { } func TestAzureMultiRecord(t *testing.T) { - zonesClient := mockZonesClient{ - mockZoneListResult: &dns.ZoneListResult{ - Value: &[]dns.Zone{ - createMockZone("example.com", "/dnszones/example.com"), - }, + zlr := dns.ZoneListResult{ + Value: &[]dns.Zone{ + createMockZone("example.com", "/dnszones/example.com"), }, } + mockZoneListResultPage := dns.NewZoneListResultPage(func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) { + return zlr, nil + }) + mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) - recordSetsClient := mockRecordSetsClient{ - mockRecordSet: &[]dns.RecordSet{ + zonesClient := mockZonesClient{ + mockZonesClientIterator: &mockZoneClientIterator, + } + + rslr := dns.RecordSetListResult{ + Value: &[]dns.RecordSet{ createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), createMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122", "234.234.234.233"), @@ -238,6 +248,16 @@ func TestAzureMultiRecord(t *testing.T) { }, } + mockRecordSetListResultPage := dns.NewRecordSetListResultPage(func(ctxParam context.Context, rslrParam dns.RecordSetListResult) (dns.RecordSetListResult, error) { + return rslr, nil + }) + + mockRecordSetListIterator := dns.NewRecordSetListResultIterator(mockRecordSetListResultPage) + + recordSetsClient := mockRecordSetsClient{ + mockRecordSetListIterator: &mockRecordSetListIterator, + } + provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordSetsClient) actual, err := provider.Records() @@ -294,14 +314,19 @@ func TestAzureApplyChangesDryRun(t *testing.T) { } func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsClient) { - zonesClient := mockZonesClient{ - mockZoneListResult: &dns.ZoneListResult{ - Value: &[]dns.Zone{ - createMockZone("example.com", "/dnszones/example.com"), - createMockZone("other.com", "/dnszones/other.com"), - }, + zlr := dns.ZoneListResult{ + Value: &[]dns.Zone{ + createMockZone("example.com", "/dnszones/example.com"), + createMockZone("other.com", "/dnszones/other.com"), }, - mockZoneListResultPage: &dns.ZoneListResultPage{}, + } + mockZoneListResultPage := dns.NewZoneListResultPage(func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) { + return zlr, nil + }) + mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) + + zonesClient := mockZonesClient{ + mockZonesClientIterator: &mockZoneClientIterator, } provider := newAzureProvider( diff --git a/provider/designate_test.go b/provider/designate_test.go index 816be30cd5..2d37eb0a36 100644 --- a/provider/designate_test.go +++ b/provider/designate_test.go @@ -114,7 +114,7 @@ func (c fakeDesignateClient) UpdateRecordSet(zoneID, recordSetID string, opts re if opts.Description != nil { rs.Description = *opts.Description } - rs.TTL = opts.TTL + rs.TTL = *opts.TTL rs.Records = opts.Records return nil } From 0bc324d0c84af66be5dde41c4421c37528b4f510 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Sat, 28 Sep 2019 09:54:25 +0100 Subject: [PATCH 30/79] Remove unused ttl field --- provider/designate_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/designate_test.go b/provider/designate_test.go index 2d37eb0a36..bfc336c689 100644 --- a/provider/designate_test.go +++ b/provider/designate_test.go @@ -114,7 +114,7 @@ func (c fakeDesignateClient) UpdateRecordSet(zoneID, recordSetID string, opts re if opts.Description != nil { rs.Description = *opts.Description } - rs.TTL = *opts.TTL + rs.Records = opts.Records return nil } From 186906e1e352c2a7cd2d4d4415a0fe7db3d9c001 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Sat, 28 Sep 2019 11:11:46 +0100 Subject: [PATCH 31/79] Fix iteration and mock, no infinite loop --- provider/azure.go | 11 ++++++++++- provider/azure_test.go | 19 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index 09bcd35f6d..626b66c16e 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -232,6 +232,11 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { return nil, err } + err = i.NextWithContext(ctx) + if err != nil { + return nil, err + } + for i.NotDone() { zone := i.Value() log.Debugf("Validating Zone: %v", *zone.Name) @@ -250,10 +255,14 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { zones = append(zones, zone) - i.NextWithContext(ctx) + err := i.NextWithContext(ctx) + if err != nil { + return nil, err + } } log.Debugf("Found %d Azure DNS zone(s).", len(zones)) + log.Printf("Found %d Azure DNS zone(s).", len(zones)) return zones, nil } diff --git a/provider/azure_test.go b/provider/azure_test.go index b9b93ac385..72cc4d3c30 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -18,6 +18,8 @@ package provider import ( "context" + "encoding/json" + "fmt" "testing" "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns" @@ -217,18 +219,33 @@ func TestAzureRecord(t *testing.T) { endpoint.NewEndpointWithTTL("hack.example.com", endpoint.RecordTypeCNAME, 10, "hack.azurewebsites.net"), } + debug, _ := json.Marshal(actual) + fmt.Printf("Debugging azure test: %v", debug) + validateAzureEndpoints(t, actual, expected) } + func TestAzureMultiRecord(t *testing.T) { + zlr := dns.ZoneListResult{ Value: &[]dns.Zone{ createMockZone("example.com", "/dnszones/example.com"), }, } + results := []dns.ZoneListResult{ + zlr, + } + mockZoneListResultPage := dns.NewZoneListResultPage(func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) { - return zlr, nil + if len(results) > 0 { + result := results[0] + results = nil + return result, nil + } else { + return dns.ZoneListResult{}, nil + } }) mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) From 4f08319438608655466764e4f08442109153ed19 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Sat, 28 Sep 2019 11:21:32 +0100 Subject: [PATCH 32/79] Fix Azure tests --- provider/azure.go | 11 ++++++++-- provider/azure_test.go | 50 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index 626b66c16e..b39791e9ab 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -262,7 +262,6 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { } log.Debugf("Found %d Azure DNS zone(s).", len(zones)) - log.Printf("Found %d Azure DNS zone(s).", len(zones)) return zones, nil } @@ -275,12 +274,20 @@ func (p *AzureProvider) iterateRecords(ctx context.Context, zoneName string, cal return err } + err = i.NextWithContext(ctx) + if err != nil { + return err + } + for i.NotDone() { if !callback(i.Value()) { return nil } - i.NextWithContext(ctx) + err := i.NextWithContext(ctx) + if err != nil { + return err + } } return nil diff --git a/provider/azure_test.go b/provider/azure_test.go index 72cc4d3c30..7f3a56dd85 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -173,8 +173,19 @@ func TestAzureRecord(t *testing.T) { createMockZone("example.com", "/dnszones/example.com"), }, } + results := []dns.ZoneListResult{ + zlr, + } + + mockZoneListResultPage := dns.NewZoneListResultPage(func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) { - return zlr, nil + if len(results) > 0 { + result := results[0] + results = nil + return result, nil + } else { + return dns.ZoneListResult{}, nil + } }) mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) @@ -194,8 +205,18 @@ func TestAzureRecord(t *testing.T) { }, } + rsResults := []dns.RecordSetListResult{ + rslr, + } + mockRecordSetListResultPage := dns.NewRecordSetListResultPage(func(ctxParam context.Context, rslrParam dns.RecordSetListResult) (dns.RecordSetListResult, error) { - return rslr, nil + if len(rsResults) > 0 { + result := rsResults[0] + rsResults = nil + return result, nil + } else { + return dns.RecordSetListResult{}, nil + } }) mockRecordSetListIterator := dns.NewRecordSetListResultIterator(mockRecordSetListResultPage) @@ -265,8 +286,18 @@ func TestAzureMultiRecord(t *testing.T) { }, } + rsResults := []dns.RecordSetListResult{ + rslr, + } + mockRecordSetListResultPage := dns.NewRecordSetListResultPage(func(ctxParam context.Context, rslrParam dns.RecordSetListResult) (dns.RecordSetListResult, error) { - return rslr, nil + if len(rsResults) > 0 { + result := rsResults[0] + rsResults = nil + return result, nil + } else { + return dns.RecordSetListResult{}, nil + } }) mockRecordSetListIterator := dns.NewRecordSetListResultIterator(mockRecordSetListResultPage) @@ -337,8 +368,19 @@ func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsC createMockZone("other.com", "/dnszones/other.com"), }, } + + results := []dns.ZoneListResult{ + zlr, + } + mockZoneListResultPage := dns.NewZoneListResultPage(func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) { - return zlr, nil + if len(results) > 0 { + result := results[0] + results = nil + return result, nil + } else { + return dns.ZoneListResult{}, nil + } }) mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) From 5a1715b5824aa9516b69f0dd1ff00e372f829f21 Mon Sep 17 00:00:00 2001 From: stsaid Date: Wed, 2 Oct 2019 11:29:24 +0200 Subject: [PATCH 33/79] fixed issue in iteration of recordset/zone-results from azure. --- provider/azure.go | 12 ------------ provider/azure_test.go | 14 ++++++++++++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index b39791e9ab..1669d47d74 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -227,12 +227,6 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { var zones []dns.Zone i, err := p.zonesClient.ListByResourceGroupComplete(ctx, p.resourceGroup, nil) - - if err != nil { - return nil, err - } - - err = i.NextWithContext(ctx) if err != nil { return nil, err } @@ -269,12 +263,6 @@ func (p *AzureProvider) iterateRecords(ctx context.Context, zoneName string, cal log.Debugf("Retrieving Azure DNS records for zone '%s'.", zoneName) i, err := p.recordSetsClient.ListAllByDNSZoneComplete(ctx, p.resourceGroup, zoneName, nil, "") - - if err != nil { - return err - } - - err = i.NextWithContext(ctx) if err != nil { return err } diff --git a/provider/azure_test.go b/provider/azure_test.go index 7f3a56dd85..44a06e7550 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -51,6 +51,12 @@ func createMockZone(zone string, id string) dns.Zone { } func (client *mockZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResultIterator, err error) { + // pre-iterate to first item to emulate behaviour of Azure SDK + err = client.mockZonesClientIterator.NextWithContext(ctx) + if err != nil { + return *client.mockZonesClientIterator, err + } + return *client.mockZonesClientIterator, nil } @@ -120,6 +126,12 @@ func createMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values } func (client *mockRecordSetsClient) ListAllByDNSZoneComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result dns.RecordSetListResultIterator, err error) { + // pre-iterate to first item to emulate behaviour of Azure SDK + err = client.mockRecordSetListIterator.NextWithContext(ctx) + if err != nil { + return *client.mockRecordSetListIterator, err + } + return *client.mockRecordSetListIterator, nil } @@ -177,7 +189,6 @@ func TestAzureRecord(t *testing.T) { zlr, } - mockZoneListResultPage := dns.NewZoneListResultPage(func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) { if len(results) > 0 { result := results[0] @@ -247,7 +258,6 @@ func TestAzureRecord(t *testing.T) { } - func TestAzureMultiRecord(t *testing.T) { zlr := dns.ZoneListResult{ From dda6a331b391942166785511d8a98924cc050ccf Mon Sep 17 00:00:00 2001 From: saidst Date: Fri, 11 Oct 2019 14:03:50 +0200 Subject: [PATCH 34/79] Changed dependency to k8s.io-libs entirely to kubernetes-1.13.11. --- source/store.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/source/store.go b/source/store.go index f8ff6a54e6..e197ae871f 100644 --- a/source/store.go +++ b/source/store.go @@ -32,6 +32,7 @@ import ( istiocontroller "istio.io/istio/pilot/pkg/config/kube/crd/controller" istiomodel "istio.io/istio/pilot/pkg/model" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ) @@ -219,13 +220,26 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err // uses KubeMaster and KubeConfig attributes to connect to the cluster. If // KubeConfig isn't provided it defaults to using the recommended default. func NewKubeClient(kubeConfig, kubeMaster string, requestTimeout time.Duration) (*kubernetes.Clientset, error) { + log.Infof("Instantiating new Kubernetes client") + if kubeConfig == "" { if _, err := os.Stat(clientcmd.RecommendedHomeFile); err == nil { kubeConfig = clientcmd.RecommendedHomeFile } } + log.Debugf("kubeMaster: %s", kubeMaster) + log.Debugf("kubeConfig: %s", kubeConfig) - config, err := clientcmd.BuildConfigFromFlags(kubeMaster, kubeConfig) + // evaluate whether to use kubeConfig-file or serviceaccount-token + var config *rest.Config + var err error + if kubeConfig == "" { + log.Infof("Using inCluster-config based on serviceaccount-token") + config, err = rest.InClusterConfig() + } else { + log.Infof("Using kubeConfig") + config, err = clientcmd.BuildConfigFromFlags(kubeMaster, kubeConfig) + } if err != nil { return nil, err } From 135b76dbbbbecf6f7c799088181d93d2e99b4245 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Mon, 14 Oct 2019 21:56:14 +0100 Subject: [PATCH 35/79] Advance loop properly --- provider/azure.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index 1669d47d74..aa2f3f3923 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -235,20 +235,10 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { zone := i.Value() log.Debugf("Validating Zone: %v", *zone.Name) - if zone.Name == nil { - continue + if zone.Name != nil && p.domainFilter.Match(*zone.Name) && p.zoneIDFilter.Match(*zone.ID) { + zones = append(zones, zone) } - if !p.domainFilter.Match(*zone.Name) { - continue - } - - if !p.zoneIDFilter.Match(*zone.ID) { - continue - } - - zones = append(zones, zone) - err := i.NextWithContext(ctx) if err != nil { return nil, err From 08bd87552bea80592e89995a365b6ea4f03a1da2 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Tue, 15 Oct 2019 21:26:50 +0100 Subject: [PATCH 36/79] Remove debug --- provider/azure_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/provider/azure_test.go b/provider/azure_test.go index 44a06e7550..df6b9ff1db 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -18,8 +18,6 @@ package provider import ( "context" - "encoding/json" - "fmt" "testing" "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns" @@ -251,9 +249,6 @@ func TestAzureRecord(t *testing.T) { endpoint.NewEndpointWithTTL("hack.example.com", endpoint.RecordTypeCNAME, 10, "hack.azurewebsites.net"), } - debug, _ := json.Marshal(actual) - fmt.Printf("Debugging azure test: %v", debug) - validateAzureEndpoints(t, actual, expected) } From fc3ca1e1eaee2dbbde2b971f2a2a452755489668 Mon Sep 17 00:00:00 2001 From: saidst Date: Thu, 17 Oct 2019 16:21:20 +0200 Subject: [PATCH 37/79] Attempt to optimize changes to azure_tests.go (#2) --- provider/azure.go | 3 +- provider/azure_test.go | 181 +++++++++++++++++-------------------- provider/designate.go | 13 +-- provider/designate_test.go | 1 + 4 files changed, 93 insertions(+), 105 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index aa2f3f3923..8fbbd91c7d 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -222,7 +222,7 @@ func (p *AzureProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) } func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { - log.Debugf("Retrieving Azure DNS zones for rg: %s.", p.resourceGroup) + log.Debugf("Retrieving Azure DNS zones for resource group: %s.", p.resourceGroup) var zones []dns.Zone @@ -233,7 +233,6 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { for i.NotDone() { zone := i.Value() - log.Debugf("Validating Zone: %v", *zone.Name) if zone.Name != nil && p.domainFilter.Match(*zone.Name) && p.zoneIDFilter.Match(*zone.ID) { zones = append(zones, zone) diff --git a/provider/azure_test.go b/provider/azure_test.go index df6b9ff1db..2835dec801 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -31,16 +31,58 @@ import ( "github.com/stretchr/testify/assert" ) +// mockZonesClient implements the methods of the Azure DNS Zones Client which are used in the Azure Provider +// and returns static results which are defined per test type mockZonesClient struct { mockZonesClientIterator *dns.ZoneListResultIterator } +// mockZonesClient implements the methods of the Azure DNS RecordSet Client which are used in the Azure Provider +// and returns static results which are defined per test type mockRecordSetsClient struct { mockRecordSetListIterator *dns.RecordSetListResultIterator deletedEndpoints []*endpoint.Endpoint updatedEndpoints []*endpoint.Endpoint } +// mockZoneListResultPageIterator is used to paginate forward through a list of zones +type mockZoneListResultPageIterator struct { + offset int + results []dns.ZoneListResult +} + +// getNextPage provides the next page based on the offset of the mockZoneListResultPageIterator +func (m *mockZoneListResultPageIterator) getNextPage(context.Context, dns.ZoneListResult) (dns.ZoneListResult, error) { + // it assumed that instances of this kind of iterator are only skimmed through once per test + // otherwise a real implementation is required, e.g. based on a linked list + if m.offset < len(m.results) { + m.offset = m.offset + 1 + return m.results[m.offset-1], nil + } + + // paged to last page or empty + return dns.ZoneListResult{}, nil +} + +// mockZoneListResultPageIterator is used to paginate forward through a list of recordsets +type mockRecordSetListResultPageIterator struct { + offset int + results []dns.RecordSetListResult +} + +// getNextPage provides the next page based on the offset of the mockRecordSetListResultPageIterator +func (m *mockRecordSetListResultPageIterator) getNextPage(context.Context, dns.RecordSetListResult) (dns.RecordSetListResult, error) { + // it assumed that instances of this kind of iterator are only skimmed through once per test + // otherwise a real implementation is required, e.g. based on a linked list + if m.offset < len(m.results) { + m.offset = m.offset + 1 + return m.results[m.offset-1], nil + } + + // paged to last page or empty + return dns.RecordSetListResult{}, nil +} + func createMockZone(zone string, id string) dns.Zone { return dns.Zone{ ID: to.StringPtr(id), @@ -162,6 +204,40 @@ func (client *mockRecordSetsClient) CreateOrUpdate(ctx context.Context, resource return parameters, nil } +// newMockedAzureProvider creates an AzureProvider comprising the mocked clients for zones and recordsets +func newMockedAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zones *[]dns.Zone, recordSets *[]dns.RecordSet) (*AzureProvider, error) { + // init zone-related parts of the mock-client + pageIterator := mockZoneListResultPageIterator{ + results: []dns.ZoneListResult{ + { + Value: zones, + }, + }, + } + + mockZoneListResultPage := dns.NewZoneListResultPage(pageIterator.getNextPage) + mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) + zonesClient := mockZonesClient{ + mockZonesClientIterator: &mockZoneClientIterator, + } + + // init record-related parts of the mock-client + resultPageIterator := mockRecordSetListResultPageIterator{ + results: []dns.RecordSetListResult{ + { + Value: recordSets, + }, + }, + } + mockRecordSetListResultPage := dns.NewRecordSetListResultPage(resultPageIterator.getNextPage) + mockRecordSetListIterator := dns.NewRecordSetListResultIterator(mockRecordSetListResultPage) + recordSetsClient := mockRecordSetsClient{ + mockRecordSetListIterator: &mockRecordSetListIterator, + } + + return newAzureProvider(domainFilter, zoneIDFilter, dryRun, resourceGroup, &zonesClient, &recordSetsClient), nil +} + func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zonesClient ZonesClient, recordsClient RecordSetsClient) *AzureProvider { return &AzureProvider{ domainFilter: domainFilter, @@ -178,32 +254,11 @@ func validateAzureEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expect } func TestAzureRecord(t *testing.T) { - zlr := dns.ZoneListResult{ - Value: &[]dns.Zone{ + provider, err := newMockedAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", + &[]dns.Zone{ createMockZone("example.com", "/dnszones/example.com"), }, - } - results := []dns.ZoneListResult{ - zlr, - } - - mockZoneListResultPage := dns.NewZoneListResultPage(func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) { - if len(results) > 0 { - result := results[0] - results = nil - return result, nil - } else { - return dns.ZoneListResult{}, nil - } - }) - mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) - - zonesClient := mockZonesClient{ - mockZonesClientIterator: &mockZoneClientIterator, - } - - rslr := dns.RecordSetListResult{ - Value: &[]dns.RecordSet{ + &[]dns.RecordSet{ createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), createMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122"), @@ -211,30 +266,7 @@ func TestAzureRecord(t *testing.T) { createMockRecordSetWithTTL("nginx", endpoint.RecordTypeA, "123.123.123.123", 3600), createMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL), createMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), - }, - } - - rsResults := []dns.RecordSetListResult{ - rslr, - } - - mockRecordSetListResultPage := dns.NewRecordSetListResultPage(func(ctxParam context.Context, rslrParam dns.RecordSetListResult) (dns.RecordSetListResult, error) { - if len(rsResults) > 0 { - result := rsResults[0] - rsResults = nil - return result, nil - } else { - return dns.RecordSetListResult{}, nil - } - }) - - mockRecordSetListIterator := dns.NewRecordSetListResultIterator(mockRecordSetListResultPage) - - recordSetsClient := mockRecordSetsClient{ - mockRecordSetListIterator: &mockRecordSetListIterator, - } - - provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordSetsClient) + }) actual, err := provider.Records() @@ -254,33 +286,11 @@ func TestAzureRecord(t *testing.T) { } func TestAzureMultiRecord(t *testing.T) { - - zlr := dns.ZoneListResult{ - Value: &[]dns.Zone{ + provider, err := newMockedAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", + &[]dns.Zone{ createMockZone("example.com", "/dnszones/example.com"), }, - } - results := []dns.ZoneListResult{ - zlr, - } - - mockZoneListResultPage := dns.NewZoneListResultPage(func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) { - if len(results) > 0 { - result := results[0] - results = nil - return result, nil - } else { - return dns.ZoneListResult{}, nil - } - }) - mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) - - zonesClient := mockZonesClient{ - mockZonesClientIterator: &mockZoneClientIterator, - } - - rslr := dns.RecordSetListResult{ - Value: &[]dns.RecordSet{ + &[]dns.RecordSet{ createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), createMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122", "234.234.234.233"), @@ -288,30 +298,7 @@ func TestAzureMultiRecord(t *testing.T) { createMockRecordSetMultiWithTTL("nginx", endpoint.RecordTypeA, 3600, "123.123.123.123", "234.234.234.234"), createMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL), createMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), - }, - } - - rsResults := []dns.RecordSetListResult{ - rslr, - } - - mockRecordSetListResultPage := dns.NewRecordSetListResultPage(func(ctxParam context.Context, rslrParam dns.RecordSetListResult) (dns.RecordSetListResult, error) { - if len(rsResults) > 0 { - result := rsResults[0] - rsResults = nil - return result, nil - } else { - return dns.RecordSetListResult{}, nil - } - }) - - mockRecordSetListIterator := dns.NewRecordSetListResultIterator(mockRecordSetListResultPage) - - recordSetsClient := mockRecordSetsClient{ - mockRecordSetListIterator: &mockRecordSetListIterator, - } - - provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordSetsClient) + }) actual, err := provider.Records() diff --git a/provider/designate.go b/provider/designate.go index 4cc1e55334..2425495ab4 100644 --- a/provider/designate.go +++ b/provider/designate.go @@ -19,18 +19,17 @@ package provider import ( "context" "fmt" - "net" - "net/http" - "os" - "strings" - "time" - "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack" "github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets" "github.com/gophercloud/gophercloud/openstack/dns/v2/zones" "github.com/gophercloud/gophercloud/pagination" log "github.com/sirupsen/logrus" + "net" + "net/http" + "os" + "strings" + "time" "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/kubernetes-sigs/external-dns/pkg/tlsutils" @@ -447,8 +446,10 @@ func (p designateProvider) upsertRecordSet(rs *recordSet, managedZones map[strin } return p.client.DeleteRecordSet(rs.zoneID, rs.recordSetID) } else { + ttl := 0 opts := recordsets.UpdateOpts{ Records: records, + TTL: &ttl, } log.Infof("Updating records: %s/%s: %s", rs.dnsName, rs.recordType, strings.Join(records, ",")) if p.dryRun { diff --git a/provider/designate_test.go b/provider/designate_test.go index bfc336c689..202ae6350b 100644 --- a/provider/designate_test.go +++ b/provider/designate_test.go @@ -114,6 +114,7 @@ func (c fakeDesignateClient) UpdateRecordSet(zoneID, recordSetID string, opts re if opts.Description != nil { rs.Description = *opts.Description } + rs.TTL = *opts.TTL rs.Records = opts.Records return nil From 6414a398901cd90f0ede255d1cdd3a2f0ae54343 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Tue, 22 Oct 2019 11:09:23 +0100 Subject: [PATCH 38/79] Address review comments --- provider/azure.go | 16 ++++++++-------- source/store.go | 6 ++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index 8fbbd91c7d..3cc8f654b1 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -226,19 +226,19 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { var zones []dns.Zone - i, err := p.zonesClient.ListByResourceGroupComplete(ctx, p.resourceGroup, nil) + zonesIterator, err := p.zonesClient.ListByResourceGroupComplete(ctx, p.resourceGroup, nil) if err != nil { return nil, err } - for i.NotDone() { - zone := i.Value() + for zonesIterator.NotDone() { + zone := zonesIterator.Value() if zone.Name != nil && p.domainFilter.Match(*zone.Name) && p.zoneIDFilter.Match(*zone.ID) { zones = append(zones, zone) } - err := i.NextWithContext(ctx) + err := zonesIterator.NextWithContext(ctx) if err != nil { return nil, err } @@ -251,17 +251,17 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { func (p *AzureProvider) iterateRecords(ctx context.Context, zoneName string, callback func(dns.RecordSet) bool) error { log.Debugf("Retrieving Azure DNS records for zone '%s'.", zoneName) - i, err := p.recordSetsClient.ListAllByDNSZoneComplete(ctx, p.resourceGroup, zoneName, nil, "") + recordSetsIterator, err := p.recordSetsClient.ListAllByDNSZoneComplete(ctx, p.resourceGroup, zoneName, nil, "") if err != nil { return err } - for i.NotDone() { - if !callback(i.Value()) { + for recordSetsIterator.NotDone() { + if !callback(recordSetsIterator.Value()) { return nil } - err := i.NextWithContext(ctx) + err := recordSetsIterator.NextWithContext(ctx) if err != nil { return err } diff --git a/source/store.go b/source/store.go index e197ae871f..e42ec5ba1b 100644 --- a/source/store.go +++ b/source/store.go @@ -231,8 +231,10 @@ func NewKubeClient(kubeConfig, kubeMaster string, requestTimeout time.Duration) log.Debugf("kubeConfig: %s", kubeConfig) // evaluate whether to use kubeConfig-file or serviceaccount-token - var config *rest.Config - var err error + var ( + config *rest.Config + err error + ) if kubeConfig == "" { log.Infof("Using inCluster-config based on serviceaccount-token") config, err = rest.InClusterConfig() From b0e1688b2d0bfcbfd598b41e0edf1585b2106f21 Mon Sep 17 00:00:00 2001 From: saidst Date: Sun, 3 Nov 2019 09:56:25 +0100 Subject: [PATCH 39/79] nail go-autorest dependencies to specific versions. --- go.mod | 67 ++++--- go.sum | 537 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 531 insertions(+), 73 deletions(-) diff --git a/go.mod b/go.mod index 321f36cf6f..17b09c4c98 100644 --- a/go.mod +++ b/go.mod @@ -3,49 +3,76 @@ module github.com/kubernetes-sigs/external-dns go 1.13 require ( - cloud.google.com/go v0.37.4 - github.com/Azure/azure-sdk-for-go v10.0.4-beta+incompatible - github.com/Azure/go-autorest v10.9.0+incompatible + cloud.google.com/go v0.44.3 + github.com/Azure/azure-sdk-for-go v36.0.0+incompatible + github.com/Azure/go-autorest/autorest v0.9.0 + github.com/Azure/go-autorest/autorest/adal v0.5.0 + github.com/Azure/go-autorest/autorest/to v0.3.0 + github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 // indirect + github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 // indirect github.com/alecthomas/kingpin v2.2.5+incompatible + github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 // indirect github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f github.com/aws/aws-sdk-go v1.23.18 + github.com/cenkalti/backoff v2.1.1+incompatible // indirect github.com/cloudflare/cloudflare-go v0.10.1 github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 - github.com/coreos/etcd v3.3.10+incompatible + github.com/coreos/etcd v3.3.15+incompatible github.com/denverdino/aliyungo v0.0.0-20180815121905-69560d9530f5 github.com/digitalocean/godo v1.19.0 + github.com/dnaeon/go-vcr v1.0.1 // indirect github.com/dnsimple/dnsimple-go v0.14.0 github.com/exoscale/egoscale v0.18.1 github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 - github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8 - github.com/heptio/contour v0.13.0 + github.com/go-resty/resty v1.8.0 // indirect + github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b // indirect + github.com/gophercloud/gophercloud v0.1.0 + github.com/heptio/contour v0.15.0 github.com/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65 - github.com/kubernetes-incubator/external-dns v0.5.17 github.com/linki/instrumented_http v0.2.0 github.com/linode/linodego v0.3.0 - github.com/miekg/dns v1.0.8 + github.com/mattn/go-isatty v0.0.7 // indirect + github.com/miekg/dns v1.0.14 github.com/nesv/go-dynect v0.6.0 github.com/nic-at/rc0go v1.1.0 github.com/oracle/oci-go-sdk v1.8.0 github.com/pkg/errors v0.8.1 - github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 + github.com/prometheus/client_golang v0.9.3 github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0 - github.com/sirupsen/logrus v1.4.1 + github.com/sergi/go-diff v1.0.0 // indirect + github.com/sirupsen/logrus v1.4.2 + github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect + github.com/smartystreets/gunit v1.0.2 // indirect github.com/stretchr/testify v1.4.0 github.com/transip/gotransip v5.8.2+incompatible + github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 // indirect github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 - golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c - golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a - google.golang.org/api v0.3.1 + golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 + golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 + google.golang.org/api v0.9.0 gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1 gopkg.in/yaml.v2 v2.2.2 - istio.io/api v0.0.0-20190321180614-db16d82d3672 + istio.io/api v0.0.0-20190820204432-483f2547d882 istio.io/istio v0.0.0-20190322063008-2b1331886076 - k8s.io/api v0.0.0-20190503184017-f1b257a4ce96 - k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841 - k8s.io/client-go v8.0.0+incompatible + k8s.io/api v0.0.0-20190620084959-7cf5895f2711 + k8s.io/apiextensions-apiserver v0.0.0-20190503184539-c338b28ceaa1 // indirect + k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719 + k8s.io/client-go v10.0.0+incompatible + k8s.io/kube-openapi v0.0.0-20190401085232-94e1e7b7574c // indirect ) -replace k8s.io/code-generator v0.0.0-20190409092313-b1289fc74931 => k8s.io/code-generator v0.0.0-20181128191024-b1289fc74931 - -replace github.com/golang/glog => github.com/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d +replace ( + github.com/Azure/go-autorest => github.com/Azure/go-autorest v13.0.1+incompatible + github.com/Azure/go-autorest/autorest => github.com/Azure/go-autorest/autorest v0.9.1 + github.com/Azure/go-autorest/autorest/adal => github.com/Azure/go-autorest/autorest/adal v0.6.0 + github.com/Azure/go-autorest/autorest/azure/auth => github.com/Azure/go-autorest/autorest/azure/auth v0.3.0 + github.com/golang/glog => github.com/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d + istio.io/api => istio.io/api v0.0.0-20190820204432-483f2547d882 + istio.io/istio => istio.io/istio v0.0.0-20190911205955-c2bd59595ce6 + k8s.io/api => k8s.io/api v0.0.0-20190817221950-ebce17126a01 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20190919022157-e8460a76b3ad + k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190817221809-bf4de9df677c + k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20190817224438-0337ccdab819 + k8s.io/client-go => k8s.io/client-go v0.0.0-20190817222206-ee6c071a42cf + k8s.io/code-generator => k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b +) diff --git a/go.sum b/go.sum index 8789be67a7..bf469b05b6 100644 --- a/go.sum +++ b/go.sum @@ -2,175 +2,416 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.3 h1:0sMegbmn/8uTwpNkB0q9cLEpZ2W5a6kl+wtBQgPWBJQ= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/logging v1.0.0/go.mod h1:V1cc3ogwobYzQq5f2R7DS/GvRIrI4FKj01Gs5glwAls= code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f h1:UrKzEwTgeiff9vxdrfdqxibzpWjxLnuXDI5m6z3GJAk= code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= -github.com/Azure/azure-sdk-for-go v10.0.4-beta+incompatible h1:FhnlL7/4O3gAB7EBgN43vA3Bb0fAlCBIMm9avXbcHlE= -github.com/Azure/azure-sdk-for-go v10.0.4-beta+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/go-autorest v10.9.0+incompatible h1:3ccqKLQg+scl0J6krcDgih2Rl+GC1eNuHZeRQYQxKkk= -github.com/Azure/go-autorest v10.9.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= +contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= +contrib.go.opencensus.io/exporter/stackdriver v0.6.0/go.mod h1:QeFzMJDAw8TXt5+aRaSuE8l5BwaMIOIlaVkBOPRuMuw= +contrib.go.opencensus.io/exporter/zipkin v0.1.1/go.mod h1:GMvdSl3eJ2gapOaLKzTKE3qDgUkJ86k9k3yY2eqwkzc= +fortio.org/fortio v1.3.0/go.mod h1:Go0fRqoPJ1xy5JOWcS23jyF58byVZxFyEePYsGmCR0k= +github.com/Azure/azure-sdk-for-go v36.0.0+incompatible h1:XIaBmA4pgKqQ7jInQPaNJQ4pOHrdJjw9gYXhbyiChaU= +github.com/Azure/azure-sdk-for-go v36.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v13.0.1+incompatible h1:wRg6hB3T3dp7qjj5v3NmVsdU9IyXodW+SQnN9xlpGEA= +github.com/Azure/go-autorest v13.0.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.9.1 h1:JB7Mqhna/7J8gZfVHjxDSTLSD6ciz2YgSMb/4qLXTtY= +github.com/Azure/go-autorest/autorest v0.9.1/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.6.0 h1:UCTq22yE3RPgbU/8u4scfnnzuCW6pwQ9n+uBtV78ouo= +github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= +github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v0.0.0-20190301161902-9f8fceff796f/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Masterminds/sprig v2.14.1+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/SAP/go-hdb v0.14.1/go.mod h1:7fdQLVC2lER3urZLjZCm0AuMQfApof92n3aylBPEkMo= +github.com/SermoDigital/jose v0.9.1/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= +github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= github.com/alecthomas/kingpin v2.2.5+incompatible h1:umWl1NNd72+ZvRti3T9C0SYean2hPZ7ZhxU8bsgc9BQ= github.com/alecthomas/kingpin v2.2.5+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= +github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAKQQZGOJ4knlw+7rfEQQcmwTbt4p5E= github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= +github.com/alicebob/miniredis v0.0.0-20180201100744-9d52b1fc8da9/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f h1:hinXH9rcBjRoIih5tl4f1BCbNjOmPJ2UnZwcYDhEHR0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= +github.com/antlr/antlr4 v0.0.0-20190223165740-dade65a895c2/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y= +github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30/go.mod h1:4AJxUpXUhv4N+ziTvIcWWXgeorXpxPZOfk9HdEVr96M= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-sdk-go v1.13.24/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k= github.com/aws/aws-sdk-go v1.23.18 h1:ADU/y1EO8yPzUJJYjcvJ0V9/suezxPh0u6hb5bSYIGQ= github.com/aws/aws-sdk-go v1.23.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 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/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/cactus/go-statsd-client v3.1.1+incompatible/go.mod h1:cMRcwZDklk7hXp+Law83urTHUiHMzCev/r4JMYr/zU0= +github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.10.1 h1:d2CL6F9k2O0Ux0w27LgogJ5UOzZRj6a/hDPFqPP68d8= github.com/cloudflare/cloudflare-go v0.10.1/go.mod h1:C0Y6eWnTJPMK2ceuOxx2pjh78UUHihcXeTTHb8r7QjU= github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 h1:rdRS5BT13Iae9ssvcslol66gfOOXjaLYwqerEn/cl9s= github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381/go.mod h1:e5+USP2j8Le2M0Jo3qKPFnNhuo1wueU4nWHCXBOfQ14= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY= +github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.15+incompatible h1:+9RjdC18gMxNQVvSiXvObLu29mOFmkgdsB4cRTlV+EE= +github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc v0.0.0-20180117170138-065b426bd416/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142 h1:3jFq2xL4ZajGK4aZY8jz+DAF0FHjI51BXjjSwCzS1Dk= +github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/prometheus-operator v0.29.0/go.mod h1:SO+r5yZUacDFPKHfPoUjI3hMsH+ZUdiuNNhuSq3WoSg= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= +github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= 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/dchest/siphash v1.1.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= +github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/denverdino/aliyungo v0.0.0-20180815121905-69560d9530f5 h1:YjnQWGUNtqeKqndapy9V1BzlfMwc/dBJf2MU9dmuXSQ= github.com/denverdino/aliyungo v0.0.0-20180815121905-69560d9530f5/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/digitalocean/godo v1.19.0 h1:9ApuchfzGD/XI8Zm0RRnZnytdfYHPjPTRKTnmzQNV7o= github.com/digitalocean/godo v1.19.0/go.mod h1:AAPQ+tiM4st79QHlEBTg8LM7JQNre4SAQCbn56wEyKY= +github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnsimple/dnsimple-go v0.14.0 h1:JGYtVVA/uHc91q0LjDWqR1oVj6EGu9Kn0lMRxjH/w30= github.com/dnsimple/dnsimple-go v0.14.0/go.mod h1:0FYu4qVNv/UcfZPNwa9zi68IkggJu3TIwM54D7rhmI4= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v0.0.0-20180612054059-a9fbbdc8dd87/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/dropbox/godropbox v0.0.0-20190501155911-5749d3b71cbe/go.mod h1:glr97hP/JuXb+WMYCizc4PIFuzw1lCR97mwbe1VVXhQ= +github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= +github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/envoyproxy/go-control-plane v0.8.0 h1:uE6Fp4fOcAJdc1wTQXLJ+SYistkbG1dNoi6Zs1+Ybvk= -github.com/envoyproxy/go-control-plane v0.8.0/go.mod h1:GSSbY9P1neVhdY7G4wu+IK1rk/dqhiCC/4ExuWJZVuk= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/elazarl/goproxy v0.0.0-20190630181448-f1e96bc0f4c5/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy/ext v0.0.0-20190630181448-f1e96bc0f4c5/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/emicklei/go-restful v2.9.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.8.2/go.mod h1:EWRTAFN6uuDZIa6KOuUfrOMJ7ySgXZ44rVKiTWjKe34= +github.com/envoyproxy/go-control-plane v0.8.7-0.20190821215049-f062b07a671a h1:SaBXBWjRmig9yVB49C6TcbDtbZTbhuFLod7YiGjuFxQ= +github.com/envoyproxy/go-control-plane v0.8.7-0.20190821215049-f062b07a671a/go.mod h1:XB9+ce7x+IrsjgIVnRnql0O61gj/np0/bGDfhJI3sCU= +github.com/envoyproxy/protoc-gen-validate v0.0.0-20190405222122-d6164de49109/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.0.14 h1:YBW6/cKy9prEGRYLnaGa4IDhzxZhRCtKsax8srGKDnM= github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exoscale/egoscale v0.18.1 h1:1FNZVk8jHUx0AvWhOZxLEDNlacTU0chMXUUNkm9EZaI= github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/stackerr v0.0.0-20150612192056-c2fcf88613f4/go.mod h1:SBHk9aNQtiw4R4bEuzHjVmZikkUKCnO1v3lPQ21HZGk= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 h1:jmwW6QWvUO2OPe22YfgFvBaaZlSr8Rlrac5lZvG6IdM= github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99/go.mod h1:4mP9w9+vYGw2jUx2+2v03IA+phyQQjNRR4AL3uxlNrs= +github.com/fluent/fluent-logger-golang v1.3.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= +github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-ini/ini v1.33.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-redis/redis v6.10.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-resty/resty v1.8.0 h1:vbNCxbHOWCototzwxf3L63PQCKx6xgT6v8SHfoqkp6U= github.com/go-resty/resty v1.8.0/go.mod h1:n37daLLGIHq2FFYHxg+FYQiwA95FpfNI+A9uxoIYGRk= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gocql/gocql v0.0.0-20190423091413-b99afaf3b163/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48 h1:X+zN6RZXsvnrSJaAIQhZezPfAfvsqihKKR8oiLHid34= +github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/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.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1/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/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f h1:kSqKc8ouCLIBHqdj9a9xxhtxlZhNqbePClixA4HoM44= +github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:YCHYtYb9c8Q7XgYVYjmJBPtFPKx5QvOcPxHZWjldabE= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/cel-go v0.2.0/go.mod h1:fTCVOuSN/Vn6d49zvRpr3fDAKFyfpLViE0gU+9Vtm7g= +github.com/google/cel-spec v0.2.0/go.mod h1:MjQm800JAGhOZXI7vatnVpmIaFTR6L8FHcKk+piiKpI= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-github v15.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 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.0.0-20190126172459-c818fa66e4c8 h1:L9JPKrtsHMQ4VCRQfHvbbHBfB2Urn8xf6QZeXZ+OrN4= -github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= +github.com/gophercloud/gophercloud v0.0.0-20190424031112-b9b92a825806 h1:Jua/oVkYNsCSNamvehem7aSkVr3FK6e8AlqTvAm0fwA= +github.com/gophercloud/gophercloud v0.0.0-20190424031112-b9b92a825806/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20171214222146-0e7658f8ee99/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/consul v1.3.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.9.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.0.1/go.mod h1:I6dKdmYhZqU0RJSheVEWgTNWdVQH5QvTgIUQ0t/t32M= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.0.0/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/heptio/contour v0.13.0 h1:kiJ7qC439vFD21DTyQPNPzOGfDqkO/y//GrLYWJ5MdY= -github.com/heptio/contour v0.13.0/go.mod h1:qYE0FAuA8W1NJEaHmyOoWkJZTRPL1x4GVO5BGZMG1Os= +github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= +github.com/hashicorp/vault v0.10.0/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/heptio/contour v0.15.0 h1:JhyJMauwoYtqTzd23jStx7Bx7S3sHbqTWZs6+Ed+UPE= +github.com/heptio/contour v0.15.0/go.mod h1:y4LmuX+86v8mlRd1HVrb2u4t77jMjOQ3DnjfRCiwrfA= +github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= github.com/imdario/mergo v0.3.7/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/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65 h1:FP5rOFP4ifbtFIjFHJmwhFrsbDyONILK/FNntl/Pou8= github.com/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI= +github.com/jefferai/jsonx v1.0.0/go.mod h1:OGmqmi2tTeI/PS+qQfBDToLHHJIy/RMp24fPo8vFvoQ= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jteeuwen/go-bindata v0.0.0-20180305030458-6025e8de665b/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20190207033735-e65537c515d7/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20190212223446-d976af380377/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/keybase/go-crypto v0.0.0-20190416182011-b785b22cc757/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 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/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +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/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d h1:JV46OtdhH2vVt8mJ1EWUE94k99vbN9fZs1WQ8kcEapU= github.com/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d/go.mod h1:CHQ3o5KBH1PIS2Fb1mRLTIWO5YzP9kSUB3KoCICwlvA= -github.com/kubernetes-incubator/external-dns v0.5.17 h1:IppndULuSmCM7GUoylCVXHx9FK6d1tu2ftlimkAMaHQ= -github.com/kubernetes-incubator/external-dns v0.5.17/go.mod h1:6LFVqEVTlTlodv3qWMzMRPQFSPKEJ4gIANaKer3kiaY= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/linki/instrumented_http v0.2.0 h1:zLhcB3Q/McQQqml3qd5kzdZ0cGnL3vquPFIW2338f5Y= github.com/linki/instrumented_http v0.2.0/go.mod h1:pjYbItoegfuVi2GUOMhEqzvm/SJKuEL3H0tc8QRLRFk= github.com/linode/linodego v0.3.0 h1:I83pEPg4owSy5pCPaKix7xkGbWIjPxmAoc/Yu5OYDDY= github.com/linode/linodego v0.3.0/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= +github.com/lyft/protoc-gen-star v0.4.10/go.mod h1:mE8fbna26u7aEA2QCVvvfBU/ZrPgocG1206xAFPcs94= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 h1:YFh+sjyJTMQSYjKwM4dFKhJPJC/wfo98tPUc17HdoYw= github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= +github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 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/mdempsky/unconvert v0.0.0-20190325185700-2f5dc3378ed3/go.mod h1:9+3Wp2ccIz73BJqVfc7n2+1A+mzvnEwtDTqEjeRngBQ= -github.com/miekg/dns v1.0.8 h1:Zi8HNpze3NeRWH1PQV6O71YcvJRQ6j0lORO6DAEmAAI= -github.com/miekg/dns v1.0.8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= +github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v0.0.0-20161203194507-b8bc1bf76747/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -180,61 +421,121 @@ github.com/nesv/go-dynect v0.6.0 h1:Ow/DiSm4LAISwnFku/FITSQHnU6pBvhQMsUE5Gu6Oq4= github.com/nesv/go-dynect v0.6.0/go.mod h1:GHRBRKzTwjAMhosHJQq/KrZaFkXIFyJ5zRE7thGXXrs= github.com/nic-at/rc0go v1.1.0 h1:k6/Bru/npTjmCSFw65ulYRw/b3ycIS30t6/YM4r42V4= github.com/nic-at/rc0go v1.1.0/go.mod h1:KEa3H5fmDNXCaXSqOeAZxkKnG/8ggr1OHIG25Ve7fjU= +github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/open-policy-agent/opa v0.8.2/go.mod h1:rlfeSeHuZmMEpmrcGla42AjkOUjP4rGIpS96H12un3o= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/openshift/api v0.0.0-20190322043348-8741ff068a47/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/operator-framework/operator-sdk v0.7.0/go.mod h1:iVyukRkam5JZa8AnjYf+/G3rk7JI1+M6GsU0sq0B9NA= github.com/oracle/oci-go-sdk v1.8.0 h1:4SO45bKV0I3/Mn1os3ANDZmV0eSE5z5CLdSUIkxtyzs= github.com/oracle/oci-go-sdk v1.8.0/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2 h1:CXwSGu/LYmbjEab5aMCs5usQRVBGThelUKBNnoSOuso= github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.2.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872 h1:0aNv3xC7DmQoy1/x1sMh18g+fihWW68LL13i8ao9kl4= github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0 h1:c8R11WC8m7KNMkTv/0+Be8vvwo4I3/Ut9AC2FW8fX3U= +github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/prom2json v1.1.0/go.mod h1:v7OY1795b9fEUZgq4UU2+15YjRv0LfpxKejIQCy3L7o= +github.com/prometheus/prom2json v1.2.1/go.mod h1:yIcXOj/TLPdtZ12qRyhswPnu+02sfDoqatDjj0WGSvo= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.2.1/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryanuber/go-glob v0.0.0-20160226084822-572520ed46db/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0 h1:vOcHdR1nu7DO4BAx1rwzdHV7jQTzW3gqcBT5qxHSc6A= github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0/go.mod h1:FeplEtXXejBYC4NPAFTrs5L7KuK+5RL9bf5nB2vZe9o= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sethgrid/pester v0.0.0-20180227223404-ed9870dad317/go.mod h1:Ad7IjTpvzZO8Fl0vh9AzQ+j/jYZfyp2diGwI8m5q+ns= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/signalfx/com_signalfx_metrics_protobuf v0.0.0-20170330202426-93e507b42f43/go.mod h1:muYA2clvwCdj7nzAJ5vJIXYpJsUumhAl4Uu1wUNpWzA= +github.com/signalfx/gohistogram v0.0.0-20160107210732-1ccfd2ff5083/go.mod h1:adPDS6s7WaajdFBV9mQ7i0dKfQ8xiDnF9ZNETVPpp7c= +github.com/signalfx/golib v1.1.6/go.mod h1:nWYefOwlUKWm/SpN/LgVSBnyH1T9NpT1ANlmgRIi1Cs= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180725160413-e900ae048470/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 h1:hp2CYQUINdZMHdvTdXtPOY2ainKl4IoMcpAXEf2xj3Q= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/gunit v1.0.2 h1:nCXf7TXGchqk8zNVQFTtbeW6rGSrlp9ir9h8wmx0xws= github.com/smartystreets/gunit v1.0.2/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ= -github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -242,67 +543,130 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf 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= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A= +github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/transip/gotransip v5.8.2+incompatible h1:aNJhw/w/3QBqFcHAIPz1ytoK5FexeMzbUCGrrhWr3H0= github.com/transip/gotransip v5.8.2+incompatible/go.mod h1:uacMoJVmrfOcscM4Bi5NVg708b7c6rz2oDTWqa7i2Ic= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/uber/jaeger-client-go v0.0.0-20190228190846-ecf2d03a9e80/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs= github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 h1:vG/gY/PxA3v3l04qxe3tDjXyu3bozii8ulSlIPOYKhI= github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA= +github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 h1:Q76MzqJu++vAfhj0mVf7t0F4xHUbg+V/d/Uk5PBQjRU= github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92/go.mod h1:AZuEfReFWdvtU0LatbLpo70t3lqdLvph2D5mqFP0bkA= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yashtewari/glob-intersection v0.0.0-20180206001645-7af743e8ec84/go.mod h1:HptNXiXVDcJjXe9SqMd0v2FsL9f8dz4GnXgltU6q/co= github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268 h1:lkoOjizoHqOcEFsvYGE5c8Ykdijjnd0R3r1yDYHzLno= github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268/go.mod h1:mq0zhomp/G6rRTb0dvHWXRHr/2+Qgeq5hMXfJ670+i4= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +github.com/yuin/gopher-lua v0.0.0-20180316054350-84ea3a3c79b3/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= +go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.20.1 h1:pMEjRZ1M4ebWGikflH7nQpV6+Zr88KBMA2XJD3sbijw= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190404164418-38d8ce5564a5 h1:bselrhR0Or1vomJZC8ZIjWtbDmn9OYFLX5Ik9alpJpE= -golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/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-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/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-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-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-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c h1:hDn6jm7snBX2O7+EeTk6Q4WXJfKt7MWgtiCCRi1rBoY= golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -315,65 +679,132 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190213192042-740235f6c0d8/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190325161752-5a8dccf5b48a/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190822000311-fc82fb2afd64/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190227213309-4f5b463f9597/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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/d4l3k/messagediff.v1 v1.2.1 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0= +gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= 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/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/logfmt.v0 v0.3.0/go.mod h1:mRLMcMLrml5h2Ux/H+4zccFOlVCiRvOvndsolsJoU8Q= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1 h1:+fgY/3ngqdBW9oLQCMwL5g+QRkKFPJH05fx2/pipqRQ= gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1/go.mod h1:VV+3haRsgDiVLxyifmMBrBIuCWFBPYKbRssXB9z67Hw= +gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/stack.v1 v1.7.0/go.mod h1:QtWz4C5wbvhA63ngux3942W/ppRxtyYjHvvhz02s7+M= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= 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= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -istio.io/api v0.0.0-20190321180614-db16d82d3672 h1:luY97pBVarSo1v++zf2kgb84Q55G5hv/ult2A4KPQuk= -istio.io/api v0.0.0-20190321180614-db16d82d3672/go.mod h1:hhLFQmpHia8zgaM37vb2ml9iS5NfNfqZGRt1pS9aVEo= -istio.io/gogo-genproto v0.0.0-20190124151557-6d926a6e6feb/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI= -istio.io/istio v0.0.0-20190322063008-2b1331886076 h1:gZhCrmVzfQJoDl4oav8i5+NF7p7v0M1Pou+2O+hZBtc= -istio.io/istio v0.0.0-20190322063008-2b1331886076/go.mod h1:OWBySrQjjk549IhxWCt7DTl9ZSsXdvbgm+SmgGVRsGA= -k8s.io/api v0.0.0-20190226173710-145d52631d00/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= -k8s.io/api v0.0.0-20190503184017-f1b257a4ce96 h1:zq/7PZXqJ6ZbPfLRbIm9Qs6gHMviY72SPk4ugPUPDvI= -k8s.io/api v0.0.0-20190503184017-f1b257a4ce96/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= -k8s.io/apiextensions-apiserver v0.0.0-20190503184539-c338b28ceaa1 h1:uNrdMFGXgDAaw+WyJSuRhnzW2eZkqZjc04SZOr4wky8= -k8s.io/apiextensions-apiserver v0.0.0-20190503184539-c338b28ceaa1/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= -k8s.io/apimachinery v0.0.0-20190221084156-01f179d85dbc/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= -k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841 h1:Q4RZrHNtlC/mSdC1sTrcZ5RchC/9vxLVj57pWiCBKv4= -k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= -k8s.io/client-go v0.0.0-20190226174127-78295b709ec6/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= -k8s.io/client-go v8.0.0+incompatible h1:tTI4hRmb1DRMl4fG6Vclfdi6nTM82oIrTT7HfitmxC4= -k8s.io/client-go v8.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= -k8s.io/code-generator v0.0.0-20181128191024-b1289fc74931/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +istio.io/api v0.0.0-20190820204432-483f2547d882 h1:L0WC/5HTk8T5eGTg/ka9jGZgw7GMuWj9rm6DFF4owL8= +istio.io/api v0.0.0-20190820204432-483f2547d882/go.mod h1:42cBjnu/rTJcCaKi8nLdIvq0n71RcLrkgZ9IQSvDdSQ= +istio.io/gogo-genproto v0.0.0-20190614210408-e88dc8b0e4db/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI= +istio.io/gogo-genproto v0.0.0-20190731221249-06e20ada0df2/go.mod h1:IjvrbUlRbbw4JCpsgvgihcz9USUwEoNTL/uwMtyV5yk= +istio.io/gogo-genproto v0.0.0-20190819131816-7a8328e41c1a h1:QN+P7SPcjI4az1Lb40MdhJg/OkV03u5XS1DVIk8PS6E= +istio.io/gogo-genproto v0.0.0-20190819131816-7a8328e41c1a/go.mod h1:IjvrbUlRbbw4JCpsgvgihcz9USUwEoNTL/uwMtyV5yk= +istio.io/istio v0.0.0-20190911205955-c2bd59595ce6 h1:SICsYFkNnMRHPPxHYUGMqZp1lQXW8+nJKBSIZVIk16M= +istio.io/istio v0.0.0-20190911205955-c2bd59595ce6/go.mod h1:dn7qqBbC/pAcJnqNvB2jv7llDBbExQVbnPIVuPPScx8= +istio.io/operator v0.0.0-20190830172131-647a5416137b/go.mod h1:NW/+IXU4IeeVtWLS8S57Vq67H/GOy92Temo4eI5efLs= +istio.io/pkg v0.0.0-20190515193414-9332430ad747/go.mod h1:0EkPwmR0tESYjN4Ilq1D52nTBurXaQvny3r2VY4j4tw= +istio.io/pkg v0.0.0-20190731230704-fcbac27d69d5 h1:HcASpvj/fuuABkYH9YbsTGEOT75YHyWvvFnTe229zXs= +istio.io/pkg v0.0.0-20190731230704-fcbac27d69d5/go.mod h1:We4ZQuCbiiNfXge2GfOshBsyDXVwzFwP8703V5DcM14= +k8s.io/api v0.0.0-20190817221950-ebce17126a01 h1:AMUY6ojynTCBURCALg9KVOsrCmWjHF7h7UbuBod7FYc= +k8s.io/api v0.0.0-20190817221950-ebce17126a01/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/apiextensions-apiserver v0.0.0-20190919022157-e8460a76b3ad h1:I3kcGO+4TazAR49NWgNiEGND6b4q5HVc7Q0K1IQxV9Q= +k8s.io/apiextensions-apiserver v0.0.0-20190919022157-e8460a76b3ad/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apimachinery v0.0.0-20190817221809-bf4de9df677c h1:TlFvXut3q9hNMA2UdjrC6LLfANYrh4lnDzb0gDNSMSg= +k8s.io/apimachinery v0.0.0-20190817221809-bf4de9df677c/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apiserver v0.0.0-20181213151703-3ccfe8365421/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w= +k8s.io/cli-runtime v0.0.0-20190817224438-0337ccdab819/go.mod h1:qWnH3/b8sp/l7EvlDh7ulDU3UWA4P4N1NFbEEP791tM= +k8s.io/client-go v0.0.0-20190817222206-ee6c071a42cf h1:ZCiWjWPoxHYlMo7N4ZPz7yqo2YuCPvBi3nNX11oBTMg= +k8s.io/client-go v0.0.0-20190817222206-ee6c071a42cf/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/klog v0.0.0-20190306015804-8e90cee79f82/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/kube-openapi v0.0.0-20190115222348-ced9eb3070a5/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= +k8s.io/helm v2.13.1+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68= +k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190401085232-94e1e7b7574c h1:kJCzg2vGCzah5icgkKR7O1Dzn0NA2iGlym27sb0ZfGE= k8s.io/kube-openapi v0.0.0-20190401085232-94e1e7b7574c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -mvdan.cc/unparam v0.0.0-20190310220240-1b9ccfa71afe/go.mod h1:BnhuWBAqxH3+J5bDybdxgw5ZfS+DsVd4iylsKQePN8o= +k8s.io/kubernetes v1.13.1/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= +k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +sigs.k8s.io/controller-runtime v0.1.10/go.mod h1:HFAYoOh6XMV+jKF1UjFwrknPbowfyHEHHRdJMf2jMX8= +sigs.k8s.io/testing_frameworks v0.1.1/go.mod h1:VVBKrHmJ6Ekkfz284YKhQePcdycOzNH9qL6ht1zEr/U= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= From 82e43e85ec06845514aedf8acd9376b89bb6b616 Mon Sep 17 00:00:00 2001 From: Mario Constanti Date: Mon, 4 Nov 2019 06:53:30 +0100 Subject: [PATCH 40/79] docs: fix log-level param in tutorials * arg --debug is now --log-level=debug * flag --log-level was merged 2017 with PR https://github.com/kubernetes-sigs/external-dns/pull/339 --- docs/tutorials/externalname.md | 2 +- docs/tutorials/hostport.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/externalname.md b/docs/tutorials/externalname.md index 6f9e724f7b..845d80f63e 100644 --- a/docs/tutorials/externalname.md +++ b/docs/tutorials/externalname.md @@ -23,7 +23,7 @@ spec: - name: external-dns image: registry.opensource.zalan.do/teapot/external-dns:latest args: - - --debug + - --log-level=debug - --source=service - --source=ingress - --namespace=dev diff --git a/docs/tutorials/hostport.md b/docs/tutorials/hostport.md index 17d81d5187..f64cbbd787 100644 --- a/docs/tutorials/hostport.md +++ b/docs/tutorials/hostport.md @@ -27,7 +27,7 @@ spec: - name: external-dns image: registry.opensource.zalan.do/teapot/external-dns:latest args: - - --debug + - --log-level=debug - --source=service - --source=ingress - --namespace=dev @@ -89,7 +89,7 @@ spec: - name: external-dns image: registry.opensource.zalan.do/teapot/external-dns:latest args: - - --debug + - --log-level=debug - --source=service - --source=ingress - --namespace=dev From a16827e73c762bb1d0a436f95d6b80475226ead3 Mon Sep 17 00:00:00 2001 From: Mario Constanti Date: Mon, 4 Nov 2019 07:18:51 +0100 Subject: [PATCH 41/79] docs/designate: add snippet for rbac env * extend the external-dns deployment to work within a RBAC enabled environment * add short hint how to mount/use/trust self-sign certificates --- docs/tutorials/designate.md | 95 ++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/designate.md b/docs/tutorials/designate.md index 34fd209e10..5ffe560c64 100644 --- a/docs/tutorials/designate.md +++ b/docs/tutorials/designate.md @@ -39,6 +39,8 @@ It is important to manually create all the zones that are going to be used for k Create a deployment file called `externaldns.yaml` with the following contents: +### Manifest (for clusters without RBAC enabled) + ```yaml apiVersion: extensions/v1beta1 kind: Deployment @@ -54,14 +56,87 @@ spec: spec: containers: - name: external-dns - image: registry.opensource.zalan.do/teapot/external-dns + image: registry.opensource.zalan.do/teapot/external-dns:latest args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --provider=designate env: # values from openrc file - name: OS_AUTH_URL - value: http://controller/identity/v3 + value: https://controller/identity/v3 + - name: OS_REGION_NAME + value: RegionOne + - name: OS_USERNAME + value: admin + - name: OS_PASSWORD + value: p@ssw0rd + - name: OS_PROJECT_NAME + value: demo + - name: OS_USER_DOMAIN_NAME + value: Default +``` + +### Manifest (for clusters without RBAC enabled) + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: external-dns +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: external-dns +rules: +- apiGroups: [""] + resources: ["services"] + verbs: ["get","watch","list"] +- apiGroups: [""] + resources: ["pods"] + verbs: ["get","watch","list"] +- apiGroups: ["extensions"] + resources: ["ingresses"] + verbs: ["get","watch","list"] +- apiGroups: [""] + resources: ["nodes"] + verbs: ["watch","list"] +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: external-dns-viewer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: external-dns +subjects: +- kind: ServiceAccount + name: external-dns + namespace: default +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: external-dns +spec: + strategy: + type: Recreate + template: + metadata: + labels: + app: external-dns + spec: + containers: + - name: external-dns + image: registry.opensource.zalan.do/teapot/external-dns:latest + args: + - --source=service # ingress is also possible + - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. + - --provider=designate + env: # values from openrc file + - name: OS_AUTH_URL + value: https://controller/identity/v3 - name: OS_REGION_NAME value: RegionOne - name: OS_USERNAME @@ -80,6 +155,22 @@ Create the deployment for ExternalDNS: $ kubectl create -f externaldns.yaml ``` +### Optional: Trust self-sign certificates +If your OpenStack-Installation is configured with a self-sign certificate, you could extend the `pod.spec` with following secret-mount: +```yaml + volumeMounts: + - mountPath: /etc/ssl/certs/ + name: cacerts + volumes: + - name: cacerts + secret: + defaultMode: 420 + secretName: self-sign-certs +``` + +content of the secret `self-sign-certs` must be the certificate/chain in PEM format. + + ## Deploying an Nginx Service Create a service file called 'nginx.yaml' with the following contents: From a9e6917d2ad5d487437c3133128420f34557911f Mon Sep 17 00:00:00 2001 From: njuettner Date: Tue, 5 Nov 2019 15:41:52 +0100 Subject: [PATCH 42/79] Drop labeler when forking Signed-off-by: njuettner --- .github/workflows/labeler.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 15e653f602..28a0488bdf 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -3,10 +3,11 @@ on: - pull_request jobs: - triage: + label: runs-on: ubuntu-latest + steps: - - uses: actions/labeler@v2 - if: github.repository == 'kubernetes-sigs/external-dns' - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" + - uses: actions/labeler@v2 + if: contains(github.repository, 'kubernetes-sigs/external-dns') + with: + repo-token: '${{ secrets.GITHUB_TOKEN }}' From b5858683722b4cd81539f2c7430c29bc552817b7 Mon Sep 17 00:00:00 2001 From: Eugene Klimov Date: Wed, 6 Nov 2019 09:09:15 +0300 Subject: [PATCH 43/79] update links to RDNS --- docs/tutorials/rdns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/rdns.md b/docs/tutorials/rdns.md index df44618909..09613f5d9e 100644 --- a/docs/tutorials/rdns.md +++ b/docs/tutorials/rdns.md @@ -1,5 +1,5 @@ # Setting up ExternalDNS for RancherDNS(RDNS) with kubernetes -This tutorial describes how to setup ExternalDNS for usage within a kubernetes cluster that makes use of [RDNS](https://github.com/rancher/rdns) and [nginx ingress controller](https://github.com/kubernetes/ingress-nginx). +This tutorial describes how to setup ExternalDNS for usage within a kubernetes cluster that makes use of [RDNS](https://github.com/rancher/rdns-server) and [nginx ingress controller](https://github.com/kubernetes/ingress-nginx). You need to: * install RDNS with [etcd](https://github.com/etcd-io/etcd) enabled * install external-dns with rdns as a provider From e70338deb05455a14f3adaf4bef33f52e30410a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Helgi=20=C3=9Eormar=20=C3=9Eorbj=C3=B6rnsson?= <70530+helgi@users.noreply.github.com> Date: Wed, 6 Nov 2019 11:43:29 -0800 Subject: [PATCH 44/79] Add gov LB hosted zone At the bottom of https://docs.aws.amazon.com/govcloud-us/latest/UserGuide/using-govcloud-endpoints.html it says: > Amazon Route 53 hosted Zone ID for the regional endpoint in the AWS GovCloud (US) region is Z1K6XKP9SAGWDV. --- provider/aws.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provider/aws.go b/provider/aws.go index 927a27536b..69b40571e4 100644 --- a/provider/aws.go +++ b/provider/aws.go @@ -42,6 +42,7 @@ const ( var ( // see: https://docs.aws.amazon.com/general/latest/gr/rande.html#elb_region + // and: https://docs.aws.amazon.com/govcloud-us/latest/UserGuide/using-govcloud-endpoints.html canonicalHostedZones = map[string]string{ // Application Load Balancers and Classic Load Balancers "us-east-2.elb.amazonaws.com": "Z3AADJGX6KTTL2", @@ -63,6 +64,7 @@ var ( "sa-east-1.elb.amazonaws.com": "Z2P70J7HTTTPLU", "cn-north-1.elb.amazonaws.com.cn": "Z3BX2TMKNYI13Y", "cn-northwest-1.elb.amazonaws.com.cn": "Z3BX2TMKNYI13Y", + "us-gov-west-1.amazonaws.com": "Z1K6XKP9SAGWDV", // Network Load Balancers "elb.us-east-2.amazonaws.com": "ZLMOA37VPKANP", "elb.us-east-1.amazonaws.com": "Z26RNL4JYFTOTI", From 4f662d48eae36e57abc6c6c9784329c2d513b382 Mon Sep 17 00:00:00 2001 From: Mostafa Dahab Date: Fri, 8 Nov 2019 21:00:34 +0300 Subject: [PATCH 45/79] Add me-south region to canonicalHostedZones https://github.com/kubernetes-sigs/external-dns/issues/1265 --- provider/aws.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provider/aws.go b/provider/aws.go index 69b40571e4..8b2911d539 100644 --- a/provider/aws.go +++ b/provider/aws.go @@ -65,6 +65,7 @@ var ( "cn-north-1.elb.amazonaws.com.cn": "Z3BX2TMKNYI13Y", "cn-northwest-1.elb.amazonaws.com.cn": "Z3BX2TMKNYI13Y", "us-gov-west-1.amazonaws.com": "Z1K6XKP9SAGWDV", + "me-south-1.elb.amazonaws.com": "ZS929ML54UICD", // Network Load Balancers "elb.us-east-2.amazonaws.com": "ZLMOA37VPKANP", "elb.us-east-1.amazonaws.com": "Z26RNL4JYFTOTI", @@ -84,6 +85,7 @@ var ( "elb.sa-east-1.amazonaws.com": "ZTK26PT1VY4CU", "elb.cn-north-1.amazonaws.com.cn": "Z3QFB96KMJ7ED6", "elb.cn-northwest-1.amazonaws.com.cn": "ZQEIKTCZ8352D", + "elb.me-south-1.amazonaws.com": "Z3QSRYVP46NYYV", } ) From 4eb3da327c0a7c2acde4fa11d7f3620d3d107a13 Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Tue, 12 Nov 2019 13:46:34 +0800 Subject: [PATCH 46/79] Fix tutorial for kubernetes 1.16+ `Deployment` has been removed from `apiVersion: extensions/v1beta1` See https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/ --- docs/tutorials/aws.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index 67a7b37172..825ccec5bd 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -70,13 +70,16 @@ For clusters with RBAC enabled, be sure to choose the correct `namespace`. ### Manifest (for clusters without RBAC enabled) ```yaml -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: strategy: type: Recreate + selector: + matchLabels: + app: external-dns template: metadata: labels: @@ -115,8 +118,8 @@ rules: - apiGroups: [""] resources: ["pods"] verbs: ["get","watch","list"] -- apiGroups: ["extensions"] - resources: ["ingresses"] +- apiGroups: ["extensions"] + resources: ["ingresses"] verbs: ["get","watch","list"] - apiGroups: [""] resources: ["nodes"] @@ -135,13 +138,16 @@ subjects: name: external-dns namespace: default --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: strategy: type: Recreate + selector: + matchLabels: + app: external-dns template: metadata: labels: From 126e1faf958e9bdef4454454ac6ee55e80132e9f Mon Sep 17 00:00:00 2001 From: sph Date: Tue, 12 Nov 2019 15:46:24 +0800 Subject: [PATCH 47/79] fix golint errors --- provider/rdns.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/provider/rdns.go b/provider/rdns.go index 3e3216b7ae..cb7ccc2eca 100644 --- a/provider/rdns.go +++ b/provider/rdns.go @@ -124,7 +124,7 @@ func (p RDNSProvider) Records() ([]*endpoint.Endpoint, error) { for _, r := range rs { domains := strings.Split(strings.TrimPrefix(r.Key, rdnsPrefix+"/"), "/") - keyToDnsNameSplits(domains) + keyToDNSNameSplits(domains) dnsName := strings.Join(domains, ".") if !p.domainFilter.Match(dnsName) { continue @@ -251,7 +251,7 @@ func (p *RDNSProvider) filterAndRemoveUseless(ep *endpoint.Endpoint, changes *pl } if !exist { ds := strings.Split(strings.TrimPrefix(r.Key, rdnsPrefix+"/"), "/") - keyToDnsNameSplits(ds) + keyToDNSNameSplits(ds) changes.Delete = append(changes.Delete, &endpoint.Endpoint{ DNSName: strings.Join(ds, "."), }) @@ -456,7 +456,7 @@ func (c etcdv3Client) aggregationRecords(result *clientv3.GetResponse) ([]RDNSRe // appendRecords append record to an array func appendRecords(r RDNSRecord, dnsType string, bx map[RDNSRecordType]RDNSRecord, rs []RDNSRecord) ([]RDNSRecord, bool) { - dnsName := keyToParentDnsName(r.Key) + dnsName := keyToParentDNSName(r.Key) bt := RDNSRecordType{Domain: dnsName, Type: dnsType} if v, ok := bx[bt]; ok { // skip the TXT records if already added to record list. @@ -502,12 +502,12 @@ func keyFor(fqdn string) string { return rdnsPrefix + dnsNameToKey(fqdn) } -// keyToParentDnsName used to get dnsName. +// keyToParentDNSName used to get dnsName. // e.g. /rdnsv3/cloud/rancher/lb/sample/xxx => xxx.sample.lb.rancher.cloud // e.g. /rdnsv3/cloud/rancher/lb/sample/xxx/1_1_1_1 => xxx.sample.lb.rancher.cloud -func keyToParentDnsName(key string) string { +func keyToParentDNSName(key string) string { ds := strings.Split(strings.TrimPrefix(key, rdnsPrefix+"/"), "/") - keyToDnsNameSplits(ds) + keyToDNSNameSplits(ds) dns := strings.Join(ds, ".") prefix := strings.Split(dns, ".")[0] @@ -533,9 +533,9 @@ func dnsNameToKey(domain string) string { return "/" + strings.Join(ss, "/") } -// keyToDnsNameSplits used to reverse etcdv3 path to domain splits. +// keyToDNSNameSplits used to reverse etcdv3 path to domain splits. // e.g. /cloud/rancher/lb/sample => [sample lb rancher cloud] -func keyToDnsNameSplits(ss []string) { +func keyToDNSNameSplits(ss []string) { for i := 0; i < len(ss)/2; i++ { j := len(ss) - i - 1 ss[i], ss[j] = ss[j], ss[i] From 7ec26546f30f48a697fbc6bbd8bcf17b48530589 Mon Sep 17 00:00:00 2001 From: Martin Linkhorst Date: Tue, 12 Nov 2019 13:24:52 +0100 Subject: [PATCH 48/79] ref(google): use non-deprecated initializer with context --- provider/google.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/provider/google.go b/provider/google.go index a0696b2955..9842c7ed8b 100644 --- a/provider/google.go +++ b/provider/google.go @@ -31,6 +31,7 @@ import ( "golang.org/x/oauth2/google" googleapi "google.golang.org/api/googleapi" + "google.golang.org/api/option" "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/kubernetes-sigs/external-dns/plan" @@ -129,7 +130,7 @@ func NewGoogleProvider(project string, domainFilter DomainFilter, zoneIDFilter Z }, }) - dnsClient, err := dns.New(gcloud) + dnsClient, err := dns.NewService(context.TODO(), option.WithHTTPClient(gcloud)) if err != nil { return nil, err } From b318f666ba8284382cb47eff51a1f27565be3812 Mon Sep 17 00:00:00 2001 From: Zhang Jinghui Date: Thu, 14 Nov 2019 23:55:18 +0800 Subject: [PATCH 49/79] normalize function return and comments on exported type --- internal/testutils/endpoint.go | 1 + provider/azure_test.go | 3 +-- provider/transip.go | 2 +- source/ingress.go | 4 ++-- source/ingressroute.go | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/testutils/endpoint.go b/internal/testutils/endpoint.go index f54fb9ced9..c9726f527e 100644 --- a/internal/testutils/endpoint.go +++ b/internal/testutils/endpoint.go @@ -76,6 +76,7 @@ func SameEndpoints(a, b []*endpoint.Endpoint) bool { return true } +// SameEndpointLabels verifies that labels of the two slices of endpoints are the same func SameEndpointLabels(a, b []*endpoint.Endpoint) bool { if len(a) != len(b) { return false diff --git a/provider/azure_test.go b/provider/azure_test.go index 2835dec801..c67aec4332 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -370,9 +370,8 @@ func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsC result := results[0] results = nil return result, nil - } else { - return dns.ZoneListResult{}, nil } + return dns.ZoneListResult{}, nil }) mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage) diff --git a/provider/transip.go b/provider/transip.go index 58192e79ab..8a09ea5a75 100644 --- a/provider/transip.go +++ b/provider/transip.go @@ -304,7 +304,7 @@ func (p *TransIPProvider) dnsEntriesAreEqual(a, b transip.DNSEntries) bool { continue } - match += 1 + match++ } } diff --git a/source/ingress.go b/source/ingress.go index c841ca26d3..c3551b8cbc 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -38,9 +38,9 @@ import ( ) const ( - // The annotation used for determining if an ALB ingress is dualstack + // ALBDualstackAnnotationKey is the annotation used for determining if an ALB ingress is dualstack ALBDualstackAnnotationKey = "alb.ingress.kubernetes.io/ip-address-type" - // The value of the ALB dualstack annotation that indicates it is dualstack + // ALBDualstackAnnotationValue is the value of the ALB dualstack annotation that indicates it is dualstack ALBDualstackAnnotationValue = "dualstack" ) diff --git a/source/ingressroute.go b/source/ingressroute.go index ad8df10c9c..4f492aa30a 100644 --- a/source/ingressroute.go +++ b/source/ingressroute.go @@ -53,7 +53,7 @@ type ingressRouteSource struct { ingressRouteInformer extinformers.IngressRouteInformer } -// NewIngressRouteSource creates a new ingressRouteSource with the given config. +// NewContourIngressRouteSource creates a new contourIngressRouteSource with the given config. func NewContourIngressRouteSource( kubeClient kubernetes.Interface, contourClient contour.Interface, From 8475895fd417d0c7469d34ee72f560f666e0a0ad Mon Sep 17 00:00:00 2001 From: Jakub Scholz Date: Thu, 14 Nov 2019 23:01:42 +0100 Subject: [PATCH 50/79] Use apps/v1 for the deployment to be compatible with Kubernetes 1.16 Signed-off-by: Jakub Scholz --- docs/tutorials/digitalocean.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/digitalocean.md b/docs/tutorials/digitalocean.md index 9a313427bd..db0fd1348d 100644 --- a/docs/tutorials/digitalocean.md +++ b/docs/tutorials/digitalocean.md @@ -25,11 +25,15 @@ Then apply one of the following manifests file to deploy ExternalDNS. ### Manifest (for clusters without RBAC enabled) ```yaml -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: + replicas: 1 + selector: + matchLabels: + app: external-dns strategy: type: Recreate template: @@ -87,11 +91,15 @@ subjects: name: external-dns namespace: default --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: + replicas: 1 + selector: + matchLabels: + app: external-dns strategy: type: Recreate template: @@ -118,11 +126,15 @@ spec: Create a service file called 'nginx.yaml' with the following contents: ```yaml -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: + replicas: 1 + selector: + matchLabels: + app: nginx template: metadata: labels: From fc35536fc7f847d46587a98b7124b5e6080e9d69 Mon Sep 17 00:00:00 2001 From: njuettner Date: Tue, 19 Nov 2019 11:29:31 +0100 Subject: [PATCH 51/79] Delete labeler --- .github/workflows/labeler.yml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .github/workflows/labeler.yml diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml deleted file mode 100644 index 28a0488bdf..0000000000 --- a/.github/workflows/labeler.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: "Pull Request Labeler" -on: -- pull_request - -jobs: - label: - runs-on: ubuntu-latest - - steps: - - uses: actions/labeler@v2 - if: contains(github.repository, 'kubernetes-sigs/external-dns') - with: - repo-token: '${{ secrets.GITHUB_TOKEN }}' From eb0cdb096228310f8bbf0a33be97e5d6e1eb0297 Mon Sep 17 00:00:00 2001 From: saidst Date: Thu, 10 Oct 2019 08:09:04 +0200 Subject: [PATCH 52/79] Created Azure Private DNS Provider by forking Azure Provider. --- README.md | 3 +- docs/tutorials/azure-private-dns.md | 372 +++++++++++++ go.mod | 5 +- go.sum | 810 ---------------------------- main.go | 4 +- pkg/apis/externaldns/types.go | 7 +- pkg/apis/externaldns/types_test.go | 5 + provider/azure_private_dns.go | 419 ++++++++++++++ 8 files changed, 809 insertions(+), 816 deletions(-) create mode 100644 docs/tutorials/azure-private-dns.md delete mode 100644 go.sum create mode 100644 provider/azure_private_dns.go diff --git a/README.md b/README.md index da755f2993..07e64f323e 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,8 @@ The following tutorials are provided: * [Route53](docs/tutorials/aws.md) * [Same domain for public and private Route53 zones](docs/tutorials/public-private-route53.md) * [Service Discovery](docs/tutorials/aws-sd.md) -* [Azure](docs/tutorials/azure.md) +* [Azure DNS](docs/tutorials/azure.md) +* [Azure Private DNS](docs/tutorials/azure-private-dns.md) * [Cloudflare](docs/tutorials/cloudflare.md) * [CoreDNS](docs/tutorials/coredns.md) * [DigitalOcean](docs/tutorials/digitalocean.md) diff --git a/docs/tutorials/azure-private-dns.md b/docs/tutorials/azure-private-dns.md new file mode 100644 index 0000000000..2ee216af07 --- /dev/null +++ b/docs/tutorials/azure-private-dns.md @@ -0,0 +1,372 @@ + +# Set up ExternalDNS for Azure Private DNS + +This tutorial describes how to setup ExternalDNS for managing records in Azure Private DNS. +It assumes to deploy ExternalDNS as a container Kubernetes. + +>Note: With Azure Private DNS we refer to the successor of the private-zone functionality in Azure DNS, which is +a separate, independent product. + + +It comprises of the following steps: +1) Provision Azure Private DNS +2) Configure service principal for managing the zone +3) Deploy ExternalDNS + +## Prerequisites +- Azure Kubernetes Service available +- nginx-ingress-controller incl. `--publish-service=namespace/nginx-ingress-controller-svcname` available +- [Azure CLI 2.0](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and `kubectl` installed on the box to execute the subsequent steps + + +## Provision Azure Private DNS + +The provider will find suitable zones for domains it manages. It will +not automatically create zones. + +For this tutorial, we will create a Azure resource group named 'externaldns' that can easily be deleted later. + +``` +$ az group create -n externaldns -l westeurope +``` + +Substitute a more suitable location for the resource group if desired. + +As a prerequisite for Azure Private DNS to resolve records is to define links with VNETs. +Thus, first create a VNET. + +``` +$ az network vnet create \ + --name myvnet \ + --resource-group externaldns \ + --location westeurope \ + --address-prefix 10.2.0.0/16 \ + --subnet-name mysubnet \ + --subnet-prefixes 10.2.0.0/24 +``` + +Next, create a Azure Private DNS zone for "example.com": + +``` +$ az network private-dns zone create -g externaldns -n example.com +``` + +Substitute a domain you own for "example.com" if desired. + +Finally, create the mentioned link with the VNET. + +``` +$ az network private-dns link vnet create -g externaldns -n mylink \ + -z example.com -v myvnet +``` + +## Configure service principal for managing the zone +ExternalDNS needs permissions to make changes in Azure Private DNS. +These permissions are roles assigned to the service principal used by ExternalDNS. + +A service principal with a minimum access level of `contributor` to the Private DNS zone(s) and `reader` to the resource group containing the Azure Private DNS zone(s) is necessary. +More powerful role-assignments like `owner` or assignments on subscription-level work too. + +Start off by **creating the service principal** without role-assignments. +``` +$ az ad sp create-for-rbac -n externaldns-sp +{ + "appId": "appId GUID", <-- aadClientId value + ... + "password": "password", <-- aadClientSecret value + "tenant": "AzureAD Tenant Id" <-- tenantId value +} +``` +> Note: Alternatively, you can issue `az account show --query "tenantId"` to retrieve the id of your AAD Tenant too. + + +Next, assign the roles to the service principal. +But first **retrieve the ID's** of the objects to assign roles on. + +``` +# find out the resource ids of the resource group where the dns zone is deployed, and the dns zone itself +$ az group show --name externaldns +{ + "id": "/subscriptions/id/resourceGroups/externaldns", + ... +} + +$ az network private-dns zone show --name example.com -g externaldns +{ + "id": "/subscriptions/.../resourceGroups/externaldns/providers/Microsoft.Network/privateDnsZones/example.com", + ... +} +``` +Now, **create role assignments**. +``` +# 1. as a reader to the resource group +$ az role assignment create --role "Reader" --assignee --scope + +# 2. as a contributor to DNS Zone itself +$ az role assignment create --role "Contributor" --assignee --scope +``` + +## Deploy ExternalDNS +Configure `kubectl` to be able to communicate and authenticate with your cluster. +This is per default done through the file `~/.kube/config`. + +For general background information on this see [kubernetes-docs](https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/). +Azure-CLI features functionality for automatically maintaining this file for AKS-Clusters. See [Azure-Docs](https://docs.microsoft.com/de-de/cli/azure/aks?view=azure-cli-latest#az-aks-get-credentials). + +Then apply one of the following manifests depending on whether you use RBAC or not. + +The credentials of the service principal are provided to ExternalDNS as environment-variables. +At the end of this section, we additionaly describe how to provide them as a _file_. + +### Manifest (for clusters without RBAC enabled) +```yaml +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: externaldns +spec: + strategy: + type: Recreate + template: + metadata: + labels: + app: externaldns + spec: + containers: + - name: externaldns + image: registry.opensource.zalan.do/teapot/external-dns:latest + args: + - --source=service + - --source=ingress + - --domain-filter=example.com + - --provider=azure-private-dns + - --azure-resource-group=externaldns + - --azure-subscription-id= + env: + - name: AZURE_TENANT_ID + value: "" + - name: AZURE_CLIENT_ID + value: "" + - name: AZURE_CLIENT_SECRET + value: "" +``` + +### Manifest (for clusters with RBAC enabled, cluster access) +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: externaldns +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: externaldns +rules: +- apiGroups: [""] + resources: ["services"] + verbs: ["get","watch","list"] +- apiGroups: [""] + resources: ["pods"] + verbs: ["get","watch","list"] +- apiGroups: ["extensions"] + resources: ["ingresses"] + verbs: ["get","watch","list"] +- apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: externaldns-viewer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: externaldns +subjects: +- kind: ServiceAccount + name: externaldns + namespace: default +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: externaldns +spec: + strategy: + type: Recreate + template: + metadata: + labels: + app: externaldns + spec: + serviceAccountName: externaldns + containers: + - name: externaldns + image: registry.opensource.zalan.do/teapot/external-dns:latest + args: + - --source=service + - --source=ingress + - --domain-filter=example.com + - --provider=azure-private-dns + - --azure-resource-group=externaldns + - --azure-subscription-id= + env: + - name: AZURE_TENANT_ID + value: "" + - name: AZURE_CLIENT_ID + value: "" + - name: AZURE_CLIENT_SECRET + value: "" +``` + +### Manifest (for clusters with RBAC enabled, namespace access) +This configuration is the same as above, except it only requires privileges for the current namespace, not for the whole cluster. +However, access to [nodes](https://kubernetes.io/docs/concepts/architecture/nodes/) requires cluster access, so when using this manifest, +services with type `NodePort` will be skipped! + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: externaldns +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: externaldns +rules: +- apiGroups: [""] + resources: ["services"] + verbs: ["get","watch","list"] +- apiGroups: [""] + resources: ["pods"] + verbs: ["get","watch","list"] +- apiGroups: ["extensions"] + resources: ["ingresses"] + verbs: ["get","watch","list"] +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: externaldns +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: externaldns +subjects: +- kind: ServiceAccount + name: externaldns +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: externaldns +spec: + strategy: + type: Recreate + template: + metadata: + labels: + app: externaldns + spec: + serviceAccountName: externaldns + containers: + - name: externaldns + image: registry.opensource.zalan.do/teapot/external-dns:latest + args: + - --source=service + - --source=ingress + - --domain-filter=example.com + - --provider=azure-private-dns + - --azure-resource-group=externaldns + - --azure-subscription-id= + env: + - name: AZURE_TENANT_ID + value: "" + - name: AZURE_CLIENT_ID + value: "" + - name: AZURE_CLIENT_SECRET + value: "" +``` + +Create the deployment for ExternalDNS: + +``` +$ kubectl create -f externaldns.yaml +``` + +## Deploying sample service + +Create a service file called 'nginx.yaml' with the following contents: + +```yaml +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: nginx +spec: + template: + metadata: + labels: + app: nginx + spec: + containers: + - image: nginx + name: nginx + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-svc +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: nginx + type: ClusterIP + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: nginx + annotations: + kubernetes.io/ingress.class: nginx +spec: + rules: + - host: server.example.com + http: + paths: + - backend: + serviceName: nginx-svc + servicePort: 80 + path: / +``` + +When using ExternalDNS with ingress objects it will automatically create DNS records based on host names specified in ingress objects that match the domain-filter argument in the externaldns deployment manifest. When those host names are removed or renamed the corresponding DNS records are also altered. + +Create the deployment, service and ingress object: + +``` +$ kubectl create -f nginx.yaml +``` + +Since your external IP would have already been assigned to the nginx-ingress service, the DNS records pointing to the IP of the nginx-ingress service should be created within a minute. + +## Verify created records + +Run the following command to view the A records for your Azure Private DNS zone: + +``` +$ az network private-dns record-set a list -g externaldns -z example.com +``` + +Substitute the zone for the one created above if a different domain was used. + +This should show the external IP address of the service as the A record for your domain ('@' indicates the record is for the zone itself). \ No newline at end of file diff --git a/go.mod b/go.mod index 17b09c4c98..7b858af448 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,8 @@ require ( cloud.google.com/go v0.44.3 github.com/Azure/azure-sdk-for-go v36.0.0+incompatible github.com/Azure/go-autorest/autorest v0.9.0 - github.com/Azure/go-autorest/autorest/adal v0.5.0 + github.com/Azure/go-autorest/autorest/adal v0.6.0 + github.com/Azure/go-autorest/autorest/azure/auth v0.0.0-00010101000000-000000000000 github.com/Azure/go-autorest/autorest/to v0.3.0 github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 // indirect github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 // indirect @@ -18,6 +19,7 @@ require ( github.com/cloudflare/cloudflare-go v0.10.1 github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 github.com/coreos/etcd v3.3.15+incompatible + github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect github.com/denverdino/aliyungo v0.0.0-20180815121905-69560d9530f5 github.com/digitalocean/godo v1.19.0 github.com/dnaeon/go-vcr v1.0.1 // indirect @@ -45,7 +47,6 @@ require ( github.com/smartystreets/gunit v1.0.2 // indirect github.com/stretchr/testify v1.4.0 github.com/transip/gotransip v5.8.2+incompatible - github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 // indirect github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 diff --git a/go.sum b/go.sum deleted file mode 100644 index bf469b05b6..0000000000 --- a/go.sum +++ /dev/null @@ -1,810 +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.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= -cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.3 h1:0sMegbmn/8uTwpNkB0q9cLEpZ2W5a6kl+wtBQgPWBJQ= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/logging v1.0.0/go.mod h1:V1cc3ogwobYzQq5f2R7DS/GvRIrI4FKj01Gs5glwAls= -code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f h1:UrKzEwTgeiff9vxdrfdqxibzpWjxLnuXDI5m6z3GJAk= -code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= -contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= -contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= -contrib.go.opencensus.io/exporter/stackdriver v0.6.0/go.mod h1:QeFzMJDAw8TXt5+aRaSuE8l5BwaMIOIlaVkBOPRuMuw= -contrib.go.opencensus.io/exporter/zipkin v0.1.1/go.mod h1:GMvdSl3eJ2gapOaLKzTKE3qDgUkJ86k9k3yY2eqwkzc= -fortio.org/fortio v1.3.0/go.mod h1:Go0fRqoPJ1xy5JOWcS23jyF58byVZxFyEePYsGmCR0k= -github.com/Azure/azure-sdk-for-go v36.0.0+incompatible h1:XIaBmA4pgKqQ7jInQPaNJQ4pOHrdJjw9gYXhbyiChaU= -github.com/Azure/azure-sdk-for-go v36.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest v13.0.1+incompatible h1:wRg6hB3T3dp7qjj5v3NmVsdU9IyXodW+SQnN9xlpGEA= -github.com/Azure/go-autorest v13.0.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.9.1 h1:JB7Mqhna/7J8gZfVHjxDSTLSD6ciz2YgSMb/4qLXTtY= -github.com/Azure/go-autorest/autorest v0.9.1/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.6.0 h1:UCTq22yE3RPgbU/8u4scfnnzuCW6pwQ9n+uBtV78ouo= -github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= -github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= -github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= -github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= -github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/sprig v0.0.0-20190301161902-9f8fceff796f/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Masterminds/sprig v2.14.1+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/SAP/go-hdb v0.14.1/go.mod h1:7fdQLVC2lER3urZLjZCm0AuMQfApof92n3aylBPEkMo= -github.com/SermoDigital/jose v0.9.1/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= -github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= -github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= -github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= -github.com/alecthomas/kingpin v2.2.5+incompatible h1:umWl1NNd72+ZvRti3T9C0SYean2hPZ7ZhxU8bsgc9BQ= -github.com/alecthomas/kingpin v2.2.5+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= -github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAKQQZGOJ4knlw+7rfEQQcmwTbt4p5E= -github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis v0.0.0-20180201100744-9d52b1fc8da9/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f h1:hinXH9rcBjRoIih5tl4f1BCbNjOmPJ2UnZwcYDhEHR0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= -github.com/antlr/antlr4 v0.0.0-20190223165740-dade65a895c2/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y= -github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30/go.mod h1:4AJxUpXUhv4N+ziTvIcWWXgeorXpxPZOfk9HdEVr96M= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-sdk-go v1.13.24/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k= -github.com/aws/aws-sdk-go v1.23.18 h1:ADU/y1EO8yPzUJJYjcvJ0V9/suezxPh0u6hb5bSYIGQ= -github.com/aws/aws-sdk-go v1.23.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -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/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/cactus/go-statsd-client v3.1.1+incompatible/go.mod h1:cMRcwZDklk7hXp+Law83urTHUiHMzCev/r4JMYr/zU0= -github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= -github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.10.1 h1:d2CL6F9k2O0Ux0w27LgogJ5UOzZRj6a/hDPFqPP68d8= -github.com/cloudflare/cloudflare-go v0.10.1/go.mod h1:C0Y6eWnTJPMK2ceuOxx2pjh78UUHihcXeTTHb8r7QjU= -github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 h1:rdRS5BT13Iae9ssvcslol66gfOOXjaLYwqerEn/cl9s= -github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381/go.mod h1:e5+USP2j8Le2M0Jo3qKPFnNhuo1wueU4nWHCXBOfQ14= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY= -github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.15+incompatible h1:+9RjdC18gMxNQVvSiXvObLu29mOFmkgdsB4cRTlV+EE= -github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v0.0.0-20180117170138-065b426bd416/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142 h1:3jFq2xL4ZajGK4aZY8jz+DAF0FHjI51BXjjSwCzS1Dk= -github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/prometheus-operator v0.29.0/go.mod h1:SO+r5yZUacDFPKHfPoUjI3hMsH+ZUdiuNNhuSq3WoSg= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= -github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= -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/dchest/siphash v1.1.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= -github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= -github.com/denverdino/aliyungo v0.0.0-20180815121905-69560d9530f5 h1:YjnQWGUNtqeKqndapy9V1BzlfMwc/dBJf2MU9dmuXSQ= -github.com/denverdino/aliyungo v0.0.0-20180815121905-69560d9530f5/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/digitalocean/godo v1.19.0 h1:9ApuchfzGD/XI8Zm0RRnZnytdfYHPjPTRKTnmzQNV7o= -github.com/digitalocean/godo v1.19.0/go.mod h1:AAPQ+tiM4st79QHlEBTg8LM7JQNre4SAQCbn56wEyKY= -github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= -github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/dnsimple/dnsimple-go v0.14.0 h1:JGYtVVA/uHc91q0LjDWqR1oVj6EGu9Kn0lMRxjH/w30= -github.com/dnsimple/dnsimple-go v0.14.0/go.mod h1:0FYu4qVNv/UcfZPNwa9zi68IkggJu3TIwM54D7rhmI4= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.0.0-20180612054059-a9fbbdc8dd87/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/dropbox/godropbox v0.0.0-20190501155911-5749d3b71cbe/go.mod h1:glr97hP/JuXb+WMYCizc4PIFuzw1lCR97mwbe1VVXhQ= -github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= -github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= -github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= -github.com/elazarl/goproxy v0.0.0-20190630181448-f1e96bc0f4c5/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/elazarl/goproxy/ext v0.0.0-20190630181448-f1e96bc0f4c5/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= -github.com/emicklei/go-restful v2.9.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/envoyproxy/go-control-plane v0.8.2/go.mod h1:EWRTAFN6uuDZIa6KOuUfrOMJ7ySgXZ44rVKiTWjKe34= -github.com/envoyproxy/go-control-plane v0.8.7-0.20190821215049-f062b07a671a h1:SaBXBWjRmig9yVB49C6TcbDtbZTbhuFLod7YiGjuFxQ= -github.com/envoyproxy/go-control-plane v0.8.7-0.20190821215049-f062b07a671a/go.mod h1:XB9+ce7x+IrsjgIVnRnql0O61gj/np0/bGDfhJI3sCU= -github.com/envoyproxy/protoc-gen-validate v0.0.0-20190405222122-d6164de49109/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.0.14 h1:YBW6/cKy9prEGRYLnaGa4IDhzxZhRCtKsax8srGKDnM= -github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= -github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/exoscale/egoscale v0.18.1 h1:1FNZVk8jHUx0AvWhOZxLEDNlacTU0chMXUUNkm9EZaI= -github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= -github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/stackerr v0.0.0-20150612192056-c2fcf88613f4/go.mod h1:SBHk9aNQtiw4R4bEuzHjVmZikkUKCnO1v3lPQ21HZGk= -github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 h1:jmwW6QWvUO2OPe22YfgFvBaaZlSr8Rlrac5lZvG6IdM= -github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99/go.mod h1:4mP9w9+vYGw2jUx2+2v03IA+phyQQjNRR4AL3uxlNrs= -github.com/fluent/fluent-logger-golang v1.3.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= -github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-ini/ini v1.33.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.19.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-redis/redis v6.10.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-resty/resty v1.8.0 h1:vbNCxbHOWCototzwxf3L63PQCKx6xgT6v8SHfoqkp6U= -github.com/go-resty/resty v1.8.0/go.mod h1:n37daLLGIHq2FFYHxg+FYQiwA95FpfNI+A9uxoIYGRk= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= -github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gocql/gocql v0.0.0-20190423091413-b99afaf3b163/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= -github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48 h1:X+zN6RZXsvnrSJaAIQhZezPfAfvsqihKKR8oiLHid34= -github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/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.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= -github.com/golang/protobuf v1.3.1/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/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f h1:kSqKc8ouCLIBHqdj9a9xxhtxlZhNqbePClixA4HoM44= -github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:YCHYtYb9c8Q7XgYVYjmJBPtFPKx5QvOcPxHZWjldabE= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/cel-go v0.2.0/go.mod h1:fTCVOuSN/Vn6d49zvRpr3fDAKFyfpLViE0gU+9Vtm7g= -github.com/google/cel-spec v0.2.0/go.mod h1:MjQm800JAGhOZXI7vatnVpmIaFTR6L8FHcKk+piiKpI= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-github v15.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -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.0.0-20190424031112-b9b92a825806 h1:Jua/oVkYNsCSNamvehem7aSkVr3FK6e8AlqTvAm0fwA= -github.com/gophercloud/gophercloud v0.0.0-20190424031112-b9b92a825806/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= -github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= -github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20171214222146-0e7658f8ee99/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/consul v1.3.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= -github.com/hashicorp/go-hclog v0.9.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-memdb v1.0.1/go.mod h1:I6dKdmYhZqU0RJSheVEWgTNWdVQH5QvTgIUQ0t/t32M= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-plugin v1.0.0/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= -github.com/hashicorp/vault v0.10.0/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/heptio/contour v0.15.0 h1:JhyJMauwoYtqTzd23jStx7Bx7S3sHbqTWZs6+Ed+UPE= -github.com/heptio/contour v0.15.0/go.mod h1:y4LmuX+86v8mlRd1HVrb2u4t77jMjOQ3DnjfRCiwrfA= -github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= -github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= -github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= -github.com/imdario/mergo v0.3.7/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/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65 h1:FP5rOFP4ifbtFIjFHJmwhFrsbDyONILK/FNntl/Pou8= -github.com/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI= -github.com/jefferai/jsonx v1.0.0/go.mod h1:OGmqmi2tTeI/PS+qQfBDToLHHJIy/RMp24fPo8vFvoQ= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jteeuwen/go-bindata v0.0.0-20180305030458-6025e8de665b/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20190207033735-e65537c515d7/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20190212223446-d976af380377/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/keybase/go-crypto v0.0.0-20190416182011-b785b22cc757/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -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/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -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/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d h1:JV46OtdhH2vVt8mJ1EWUE94k99vbN9fZs1WQ8kcEapU= -github.com/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d/go.mod h1:CHQ3o5KBH1PIS2Fb1mRLTIWO5YzP9kSUB3KoCICwlvA= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/linki/instrumented_http v0.2.0 h1:zLhcB3Q/McQQqml3qd5kzdZ0cGnL3vquPFIW2338f5Y= -github.com/linki/instrumented_http v0.2.0/go.mod h1:pjYbItoegfuVi2GUOMhEqzvm/SJKuEL3H0tc8QRLRFk= -github.com/linode/linodego v0.3.0 h1:I83pEPg4owSy5pCPaKix7xkGbWIjPxmAoc/Yu5OYDDY= -github.com/linode/linodego v0.3.0/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= -github.com/lyft/protoc-gen-star v0.4.10/go.mod h1:mE8fbna26u7aEA2QCVvvfBU/ZrPgocG1206xAFPcs94= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 h1:YFh+sjyJTMQSYjKwM4dFKhJPJC/wfo98tPUc17HdoYw= -github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= -github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -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/mdempsky/unconvert v0.0.0-20190325185700-2f5dc3378ed3/go.mod h1:9+3Wp2ccIz73BJqVfc7n2+1A+mzvnEwtDTqEjeRngBQ= -github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= -github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-homedir v0.0.0-20161203194507-b8bc1bf76747/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= -github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -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 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= -github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= -github.com/nesv/go-dynect v0.6.0 h1:Ow/DiSm4LAISwnFku/FITSQHnU6pBvhQMsUE5Gu6Oq4= -github.com/nesv/go-dynect v0.6.0/go.mod h1:GHRBRKzTwjAMhosHJQq/KrZaFkXIFyJ5zRE7thGXXrs= -github.com/nic-at/rc0go v1.1.0 h1:k6/Bru/npTjmCSFw65ulYRw/b3ycIS30t6/YM4r42V4= -github.com/nic-at/rc0go v1.1.0/go.mod h1:KEa3H5fmDNXCaXSqOeAZxkKnG/8ggr1OHIG25Ve7fjU= -github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/open-policy-agent/opa v0.8.2/go.mod h1:rlfeSeHuZmMEpmrcGla42AjkOUjP4rGIpS96H12un3o= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/openshift/api v0.0.0-20190322043348-8741ff068a47/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/operator-framework/operator-sdk v0.7.0/go.mod h1:iVyukRkam5JZa8AnjYf+/G3rk7JI1+M6GsU0sq0B9NA= -github.com/oracle/oci-go-sdk v1.8.0 h1:4SO45bKV0I3/Mn1os3ANDZmV0eSE5z5CLdSUIkxtyzs= -github.com/oracle/oci-go-sdk v1.8.0/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= -github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= -github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2 h1:CXwSGu/LYmbjEab5aMCs5usQRVBGThelUKBNnoSOuso= -github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.2.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872 h1:0aNv3xC7DmQoy1/x1sMh18g+fihWW68LL13i8ao9kl4= -github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0 h1:c8R11WC8m7KNMkTv/0+Be8vvwo4I3/Ut9AC2FW8fX3U= -github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/prom2json v1.1.0/go.mod h1:v7OY1795b9fEUZgq4UU2+15YjRv0LfpxKejIQCy3L7o= -github.com/prometheus/prom2json v1.2.1/go.mod h1:yIcXOj/TLPdtZ12qRyhswPnu+02sfDoqatDjj0WGSvo= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/ryanuber/go-glob v0.0.0-20160226084822-572520ed46db/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0 h1:vOcHdR1nu7DO4BAx1rwzdHV7jQTzW3gqcBT5qxHSc6A= -github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0/go.mod h1:FeplEtXXejBYC4NPAFTrs5L7KuK+5RL9bf5nB2vZe9o= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sethgrid/pester v0.0.0-20180227223404-ed9870dad317/go.mod h1:Ad7IjTpvzZO8Fl0vh9AzQ+j/jYZfyp2diGwI8m5q+ns= -github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/signalfx/com_signalfx_metrics_protobuf v0.0.0-20170330202426-93e507b42f43/go.mod h1:muYA2clvwCdj7nzAJ5vJIXYpJsUumhAl4Uu1wUNpWzA= -github.com/signalfx/gohistogram v0.0.0-20160107210732-1ccfd2ff5083/go.mod h1:adPDS6s7WaajdFBV9mQ7i0dKfQ8xiDnF9ZNETVPpp7c= -github.com/signalfx/golib v1.1.6/go.mod h1:nWYefOwlUKWm/SpN/LgVSBnyH1T9NpT1ANlmgRIi1Cs= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/smartystreets/assertions v0.0.0-20180725160413-e900ae048470/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 h1:hp2CYQUINdZMHdvTdXtPOY2ainKl4IoMcpAXEf2xj3Q= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= -github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/gunit v1.0.2 h1:nCXf7TXGchqk8zNVQFTtbeW6rGSrlp9ir9h8wmx0xws= -github.com/smartystreets/gunit v1.0.2/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ= -github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= -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/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= -github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/transip/gotransip v5.8.2+incompatible h1:aNJhw/w/3QBqFcHAIPz1ytoK5FexeMzbUCGrrhWr3H0= -github.com/transip/gotransip v5.8.2+incompatible/go.mod h1:uacMoJVmrfOcscM4Bi5NVg708b7c6rz2oDTWqa7i2Ic= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber/jaeger-client-go v0.0.0-20190228190846-ecf2d03a9e80/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs= -github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 h1:vG/gY/PxA3v3l04qxe3tDjXyu3bozii8ulSlIPOYKhI= -github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA= -github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= -github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= -github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 h1:Q76MzqJu++vAfhj0mVf7t0F4xHUbg+V/d/Uk5PBQjRU= -github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92/go.mod h1:AZuEfReFWdvtU0LatbLpo70t3lqdLvph2D5mqFP0bkA= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yashtewari/glob-intersection v0.0.0-20180206001645-7af743e8ec84/go.mod h1:HptNXiXVDcJjXe9SqMd0v2FsL9f8dz4GnXgltU6q/co= -github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268 h1:lkoOjizoHqOcEFsvYGE5c8Ykdijjnd0R3r1yDYHzLno= -github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268/go.mod h1:mq0zhomp/G6rRTb0dvHWXRHr/2+Qgeq5hMXfJ670+i4= -github.com/yuin/gopher-lua v0.0.0-20180316054350-84ea3a3c79b3/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= -go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.20.1 h1:pMEjRZ1M4ebWGikflH7nQpV6+Zr88KBMA2XJD3sbijw= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/net v0.0.0-20180611182652-db08ff08e862/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-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/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-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-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-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c h1:hDn6jm7snBX2O7+EeTk6Q4WXJfKt7MWgtiCCRi1rBoY= -golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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/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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190325161752-5a8dccf5b48a/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -golang.org/x/tools v0.0.0-20190822000311-fc82fb2afd64/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190227213309-4f5b463f9597/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -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/d4l3k/messagediff.v1 v1.2.1 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0= -gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -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/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/logfmt.v0 v0.3.0/go.mod h1:mRLMcMLrml5h2Ux/H+4zccFOlVCiRvOvndsolsJoU8Q= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1 h1:+fgY/3ngqdBW9oLQCMwL5g+QRkKFPJH05fx2/pipqRQ= -gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1/go.mod h1:VV+3haRsgDiVLxyifmMBrBIuCWFBPYKbRssXB9z67Hw= -gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= -gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/stack.v1 v1.7.0/go.mod h1:QtWz4C5wbvhA63ngux3942W/ppRxtyYjHvvhz02s7+M= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -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= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -istio.io/api v0.0.0-20190820204432-483f2547d882 h1:L0WC/5HTk8T5eGTg/ka9jGZgw7GMuWj9rm6DFF4owL8= -istio.io/api v0.0.0-20190820204432-483f2547d882/go.mod h1:42cBjnu/rTJcCaKi8nLdIvq0n71RcLrkgZ9IQSvDdSQ= -istio.io/gogo-genproto v0.0.0-20190614210408-e88dc8b0e4db/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI= -istio.io/gogo-genproto v0.0.0-20190731221249-06e20ada0df2/go.mod h1:IjvrbUlRbbw4JCpsgvgihcz9USUwEoNTL/uwMtyV5yk= -istio.io/gogo-genproto v0.0.0-20190819131816-7a8328e41c1a h1:QN+P7SPcjI4az1Lb40MdhJg/OkV03u5XS1DVIk8PS6E= -istio.io/gogo-genproto v0.0.0-20190819131816-7a8328e41c1a/go.mod h1:IjvrbUlRbbw4JCpsgvgihcz9USUwEoNTL/uwMtyV5yk= -istio.io/istio v0.0.0-20190911205955-c2bd59595ce6 h1:SICsYFkNnMRHPPxHYUGMqZp1lQXW8+nJKBSIZVIk16M= -istio.io/istio v0.0.0-20190911205955-c2bd59595ce6/go.mod h1:dn7qqBbC/pAcJnqNvB2jv7llDBbExQVbnPIVuPPScx8= -istio.io/operator v0.0.0-20190830172131-647a5416137b/go.mod h1:NW/+IXU4IeeVtWLS8S57Vq67H/GOy92Temo4eI5efLs= -istio.io/pkg v0.0.0-20190515193414-9332430ad747/go.mod h1:0EkPwmR0tESYjN4Ilq1D52nTBurXaQvny3r2VY4j4tw= -istio.io/pkg v0.0.0-20190731230704-fcbac27d69d5 h1:HcASpvj/fuuABkYH9YbsTGEOT75YHyWvvFnTe229zXs= -istio.io/pkg v0.0.0-20190731230704-fcbac27d69d5/go.mod h1:We4ZQuCbiiNfXge2GfOshBsyDXVwzFwP8703V5DcM14= -k8s.io/api v0.0.0-20190817221950-ebce17126a01 h1:AMUY6ojynTCBURCALg9KVOsrCmWjHF7h7UbuBod7FYc= -k8s.io/api v0.0.0-20190817221950-ebce17126a01/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= -k8s.io/apiextensions-apiserver v0.0.0-20190919022157-e8460a76b3ad h1:I3kcGO+4TazAR49NWgNiEGND6b4q5HVc7Q0K1IQxV9Q= -k8s.io/apiextensions-apiserver v0.0.0-20190919022157-e8460a76b3ad/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= -k8s.io/apimachinery v0.0.0-20190817221809-bf4de9df677c h1:TlFvXut3q9hNMA2UdjrC6LLfANYrh4lnDzb0gDNSMSg= -k8s.io/apimachinery v0.0.0-20190817221809-bf4de9df677c/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= -k8s.io/apiserver v0.0.0-20181213151703-3ccfe8365421/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w= -k8s.io/cli-runtime v0.0.0-20190817224438-0337ccdab819/go.mod h1:qWnH3/b8sp/l7EvlDh7ulDU3UWA4P4N1NFbEEP791tM= -k8s.io/client-go v0.0.0-20190817222206-ee6c071a42cf h1:ZCiWjWPoxHYlMo7N4ZPz7yqo2YuCPvBi3nNX11oBTMg= -k8s.io/client-go v0.0.0-20190817222206-ee6c071a42cf/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= -k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= -k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/helm v2.13.1+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68= -k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20190401085232-94e1e7b7574c h1:kJCzg2vGCzah5icgkKR7O1Dzn0NA2iGlym27sb0ZfGE= -k8s.io/kube-openapi v0.0.0-20190401085232-94e1e7b7574c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kubernetes v1.13.1/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= -k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -sigs.k8s.io/controller-runtime v0.1.10/go.mod h1:HFAYoOh6XMV+jKF1UjFwrknPbowfyHEHHRdJMf2jMX8= -sigs.k8s.io/testing_frameworks v0.1.1/go.mod h1:VVBKrHmJ6Ekkfz284YKhQePcdycOzNH9qL6ht1zEr/U= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/main.go b/main.go index 70fe855b25..658d8e2599 100644 --- a/main.go +++ b/main.go @@ -133,8 +133,10 @@ func main() { cfg.Registry = "aws-sd" } p, err = provider.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.AWSAssumeRole, cfg.DryRun) - case "azure": + case "azure-dns", "azure": p, err = provider.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.DryRun) + case "azure-private-dns": + p, err = provider.NewAzurePrivateDNSProvider(domainFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.AzureSubscriptionID, cfg.DryRun) case "vinyldns": p, err = provider.NewVinylDNSProvider(domainFilter, zoneIDFilter, cfg.DryRun) case "cloudflare": diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index e89bb40b3a..e6ea64c4c5 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -71,6 +71,7 @@ type Config struct { AWSPreferCNAME bool AzureConfigFile string AzureResourceGroup string + AzureSubscriptionID string CloudflareProxied bool CloudflareZonesPerPage int CoreDNSPrefix string @@ -162,6 +163,7 @@ var defaultConfig = &Config{ AWSPreferCNAME: false, AzureConfigFile: "/etc/kubernetes/azure.json", AzureResourceGroup: "", + AzureSubscriptionID: "", CloudflareProxied: false, CloudflareZonesPerPage: 50, CoreDNSPrefix: "/skydns/", @@ -289,7 +291,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("service-type-filter", "The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName)").StringsVar(&cfg.ServiceTypeFilter) // Flags related to providers - app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, aws-sd, google, azure, cloudflare, rcodezero, digitalocean, dnsimple, infoblox, dyn, designate, coredns, skydns, inmemory, pdns, oci, exoscale, linode, rfc2136, ns1, transip, vinyldns, rdns)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "aws-sd", "google", "azure", "alibabacloud", "cloudflare", "rcodezero", "digitalocean", "dnsimple", "infoblox", "dyn", "designate", "coredns", "skydns", "inmemory", "pdns", "oci", "exoscale", "linode", "rfc2136", "ns1", "transip", "vinyldns", "rdns") + app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, aws-sd, google, azure, azure-dns, azure-private-dns, cloudflare, rcodezero, digitalocean, dnsimple, infoblox, dyn, designate, coredns, skydns, inmemory, pdns, oci, exoscale, linode, rfc2136, ns1, transip, vinyldns, rdns)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "aws-sd", "google", "azure", "azure-dns", "azure-private-dns", "alibabacloud", "cloudflare", "rcodezero", "digitalocean", "dnsimple", "infoblox", "dyn", "designate", "coredns", "skydns", "inmemory", "pdns", "oci", "exoscale", "linode", "rfc2136", "ns1", "transip", "vinyldns", "rdns") app.Flag("domain-filter", "Limit possible target zones by a domain suffix; specify multiple times for multiple domains (optional)").Default("").StringsVar(&cfg.DomainFilter) app.Flag("exclude-domains", "Exclude subdomains (optional)").Default("").StringsVar(&cfg.ExcludeDomains) app.Flag("zone-id-filter", "Filter target zones by hosted zone id; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.ZoneIDFilter) @@ -307,7 +309,8 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("aws-api-retries", "When using the AWS provider, set the maximum number of retries for API calls before giving up.").Default(strconv.Itoa(defaultConfig.AWSAPIRetries)).IntVar(&cfg.AWSAPIRetries) app.Flag("aws-prefer-cname", "When using the AWS provider, prefer using CNAME instead of ALIAS (default: disabled)").BoolVar(&cfg.AWSPreferCNAME) app.Flag("azure-config-file", "When using the Azure provider, specify the Azure configuration file (required when --provider=azure").Default(defaultConfig.AzureConfigFile).StringVar(&cfg.AzureConfigFile) - app.Flag("azure-resource-group", "When using the Azure provider, override the Azure resource group to use (optional)").Default(defaultConfig.AzureResourceGroup).StringVar(&cfg.AzureResourceGroup) + app.Flag("azure-resource-group", "When using the Azure provider, override the Azure resource group to use (required when --provider=azure-private-dns)").Default(defaultConfig.AzureResourceGroup).StringVar(&cfg.AzureResourceGroup) + app.Flag("azure-subscription-id", "When using the Azure provider, specify the Azure configuration file (required when --provider=azure-private-dns)").Default(defaultConfig.AzureSubscriptionID).StringVar(&cfg.AzureSubscriptionID) app.Flag("cloudflare-proxied", "When using the Cloudflare provider, specify if the proxy mode must be enabled (default: disabled)").BoolVar(&cfg.CloudflareProxied) app.Flag("cloudflare-zones-per-page", "When using the Cloudflare provider, specify how many zones per page listed, max. possible 50 (default: 50)").Default(strconv.Itoa(defaultConfig.CloudflareZonesPerPage)).IntVar(&cfg.CloudflareZonesPerPage) app.Flag("coredns-prefix", "When using the CoreDNS provider, specify the prefix name").Default(defaultConfig.CoreDNSPrefix).StringVar(&cfg.CoreDNSPrefix) diff --git a/pkg/apis/externaldns/types_test.go b/pkg/apis/externaldns/types_test.go index 3134b51941..80c68af235 100644 --- a/pkg/apis/externaldns/types_test.go +++ b/pkg/apis/externaldns/types_test.go @@ -56,6 +56,7 @@ var ( AWSPreferCNAME: false, AzureConfigFile: "/etc/kubernetes/azure.json", AzureResourceGroup: "", + AzureSubscriptionID: "", CloudflareProxied: false, CloudflareZonesPerPage: 50, CoreDNSPrefix: "/skydns/", @@ -122,6 +123,7 @@ var ( AWSPreferCNAME: true, AzureConfigFile: "azure.json", AzureResourceGroup: "arg", + AzureSubscriptionID: "arg", CloudflareProxied: true, CloudflareZonesPerPage: 20, CoreDNSPrefix: "/coredns/", @@ -194,6 +196,7 @@ var ( AWSPreferCNAME: false, AzureConfigFile: "/etc/kubernetes/azure.json", AzureResourceGroup: "", + AzureSubscriptionID: "", CloudflareProxied: false, CloudflareZonesPerPage: 50, CoreDNSPrefix: "/skydns/", @@ -266,6 +269,7 @@ func TestParseFlags(t *testing.T) { "--google-batch-change-interval=2s", "--azure-config-file=azure.json", "--azure-resource-group=arg", + "--azure-subscription-id=arg", "--cloudflare-proxied", "--cloudflare-zones-per-page=20", "--coredns-prefix=/coredns/", @@ -346,6 +350,7 @@ func TestParseFlags(t *testing.T) { "EXTERNAL_DNS_GOOGLE_BATCH_CHANGE_INTERVAL": "2s", "EXTERNAL_DNS_AZURE_CONFIG_FILE": "azure.json", "EXTERNAL_DNS_AZURE_RESOURCE_GROUP": "arg", + "EXTERNAL_DNS_AZURE_SUBSCRIPTION_ID": "arg", "EXTERNAL_DNS_CLOUDFLARE_PROXIED": "1", "EXTERNAL_DNS_CLOUDFLARE_ZONES_PER_PAGE": "20", "EXTERNAL_DNS_COREDNS_PREFIX": "/coredns/", diff --git a/provider/azure_private_dns.go b/provider/azure_private_dns.go new file mode 100644 index 0000000000..354deac3b9 --- /dev/null +++ b/provider/azure_private_dns.go @@ -0,0 +1,419 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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. +*/ + +package provider + +import ( + "context" + "fmt" + "strings" + + log "github.com/sirupsen/logrus" + + "github.com/Azure/azure-sdk-for-go/profiles/latest/privatedns/mgmt/privatedns" + "github.com/Azure/go-autorest/autorest/azure/auth" + "github.com/Azure/go-autorest/autorest/to" + + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" +) + +type azurePrivateDNSConfig struct { + SubscriptionID string `json:"subscriptionId" yaml:"subscriptionId"` + ResourceGroup string `json:"resourceGroup" yaml:"resourceGroup"` +} + +// AzureProvider implements the DNS provider for Microsoft's Azure cloud platform. +type AzurePrivateDNSProvider struct { + domainFilter DomainFilter + zoneIDFilter ZoneIDFilter + dryRun bool + subscriptionID string + resourceGroup string + zonesClient privatedns.PrivateZonesClient + recordSetsClient privatedns.RecordSetsClient +} + +// NewAzureProvider creates a new Azure provider. +// +// Returns the provider or an error if a provider could not be created. +func NewAzurePrivateDNSProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, resourceGroup string, subscriptionID string, dryRun bool) (*AzurePrivateDNSProvider, error) { + authorizer, err := auth.NewAuthorizerFromEnvironment() + if err != nil { + return nil, err + } + + zonesClient := privatedns.NewPrivateZonesClient(subscriptionID) + zonesClient.Authorizer = authorizer + recordSetsClient := privatedns.NewRecordSetsClient(subscriptionID) + recordSetsClient.Authorizer = authorizer + + provider := &AzurePrivateDNSProvider{ + domainFilter: domainFilter, + zoneIDFilter: zoneIDFilter, + dryRun: dryRun, + subscriptionID: subscriptionID, + resourceGroup: resourceGroup, + zonesClient: zonesClient, + recordSetsClient: recordSetsClient, + } + return provider, nil +} + +// Records gets the current records. +// +// Returns the current records or an error if the operation failed. +func (p *AzurePrivateDNSProvider) Records() (endpoints []*endpoint.Endpoint, _ error) { + ctx := context.Background() + zones, err := p.zones(ctx) + if err != nil { + return nil, err + } + + log.Debugf("Retrieving Azure Private DNS Records for resource group '%s'", p.resourceGroup) + + for _, zone := range zones { + err := p.iterateRecords(ctx, *zone.Name, func(recordSet privatedns.RecordSet) { + var recordType string + if recordSet.Type == nil { + log.Debugf("Skipping invalid record set with missing type.") + return + } else { + recordType = strings.TrimLeft(*recordSet.Type, "Microsoft.Network/privateDnsZones") + } + + var name string + if recordSet.Name == nil { + log.Debugf("Skipping invalid record set with missing name.") + return + } else { + name = formatAzureDNSName(*recordSet.Name, *zone.Name) + } + + targets := extractAzurePrivateDNSTargets(&recordSet) + if len(targets) == 0 { + log.Debugf("Failed to extract targets for '%s' with type '%s'.", name, recordType) + return + } + + var ttl endpoint.TTL + if recordSet.TTL != nil { + ttl = endpoint.TTL(*recordSet.TTL) + } + + ep := endpoint.NewEndpointWithTTL(name, recordType, endpoint.TTL(ttl), targets...) + log.Debugf( + "Found %s record for '%s' with target '%s'.", + ep.RecordType, + ep.DNSName, + ep.Targets, + ) + endpoints = append(endpoints, ep) + }) + if err != nil { + return nil, err + } + } + + log.Debugf("Returning %d Azure Private DNS Records for resource group '%s'", len(endpoints), p.resourceGroup) + + return endpoints, nil +} + +// ApplyChanges applies the given changes. +// +// Returns nil if the operation was successful or an error if the operation failed. +func (p *AzurePrivateDNSProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { + log.Debugf("Received %d changes to process", len(changes.Create)+len(changes.Delete)+len(changes.UpdateNew)+len(changes.UpdateOld)) + + zones, err := p.zones(ctx) + if err != nil { + return err + } + + deleted, updated := p.mapChanges(zones, changes) + p.deleteRecords(ctx, deleted) + p.updateRecords(ctx, updated) + return nil +} + +func (p *AzurePrivateDNSProvider) zones(ctx context.Context) ([]privatedns.PrivateZone, error) { + log.Debugf("Retrieving Azure DNS zones for Resource Group '%s'", p.resourceGroup) + + var zones []privatedns.PrivateZone + + i, err := p.zonesClient.ListByResourceGroupComplete(ctx, p.resourceGroup, nil) + if err != nil { + return nil, err + } + + for i.NotDone() { + zone := i.Value() + log.Debugf("Validating Zone: %v", *zone.Name) + + if zone.Name == nil { + continue + } + + if !p.domainFilter.Match(*zone.Name) { + continue + } + + if !p.zoneIDFilter.Match(*zone.ID) { + continue + } + + zones = append(zones, zone) + + err := i.NextWithContext(ctx) + if err != nil { + return nil, err + } + } + + log.Debugf("Found %d Azure DNS zone(s).", len(zones)) + return zones, nil +} + +func (p *AzurePrivateDNSProvider) iterateRecords(ctx context.Context, zoneName string, callback func(privatedns.RecordSet)) error { + log.Debugf("Retrieving Azure Private DNS Records for zone '%s'.", zoneName) + + i, err := p.recordSetsClient.ListComplete(ctx, p.resourceGroup, zoneName, nil, "") + if err != nil { + return err + } + + for i.NotDone() { + callback(i.Value()) + + err := i.NextWithContext(ctx) + if err != nil { + return err + } + } + + return nil +} + +type azurePrivateDNSChangeMap map[string][]*endpoint.Endpoint + +func (p *AzurePrivateDNSProvider) mapChanges(zones []privatedns.PrivateZone, changes *plan.Changes) (azurePrivateDNSChangeMap, azurePrivateDNSChangeMap) { + ignored := map[string]bool{} + deleted := azurePrivateDNSChangeMap{} + updated := azurePrivateDNSChangeMap{} + zoneNameIDMapper := zoneIDName{} + for _, z := range zones { + if z.Name != nil { + zoneNameIDMapper.Add(*z.Name, *z.Name) + } + } + mapChange := func(changeMap azurePrivateDNSChangeMap, change *endpoint.Endpoint) { + zone, _ := zoneNameIDMapper.FindZone(change.DNSName) + if zone == "" { + if _, ok := ignored[change.DNSName]; !ok { + ignored[change.DNSName] = true + log.Infof("Ignoring changes to '%s' because a suitable Azure DNS zone was not found.", change.DNSName) + } + return + } + // Ensure the record type is suitable + changeMap[zone] = append(changeMap[zone], change) + } + + for _, change := range changes.Delete { + mapChange(deleted, change) + } + + for _, change := range changes.UpdateOld { + mapChange(deleted, change) + } + + for _, change := range changes.Create { + mapChange(updated, change) + } + + for _, change := range changes.UpdateNew { + mapChange(updated, change) + } + return deleted, updated +} + +func (p *AzurePrivateDNSProvider) deleteRecords(ctx context.Context, deleted azurePrivateDNSChangeMap) { + log.Debugf("Records to be deleted: %d", len(deleted)) + // Delete records first + for zone, endpoints := range deleted { + for _, endpoint := range endpoints { + name := p.recordSetNameForZone(zone, endpoint) + if p.dryRun { + log.Infof("Would delete %s record named '%s' for Azure DNS zone '%s'.", endpoint.RecordType, name, zone) + } else { + log.Infof("Deleting %s record named '%s' for Azure DNS zone '%s'.", endpoint.RecordType, name, zone) + if _, err := p.recordSetsClient.Delete(ctx, p.resourceGroup, zone, privatedns.RecordType(endpoint.RecordType), name, ""); err != nil { + log.Errorf( + "Failed to delete %s record named '%s' for Azure DNS zone '%s': %v", + endpoint.RecordType, + name, + zone, + err, + ) + } + } + } + } +} + +func (p *AzurePrivateDNSProvider) updateRecords(ctx context.Context, updated azurePrivateDNSChangeMap) { + log.Debugf("Records to be updated: %d", len(updated)) + for zone, endpoints := range updated { + for _, endpoint := range endpoints { + name := p.recordSetNameForZone(zone, endpoint) + if p.dryRun { + log.Infof( + "Would update %s record named '%s' to '%s' for Azure DNS zone '%s'.", + endpoint.RecordType, + name, + endpoint.Targets, + zone, + ) + continue + } + + log.Infof( + "Updating %s record named '%s' to '%s' for Azure DNS zone '%s'.", + endpoint.RecordType, + name, + endpoint.Targets, + zone, + ) + + recordSet, err := p.newRecordSet(endpoint) + if err == nil { + _, err = p.recordSetsClient.CreateOrUpdate( + ctx, + p.resourceGroup, + zone, + privatedns.RecordType(endpoint.RecordType), + name, + recordSet, + "", + "", + ) + } + if err != nil { + log.Errorf( + "Failed to update %s record named '%s' to '%s' for DNS zone '%s': %v", + endpoint.RecordType, + name, + endpoint.Targets, + zone, + err, + ) + } + } + } +} + +func (p *AzurePrivateDNSProvider) recordSetNameForZone(zone string, endpoint *endpoint.Endpoint) string { + // Remove the zone from the record set + name := endpoint.DNSName + name = name[:len(name)-len(zone)] + name = strings.TrimSuffix(name, ".") + + // For root, use @ + if name == "" { + return "@" + } + return name +} + +func (p *AzurePrivateDNSProvider) newRecordSet(endpoint *endpoint.Endpoint) (privatedns.RecordSet, error) { + var ttl int64 = azureRecordTTL + if endpoint.RecordTTL.IsConfigured() { + ttl = int64(endpoint.RecordTTL) + } + switch privatedns.RecordType(endpoint.RecordType) { + case privatedns.A: + aRecords := make([]privatedns.ARecord, len(endpoint.Targets)) + for i, target := range endpoint.Targets { + aRecords[i] = privatedns.ARecord{ + Ipv4Address: to.StringPtr(target), + } + } + return privatedns.RecordSet{ + RecordSetProperties: &privatedns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + ARecords: &aRecords, + }, + }, nil + case privatedns.CNAME: + return privatedns.RecordSet{ + RecordSetProperties: &privatedns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + CnameRecord: &privatedns.CnameRecord{ + Cname: to.StringPtr(endpoint.Targets[0]), + }, + }, + }, nil + case privatedns.TXT: + return privatedns.RecordSet{ + RecordSetProperties: &privatedns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + TxtRecords: &[]privatedns.TxtRecord{ + { + Value: &[]string{ + endpoint.Targets[0], + }, + }, + }, + }, + }, nil + } + return privatedns.RecordSet{}, fmt.Errorf("unsupported record type '%s'", endpoint.RecordType) +} + +// Helper function (shared with test code) +func extractAzurePrivateDNSTargets(recordSet *privatedns.RecordSet) []string { + properties := recordSet.RecordSetProperties + if properties == nil { + return []string{} + } + + // Check for A records + aRecords := properties.ARecords + if aRecords != nil && len(*aRecords) > 0 && (*aRecords)[0].Ipv4Address != nil { + targets := make([]string, len(*aRecords)) + for i, aRecord := range *aRecords { + targets[i] = *aRecord.Ipv4Address + } + return targets + } + + // Check for CNAME records + cnameRecord := properties.CnameRecord + if cnameRecord != nil && cnameRecord.Cname != nil { + return []string{*cnameRecord.Cname} + } + + // Check for TXT records + txtRecords := properties.TxtRecords + if txtRecords != nil && len(*txtRecords) > 0 && (*txtRecords)[0].Value != nil { + values := (*txtRecords)[0].Value + if values != nil && len(*values) > 0 { + return []string{(*values)[0]} + } + } + return []string{} +} From a5a3aa7db15c7576379f3948e626f0bc1056bcb3 Mon Sep 17 00:00:00 2001 From: saidst Date: Tue, 12 Nov 2019 12:50:47 +0100 Subject: [PATCH 53/79] added unit-test for Azure Private DNS Provider. --- go.sum | 793 ++++++++++++++++++++++++++++++ provider/azure_private_dns.go | 21 +- provider/azure_privatedns_test.go | 425 ++++++++++++++++ 3 files changed, 1235 insertions(+), 4 deletions(-) create mode 100644 go.sum create mode 100644 provider/azure_privatedns_test.go diff --git a/go.sum b/go.sum new file mode 100644 index 0000000000..1877062ea5 --- /dev/null +++ b/go.sum @@ -0,0 +1,793 @@ +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.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.3 h1:0sMegbmn/8uTwpNkB0q9cLEpZ2W5a6kl+wtBQgPWBJQ= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/logging v1.0.0/go.mod h1:V1cc3ogwobYzQq5f2R7DS/GvRIrI4FKj01Gs5glwAls= +code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f h1:UrKzEwTgeiff9vxdrfdqxibzpWjxLnuXDI5m6z3GJAk= +code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= +contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= +contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= +contrib.go.opencensus.io/exporter/stackdriver v0.6.0/go.mod h1:QeFzMJDAw8TXt5+aRaSuE8l5BwaMIOIlaVkBOPRuMuw= +contrib.go.opencensus.io/exporter/zipkin v0.1.1/go.mod h1:GMvdSl3eJ2gapOaLKzTKE3qDgUkJ86k9k3yY2eqwkzc= +fortio.org/fortio v1.3.0/go.mod h1:Go0fRqoPJ1xy5JOWcS23jyF58byVZxFyEePYsGmCR0k= +github.com/Azure/azure-sdk-for-go v36.0.0+incompatible h1:XIaBmA4pgKqQ7jInQPaNJQ4pOHrdJjw9gYXhbyiChaU= +github.com/Azure/azure-sdk-for-go v36.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v13.0.1+incompatible h1:wRg6hB3T3dp7qjj5v3NmVsdU9IyXodW+SQnN9xlpGEA= +github.com/Azure/go-autorest v13.0.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.9.1 h1:JB7Mqhna/7J8gZfVHjxDSTLSD6ciz2YgSMb/4qLXTtY= +github.com/Azure/go-autorest/autorest v0.9.1/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.6.0 h1:UCTq22yE3RPgbU/8u4scfnnzuCW6pwQ9n+uBtV78ouo= +github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/azure/auth v0.3.0 h1:JwftqZDtWkr3qt1kcEgPd7H57uCHsXKXf66agWUQcGw= +github.com/Azure/go-autorest/autorest/azure/auth v0.3.0/go.mod h1:CI4BQYBct8NS7BXNBBX+RchsFsUu5+oz+OSyR/ZIi7U= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.0 h1:5PAqnv+CSTwW9mlZWZAizmzrazFWEgZykEZXpr2hDtY= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.0/go.mod h1:rNYMNAefZMRowqCV0cVhr/YDW5dD7afFq9nXAXL4ykE= +github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= +github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v0.0.0-20190301161902-9f8fceff796f/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Masterminds/sprig v2.14.1+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/SAP/go-hdb v0.14.1/go.mod h1:7fdQLVC2lER3urZLjZCm0AuMQfApof92n3aylBPEkMo= +github.com/SermoDigital/jose v0.9.1/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= +github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= +github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= +github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= +github.com/alecthomas/kingpin v2.2.5+incompatible h1:umWl1NNd72+ZvRti3T9C0SYean2hPZ7ZhxU8bsgc9BQ= +github.com/alecthomas/kingpin v2.2.5+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= +github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAKQQZGOJ4knlw+7rfEQQcmwTbt4p5E= +github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= +github.com/alicebob/miniredis v0.0.0-20180201100744-9d52b1fc8da9/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= +github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f h1:hinXH9rcBjRoIih5tl4f1BCbNjOmPJ2UnZwcYDhEHR0= +github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= +github.com/antlr/antlr4 v0.0.0-20190223165740-dade65a895c2/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y= +github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30/go.mod h1:4AJxUpXUhv4N+ziTvIcWWXgeorXpxPZOfk9HdEVr96M= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-sdk-go v1.13.24/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k= +github.com/aws/aws-sdk-go v1.23.18 h1:ADU/y1EO8yPzUJJYjcvJ0V9/suezxPh0u6hb5bSYIGQ= +github.com/aws/aws-sdk-go v1.23.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/cactus/go-statsd-client v3.1.1+incompatible/go.mod h1:cMRcwZDklk7hXp+Law83urTHUiHMzCev/r4JMYr/zU0= +github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= +github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cloudflare-go v0.10.1 h1:d2CL6F9k2O0Ux0w27LgogJ5UOzZRj6a/hDPFqPP68d8= +github.com/cloudflare/cloudflare-go v0.10.1/go.mod h1:C0Y6eWnTJPMK2ceuOxx2pjh78UUHihcXeTTHb8r7QjU= +github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 h1:rdRS5BT13Iae9ssvcslol66gfOOXjaLYwqerEn/cl9s= +github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381/go.mod h1:e5+USP2j8Le2M0Jo3qKPFnNhuo1wueU4nWHCXBOfQ14= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY= +github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.15+incompatible h1:+9RjdC18gMxNQVvSiXvObLu29mOFmkgdsB4cRTlV+EE= +github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc v0.0.0-20180117170138-065b426bd416/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142 h1:3jFq2xL4ZajGK4aZY8jz+DAF0FHjI51BXjjSwCzS1Dk= +github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/prometheus-operator v0.29.0/go.mod h1:SO+r5yZUacDFPKHfPoUjI3hMsH+ZUdiuNNhuSq3WoSg= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= +github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= +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/dchest/siphash v1.1.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= +github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= +github.com/denverdino/aliyungo v0.0.0-20180815121905-69560d9530f5 h1:YjnQWGUNtqeKqndapy9V1BzlfMwc/dBJf2MU9dmuXSQ= +github.com/denverdino/aliyungo v0.0.0-20180815121905-69560d9530f5/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/digitalocean/godo v1.19.0 h1:9ApuchfzGD/XI8Zm0RRnZnytdfYHPjPTRKTnmzQNV7o= +github.com/digitalocean/godo v1.19.0/go.mod h1:AAPQ+tiM4st79QHlEBTg8LM7JQNre4SAQCbn56wEyKY= +github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/dnsimple/dnsimple-go v0.14.0 h1:JGYtVVA/uHc91q0LjDWqR1oVj6EGu9Kn0lMRxjH/w30= +github.com/dnsimple/dnsimple-go v0.14.0/go.mod h1:0FYu4qVNv/UcfZPNwa9zi68IkggJu3TIwM54D7rhmI4= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v0.0.0-20180612054059-a9fbbdc8dd87/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/dropbox/godropbox v0.0.0-20190501155911-5749d3b71cbe/go.mod h1:glr97hP/JuXb+WMYCizc4PIFuzw1lCR97mwbe1VVXhQ= +github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= +github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/elazarl/goproxy v0.0.0-20190630181448-f1e96bc0f4c5/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy/ext v0.0.0-20190630181448-f1e96bc0f4c5/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/emicklei/go-restful v2.9.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.8.2/go.mod h1:EWRTAFN6uuDZIa6KOuUfrOMJ7ySgXZ44rVKiTWjKe34= +github.com/envoyproxy/go-control-plane v0.8.7-0.20190821215049-f062b07a671a h1:SaBXBWjRmig9yVB49C6TcbDtbZTbhuFLod7YiGjuFxQ= +github.com/envoyproxy/go-control-plane v0.8.7-0.20190821215049-f062b07a671a/go.mod h1:XB9+ce7x+IrsjgIVnRnql0O61gj/np0/bGDfhJI3sCU= +github.com/envoyproxy/protoc-gen-validate v0.0.0-20190405222122-d6164de49109/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/exoscale/egoscale v0.18.1 h1:1FNZVk8jHUx0AvWhOZxLEDNlacTU0chMXUUNkm9EZaI= +github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/stackerr v0.0.0-20150612192056-c2fcf88613f4/go.mod h1:SBHk9aNQtiw4R4bEuzHjVmZikkUKCnO1v3lPQ21HZGk= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 h1:jmwW6QWvUO2OPe22YfgFvBaaZlSr8Rlrac5lZvG6IdM= +github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99/go.mod h1:4mP9w9+vYGw2jUx2+2v03IA+phyQQjNRR4AL3uxlNrs= +github.com/fluent/fluent-logger-golang v1.3.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= +github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-ini/ini v1.33.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-redis/redis v6.10.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-resty/resty v1.8.0 h1:vbNCxbHOWCototzwxf3L63PQCKx6xgT6v8SHfoqkp6U= +github.com/go-resty/resty v1.8.0/go.mod h1:n37daLLGIHq2FFYHxg+FYQiwA95FpfNI+A9uxoIYGRk= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= +github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gocql/gocql v0.0.0-20190423091413-b99afaf3b163/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= +github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48 h1:X+zN6RZXsvnrSJaAIQhZezPfAfvsqihKKR8oiLHid34= +github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1/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/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f h1:kSqKc8ouCLIBHqdj9a9xxhtxlZhNqbePClixA4HoM44= +github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:YCHYtYb9c8Q7XgYVYjmJBPtFPKx5QvOcPxHZWjldabE= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/cel-go v0.2.0/go.mod h1:fTCVOuSN/Vn6d49zvRpr3fDAKFyfpLViE0gU+9Vtm7g= +github.com/google/cel-spec v0.2.0/go.mod h1:MjQm800JAGhOZXI7vatnVpmIaFTR6L8FHcKk+piiKpI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-github v15.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +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.0.0-20190424031112-b9b92a825806/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= +github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= +github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= +github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20171214222146-0e7658f8ee99/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/consul v1.3.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.9.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.0.1/go.mod h1:I6dKdmYhZqU0RJSheVEWgTNWdVQH5QvTgIUQ0t/t32M= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.0.0/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +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/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= +github.com/hashicorp/vault v0.10.0/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/heptio/contour v0.15.0 h1:JhyJMauwoYtqTzd23jStx7Bx7S3sHbqTWZs6+Ed+UPE= +github.com/heptio/contour v0.15.0/go.mod h1:y4LmuX+86v8mlRd1HVrb2u4t77jMjOQ3DnjfRCiwrfA= +github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= +github.com/imdario/mergo v0.3.7/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/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65 h1:FP5rOFP4ifbtFIjFHJmwhFrsbDyONILK/FNntl/Pou8= +github.com/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI= +github.com/jefferai/jsonx v1.0.0/go.mod h1:OGmqmi2tTeI/PS+qQfBDToLHHJIy/RMp24fPo8vFvoQ= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jteeuwen/go-bindata v0.0.0-20180305030458-6025e8de665b/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20190207033735-e65537c515d7/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20190212223446-d976af380377/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/keybase/go-crypto v0.0.0-20190416182011-b785b22cc757/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +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/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +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/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d h1:JV46OtdhH2vVt8mJ1EWUE94k99vbN9fZs1WQ8kcEapU= +github.com/kubermatic/glog-logrus v0.0.0-20180829085450-3fa5b9870d1d/go.mod h1:CHQ3o5KBH1PIS2Fb1mRLTIWO5YzP9kSUB3KoCICwlvA= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/linki/instrumented_http v0.2.0 h1:zLhcB3Q/McQQqml3qd5kzdZ0cGnL3vquPFIW2338f5Y= +github.com/linki/instrumented_http v0.2.0/go.mod h1:pjYbItoegfuVi2GUOMhEqzvm/SJKuEL3H0tc8QRLRFk= +github.com/linode/linodego v0.3.0 h1:I83pEPg4owSy5pCPaKix7xkGbWIjPxmAoc/Yu5OYDDY= +github.com/linode/linodego v0.3.0/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= +github.com/lyft/protoc-gen-star v0.4.10/go.mod h1:mE8fbna26u7aEA2QCVvvfBU/ZrPgocG1206xAFPcs94= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 h1:YFh+sjyJTMQSYjKwM4dFKhJPJC/wfo98tPUc17HdoYw= +github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= +github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +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/mdempsky/unconvert v0.0.0-20190325185700-2f5dc3378ed3/go.mod h1:9+3Wp2ccIz73BJqVfc7n2+1A+mzvnEwtDTqEjeRngBQ= +github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= +github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v0.0.0-20161203194507-b8bc1bf76747/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +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 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= +github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= +github.com/nesv/go-dynect v0.6.0 h1:Ow/DiSm4LAISwnFku/FITSQHnU6pBvhQMsUE5Gu6Oq4= +github.com/nesv/go-dynect v0.6.0/go.mod h1:GHRBRKzTwjAMhosHJQq/KrZaFkXIFyJ5zRE7thGXXrs= +github.com/nic-at/rc0go v1.1.0 h1:k6/Bru/npTjmCSFw65ulYRw/b3ycIS30t6/YM4r42V4= +github.com/nic-at/rc0go v1.1.0/go.mod h1:KEa3H5fmDNXCaXSqOeAZxkKnG/8ggr1OHIG25Ve7fjU= +github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/open-policy-agent/opa v0.8.2/go.mod h1:rlfeSeHuZmMEpmrcGla42AjkOUjP4rGIpS96H12un3o= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/openshift/api v0.0.0-20190322043348-8741ff068a47/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/operator-framework/operator-sdk v0.7.0/go.mod h1:iVyukRkam5JZa8AnjYf+/G3rk7JI1+M6GsU0sq0B9NA= +github.com/oracle/oci-go-sdk v1.8.0 h1:4SO45bKV0I3/Mn1os3ANDZmV0eSE5z5CLdSUIkxtyzs= +github.com/oracle/oci-go-sdk v1.8.0/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2 h1:CXwSGu/LYmbjEab5aMCs5usQRVBGThelUKBNnoSOuso= +github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.2.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/prom2json v1.1.0/go.mod h1:v7OY1795b9fEUZgq4UU2+15YjRv0LfpxKejIQCy3L7o= +github.com/prometheus/prom2json v1.2.1/go.mod h1:yIcXOj/TLPdtZ12qRyhswPnu+02sfDoqatDjj0WGSvo= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryanuber/go-glob v0.0.0-20160226084822-572520ed46db/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0 h1:vOcHdR1nu7DO4BAx1rwzdHV7jQTzW3gqcBT5qxHSc6A= +github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0/go.mod h1:FeplEtXXejBYC4NPAFTrs5L7KuK+5RL9bf5nB2vZe9o= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sethgrid/pester v0.0.0-20180227223404-ed9870dad317/go.mod h1:Ad7IjTpvzZO8Fl0vh9AzQ+j/jYZfyp2diGwI8m5q+ns= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/signalfx/com_signalfx_metrics_protobuf v0.0.0-20170330202426-93e507b42f43/go.mod h1:muYA2clvwCdj7nzAJ5vJIXYpJsUumhAl4Uu1wUNpWzA= +github.com/signalfx/gohistogram v0.0.0-20160107210732-1ccfd2ff5083/go.mod h1:adPDS6s7WaajdFBV9mQ7i0dKfQ8xiDnF9ZNETVPpp7c= +github.com/signalfx/golib v1.1.6/go.mod h1:nWYefOwlUKWm/SpN/LgVSBnyH1T9NpT1ANlmgRIi1Cs= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180725160413-e900ae048470/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= +github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 h1:hp2CYQUINdZMHdvTdXtPOY2ainKl4IoMcpAXEf2xj3Q= +github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= +github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/gunit v1.0.2 h1:nCXf7TXGchqk8zNVQFTtbeW6rGSrlp9ir9h8wmx0xws= +github.com/smartystreets/gunit v1.0.2/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= +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/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= +github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A= +github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/transip/gotransip v5.8.2+incompatible h1:aNJhw/w/3QBqFcHAIPz1ytoK5FexeMzbUCGrrhWr3H0= +github.com/transip/gotransip v5.8.2+incompatible/go.mod h1:uacMoJVmrfOcscM4Bi5NVg708b7c6rz2oDTWqa7i2Ic= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/uber/jaeger-client-go v0.0.0-20190228190846-ecf2d03a9e80/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= +github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 h1:Q76MzqJu++vAfhj0mVf7t0F4xHUbg+V/d/Uk5PBQjRU= +github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92/go.mod h1:AZuEfReFWdvtU0LatbLpo70t3lqdLvph2D5mqFP0bkA= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yashtewari/glob-intersection v0.0.0-20180206001645-7af743e8ec84/go.mod h1:HptNXiXVDcJjXe9SqMd0v2FsL9f8dz4GnXgltU6q/co= +github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268 h1:lkoOjizoHqOcEFsvYGE5c8Ykdijjnd0R3r1yDYHzLno= +github.com/yl2chen/cidranger v0.0.0-20180214081945-928b519e5268/go.mod h1:mq0zhomp/G6rRTb0dvHWXRHr/2+Qgeq5hMXfJ670+i4= +github.com/yuin/gopher-lua v0.0.0-20180316054350-84ea3a3c79b3/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= +go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/net v0.0.0-20180611182652-db08ff08e862/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-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/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-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-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-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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/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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190325161752-5a8dccf5b48a/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190822000311-fc82fb2afd64/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190227213309-4f5b463f9597/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +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/d4l3k/messagediff.v1 v1.2.1 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0= +gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +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/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/logfmt.v0 v0.3.0/go.mod h1:mRLMcMLrml5h2Ux/H+4zccFOlVCiRvOvndsolsJoU8Q= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1 h1:+fgY/3ngqdBW9oLQCMwL5g+QRkKFPJH05fx2/pipqRQ= +gopkg.in/ns1/ns1-go.v2 v2.0.0-20190322154155-0dafb5275fd1/go.mod h1:VV+3haRsgDiVLxyifmMBrBIuCWFBPYKbRssXB9z67Hw= +gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/stack.v1 v1.7.0/go.mod h1:QtWz4C5wbvhA63ngux3942W/ppRxtyYjHvvhz02s7+M= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +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= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +istio.io/api v0.0.0-20190820204432-483f2547d882 h1:L0WC/5HTk8T5eGTg/ka9jGZgw7GMuWj9rm6DFF4owL8= +istio.io/api v0.0.0-20190820204432-483f2547d882/go.mod h1:42cBjnu/rTJcCaKi8nLdIvq0n71RcLrkgZ9IQSvDdSQ= +istio.io/gogo-genproto v0.0.0-20190614210408-e88dc8b0e4db/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI= +istio.io/gogo-genproto v0.0.0-20190731221249-06e20ada0df2/go.mod h1:IjvrbUlRbbw4JCpsgvgihcz9USUwEoNTL/uwMtyV5yk= +istio.io/gogo-genproto v0.0.0-20190819131816-7a8328e41c1a h1:QN+P7SPcjI4az1Lb40MdhJg/OkV03u5XS1DVIk8PS6E= +istio.io/gogo-genproto v0.0.0-20190819131816-7a8328e41c1a/go.mod h1:IjvrbUlRbbw4JCpsgvgihcz9USUwEoNTL/uwMtyV5yk= +istio.io/istio v0.0.0-20190911205955-c2bd59595ce6 h1:SICsYFkNnMRHPPxHYUGMqZp1lQXW8+nJKBSIZVIk16M= +istio.io/istio v0.0.0-20190911205955-c2bd59595ce6/go.mod h1:dn7qqBbC/pAcJnqNvB2jv7llDBbExQVbnPIVuPPScx8= +istio.io/operator v0.0.0-20190830172131-647a5416137b/go.mod h1:NW/+IXU4IeeVtWLS8S57Vq67H/GOy92Temo4eI5efLs= +istio.io/pkg v0.0.0-20190515193414-9332430ad747/go.mod h1:0EkPwmR0tESYjN4Ilq1D52nTBurXaQvny3r2VY4j4tw= +istio.io/pkg v0.0.0-20190731230704-fcbac27d69d5 h1:HcASpvj/fuuABkYH9YbsTGEOT75YHyWvvFnTe229zXs= +istio.io/pkg v0.0.0-20190731230704-fcbac27d69d5/go.mod h1:We4ZQuCbiiNfXge2GfOshBsyDXVwzFwP8703V5DcM14= +k8s.io/api v0.0.0-20190817221950-ebce17126a01 h1:AMUY6ojynTCBURCALg9KVOsrCmWjHF7h7UbuBod7FYc= +k8s.io/api v0.0.0-20190817221950-ebce17126a01/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/apiextensions-apiserver v0.0.0-20190919022157-e8460a76b3ad h1:I3kcGO+4TazAR49NWgNiEGND6b4q5HVc7Q0K1IQxV9Q= +k8s.io/apiextensions-apiserver v0.0.0-20190919022157-e8460a76b3ad/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apimachinery v0.0.0-20190817221809-bf4de9df677c h1:TlFvXut3q9hNMA2UdjrC6LLfANYrh4lnDzb0gDNSMSg= +k8s.io/apimachinery v0.0.0-20190817221809-bf4de9df677c/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apiserver v0.0.0-20181213151703-3ccfe8365421/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w= +k8s.io/cli-runtime v0.0.0-20190817224438-0337ccdab819/go.mod h1:qWnH3/b8sp/l7EvlDh7ulDU3UWA4P4N1NFbEEP791tM= +k8s.io/client-go v0.0.0-20190817222206-ee6c071a42cf h1:ZCiWjWPoxHYlMo7N4ZPz7yqo2YuCPvBi3nNX11oBTMg= +k8s.io/client-go v0.0.0-20190817222206-ee6c071a42cf/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/helm v2.13.1+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68= +k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= +k8s.io/kube-openapi v0.0.0-20190401085232-94e1e7b7574c h1:kJCzg2vGCzah5icgkKR7O1Dzn0NA2iGlym27sb0ZfGE= +k8s.io/kube-openapi v0.0.0-20190401085232-94e1e7b7574c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= +k8s.io/kubernetes v1.13.1/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= +k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +sigs.k8s.io/controller-runtime v0.1.10/go.mod h1:HFAYoOh6XMV+jKF1UjFwrknPbowfyHEHHRdJMf2jMX8= +sigs.k8s.io/testing_frameworks v0.1.1/go.mod h1:VVBKrHmJ6Ekkfz284YKhQePcdycOzNH9qL6ht1zEr/U= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/provider/azure_private_dns.go b/provider/azure_private_dns.go index 354deac3b9..519877d907 100644 --- a/provider/azure_private_dns.go +++ b/provider/azure_private_dns.go @@ -19,6 +19,7 @@ package provider import ( "context" "fmt" + "github.com/Azure/go-autorest/autorest" "strings" log "github.com/sirupsen/logrus" @@ -36,18 +37,30 @@ type azurePrivateDNSConfig struct { ResourceGroup string `json:"resourceGroup" yaml:"resourceGroup"` } -// AzureProvider implements the DNS provider for Microsoft's Azure cloud platform. +// PrivateZonesClient is an interface of privatedns.PrivateZoneClient that can be stubbed for testing. +type PrivateZonesClient interface { + ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result privatedns.PrivateZoneListResultIterator, err error) +} + +// PrivateRecordSetsClient is an interface of privatedns.RecordSetsClient that can be stubbed for testing. +type PrivateRecordSetsClient interface { + ListComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result privatedns.RecordSetListResultIterator, err error) + Delete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, ifMatch string) (result autorest.Response, err error) + CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, parameters privatedns.RecordSet, ifMatch string, ifNoneMatch string) (result privatedns.RecordSet, err error) +} + +// AzurePrivateDNSProvider implements the DNS provider for Microsoft's Azure Private DNS service type AzurePrivateDNSProvider struct { domainFilter DomainFilter zoneIDFilter ZoneIDFilter dryRun bool subscriptionID string resourceGroup string - zonesClient privatedns.PrivateZonesClient - recordSetsClient privatedns.RecordSetsClient + zonesClient PrivateZonesClient + recordSetsClient PrivateRecordSetsClient } -// NewAzureProvider creates a new Azure provider. +// NewAzurePrivateDNSProvider creates a new Azure Private DNS provider. // // Returns the provider or an error if a provider could not be created. func NewAzurePrivateDNSProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, resourceGroup string, subscriptionID string, dryRun bool) (*AzurePrivateDNSProvider, error) { diff --git a/provider/azure_privatedns_test.go b/provider/azure_privatedns_test.go new file mode 100644 index 0000000000..7fcc3b0589 --- /dev/null +++ b/provider/azure_privatedns_test.go @@ -0,0 +1,425 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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. +*/ + +package provider + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "testing" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/to" + + "github.com/kubernetes-sigs/external-dns/endpoint" + "github.com/kubernetes-sigs/external-dns/plan" +) + +// mockPrivateZonesClient implements the methods of the Azure Private DNS Zones Client which are used in the Azure Private DNS Provider +// and returns static results which are defined per test +type mockPrivateZonesClient struct { + mockZonesClientIterator *privatedns.PrivateZoneListResultIterator +} + +// mockPrivateRecordSetsClient implements the methods of the Azure Private DNS RecordSet Client which are used in the Azure Private DNS Provider +// and returns static results which are defined per test +type mockPrivateRecordSetsClient struct { + mockRecordSetListIterator *privatedns.RecordSetListResultIterator + deletedEndpoints []*endpoint.Endpoint + updatedEndpoints []*endpoint.Endpoint +} + +// mockPrivateZoneListResultPageIterator is used to paginate forward through a list of zones +type mockPrivateZoneListResultPageIterator struct { + offset int + results []privatedns.PrivateZoneListResult +} + +// getNextPage provides the next page based on the offset of the mockZoneListResultPageIterator +func (m *mockPrivateZoneListResultPageIterator) getNextPage(context.Context, privatedns.PrivateZoneListResult) (privatedns.PrivateZoneListResult, error) { + // it assumed that instances of this kind of iterator are only skimmed through once per test + // otherwise a real implementation is required, e.g. based on a linked list + if m.offset < len(m.results) { + m.offset = m.offset + 1 + return m.results[m.offset-1], nil + } + + // paged to last page or empty + return privatedns.PrivateZoneListResult{}, nil +} + +// mockPrivateRecordSetListResultPageIterator is used to paginate forward through a list of recordsets +type mockPrivateRecordSetListResultPageIterator struct { + offset int + results []privatedns.RecordSetListResult +} + +// getNextPage provides the next page based on the offset of the mockRecordSetListResultPageIterator +func (m *mockPrivateRecordSetListResultPageIterator) getNextPage(context.Context, privatedns.RecordSetListResult) (privatedns.RecordSetListResult, error) { + // it assumed that instances of this kind of iterator are only skimmed through once per test + // otherwise a real implementation is required, e.g. based on a linked list + if m.offset < len(m.results) { + m.offset = m.offset + 1 + return m.results[m.offset-1], nil + } + + // paged to last page or empty + return privatedns.RecordSetListResult{}, nil +} + +func createMockPrivateZone(zone string, id string) privatedns.PrivateZone { + return privatedns.PrivateZone{ + ID: to.StringPtr(id), + Name: to.StringPtr(zone), + } +} + +func (client *mockPrivateZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result privatedns.PrivateZoneListResultIterator, err error) { + // pre-iterate to first item to emulate behaviour of Azure SDK + err = client.mockZonesClientIterator.NextWithContext(ctx) + if err != nil { + return *client.mockZonesClientIterator, err + } + + return *client.mockZonesClientIterator, nil +} + +func privateARecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties { + aRecords := make([]privatedns.ARecord, len(values)) + for i, value := range values { + aRecords[i] = privatedns.ARecord{ + Ipv4Address: to.StringPtr(value), + } + } + return &privatedns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + ARecords: &aRecords, + } +} + +func privateCNameRecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties { + return &privatedns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + CnameRecord: &privatedns.CnameRecord{ + Cname: to.StringPtr(values[0]), + }, + } +} + +func privateTxtRecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties { + return &privatedns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + TxtRecords: &[]privatedns.TxtRecord{ + { + Value: &[]string{values[0]}, + }, + }, + } +} + +func privateOthersRecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties { + return &privatedns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + } +} +func createPrivateMockRecordSet(name, recordType string, values ...string) privatedns.RecordSet { + return createPrivateMockRecordSetMultiWithTTL(name, recordType, 0, values...) +} +func createPrivateMockRecordSetWithTTL(name, recordType, value string, ttl int64) privatedns.RecordSet { + return createPrivateMockRecordSetMultiWithTTL(name, recordType, ttl, value) +} +func createPrivateMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values ...string) privatedns.RecordSet { + var getterFunc func(values []string, ttl int64) *privatedns.RecordSetProperties + + switch recordType { + case endpoint.RecordTypeA: + getterFunc = privateARecordSetPropertiesGetter + case endpoint.RecordTypeCNAME: + getterFunc = privateCNameRecordSetPropertiesGetter + case endpoint.RecordTypeTXT: + getterFunc = privateTxtRecordSetPropertiesGetter + default: + getterFunc = privateOthersRecordSetPropertiesGetter + } + return privatedns.RecordSet{ + Name: to.StringPtr(name), + Type: to.StringPtr("Microsoft.Network/privateDnsZones" + recordType), + RecordSetProperties: getterFunc(values, ttl), + } + +} + +func (client *mockPrivateRecordSetsClient) ListComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result privatedns.RecordSetListResultIterator, err error) { + // pre-iterate to first item to emulate behaviour of Azure SDK + err = client.mockRecordSetListIterator.NextWithContext(ctx) + if err != nil { + return *client.mockRecordSetListIterator, err + } + + return *client.mockRecordSetListIterator, nil +} + +func (client *mockPrivateRecordSetsClient) Delete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, ifMatch string) (result autorest.Response, err error) { + client.deletedEndpoints = append( + client.deletedEndpoints, + endpoint.NewEndpoint( + formatAzureDNSName(relativeRecordSetName, privateZoneName), + string(recordType), + "", + ), + ) + return autorest.Response{}, nil +} + +func (client *mockPrivateRecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, parameters privatedns.RecordSet, ifMatch string, ifNoneMatch string) (result privatedns.RecordSet, err error) { + var ttl endpoint.TTL + if parameters.TTL != nil { + ttl = endpoint.TTL(*parameters.TTL) + } + client.updatedEndpoints = append( + client.updatedEndpoints, + endpoint.NewEndpointWithTTL( + formatAzureDNSName(relativeRecordSetName, privateZoneName), + string(recordType), + ttl, + extractAzurePrivateDNSTargets(¶meters)..., + ), + ) + return parameters, nil +} + +// newMockedAzurePrivateDNSProvider creates an AzureProvider comprising the mocked clients for zones and recordsets +func newMockedAzurePrivateDNSProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zones *[]privatedns.PrivateZone, recordSets *[]privatedns.RecordSet) (*AzurePrivateDNSProvider, error) { + // init zone-related parts of the mock-client + pageIterator := mockPrivateZoneListResultPageIterator{ + results: []privatedns.PrivateZoneListResult{ + { + Value: zones, + }, + }, + } + + mockZoneListResultPage := privatedns.NewPrivateZoneListResultPage(pageIterator.getNextPage) + mockZoneClientIterator := privatedns.NewPrivateZoneListResultIterator(mockZoneListResultPage) + zonesClient := mockPrivateZonesClient{ + mockZonesClientIterator: &mockZoneClientIterator, + } + + // init record-related parts of the mock-client + resultPageIterator := mockPrivateRecordSetListResultPageIterator{ + results: []privatedns.RecordSetListResult{ + { + Value: recordSets, + }, + }, + } + mockRecordSetListResultPage := privatedns.NewRecordSetListResultPage(resultPageIterator.getNextPage) + mockRecordSetListIterator := privatedns.NewRecordSetListResultIterator(mockRecordSetListResultPage) + recordSetsClient := mockPrivateRecordSetsClient{ + mockRecordSetListIterator: &mockRecordSetListIterator, + } + + return newAzurePrivateDNSProvider(domainFilter, zoneIDFilter, dryRun, resourceGroup, &zonesClient, &recordSetsClient), nil +} + +func newAzurePrivateDNSProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, privateZonesClient PrivateZonesClient, privateRecordsClient PrivateRecordSetsClient) *AzurePrivateDNSProvider { + return &AzurePrivateDNSProvider{ + domainFilter: domainFilter, + zoneIDFilter: zoneIDFilter, + dryRun: dryRun, + resourceGroup: resourceGroup, + zonesClient: privateZonesClient, + recordSetsClient: privateRecordsClient, + } +} + +func TestAzurePrivateDNSRecord(t *testing.T) { + provider, err := newMockedAzurePrivateDNSProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", + &[]privatedns.PrivateZone{ + createMockPrivateZone("example.com", "/privateDnsZones/example.com"), + }, + &[]privatedns.RecordSet{ + createPrivateMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), + createPrivateMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), + createPrivateMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122"), + createPrivateMockRecordSet("@", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default"), + createPrivateMockRecordSetWithTTL("nginx", endpoint.RecordTypeA, "123.123.123.123", 3600), + createPrivateMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL), + createPrivateMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), + }) + + actual, err := provider.Records() + + if err != nil { + t.Fatal(err) + } + expected := []*endpoint.Endpoint{ + endpoint.NewEndpoint("example.com", endpoint.RecordTypeA, "123.123.123.122"), + endpoint.NewEndpoint("example.com", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default"), + endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeA, 3600, "123.123.123.123"), + endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeTXT, recordTTL, "heritage=external-dns,external-dns/owner=default"), + endpoint.NewEndpointWithTTL("hack.example.com", endpoint.RecordTypeCNAME, 10, "hack.azurewebsites.net"), + } + + validateAzureEndpoints(t, actual, expected) + +} + +func TestAzurePrivateDNSMultiRecord(t *testing.T) { + provider, err := newMockedAzurePrivateDNSProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", + &[]privatedns.PrivateZone{ + createMockPrivateZone("example.com", "/privateDnsZones/example.com"), + }, + &[]privatedns.RecordSet{ + createPrivateMockRecordSet("@", "NS", "ns1-03.azure-dns.com."), + createPrivateMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), + createPrivateMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122", "234.234.234.233"), + createPrivateMockRecordSet("@", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default"), + createPrivateMockRecordSetMultiWithTTL("nginx", endpoint.RecordTypeA, 3600, "123.123.123.123", "234.234.234.234"), + createPrivateMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL), + createPrivateMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), + }) + + actual, err := provider.Records() + + if err != nil { + t.Fatal(err) + } + expected := []*endpoint.Endpoint{ + endpoint.NewEndpoint("example.com", endpoint.RecordTypeA, "123.123.123.122", "234.234.234.233"), + endpoint.NewEndpoint("example.com", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default"), + endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeA, 3600, "123.123.123.123", "234.234.234.234"), + endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeTXT, recordTTL, "heritage=external-dns,external-dns/owner=default"), + endpoint.NewEndpointWithTTL("hack.example.com", endpoint.RecordTypeCNAME, 10, "hack.azurewebsites.net"), + } + + validateAzureEndpoints(t, actual, expected) + +} + +func TestAzurePrivateDNSApplyChanges(t *testing.T) { + recordsClient := mockPrivateRecordSetsClient{} + + testAzurePrivateDNSApplyChangesInternal(t, false, &recordsClient) + + validateAzureEndpoints(t, recordsClient.deletedEndpoints, []*endpoint.Endpoint{ + endpoint.NewEndpoint("old.example.com", endpoint.RecordTypeA, ""), + endpoint.NewEndpoint("oldcname.example.com", endpoint.RecordTypeCNAME, ""), + endpoint.NewEndpoint("deleted.example.com", endpoint.RecordTypeA, ""), + endpoint.NewEndpoint("deletedcname.example.com", endpoint.RecordTypeCNAME, ""), + }) + + validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{ + endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), + endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "tag"), + endpoint.NewEndpointWithTTL("foo.example.com", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4", "1.2.3.5"), + endpoint.NewEndpointWithTTL("foo.example.com", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "tag"), + endpoint.NewEndpointWithTTL("bar.example.com", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "other.com"), + endpoint.NewEndpointWithTTL("bar.example.com", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "tag"), + endpoint.NewEndpointWithTTL("other.com", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "5.6.7.8"), + endpoint.NewEndpointWithTTL("other.com", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "tag"), + endpoint.NewEndpointWithTTL("new.example.com", endpoint.RecordTypeA, 3600, "111.222.111.222"), + endpoint.NewEndpointWithTTL("newcname.example.com", endpoint.RecordTypeCNAME, 10, "other.com"), + }) +} + +func TestAzurePrivateDNSApplyChangesDryRun(t *testing.T) { + recordsClient := mockRecordSetsClient{} + + testAzureApplyChangesInternal(t, true, &recordsClient) + + validateAzureEndpoints(t, recordsClient.deletedEndpoints, []*endpoint.Endpoint{}) + + validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{}) +} + +func testAzurePrivateDNSApplyChangesInternal(t *testing.T, dryRun bool, client PrivateRecordSetsClient) { + zlr := privatedns.PrivateZoneListResult{ + Value: &[]privatedns.PrivateZone{ + createMockPrivateZone("example.com", "/privateDnsZones/example.com"), + createMockPrivateZone("other.com", "/privateDnsZones/other.com"), + }, + } + + results := []privatedns.PrivateZoneListResult{ + zlr, + } + + mockZoneListResultPage := privatedns.NewPrivateZoneListResultPage(func(ctxParam context.Context, zlrParam privatedns.PrivateZoneListResult) (privatedns.PrivateZoneListResult, error) { + if len(results) > 0 { + result := results[0] + results = nil + return result, nil + } else { + return privatedns.PrivateZoneListResult{}, nil + } + }) + mockZoneClientIterator := privatedns.NewPrivateZoneListResultIterator(mockZoneListResultPage) + + zonesClient := mockPrivateZonesClient{ + mockZonesClientIterator: &mockZoneClientIterator, + } + + provider := newAzurePrivateDNSProvider( + NewDomainFilter([]string{""}), + NewZoneIDFilter([]string{""}), + dryRun, + "group", + &zonesClient, + client, + ) + + createRecords := []*endpoint.Endpoint{ + endpoint.NewEndpoint("example.com", endpoint.RecordTypeA, "1.2.3.4"), + endpoint.NewEndpoint("example.com", endpoint.RecordTypeTXT, "tag"), + endpoint.NewEndpoint("foo.example.com", endpoint.RecordTypeA, "1.2.3.5", "1.2.3.4"), + endpoint.NewEndpoint("foo.example.com", endpoint.RecordTypeTXT, "tag"), + endpoint.NewEndpoint("bar.example.com", endpoint.RecordTypeCNAME, "other.com"), + endpoint.NewEndpoint("bar.example.com", endpoint.RecordTypeTXT, "tag"), + endpoint.NewEndpoint("other.com", endpoint.RecordTypeA, "5.6.7.8"), + endpoint.NewEndpoint("other.com", endpoint.RecordTypeTXT, "tag"), + endpoint.NewEndpoint("nope.com", endpoint.RecordTypeA, "4.4.4.4"), + endpoint.NewEndpoint("nope.com", endpoint.RecordTypeTXT, "tag"), + } + + currentRecords := []*endpoint.Endpoint{ + endpoint.NewEndpoint("old.example.com", endpoint.RecordTypeA, "121.212.121.212"), + endpoint.NewEndpoint("oldcname.example.com", endpoint.RecordTypeCNAME, "other.com"), + endpoint.NewEndpoint("old.nope.com", endpoint.RecordTypeA, "121.212.121.212"), + } + updatedRecords := []*endpoint.Endpoint{ + endpoint.NewEndpointWithTTL("new.example.com", endpoint.RecordTypeA, 3600, "111.222.111.222"), + endpoint.NewEndpointWithTTL("newcname.example.com", endpoint.RecordTypeCNAME, 10, "other.com"), + endpoint.NewEndpoint("new.nope.com", endpoint.RecordTypeA, "222.111.222.111"), + } + + deleteRecords := []*endpoint.Endpoint{ + endpoint.NewEndpoint("deleted.example.com", endpoint.RecordTypeA, "111.222.111.222"), + endpoint.NewEndpoint("deletedcname.example.com", endpoint.RecordTypeCNAME, "other.com"), + endpoint.NewEndpoint("deleted.nope.com", endpoint.RecordTypeA, "222.111.222.111"), + } + + changes := &plan.Changes{ + Create: createRecords, + UpdateNew: updatedRecords, + UpdateOld: currentRecords, + Delete: deleteRecords, + } + + if err := provider.ApplyChanges(context.Background(), changes); err != nil { + t.Fatal(err) + } +} From f14d7923156cef98f3039591ff98195f8af16789 Mon Sep 17 00:00:00 2001 From: saidst Date: Tue, 12 Nov 2019 19:48:31 +0100 Subject: [PATCH 54/79] resolved review findings as of nov 12. --- docs/tutorials/azure-private-dns.md | 3 --- provider/azure_private_dns.go | 18 +++++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/docs/tutorials/azure-private-dns.md b/docs/tutorials/azure-private-dns.md index 2ee216af07..bfa064f6c1 100644 --- a/docs/tutorials/azure-private-dns.md +++ b/docs/tutorials/azure-private-dns.md @@ -4,9 +4,6 @@ This tutorial describes how to setup ExternalDNS for managing records in Azure Private DNS. It assumes to deploy ExternalDNS as a container Kubernetes. ->Note: With Azure Private DNS we refer to the successor of the private-zone functionality in Azure DNS, which is -a separate, independent product. - It comprises of the following steps: 1) Provision Azure Private DNS diff --git a/provider/azure_private_dns.go b/provider/azure_private_dns.go index 519877d907..5e36f8a860 100644 --- a/provider/azure_private_dns.go +++ b/provider/azure_private_dns.go @@ -164,7 +164,7 @@ func (p *AzurePrivateDNSProvider) ApplyChanges(ctx context.Context, changes *pla } func (p *AzurePrivateDNSProvider) zones(ctx context.Context) ([]privatedns.PrivateZone, error) { - log.Debugf("Retrieving Azure DNS zones for Resource Group '%s'", p.resourceGroup) + log.Debugf("Retrieving Azure Private DNS zones for Resource Group '%s'", p.resourceGroup) var zones []privatedns.PrivateZone @@ -197,7 +197,7 @@ func (p *AzurePrivateDNSProvider) zones(ctx context.Context) ([]privatedns.Priva } } - log.Debugf("Found %d Azure DNS zone(s).", len(zones)) + log.Debugf("Found %d Azure Private DNS zone(s).", len(zones)) return zones, nil } @@ -238,7 +238,7 @@ func (p *AzurePrivateDNSProvider) mapChanges(zones []privatedns.PrivateZone, cha if zone == "" { if _, ok := ignored[change.DNSName]; !ok { ignored[change.DNSName] = true - log.Infof("Ignoring changes to '%s' because a suitable Azure DNS zone was not found.", change.DNSName) + log.Infof("Ignoring changes to '%s' because a suitable Azure Private DNS zone was not found.", change.DNSName) } return } @@ -271,12 +271,12 @@ func (p *AzurePrivateDNSProvider) deleteRecords(ctx context.Context, deleted azu for _, endpoint := range endpoints { name := p.recordSetNameForZone(zone, endpoint) if p.dryRun { - log.Infof("Would delete %s record named '%s' for Azure DNS zone '%s'.", endpoint.RecordType, name, zone) + log.Infof("Would delete %s record named '%s' for Azure Private DNS zone '%s'.", endpoint.RecordType, name, zone) } else { - log.Infof("Deleting %s record named '%s' for Azure DNS zone '%s'.", endpoint.RecordType, name, zone) + log.Infof("Deleting %s record named '%s' for Azure Private DNS zone '%s'.", endpoint.RecordType, name, zone) if _, err := p.recordSetsClient.Delete(ctx, p.resourceGroup, zone, privatedns.RecordType(endpoint.RecordType), name, ""); err != nil { log.Errorf( - "Failed to delete %s record named '%s' for Azure DNS zone '%s': %v", + "Failed to delete %s record named '%s' for Azure Private DNS zone '%s': %v", endpoint.RecordType, name, zone, @@ -295,7 +295,7 @@ func (p *AzurePrivateDNSProvider) updateRecords(ctx context.Context, updated azu name := p.recordSetNameForZone(zone, endpoint) if p.dryRun { log.Infof( - "Would update %s record named '%s' to '%s' for Azure DNS zone '%s'.", + "Would update %s record named '%s' to '%s' for Azure Private DNS zone '%s'.", endpoint.RecordType, name, endpoint.Targets, @@ -305,7 +305,7 @@ func (p *AzurePrivateDNSProvider) updateRecords(ctx context.Context, updated azu } log.Infof( - "Updating %s record named '%s' to '%s' for Azure DNS zone '%s'.", + "Updating %s record named '%s' to '%s' for Azure Private DNS zone '%s'.", endpoint.RecordType, name, endpoint.Targets, @@ -327,7 +327,7 @@ func (p *AzurePrivateDNSProvider) updateRecords(ctx context.Context, updated azu } if err != nil { log.Errorf( - "Failed to update %s record named '%s' to '%s' for DNS zone '%s': %v", + "Failed to update %s record named '%s' to '%s' for Azure Private DNS zone '%s': %v", endpoint.RecordType, name, endpoint.Targets, From b7ea40ff7800469ed55792de861cdbf3169e850e Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Mon, 18 Nov 2019 07:50:40 +0000 Subject: [PATCH 55/79] Refine azure-private-dns tutorial --- docs/tutorials/azure-private-dns.md | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/docs/tutorials/azure-private-dns.md b/docs/tutorials/azure-private-dns.md index bfa064f6c1..5e7bf917d1 100644 --- a/docs/tutorials/azure-private-dns.md +++ b/docs/tutorials/azure-private-dns.md @@ -54,7 +54,7 @@ Finally, create the mentioned link with the VNET. ``` $ az network private-dns link vnet create -g externaldns -n mylink \ - -z example.com -v myvnet + -z example.com -v myvnet --registration-enabled false ``` ## Configure service principal for managing the zone @@ -66,7 +66,7 @@ More powerful role-assignments like `owner` or assignments on subscription-level Start off by **creating the service principal** without role-assignments. ``` -$ az ad sp create-for-rbac -n externaldns-sp +$ az ad sp create-for-rbac --skip-assignment -n http://externaldns-sp { "appId": "appId GUID", <-- aadClientId value ... @@ -82,17 +82,11 @@ But first **retrieve the ID's** of the objects to assign roles on. ``` # find out the resource ids of the resource group where the dns zone is deployed, and the dns zone itself -$ az group show --name externaldns -{ - "id": "/subscriptions/id/resourceGroups/externaldns", - ... -} +$ az group show --name externaldns --query id -o tsv +/subscriptions/id/resourceGroups/externaldns -$ az network private-dns zone show --name example.com -g externaldns -{ - "id": "/subscriptions/.../resourceGroups/externaldns/providers/Microsoft.Network/privateDnsZones/example.com", - ... -} +$ az network private-dns zone show --name example.com -g externaldns --query id -o tsv +/subscriptions/.../resourceGroups/externaldns/providers/Microsoft.Network/privateDnsZones/example.com ``` Now, **create role assignments**. ``` @@ -113,7 +107,7 @@ Azure-CLI features functionality for automatically maintaining this file for AKS Then apply one of the following manifests depending on whether you use RBAC or not. The credentials of the service principal are provided to ExternalDNS as environment-variables. -At the end of this section, we additionaly describe how to provide them as a _file_. +At the end of this section, we additionally describe how to provide them as a _file_. ### Manifest (for clusters without RBAC enabled) ```yaml From ccf9c7499afadc05dcdd9c961a7833c29f7a7994 Mon Sep 17 00:00:00 2001 From: saidst Date: Tue, 19 Nov 2019 11:57:39 +0100 Subject: [PATCH 56/79] added azure private dns to version 0.5 in roadmap. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 07e64f323e..5be92cc9a2 100644 --- a/README.md +++ b/README.md @@ -262,6 +262,7 @@ Here's a rough outline on what is to come (subject to change): - [x] Support for RcodeZero - [x] Support for NS1 - [x] Support for TransIP +- [x] Support for Azure Private DNS ### v0.6 From 1e41400149b23e9a3f03aaec87c5e68ee5a3ca0e Mon Sep 17 00:00:00 2001 From: Zhang Jinghui Date: Fri, 22 Nov 2019 21:01:57 +0800 Subject: [PATCH 57/79] fix broken link of ingress-gce and ingress-nginx --- docs/tutorials/nginx-ingress.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/nginx-ingress.md b/docs/tutorials/nginx-ingress.md index d180e2a0da..119348cbaa 100644 --- a/docs/tutorials/nginx-ingress.md +++ b/docs/tutorials/nginx-ingress.md @@ -1,6 +1,6 @@ # Setting up ExternalDNS on GKE with nginx-ingress-controller -This tutorial describes how to setup ExternalDNS for usage within a GKE cluster that doesn't make use of Google's [default ingress controller](https://github.com/kubernetes/ingress/tree/master/controllers/gce) but rather uses [nginx-ingress-controller](https://github.com/kubernetes/ingress/tree/master/controllers/nginx) for that task. +This tutorial describes how to setup ExternalDNS for usage within a GKE cluster that doesn't make use of Google's [default ingress controller](https://github.com/kubernetes/ingress-gce) but rather uses [nginx-ingress-controller](https://github.com/kubernetes/ingress-nginx) for that task. Setup your environment to work with Google Cloud Platform. Fill in your values as needed, e.g. target project. From cbd7adc95ad01b45c0c017aeb29edc7c2dd2cdc7 Mon Sep 17 00:00:00 2001 From: njuettner Date: Tue, 26 Nov 2019 14:36:27 +0100 Subject: [PATCH 58/79] Bump the version of golangci-lint --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c044419d76..850b8368a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ matrix: - go: tip env: -- GOLANGCI_RELEASE="v1.17.1" +- GOLANGCI_RELEASE="v1.21.0" before_install: - GO111MODULE=off go get github.com/mattn/goveralls From ea2368c514aa1455569b1d47a67c9f62ded1f008 Mon Sep 17 00:00:00 2001 From: njuettner Date: Tue, 26 Nov 2019 14:49:48 +0100 Subject: [PATCH 59/79] Increase the timeout of golangci-lint --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1230a1efcd..48db48cad8 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ cover-html: cover # Run all the linters lint: - golangci-lint run ./... + golangci-lint run --timeout=5m ./... # The verify target runs tasks similar to the CI tasks, but without code coverage From 1f1809f5a156ec165e31806f04076a6b4b0d72a9 Mon Sep 17 00:00:00 2001 From: njuettner Date: Tue, 26 Nov 2019 15:14:49 +0100 Subject: [PATCH 60/79] Fix linter flaws --- provider/azure_private_dns.go | 9 ++++----- provider/azure_privatedns_test.go | 14 +++++++++++--- provider/azure_test.go | 8 ++++++++ provider/designate.go | 11 ++++++----- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/provider/azure_private_dns.go b/provider/azure_private_dns.go index 5e36f8a860..45563321ca 100644 --- a/provider/azure_private_dns.go +++ b/provider/azure_private_dns.go @@ -19,9 +19,10 @@ package provider import ( "context" "fmt" - "github.com/Azure/go-autorest/autorest" "strings" + "github.com/Azure/go-autorest/autorest" + log "github.com/sirupsen/logrus" "github.com/Azure/azure-sdk-for-go/profiles/latest/privatedns/mgmt/privatedns" @@ -104,17 +105,15 @@ func (p *AzurePrivateDNSProvider) Records() (endpoints []*endpoint.Endpoint, _ e if recordSet.Type == nil { log.Debugf("Skipping invalid record set with missing type.") return - } else { - recordType = strings.TrimLeft(*recordSet.Type, "Microsoft.Network/privateDnsZones") } + recordType = strings.TrimLeft(*recordSet.Type, "Microsoft.Network/privateDnsZones") var name string if recordSet.Name == nil { log.Debugf("Skipping invalid record set with missing name.") return - } else { - name = formatAzureDNSName(*recordSet.Name, *zone.Name) } + name = formatAzureDNSName(*recordSet.Name, *zone.Name) targets := extractAzurePrivateDNSTargets(&recordSet) if len(targets) == 0 { diff --git a/provider/azure_privatedns_test.go b/provider/azure_privatedns_test.go index 7fcc3b0589..e64b3fc600 100644 --- a/provider/azure_privatedns_test.go +++ b/provider/azure_privatedns_test.go @@ -18,9 +18,10 @@ package provider import ( "context" - "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" "testing" + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/to" @@ -261,6 +262,10 @@ func TestAzurePrivateDNSRecord(t *testing.T) { createPrivateMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), }) + if err != nil { + t.Fatal(err) + } + actual, err := provider.Records() if err != nil { @@ -293,6 +298,10 @@ func TestAzurePrivateDNSMultiRecord(t *testing.T) { createPrivateMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), }) + if err != nil { + t.Fatal(err) + } + actual, err := provider.Records() if err != nil { @@ -363,9 +372,8 @@ func testAzurePrivateDNSApplyChangesInternal(t *testing.T, dryRun bool, client P result := results[0] results = nil return result, nil - } else { - return privatedns.PrivateZoneListResult{}, nil } + return privatedns.PrivateZoneListResult{}, nil }) mockZoneClientIterator := privatedns.NewPrivateZoneListResultIterator(mockZoneListResultPage) diff --git a/provider/azure_test.go b/provider/azure_test.go index c67aec4332..32f8c29c0e 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -268,6 +268,10 @@ func TestAzureRecord(t *testing.T) { createMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), }) + if err != nil { + t.Fatal(err) + } + actual, err := provider.Records() if err != nil { @@ -300,6 +304,10 @@ func TestAzureMultiRecord(t *testing.T) { createMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), }) + if err != nil { + t.Fatal(err) + } + actual, err := provider.Records() if err != nil { diff --git a/provider/designate.go b/provider/designate.go index 2425495ab4..aa2ce31f6f 100644 --- a/provider/designate.go +++ b/provider/designate.go @@ -19,17 +19,18 @@ package provider import ( "context" "fmt" + "net" + "net/http" + "os" + "strings" + "time" + "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack" "github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets" "github.com/gophercloud/gophercloud/openstack/dns/v2/zones" "github.com/gophercloud/gophercloud/pagination" log "github.com/sirupsen/logrus" - "net" - "net/http" - "os" - "strings" - "time" "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/kubernetes-sigs/external-dns/pkg/tlsutils" From 0d50f6c0d90fdceda6655f18acdcdc0d75ad754a Mon Sep 17 00:00:00 2001 From: njuettner Date: Tue, 26 Nov 2019 15:40:17 +0100 Subject: [PATCH 61/79] Fix linter flaws --- source/node_test.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/source/node_test.go b/source/node_test.go index d347945f5a..8ac2858514 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -78,7 +78,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ @@ -91,7 +91,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1.example.org", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ @@ -104,7 +104,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "{{.Name}}.example.org", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ @@ -117,7 +117,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "{{.Name}}.example.org", "node1.example.org", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ @@ -130,7 +130,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "{{.Name}}.example.org", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}, {v1.NodeExternalIP, "5.6.7.8"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeExternalIP, Address: "5.6.7.8"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ @@ -143,7 +143,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}, {v1.NodeInternalIP, "2.3.4.5"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2.3.4.5"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ @@ -156,7 +156,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1", - []v1.NodeAddress{{v1.NodeInternalIP, "2.3.4.5"}}, + []v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "2.3.4.5"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ @@ -180,7 +180,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{ "service.beta.kubernetes.io/external-traffic": "OnlyLocal", @@ -195,7 +195,7 @@ func testNodeSourceEndpoints(t *testing.T) { "service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{ "service.beta.kubernetes.io/external-traffic": "OnlyLocal", @@ -210,7 +210,7 @@ func testNodeSourceEndpoints(t *testing.T) { "service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{ "service.beta.kubernetes.io/external-traffic": "SomethingElse", @@ -223,7 +223,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{ controllerAnnotationKey: controllerAnnotationValue, @@ -238,7 +238,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{ controllerAnnotationKey: "not-dns-controller", @@ -251,7 +251,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{}, []*endpoint.Endpoint{ @@ -264,7 +264,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{ ttlAnnotationKey: "foo", @@ -279,7 +279,7 @@ func testNodeSourceEndpoints(t *testing.T) { "", "", "node1", - []v1.NodeAddress{{v1.NodeExternalIP, "1.2.3.4"}}, + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}}, map[string]string{}, map[string]string{ ttlAnnotationKey: "10", From 1c8b18985935ff952ce949813c811e151a609a80 Mon Sep 17 00:00:00 2001 From: Alex Orange Date: Tue, 26 Nov 2019 11:22:13 -0700 Subject: [PATCH 62/79] Improve RFC2136 documentation. --- docs/ttl.md | 1 + docs/tutorials/rfc2136.md | 270 ++++++++++++++++++++++++++++++++------ 2 files changed, 229 insertions(+), 42 deletions(-) diff --git a/docs/ttl.md b/docs/ttl.md index 35295e90b1..57a262aab8 100644 --- a/docs/ttl.md +++ b/docs/ttl.md @@ -28,6 +28,7 @@ Providers - [ ] InMemory - [x] Linode - [x] TransIP +- [x] RFC2136 PRs welcome! diff --git a/docs/tutorials/rfc2136.md b/docs/tutorials/rfc2136.md index 154a836d07..3fa790ca6c 100644 --- a/docs/tutorials/rfc2136.md +++ b/docs/tutorials/rfc2136.md @@ -1,69 +1,255 @@ # Configuring RFC2136 provider +This tutorial describes how to use the RFC2136 with either BIND or Windows DNS. ## Using with BIND +To use external-dns with BIND: generate/procure a key, configure DNS and add a +deployment of external-dns. + ### Server credentials: -- RFC2136 was developed for and tested with [BIND](https://www.isc.org/downloads/bind/) DNS server. This documentation assumes that you already have a configured and working server. If you don't, please check BIND documents or tutorials. -- So you should obtain from your administrator a TSIG key. It will look like: +- RFC2136 was developed for and tested with +[BIND](https://www.isc.org/downloads/bind/) DNS server. This documentation +assumes that you already have a configured and working server. If you don't, +please check BIND documents or tutorials. +- If your DNS is provided for you, ask for a TSIG key authorized to update and +transfer the zone you wish to update. The key will look something like below. +Skip the next steps wrt BIND setup. ```text key "externaldns-key" { algorithm hmac-sha256; - secret "XXXXXXXXXXXXXXXXXXXXXX=="; + secret "96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8="; }; ``` -- **Warning!** Bind server configuration should enable this key for AFXR zone transfer. `external-dns` uses it for listing DNS records. +- If you are your own DNS administrator create a TSIG key. Use +`tsig-keygen -a hmac-sha256 externaldns` or on older distributions +`dnssec-keygen -a HMAC-SHA256 -b 256 -n HOST externaldns`. You will end up with +a key printed to standard out like above (or in the case of dnssec-keygen in a +file called `Kexternaldns......key`). -```text -# cat /etc/named.conf -... -include "/etc/rndc.key"; +### BIND Configuration: +If you do not administer your own DNS, skip to RFC provider configuration -controls { - inet 123.123.123.123 port 953 allow { 10.x.y.151; } keys { "externaldns-key"; }; -}; -options { - include "/etc/named/options.conf"; -}; - -include "/etc/named/zones.conf"; -... +- Edit your named.conf file (or appropriate included file) and add/change the +following. + - Make sure You are listening on the right interfaces. At least whatever + interface external-dns will be communicating over and the interface that + faces the internet. + - Add the key that you generated/was given to you above. Copy paste the four + lines that you got (not the same as the example key) into your file. + - Create a zone for kubernetes. If you already have a zone, skip to the next + step. (I put the zone in it's own subdirectory because named, + which shouldn't be running as root, needs to create a journal file and the + default zone directory isn't writeable by named). + ```text + zone "k8s.example.org" { + type master; + file "/etc/bind/pri/k8s/k8s.zone"; + }; + ``` + - Add your key to both transfer and update. For instance with our previous + zone. + ```text + zone "k8s.example.org" { + type master; + file "/etc/bind/pri/k8s/k8s.zone"; + allow-transfer { + key "externaldns-key"; + }; + update-policy { + grant externaldns-key zonesub ANY; + }; + }; + ``` + - Create a zone file (k8s.zone): + ```text + $TTL 60 ; 1 minute + k8s.example.org IN SOA k8s.example.org. root.k8s.example.org. ( + 16 ; serial + 60 ; refresh (1 minute) + 60 ; retry (1 minute) + 60 ; expire (1 minute) + 60 ; minimum (1 minute) + ) + NS ns.k8s.example.org. + ns A 123.456.789.012 + ``` + - Reload (or restart) named -# cat /etc/named/options.conf -... -dnssec-enable yes; -dnssec-validation yes; -... -# cat /etc/named/zones.conf -... -zone "example.com" { - type master; - file "/var/named/dynamic/db.example.com"; - update-policy { - grant externaldns-key zonesub ANY; - }; -}; -... +### Using external-dns +To use external-dns add an ingress or a LoadBalancer service with a host that +is part of the domain-filter. For example both of the following would produce +A records. +```text +apiVersion: v1 +kind: Service +metadata: + name: nginx + annotations: + external-dns.alpha.kubernetes.io/hostname: svc.example.org +spec: + type: LoadBalancer + ports: + - port: 80 + targetPort: 80 + selector: + app: nginx +--- +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + name: my-ingress +spec: + rules: + - host: ingress.example.org + http: + paths: + - path: / + backend: + serviceName: my-service + servicePort: 8000 ``` +There are other annotation that can affect the generation of DNS records like +external-dns.alpha.kubernetes.io/ttl. These are beyond the scope of this +tutorial and are covered elsewhere in the docs. + +### Test with external-dns installed on local machine (optional) +You may install external-dns and test on a local machine by running: +```external-dns --txt-owner-id k8s --provider rfc2136 --rfc2136-host=192.168.0.1 --rfc2136-port=53 --rfc2136-zone=k8s.example.org --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8= --rfc2136-tsig-secret-alg=hmac-sha256 --rfc2136-tsig-keyname=externaldns-key --rfc2136-tsig-axfr --source ingress --once --domain-filter=k8s.example.org --dry-run``` +- host should be the IP of your master DNS server. +- tsig-secret should be changed to match your secret. +- tsig-keyname needs to match the keyname you used (if you changed it). +- domain-filter can be used as shown to filter the domains you wish to update. ### RFC2136 provider configuration: -- Example fragment of real configuration of ExternalDNS service pod. +In order to use external-dns with your cluster you need to add a deployment +with access to your ingress and service resources. The following are two +example manifests with and without RBAC respectively. +- With RBAC: ```text -... +apiVersion: v1 +kind: Namespace +metadata: + name: external-dns + labels: + name: external-dns +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: external-dns + namespace: external-dns +rules: +- apiGroups: + - "" + resources: + - services + verbs: + - get + - watch + - list +- apiGroups: + - extensions + resources: + - ingresses + verbs: + - get + - list + - watch +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: external-dns + namespace: external-dns +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: external-dns-viewer + namespace: external-dns +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: external-dns +subjects: +- kind: ServiceAccount + name: external-dns + namespace: external-dns +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: external-dns + namespace: external-dns +spec: + selector: + matchLabels: + app: external-dns + template: + metadata: + labels: + app: external-dns + spec: + serviceAccountName: external-dns + containers: + - name: external-dns + image: registry.opensource.zalan.do/teapot/external-dns:v0.5.17 + args: + - --txt-owner-id=k8s - --provider=rfc2136 - - --rfc2136-host=123.123.123.123 + - --rfc2136-host=192.168.0.1 - --rfc2136-port=53 - - --rfc2136-zone=your-domain.com - - --rfc2136-tsig-secret=${rfc2136_tsig_secret} + - --rfc2136-zone=k8s.example.org + - --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8= - --rfc2136-tsig-secret-alg=hmac-sha256 - --rfc2136-tsig-keyname=externaldns-key - --rfc2136-tsig-axfr -... + - --source=ingress + - --domain-filter=k8s.example.org ``` -- `--rfc2136-tsig-secret` - environment variable containing actual secret value from TSIG key. Something like `XXXXXXXXXXXXXXXXXXXXXX==`. -- `--rfc2136-tsig-keyname` - this is a string parameter with the key name in the Kubernetes secret. It **must match** with key name on the DNS server. In this example it is `externaldns-key`. - -## Using with Microsoft DNS + +- Without RBAC: +```text +apiVersion: v1 +kind: Namespace +metadata: + name: external-dns + labels: + name: external-dns +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: external-dns + namespace: external-dns +spec: + selector: + matchLabels: + app: external-dns + template: + metadata: + labels: + app: external-dns + spec: + containers: + - name: external-dns + image: registry.opensource.zalan.do/teapot/external-dns:v0.5.17 + args: + - --txt-owner-id=k8s + - --provider=rfc2136 + - --rfc2136-host=192.168.0.1 + - --rfc2136-port=53 + - --rfc2136-zone=k8s.example.org + - --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8= + - --rfc2136-tsig-secret-alg=hmac-sha256 + - --rfc2136-tsig-keyname=externaldns-key + - --rfc2136-tsig-axfr + - --source=ingress + - --domain-filter=k8s.example.org +``` + +## Microsoft DNS While `external-dns` was not developed or tested against Microsoft DNS, it can be configured to work against it. YMMV. From 0c4878f115c3d5e8b33bcba1c7489ff3e439d2bb Mon Sep 17 00:00:00 2001 From: Tongyao Si Date: Thu, 28 Nov 2019 19:08:45 +0800 Subject: [PATCH 63/79] feat(Azure): support specifying user assigned identity's clientID to authenticate --- main.go | 2 +- pkg/apis/externaldns/types.go | 184 +++++++++++++++++----------------- provider/azure.go | 75 ++++++++------ provider/azure_test.go | 24 +++-- 4 files changed, 154 insertions(+), 131 deletions(-) diff --git a/main.go b/main.go index 658d8e2599..f0aa9b708b 100644 --- a/main.go +++ b/main.go @@ -134,7 +134,7 @@ func main() { } p, err = provider.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.AWSAssumeRole, cfg.DryRun) case "azure-dns", "azure": - p, err = provider.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.DryRun) + p, err = provider.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.DryRun) case "azure-private-dns": p, err = provider.NewAzurePrivateDNSProvider(domainFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.AzureSubscriptionID, cfg.DryRun) case "vinyldns": diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index e6ea64c4c5..4bf5fece83 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -37,97 +37,98 @@ var ( // Config is a project-wide configuration type Config struct { - Master string - KubeConfig string - RequestTimeout time.Duration - IstioIngressGatewayServices []string - ContourLoadBalancerService string - Sources []string - Namespace string - AnnotationFilter string - FQDNTemplate string - CombineFQDNAndAnnotation bool - IgnoreHostnameAnnotation bool - Compatibility string - PublishInternal bool - PublishHostIP bool - ConnectorSourceServer string - Provider string - GoogleProject string - GoogleBatchChangeSize int - GoogleBatchChangeInterval time.Duration - DomainFilter []string - ExcludeDomains []string - ZoneIDFilter []string - AlibabaCloudConfigFile string - AlibabaCloudZoneType string - AWSZoneType string - AWSZoneTagFilter []string - AWSAssumeRole string - AWSBatchChangeSize int - AWSBatchChangeInterval time.Duration - AWSEvaluateTargetHealth bool - AWSAPIRetries int - AWSPreferCNAME bool - AzureConfigFile string - AzureResourceGroup string - AzureSubscriptionID string - CloudflareProxied bool - CloudflareZonesPerPage int - CoreDNSPrefix string - RcodezeroTXTEncrypt bool - InfobloxGridHost string - InfobloxWapiPort int - InfobloxWapiUsername string - InfobloxWapiPassword string `secure:"yes"` - InfobloxWapiVersion string - InfobloxSSLVerify bool - InfobloxView string - InfobloxMaxResults int - DynCustomerName string - DynUsername string - DynPassword string `secure:"yes"` - DynMinTTLSeconds int - OCIConfigFile string - InMemoryZones []string - PDNSServer string - PDNSAPIKey string `secure:"yes"` - PDNSTLSEnabled bool - TLSCA string - TLSClientCert string - TLSClientCertKey string - Policy string - Registry string - TXTOwnerID string - TXTPrefix string - Interval time.Duration - Once bool - DryRun bool - LogFormat string - MetricsAddress string - LogLevel string - TXTCacheInterval time.Duration - ExoscaleEndpoint string - ExoscaleAPIKey string `secure:"yes"` - ExoscaleAPISecret string `secure:"yes"` - CRDSourceAPIVersion string - CRDSourceKind string - ServiceTypeFilter []string - CFAPIEndpoint string - CFUsername string - CFPassword string - RFC2136Host string - RFC2136Port int - RFC2136Zone string - RFC2136Insecure bool - RFC2136TSIGKeyName string - RFC2136TSIGSecret string `secure:"yes"` - RFC2136TSIGSecretAlg string - RFC2136TAXFR bool - NS1Endpoint string - NS1IgnoreSSL bool - TransIPAccountName string - TransIPPrivateKeyFile string + Master string + KubeConfig string + RequestTimeout time.Duration + IstioIngressGatewayServices []string + ContourLoadBalancerService string + Sources []string + Namespace string + AnnotationFilter string + FQDNTemplate string + CombineFQDNAndAnnotation bool + IgnoreHostnameAnnotation bool + Compatibility string + PublishInternal bool + PublishHostIP bool + ConnectorSourceServer string + Provider string + GoogleProject string + GoogleBatchChangeSize int + GoogleBatchChangeInterval time.Duration + DomainFilter []string + ExcludeDomains []string + ZoneIDFilter []string + AlibabaCloudConfigFile string + AlibabaCloudZoneType string + AWSZoneType string + AWSZoneTagFilter []string + AWSAssumeRole string + AWSBatchChangeSize int + AWSBatchChangeInterval time.Duration + AWSEvaluateTargetHealth bool + AWSAPIRetries int + AWSPreferCNAME bool + AzureConfigFile string + AzureResourceGroup string + AzureSubscriptionID string + AzureUserAssignedIdentityClientID string + CloudflareProxied bool + CloudflareZonesPerPage int + CoreDNSPrefix string + RcodezeroTXTEncrypt bool + InfobloxGridHost string + InfobloxWapiPort int + InfobloxWapiUsername string + InfobloxWapiPassword string `secure:"yes"` + InfobloxWapiVersion string + InfobloxSSLVerify bool + InfobloxView string + InfobloxMaxResults int + DynCustomerName string + DynUsername string + DynPassword string `secure:"yes"` + DynMinTTLSeconds int + OCIConfigFile string + InMemoryZones []string + PDNSServer string + PDNSAPIKey string `secure:"yes"` + PDNSTLSEnabled bool + TLSCA string + TLSClientCert string + TLSClientCertKey string + Policy string + Registry string + TXTOwnerID string + TXTPrefix string + Interval time.Duration + Once bool + DryRun bool + LogFormat string + MetricsAddress string + LogLevel string + TXTCacheInterval time.Duration + ExoscaleEndpoint string + ExoscaleAPIKey string `secure:"yes"` + ExoscaleAPISecret string `secure:"yes"` + CRDSourceAPIVersion string + CRDSourceKind string + ServiceTypeFilter []string + CFAPIEndpoint string + CFUsername string + CFPassword string + RFC2136Host string + RFC2136Port int + RFC2136Zone string + RFC2136Insecure bool + RFC2136TSIGKeyName string + RFC2136TSIGSecret string `secure:"yes"` + RFC2136TSIGSecretAlg string + RFC2136TAXFR bool + NS1Endpoint string + NS1IgnoreSSL bool + TransIPAccountName string + TransIPPrivateKeyFile string } var defaultConfig = &Config{ @@ -311,6 +312,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("azure-config-file", "When using the Azure provider, specify the Azure configuration file (required when --provider=azure").Default(defaultConfig.AzureConfigFile).StringVar(&cfg.AzureConfigFile) app.Flag("azure-resource-group", "When using the Azure provider, override the Azure resource group to use (required when --provider=azure-private-dns)").Default(defaultConfig.AzureResourceGroup).StringVar(&cfg.AzureResourceGroup) app.Flag("azure-subscription-id", "When using the Azure provider, specify the Azure configuration file (required when --provider=azure-private-dns)").Default(defaultConfig.AzureSubscriptionID).StringVar(&cfg.AzureSubscriptionID) + app.Flag("azure-user-assigned-identity-client-id", "When using the Azure provider, override the client id of user assigned identity in config file (optional)").Default("").StringVar(&cfg.AzureUserAssignedIdentityClientID) app.Flag("cloudflare-proxied", "When using the Cloudflare provider, specify if the proxy mode must be enabled (default: disabled)").BoolVar(&cfg.CloudflareProxied) app.Flag("cloudflare-zones-per-page", "When using the Cloudflare provider, specify how many zones per page listed, max. possible 50 (default: 50)").Default(strconv.Itoa(defaultConfig.CloudflareZonesPerPage)).IntVar(&cfg.CloudflareZonesPerPage) app.Flag("coredns-prefix", "When using the CoreDNS provider, specify the prefix name").Default(defaultConfig.CoreDNSPrefix).StringVar(&cfg.CoreDNSPrefix) diff --git a/provider/azure.go b/provider/azure.go index 3cc8f654b1..c1cfe735d1 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -49,6 +49,7 @@ type config struct { ClientID string `json:"aadClientId" yaml:"aadClientId"` ClientSecret string `json:"aadClientSecret" yaml:"aadClientSecret"` UseManagedIdentityExtension bool `json:"useManagedIdentityExtension" yaml:"useManagedIdentityExtension"` + UserAssignedIdentityID string `json:"userAssignedIdentityID" yaml:"userAssignedIdentityID"` } // ZonesClient is an interface of dns.ZoneClient that can be stubbed for testing. @@ -65,18 +66,19 @@ type RecordSetsClient interface { // AzureProvider implements the DNS provider for Microsoft's Azure cloud platform. type AzureProvider struct { - domainFilter DomainFilter - zoneIDFilter ZoneIDFilter - dryRun bool - resourceGroup string - zonesClient ZonesClient - recordSetsClient RecordSetsClient + domainFilter DomainFilter + zoneIDFilter ZoneIDFilter + dryRun bool + resourceGroup string + userAssignedIdentityClientID string + zonesClient ZonesClient + recordSetsClient RecordSetsClient } // NewAzureProvider creates a new Azure provider. // // Returns the provider or an error if a provider could not be created. -func NewAzureProvider(configFile string, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, resourceGroup string, dryRun bool) (*AzureProvider, error) { +func NewAzureProvider(configFile string, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, resourceGroup string, userAssignedIdentityClientID string, dryRun bool) (*AzureProvider, error) { contents, err := ioutil.ReadFile(configFile) if err != nil { return nil, fmt.Errorf("failed to read Azure config file '%s': %v", configFile, err) @@ -91,6 +93,10 @@ func NewAzureProvider(configFile string, domainFilter DomainFilter, zoneIDFilter if resourceGroup != "" { cfg.ResourceGroup = resourceGroup } + // If userAssignedIdentityClientID is provided explicitly, override existing one in config file + if userAssignedIdentityClientID != "" { + cfg.UserAssignedIdentityID = userAssignedIdentityClientID + } var environment azure.Environment if cfg.Cloud == "" { @@ -113,34 +119,22 @@ func NewAzureProvider(configFile string, domainFilter DomainFilter, zoneIDFilter recordSetsClient.Authorizer = autorest.NewBearerAuthorizer(token) provider := &AzureProvider{ - domainFilter: domainFilter, - zoneIDFilter: zoneIDFilter, - dryRun: dryRun, - resourceGroup: cfg.ResourceGroup, - zonesClient: zonesClient, - recordSetsClient: recordSetsClient, + domainFilter: domainFilter, + zoneIDFilter: zoneIDFilter, + dryRun: dryRun, + resourceGroup: cfg.ResourceGroup, + userAssignedIdentityClientID: cfg.UserAssignedIdentityID, + zonesClient: zonesClient, + recordSetsClient: recordSetsClient, } return provider, nil } // getAccessToken retrieves Azure API access token. func getAccessToken(cfg config, environment azure.Environment) (*adal.ServicePrincipalToken, error) { - // Try to retrive token with MSI. - if cfg.UseManagedIdentityExtension { - log.Info("Using managed identity extension to retrieve access token for Azure API.") - msiEndpoint, err := adal.GetMSIVMEndpoint() - if err != nil { - return nil, fmt.Errorf("failed to get the managed service identity endpoint: %v", err) - } - - token, err := adal.NewServicePrincipalTokenFromMSI(msiEndpoint, environment.ServiceManagementEndpoint) - if err != nil { - return nil, fmt.Errorf("failed to create the managed service identity token: %v", err) - } - return token, nil - } - // Try to retrieve token with service principal credentials. + // Try to use service principal first, some AKS clusters are in an intermediate state that `UseManagedIdentityExtension` is `true` + // and service principal exists. In this case, we still want to use service principal to authenticate. if len(cfg.ClientID) > 0 && len(cfg.ClientSecret) > 0 { log.Info("Using client_id+client_secret to retrieve access token for Azure API.") oauthConfig, err := adal.NewOAuthConfig(environment.ActiveDirectoryEndpoint, cfg.TenantID) @@ -155,6 +149,31 @@ func getAccessToken(cfg config, environment azure.Environment) (*adal.ServicePri return token, nil } + // Try to retrive token with MSI. + if cfg.UseManagedIdentityExtension { + log.Info("Using managed identity extension to retrieve access token for Azure API.") + msiEndpoint, err := adal.GetMSIVMEndpoint() + if err != nil { + return nil, fmt.Errorf("failed to get the managed service identity endpoint: %v", err) + } + + if cfg.UserAssignedIdentityID != "" { + log.Infof("Resolving to user assigned identity, client id is %s.", cfg.UserAssignedIdentityID) + token, err := adal.NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, environment.ServiceManagementEndpoint, cfg.UserAssignedIdentityID) + if err != nil { + return nil, fmt.Errorf("failed to create the managed service identity token: %v", err) + } + return token, nil + } else { + log.Info("Resolving to system assigned identity.") + token, err := adal.NewServicePrincipalTokenFromMSI(msiEndpoint, environment.ServiceManagementEndpoint) + if err != nil { + return nil, fmt.Errorf("failed to create the managed service identity token: %v", err) + } + return token, nil + } + } + return nil, fmt.Errorf("no credentials provided for Azure API") } diff --git a/provider/azure_test.go b/provider/azure_test.go index 32f8c29c0e..ebc29cd109 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -205,7 +205,7 @@ func (client *mockRecordSetsClient) CreateOrUpdate(ctx context.Context, resource } // newMockedAzureProvider creates an AzureProvider comprising the mocked clients for zones and recordsets -func newMockedAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zones *[]dns.Zone, recordSets *[]dns.RecordSet) (*AzureProvider, error) { +func newMockedAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, zones *[]dns.Zone, recordSets *[]dns.RecordSet) (*AzureProvider, error) { // init zone-related parts of the mock-client pageIterator := mockZoneListResultPageIterator{ results: []dns.ZoneListResult{ @@ -235,17 +235,18 @@ func newMockedAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter mockRecordSetListIterator: &mockRecordSetListIterator, } - return newAzureProvider(domainFilter, zoneIDFilter, dryRun, resourceGroup, &zonesClient, &recordSetsClient), nil + return newAzureProvider(domainFilter, zoneIDFilter, dryRun, resourceGroup, userAssignedIdentityClientID, &zonesClient, &recordSetsClient), nil } -func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zonesClient ZonesClient, recordsClient RecordSetsClient) *AzureProvider { +func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, zonesClient ZonesClient, recordsClient RecordsClient) *AzureProvider { return &AzureProvider{ - domainFilter: domainFilter, - zoneIDFilter: zoneIDFilter, - dryRun: dryRun, - resourceGroup: resourceGroup, - zonesClient: zonesClient, - recordSetsClient: recordsClient, + domainFilter: domainFilter, + zoneIDFilter: zoneIDFilter, + dryRun: dryRun, + resourceGroup: resourceGroup, + userAssignedIdentityClientID: userAssignedIdentityClientID, + zonesClient: zonesClient, + recordSetsClient: recordsClient, } } @@ -254,7 +255,7 @@ func validateAzureEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expect } func TestAzureRecord(t *testing.T) { - provider, err := newMockedAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", + provider, err := newMockedAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", "", &[]dns.Zone{ createMockZone("example.com", "/dnszones/example.com"), }, @@ -290,7 +291,7 @@ func TestAzureRecord(t *testing.T) { } func TestAzureMultiRecord(t *testing.T) { - provider, err := newMockedAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", + provider, err := newMockedAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", "", &[]dns.Zone{ createMockZone("example.com", "/dnszones/example.com"), }, @@ -392,6 +393,7 @@ func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsC NewZoneIDFilter([]string{""}), dryRun, "group", + "", &zonesClient, client, ) From 14c391ba1f9df932c031fef29ba9e8131c0cc2f8 Mon Sep 17 00:00:00 2001 From: Tongyao Si Date: Thu, 28 Nov 2019 19:16:03 +0800 Subject: [PATCH 64/79] fix: typo --- provider/azure_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/azure_test.go b/provider/azure_test.go index ebc29cd109..878880af02 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -238,7 +238,7 @@ func newMockedAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter return newAzureProvider(domainFilter, zoneIDFilter, dryRun, resourceGroup, userAssignedIdentityClientID, &zonesClient, &recordSetsClient), nil } -func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, zonesClient ZonesClient, recordsClient RecordsClient) *AzureProvider { +func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, zonesClient ZonesClient, recordsClient RecordSetsClient) *AzureProvider { return &AzureProvider{ domainFilter: domainFilter, zoneIDFilter: zoneIDFilter, From 97acc4f3391f6b203cea4a66b4333b5691052b28 Mon Sep 17 00:00:00 2001 From: Tongyao Si Date: Thu, 28 Nov 2019 19:58:01 +0800 Subject: [PATCH 65/79] fix: lint --- provider/azure.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/provider/azure.go b/provider/azure.go index c1cfe735d1..d3a1638027 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -164,14 +164,14 @@ func getAccessToken(cfg config, environment azure.Environment) (*adal.ServicePri return nil, fmt.Errorf("failed to create the managed service identity token: %v", err) } return token, nil - } else { - log.Info("Resolving to system assigned identity.") - token, err := adal.NewServicePrincipalTokenFromMSI(msiEndpoint, environment.ServiceManagementEndpoint) - if err != nil { - return nil, fmt.Errorf("failed to create the managed service identity token: %v", err) - } - return token, nil } + + log.Info("Resolving to system assigned identity.") + token, err := adal.NewServicePrincipalTokenFromMSI(msiEndpoint, environment.ServiceManagementEndpoint) + if err != nil { + return nil, fmt.Errorf("failed to create the managed service identity token: %v", err) + } + return token, nil } return nil, fmt.Errorf("no credentials provided for Azure API") From d5709d04d6fd5e7b8a6f53e1d6521eee535f697f Mon Sep 17 00:00:00 2001 From: Martin Linkhorst Date: Mon, 2 Dec 2019 13:49:08 +0100 Subject: [PATCH 66/79] docs: add missing service account to spec --- docs/tutorials/dnsimple.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/tutorials/dnsimple.md b/docs/tutorials/dnsimple.md index 1d43e7ff82..80b038b642 100644 --- a/docs/tutorials/dnsimple.md +++ b/docs/tutorials/dnsimple.md @@ -94,6 +94,7 @@ spec: labels: app: external-dns spec: + serviceAccountName: external-dns containers: - name: external-dns image: registry.opensource.zalan.do/teapot/external-dns:latest From 3ab27bfc6bfa8e03eb06423742c934020236b1f5 Mon Sep 17 00:00:00 2001 From: Max Rosin Date: Tue, 3 Dec 2019 16:24:34 +0100 Subject: [PATCH 67/79] Add missing bracket in help output --- pkg/apis/externaldns/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 4bf5fece83..7caf6214c2 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -277,7 +277,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("contour-load-balancer", "The fully-qualified name of the Contour load balancer service. (default: heptio-contour/contour)").Default("heptio-contour/contour").StringVar(&cfg.ContourLoadBalancerService) // Flags related to processing sources - app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, istio-gateway, cloudfoundry, contour-ingressroute, crd, empty").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "istio-gateway", "cloudfoundry", "contour-ingressroute", "fake", "connector", "crd", "empty") + app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, istio-gateway, cloudfoundry, contour-ingressroute, crd, empty)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "istio-gateway", "cloudfoundry", "contour-ingressroute", "fake", "connector", "crd", "empty") app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate) From 26b32f3e4f49522844754ef5a940cc6538722466 Mon Sep 17 00:00:00 2001 From: Bryan Stenson Date: Fri, 6 Dec 2019 13:37:48 -0800 Subject: [PATCH 68/79] typo; remove extra space --- provider/aws.go | 2 +- provider/cloudflare.go | 2 +- provider/designate.go | 2 +- provider/digital_ocean.go | 2 +- provider/dnsimple.go | 2 +- provider/linode.go | 2 +- provider/ns1.go | 2 +- provider/rcode0.go | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/provider/aws.go b/provider/aws.go index c822e073de..b06ff3662a 100644 --- a/provider/aws.go +++ b/provider/aws.go @@ -662,7 +662,7 @@ func changesByZone(zones map[string]*route53.HostedZone, changeSet []*route53.Ch zones := suitableZones(hostname, zones) if len(zones) == 0 { - log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected ", c.String()) + log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected", c.String()) continue } for _, z := range zones { diff --git a/provider/cloudflare.go b/provider/cloudflare.go index 893c757272..7921949cd6 100644 --- a/provider/cloudflare.go +++ b/provider/cloudflare.go @@ -284,7 +284,7 @@ func (p *CloudFlareProvider) changesByZone(zones []cloudflare.Zone, changeSet [] for _, c := range changeSet { zoneID, _ := zoneNameIDMapper.FindZone(c.ResourceRecordSet[0].Name) if zoneID == "" { - log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected ", c.ResourceRecordSet[0].Name) + log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected", c.ResourceRecordSet[0].Name) continue } changes[zoneID] = append(changes[zoneID], c) diff --git a/provider/designate.go b/provider/designate.go index aa2ce31f6f..3ab6cb8bab 100644 --- a/provider/designate.go +++ b/provider/designate.go @@ -415,7 +415,7 @@ func (p designateProvider) upsertRecordSet(rs *recordSet, managedZones map[strin return err } if rs.zoneID == "" { - log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected ", rs.dnsName) + log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected", rs.dnsName) return nil } } diff --git a/provider/digital_ocean.go b/provider/digital_ocean.go index e6d5f65493..fb9849dd3b 100644 --- a/provider/digital_ocean.go +++ b/provider/digital_ocean.go @@ -323,7 +323,7 @@ func digitalOceanChangesByZone(zones []godo.Domain, changeSet []*DigitalOceanCha for _, c := range changeSet { zone, _ := zoneNameIDMapper.FindZone(c.ResourceRecordSet.Name) if zone == "" { - log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected ", c.ResourceRecordSet.Name) + log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected", c.ResourceRecordSet.Name) continue } changes[zone] = append(changes[zone], c) diff --git a/provider/dnsimple.go b/provider/dnsimple.go index 4d827d8cb7..74b7f6e117 100644 --- a/provider/dnsimple.go +++ b/provider/dnsimple.go @@ -235,7 +235,7 @@ func (p *dnsimpleProvider) submitChanges(changes []*dnsimpleChange) error { for _, change := range changes { zone := dnsimpleSuitableZone(change.ResourceRecordSet.Name, zones) if zone == nil { - log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected ", change.ResourceRecordSet.Name) + log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected", change.ResourceRecordSet.Name) continue } diff --git a/provider/linode.go b/provider/linode.go index 04f442c153..53c9760dc0 100644 --- a/provider/linode.go +++ b/provider/linode.go @@ -504,7 +504,7 @@ func endpointsByZone(zoneNameIDMapper zoneIDName, endpoints []*endpoint.Endpoint for _, ep := range endpoints { zoneID, _ := zoneNameIDMapper.FindZone(ep.DNSName) if zoneID == "" { - log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected ", ep.DNSName) + log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected", ep.DNSName) continue } endpointsByZone[zoneID] = append(endpointsByZone[zoneID], ep) diff --git a/provider/ns1.go b/provider/ns1.go index 4540059235..924c13301d 100644 --- a/provider/ns1.go +++ b/provider/ns1.go @@ -309,7 +309,7 @@ func ns1ChangesByZone(zones []*dns.Zone, changeSets []*ns1Change) map[string][]* for _, c := range changeSets { zone, _ := zoneNameIDMapper.FindZone(c.Endpoint.DNSName) if zone == "" { - log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected ", c.Endpoint.DNSName) + log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected", c.Endpoint.DNSName) continue } changes[zone] = append(changes[zone], c) diff --git a/provider/rcode0.go b/provider/rcode0.go index 5827b82ac3..f37c870985 100644 --- a/provider/rcode0.go +++ b/provider/rcode0.go @@ -166,7 +166,7 @@ func rcodezeroChangesByZone(zones []*rc0.Zone, changeSet []*rc0.RRSetChange) map for _, c := range changeSet { zone, _ := zoneNameIDMapper.FindZone(c.Name) if zone == "" { - log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected ", c.Name) + log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected", c.Name) continue } changes[zone] = append(changes[zone], c) From 48ed325c56cd4c92114c2e605fc1f9929e7e84c9 Mon Sep 17 00:00:00 2001 From: saidst Date: Thu, 12 Dec 2019 11:37:19 +0100 Subject: [PATCH 69/79] added details for configuring nginx-ingress-controller in azure private dns tutorial. --- docs/tutorials/azure-private-dns.md | 49 ++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/docs/tutorials/azure-private-dns.md b/docs/tutorials/azure-private-dns.md index 5e7bf917d1..58d930fdfe 100644 --- a/docs/tutorials/azure-private-dns.md +++ b/docs/tutorials/azure-private-dns.md @@ -1,20 +1,48 @@ - # Set up ExternalDNS for Azure Private DNS -This tutorial describes how to setup ExternalDNS for managing records in Azure Private DNS. -It assumes to deploy ExternalDNS as a container Kubernetes. - +This tutorial describes how to set up ExternalDNS for managing records in Azure Private DNS. It comprises of the following steps: -1) Provision Azure Private DNS -2) Configure service principal for managing the zone -3) Deploy ExternalDNS +1) Install NGINX Ingress Controller +2) Provision Azure Private DNS +3) Configure service principal for managing the zone +4) Deploy ExternalDNS + +Everything will be deployed on Kubernetes. +Therefore, please see the subsequent prerequisites. ## Prerequisites -- Azure Kubernetes Service available -- nginx-ingress-controller incl. `--publish-service=namespace/nginx-ingress-controller-svcname` available +- Azure Kubernetes Service is deployed and ready - [Azure CLI 2.0](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and `kubectl` installed on the box to execute the subsequent steps +## Install NGINX Ingress Controller + +Helm is used to deploy the ingress controller. + +We employ the popular chart [stable/nginx-ingress](https://github.com/helm/charts/tree/master/stable/nginx-ingress). + +``` +helm install stable/nginx-ingress \ + --name nginx-ingress \ + --set controller.publishService.enabled=true +``` + +The parameter `controller.publishService.enabled` needs to be set to `true.` + +It will make the ingress controller update the endpoint records of ingress-resources to contain the external-ip of the loadbalancer serving the ingress-controller. +This is crucial as ExternalDNS reads those endpoints records when creating DNS-Records from ingress-resources. +In the subsequent parameter we will make use of this. If you don't want to work with ingress-resources in your later use, you can leave the parameter out. + +If you do not want to deploy the ingress controller with Helm, ensure to pass the following cmdline-flags to it through the mechanism of your choice: + +``` +flags: +--publish-service=/ +--update-status=true (default-value) + +example: +./nginx-ingress-controller --publish-service=default/nginx-ingress-controller +``` ## Provision Azure Private DNS @@ -106,8 +134,7 @@ Azure-CLI features functionality for automatically maintaining this file for AKS Then apply one of the following manifests depending on whether you use RBAC or not. -The credentials of the service principal are provided to ExternalDNS as environment-variables. -At the end of this section, we additionally describe how to provide them as a _file_. +The credentials of the service principal are provided to ExternalDNS as environment-variables. ### Manifest (for clusters without RBAC enabled) ```yaml From 7706910fe0d5668891bcaf6860e8458cd65ca23e Mon Sep 17 00:00:00 2001 From: Andrew Hemming Date: Mon, 16 Dec 2019 09:00:17 +0000 Subject: [PATCH 70/79] Corrected typo in readme --- docs/tutorials/designate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/designate.md b/docs/tutorials/designate.md index 5ffe560c64..8203455167 100644 --- a/docs/tutorials/designate.md +++ b/docs/tutorials/designate.md @@ -76,7 +76,7 @@ spec: value: Default ``` -### Manifest (for clusters without RBAC enabled) +### Manifest (for clusters with RBAC enabled) ```yaml apiVersion: v1 From 4ebf88d5786668bee0ca53af36d6edd045fbf474 Mon Sep 17 00:00:00 2001 From: njuettner Date: Tue, 17 Dec 2019 14:46:41 +0100 Subject: [PATCH 71/79] Enable image publishing --- Makefile | 12 +++++++++++- cloudbuild.yaml | 14 ++++++++++++++ delivery.yaml | 23 ----------------------- 3 files changed, 25 insertions(+), 24 deletions(-) create mode 100644 cloudbuild.yaml delete mode 100644 delivery.yaml diff --git a/Makefile b/Makefile index 48db48cad8..04dbf243a8 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,8 @@ test: BINARY ?= external-dns SOURCES = $(shell find . -name '*.go') -IMAGE ?= registry.opensource.zalan.do/teapot/$(BINARY) +IMAGE_STAGING = gcr.io/k8s-staging-external-dns/$(BINARY) +IMAGE ?= us.gcr.io/k8s-artifacts-prod/external-dns/$(BINARY) VERSION ?= $(shell git describe --tags --always --dirty) BUILD_FLAGS ?= -v LDFLAGS ?= -X github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns.Version=$(VERSION) -w -s @@ -66,3 +67,12 @@ build.mini: clean: @rm -rf build + + # Builds and push container images to the staging bucket. +.PHONY: release.staging + +release.staging: + IMAGE=$(IMAGE_STAGING) $(MAKE) build.docker build.push + +release.prod: + $(MAKE) build.docker build.push \ No newline at end of file diff --git a/cloudbuild.yaml b/cloudbuild.yaml new file mode 100644 index 0000000000..9b5d134b5e --- /dev/null +++ b/cloudbuild.yaml @@ -0,0 +1,14 @@ +# See https://cloud.google.com/cloud-build/docs/build-config +timeout: 1200s +steps: + - name: "gcr.io/k8s-testimages/gcb-docker-gcloud:v20190906-745fed4" + entrypoint: make + env: + - DOCKER_CLI_EXPERIMENTAL=enabled + - TAG=$_GIT_TAG + args: + - release.staging +substitutions: + # _GIT_TAG will be filled with a git-based tag for the image, of the form vYYYYMMDD-hash, and + # can be used as a substitution + _GIT_TAG: "12345" diff --git a/delivery.yaml b/delivery.yaml deleted file mode 100644 index 6df6938cdd..0000000000 --- a/delivery.yaml +++ /dev/null @@ -1,23 +0,0 @@ -version: "2017-09-20" -pipeline: -- id: build - overlay: ci/golang - cache: - paths: - - /go/pkg/mod # pkg cache for Go modules - - ~/.cache/go-build # Go build cache - type: script - commands: - - desc: build - cmd: | - make build.docker - - desc: push - cmd: | - if [[ $CDP_TARGET_BRANCH == master && ! $CDP_PULL_REQUEST_NUMBER ]]; then - IMAGE=registry-write.opensource.zalan.do/teapot/external-dns - VERSION=$(git describe --tags --always --dirty) - else - IMAGE=registry-write.opensource.zalan.do/teapot/external-dns-test - VERSION=$CDP_BUILD_VERSION - fi - IMAGE=$IMAGE VERSION=$VERSION make build.push From c66576112baaa83d699a1d75144ad4bd9b698919 Mon Sep 17 00:00:00 2001 From: saidst Date: Tue, 17 Dec 2019 19:43:38 +0100 Subject: [PATCH 72/79] added example for simple check of correct ingress-controller configuration. --- docs/tutorials/azure-private-dns.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/azure-private-dns.md b/docs/tutorials/azure-private-dns.md index 58d930fdfe..9f191ef3ea 100644 --- a/docs/tutorials/azure-private-dns.md +++ b/docs/tutorials/azure-private-dns.md @@ -22,7 +22,7 @@ Helm is used to deploy the ingress controller. We employ the popular chart [stable/nginx-ingress](https://github.com/helm/charts/tree/master/stable/nginx-ingress). ``` -helm install stable/nginx-ingress \ +$ helm install stable/nginx-ingress \ --name nginx-ingress \ --set controller.publishService.enabled=true ``` @@ -33,6 +33,18 @@ It will make the ingress controller update the endpoint records of ingress-resou This is crucial as ExternalDNS reads those endpoints records when creating DNS-Records from ingress-resources. In the subsequent parameter we will make use of this. If you don't want to work with ingress-resources in your later use, you can leave the parameter out. +Verify the correct propagation of the loadbalancer's ip by listing the ingresses. +``` +$ kubectl get ingress +``` +The address column should contain the ip for each ingress. ExternalDNS will pick up exactly this piece of information. +``` +NAME HOSTS ADDRESS PORTS AGE +nginx1 sample1.aks.com 52.167.195.110 80 6d22h +nginx2 sample2.aks.com 52.167.195.110 80 6d21h +``` + + If you do not want to deploy the ingress controller with Helm, ensure to pass the following cmdline-flags to it through the mechanism of your choice: ``` From a567ac58d808b881e146305b4ededaea347ec528 Mon Sep 17 00:00:00 2001 From: saidst Date: Fri, 20 Dec 2019 09:00:38 +0100 Subject: [PATCH 73/79] changed intending. --- docs/tutorials/azure-private-dns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/azure-private-dns.md b/docs/tutorials/azure-private-dns.md index 9f191ef3ea..63999a3802 100644 --- a/docs/tutorials/azure-private-dns.md +++ b/docs/tutorials/azure-private-dns.md @@ -3,7 +3,7 @@ This tutorial describes how to set up ExternalDNS for managing records in Azure Private DNS. It comprises of the following steps: -1) Install NGINX Ingress Controller +1) Install NGINX Ingress Controller 2) Provision Azure Private DNS 3) Configure service principal for managing the zone 4) Deploy ExternalDNS From 9aee917964250dc61be8d34087d8601a2d784e0d Mon Sep 17 00:00:00 2001 From: fcarletti Date: Tue, 20 Aug 2019 12:41:48 -0500 Subject: [PATCH 74/79] fix: use ingress gateway service as target instead of hard-coded ones --- docs/tutorials/istio.md | 2 - pkg/apis/externaldns/types.go | 3 - pkg/apis/externaldns/types_test.go | 351 +++++++++++------------------ source/gateway.go | 113 ++++++---- source/gateway_test.go | 32 ++- source/store.go | 2 +- 6 files changed, 218 insertions(+), 285 deletions(-) diff --git a/docs/tutorials/istio.md b/docs/tutorials/istio.md index 269c10bcb3..4ccb09ae56 100644 --- a/docs/tutorials/istio.md +++ b/docs/tutorials/istio.md @@ -25,7 +25,6 @@ spec: - --source=service - --source=ingress - --source=istio-gateway - - --istio-ingress-gateway=custom-istio-namespace/custom-istio-ingressgateway # load balancer service to be used; can be specified multiple times. Omit to use the default (istio-system/istio-ingressgateway) - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones - --provider=aws - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization @@ -95,7 +94,6 @@ spec: - --source=service - --source=ingress - --source=istio-gateway - - --istio-ingress-gateway=custom-istio-namespace/custom-istio-ingressgateway # load balancer service to be used; can be specified multiple times. Omit to use the default (istio-system/istio-ingressgateway) - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones - --provider=aws - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 7caf6214c2..bc9953bd98 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -265,9 +265,6 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("kubeconfig", "Retrieve target cluster configuration from a Kubernetes configuration file (default: auto-detect)").Default(defaultConfig.KubeConfig).StringVar(&cfg.KubeConfig) app.Flag("request-timeout", "Request timeout when calling Kubernetes APIs. 0s means no timeout").Default(defaultConfig.RequestTimeout.String()).DurationVar(&cfg.RequestTimeout) - // Flags related to Istio - app.Flag("istio-ingress-gateway", "The fully-qualified name of the Istio ingress gateway service. Flag can be specified multiple times (default: istio-system/istio-ingressgateway)").Default("istio-system/istio-ingressgateway").StringsVar(&cfg.IstioIngressGatewayServices) - // Flags related to cloud foundry app.Flag("cf-api-endpoint", "The fully-qualified domain name of the cloud foundry instance you are targeting").Default(defaultConfig.CFAPIEndpoint).StringVar(&cfg.CFAPIEndpoint) app.Flag("cf-username", "The username to log into the cloud foundry API").Default(defaultConfig.CFUsername).StringVar(&cfg.CFUsername) diff --git a/pkg/apis/externaldns/types_test.go b/pkg/apis/externaldns/types_test.go index 80c68af235..278df11dea 100644 --- a/pkg/apis/externaldns/types_test.go +++ b/pkg/apis/externaldns/types_test.go @@ -29,206 +29,140 @@ import ( var ( minimalConfig = &Config{ - Master: "", - KubeConfig: "", - RequestTimeout: time.Second * 30, - IstioIngressGatewayServices: []string{"istio-system/istio-ingressgateway"}, - ContourLoadBalancerService: "heptio-contour/contour", - Sources: []string{"service"}, - Namespace: "", - FQDNTemplate: "", - Compatibility: "", - Provider: "google", - GoogleProject: "", - GoogleBatchChangeSize: 1000, - GoogleBatchChangeInterval: time.Second, - DomainFilter: []string{""}, - ExcludeDomains: []string{""}, - ZoneIDFilter: []string{""}, - AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json", - AWSZoneType: "", - AWSZoneTagFilter: []string{""}, - AWSAssumeRole: "", - AWSBatchChangeSize: 1000, - AWSBatchChangeInterval: time.Second, - AWSEvaluateTargetHealth: true, - AWSAPIRetries: 3, - AWSPreferCNAME: false, - AzureConfigFile: "/etc/kubernetes/azure.json", - AzureResourceGroup: "", - AzureSubscriptionID: "", - CloudflareProxied: false, - CloudflareZonesPerPage: 50, - CoreDNSPrefix: "/skydns/", - InfobloxGridHost: "", - InfobloxWapiPort: 443, - InfobloxWapiUsername: "admin", - InfobloxWapiPassword: "", - InfobloxWapiVersion: "2.3.1", - InfobloxView: "", - InfobloxSSLVerify: true, - InfobloxMaxResults: 0, - OCIConfigFile: "/etc/kubernetes/oci.yaml", - InMemoryZones: []string{""}, - PDNSServer: "http://localhost:8081", - PDNSAPIKey: "", - Policy: "sync", - Registry: "txt", - TXTOwnerID: "default", - TXTPrefix: "", - TXTCacheInterval: 0, - Interval: time.Minute, - Once: false, - DryRun: false, - LogFormat: "text", - MetricsAddress: ":7979", - LogLevel: logrus.InfoLevel.String(), - ConnectorSourceServer: "localhost:8080", - ExoscaleEndpoint: "https://api.exoscale.ch/dns", - ExoscaleAPIKey: "", - ExoscaleAPISecret: "", - CRDSourceAPIVersion: "externaldns.k8s.io/v1alpha1", - CRDSourceKind: "DNSEndpoint", - RcodezeroTXTEncrypt: false, - TransIPAccountName: "", - TransIPPrivateKeyFile: "", + Master: "", + KubeConfig: "", + RequestTimeout: time.Second * 30, + ContourLoadBalancerService: "heptio-contour/contour", + Sources: []string{"service"}, + Namespace: "", + FQDNTemplate: "", + Compatibility: "", + Provider: "google", + GoogleProject: "", + GoogleBatchChangeSize: 1000, + GoogleBatchChangeInterval: time.Second, + DomainFilter: []string{""}, + ExcludeDomains: []string{""}, + ZoneIDFilter: []string{""}, + AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json", + AWSZoneType: "", + AWSZoneTagFilter: []string{""}, + AWSAssumeRole: "", + AWSBatchChangeSize: 1000, + AWSBatchChangeInterval: time.Second, + AWSEvaluateTargetHealth: true, + AWSAPIRetries: 3, + AWSPreferCNAME: false, + AzureConfigFile: "/etc/kubernetes/azure.json", + AzureResourceGroup: "", + AzureSubscriptionID: "", + CloudflareProxied: false, + CloudflareZonesPerPage: 50, + CoreDNSPrefix: "/skydns/", + InfobloxGridHost: "", + InfobloxWapiPort: 443, + InfobloxWapiUsername: "admin", + InfobloxWapiPassword: "", + InfobloxWapiVersion: "2.3.1", + InfobloxView: "", + InfobloxSSLVerify: true, + InfobloxMaxResults: 0, + OCIConfigFile: "/etc/kubernetes/oci.yaml", + InMemoryZones: []string{""}, + PDNSServer: "http://localhost:8081", + PDNSAPIKey: "", + Policy: "sync", + Registry: "txt", + TXTOwnerID: "default", + TXTPrefix: "", + TXTCacheInterval: 0, + Interval: time.Minute, + Once: false, + DryRun: false, + LogFormat: "text", + MetricsAddress: ":7979", + LogLevel: logrus.InfoLevel.String(), + ConnectorSourceServer: "localhost:8080", + ExoscaleEndpoint: "https://api.exoscale.ch/dns", + ExoscaleAPIKey: "", + ExoscaleAPISecret: "", + CRDSourceAPIVersion: "externaldns.k8s.io/v1alpha1", + CRDSourceKind: "DNSEndpoint", + RcodezeroTXTEncrypt: false, + TransIPAccountName: "", + TransIPPrivateKeyFile: "", } overriddenConfig = &Config{ - Master: "http://127.0.0.1:8080", - KubeConfig: "/some/path", - RequestTimeout: time.Second * 77, - IstioIngressGatewayServices: []string{"istio-other/istio-otheringressgateway"}, - ContourLoadBalancerService: "heptio-contour-other/contour-other", - Sources: []string{"service", "ingress", "connector"}, - Namespace: "namespace", - IgnoreHostnameAnnotation: true, - FQDNTemplate: "{{.Name}}.service.example.com", - Compatibility: "mate", - Provider: "google", - GoogleProject: "project", - GoogleBatchChangeSize: 100, - GoogleBatchChangeInterval: time.Second * 2, - DomainFilter: []string{"example.org", "company.com"}, - ExcludeDomains: []string{"xapi.example.org", "xapi.company.com"}, - ZoneIDFilter: []string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"}, - AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json", - AWSZoneType: "private", - AWSZoneTagFilter: []string{"tag=foo"}, - AWSAssumeRole: "some-other-role", - AWSBatchChangeSize: 100, - AWSBatchChangeInterval: time.Second * 2, - AWSEvaluateTargetHealth: false, - AWSAPIRetries: 13, - AWSPreferCNAME: true, - AzureConfigFile: "azure.json", - AzureResourceGroup: "arg", - AzureSubscriptionID: "arg", - CloudflareProxied: true, - CloudflareZonesPerPage: 20, - CoreDNSPrefix: "/coredns/", - InfobloxGridHost: "127.0.0.1", - InfobloxWapiPort: 8443, - InfobloxWapiUsername: "infoblox", - InfobloxWapiPassword: "infoblox", - InfobloxWapiVersion: "2.6.1", - InfobloxView: "internal", - InfobloxSSLVerify: false, - InfobloxMaxResults: 2000, - OCIConfigFile: "oci.yaml", - InMemoryZones: []string{"example.org", "company.com"}, - PDNSServer: "http://ns.example.com:8081", - PDNSAPIKey: "some-secret-key", - PDNSTLSEnabled: true, - TLSCA: "/path/to/ca.crt", - TLSClientCert: "/path/to/cert.pem", - TLSClientCertKey: "/path/to/key.pem", - Policy: "upsert-only", - Registry: "noop", - TXTOwnerID: "owner-1", - TXTPrefix: "associated-txt-record", - TXTCacheInterval: 12 * time.Hour, - Interval: 10 * time.Minute, - Once: true, - DryRun: true, - LogFormat: "json", - MetricsAddress: "127.0.0.1:9099", - LogLevel: logrus.DebugLevel.String(), - ConnectorSourceServer: "localhost:8081", - ExoscaleEndpoint: "https://api.foo.ch/dns", - ExoscaleAPIKey: "1", - ExoscaleAPISecret: "2", - CRDSourceAPIVersion: "test.k8s.io/v1alpha1", - CRDSourceKind: "Endpoint", - RcodezeroTXTEncrypt: true, - NS1Endpoint: "https://api.example.com/v1", - NS1IgnoreSSL: true, - TransIPAccountName: "transip", - TransIPPrivateKeyFile: "/path/to/transip.key", - } - - // minimal config with istio gateway source and multiple ingressgateway load balancer services - multipleIstioIngressGatewaysConfig = &Config{ - Master: "", - KubeConfig: "", - RequestTimeout: time.Second * 30, - IstioIngressGatewayServices: []string{"istio-system/istio-ingressgateway", "istio-other/istio-otheringressgateway"}, - Sources: []string{"istio-gateway"}, - ContourLoadBalancerService: "heptio-contour/contour", - Namespace: "", - FQDNTemplate: "", - Compatibility: "", - Provider: "google", - GoogleProject: "", - GoogleBatchChangeSize: 1000, - GoogleBatchChangeInterval: time.Second, - DomainFilter: []string{""}, - ExcludeDomains: []string{""}, - ZoneIDFilter: []string{""}, - AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json", - AWSZoneType: "", - AWSZoneTagFilter: []string{""}, - AWSAssumeRole: "", - AWSBatchChangeSize: 1000, - AWSBatchChangeInterval: time.Second, - AWSEvaluateTargetHealth: true, - AWSAPIRetries: 3, - AWSPreferCNAME: false, - AzureConfigFile: "/etc/kubernetes/azure.json", - AzureResourceGroup: "", - AzureSubscriptionID: "", - CloudflareProxied: false, - CloudflareZonesPerPage: 50, - CoreDNSPrefix: "/skydns/", - InfobloxGridHost: "", - InfobloxWapiPort: 443, - InfobloxWapiUsername: "admin", - InfobloxWapiPassword: "", - InfobloxWapiVersion: "2.3.1", - InfobloxView: "", - InfobloxSSLVerify: true, - OCIConfigFile: "/etc/kubernetes/oci.yaml", - InMemoryZones: []string{""}, - PDNSServer: "http://localhost:8081", - PDNSAPIKey: "", - Policy: "sync", - Registry: "txt", - TXTOwnerID: "default", - TXTPrefix: "", - TXTCacheInterval: 0, - Interval: time.Minute, - Once: false, - DryRun: false, - LogFormat: "text", - MetricsAddress: ":7979", - LogLevel: logrus.InfoLevel.String(), - ConnectorSourceServer: "localhost:8080", - ExoscaleEndpoint: "https://api.exoscale.ch/dns", - ExoscaleAPIKey: "", - ExoscaleAPISecret: "", - CRDSourceAPIVersion: "externaldns.k8s.io/v1alpha1", - CRDSourceKind: "DNSEndpoint", - RcodezeroTXTEncrypt: false, + Master: "http://127.0.0.1:8080", + KubeConfig: "/some/path", + RequestTimeout: time.Second * 77, + ContourLoadBalancerService: "heptio-contour-other/contour-other", + Sources: []string{"service", "ingress", "connector"}, + Namespace: "namespace", + IgnoreHostnameAnnotation: true, + FQDNTemplate: "{{.Name}}.service.example.com", + Compatibility: "mate", + Provider: "google", + GoogleProject: "project", + GoogleBatchChangeSize: 100, + GoogleBatchChangeInterval: time.Second * 2, + DomainFilter: []string{"example.org", "company.com"}, + ExcludeDomains: []string{"xapi.example.org", "xapi.company.com"}, + ZoneIDFilter: []string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"}, + AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json", + AWSZoneType: "private", + AWSZoneTagFilter: []string{"tag=foo"}, + AWSAssumeRole: "some-other-role", + AWSBatchChangeSize: 100, + AWSBatchChangeInterval: time.Second * 2, + AWSEvaluateTargetHealth: false, + AWSAPIRetries: 13, + AWSPreferCNAME: true, + AzureConfigFile: "azure.json", + AzureResourceGroup: "arg", + AzureSubscriptionID: "arg", + CloudflareProxied: true, + CloudflareZonesPerPage: 20, + CoreDNSPrefix: "/coredns/", + InfobloxGridHost: "127.0.0.1", + InfobloxWapiPort: 8443, + InfobloxWapiUsername: "infoblox", + InfobloxWapiPassword: "infoblox", + InfobloxWapiVersion: "2.6.1", + InfobloxView: "internal", + InfobloxSSLVerify: false, + InfobloxMaxResults: 2000, + OCIConfigFile: "oci.yaml", + InMemoryZones: []string{"example.org", "company.com"}, + PDNSServer: "http://ns.example.com:8081", + PDNSAPIKey: "some-secret-key", + PDNSTLSEnabled: true, + TLSCA: "/path/to/ca.crt", + TLSClientCert: "/path/to/cert.pem", + TLSClientCertKey: "/path/to/key.pem", + Policy: "upsert-only", + Registry: "noop", + TXTOwnerID: "owner-1", + TXTPrefix: "associated-txt-record", + TXTCacheInterval: 12 * time.Hour, + Interval: 10 * time.Minute, + Once: true, + DryRun: true, + LogFormat: "json", + MetricsAddress: "127.0.0.1:9099", + LogLevel: logrus.DebugLevel.String(), + ConnectorSourceServer: "localhost:8081", + ExoscaleEndpoint: "https://api.foo.ch/dns", + ExoscaleAPIKey: "1", + ExoscaleAPISecret: "2", + CRDSourceAPIVersion: "test.k8s.io/v1alpha1", + CRDSourceKind: "Endpoint", + RcodezeroTXTEncrypt: true, + NS1Endpoint: "https://api.example.com/v1", + NS1IgnoreSSL: true, + TransIPAccountName: "transip", + TransIPPrivateKeyFile: "/path/to/transip.key", } ) @@ -254,7 +188,6 @@ func TestParseFlags(t *testing.T) { "--master=http://127.0.0.1:8080", "--kubeconfig=/some/path", "--request-timeout=77s", - "--istio-ingress-gateway=istio-other/istio-otheringressgateway", "--contour-load-balancer=heptio-contour-other/contour-other", "--source=service", "--source=ingress", @@ -337,7 +270,6 @@ func TestParseFlags(t *testing.T) { "EXTERNAL_DNS_MASTER": "http://127.0.0.1:8080", "EXTERNAL_DNS_KUBECONFIG": "/some/path", "EXTERNAL_DNS_REQUEST_TIMEOUT": "77s", - "EXTERNAL_DNS_ISTIO_INGRESS_GATEWAY": "istio-other/istio-otheringressgateway", "EXTERNAL_DNS_CONTOUR_LOAD_BALANCER": "heptio-contour-other/contour-other", "EXTERNAL_DNS_SOURCE": "service\ningress\nconnector", "EXTERNAL_DNS_NAMESPACE": "namespace", @@ -407,27 +339,6 @@ func TestParseFlags(t *testing.T) { }, expected: overriddenConfig, }, - { - title: "istio config with 2 ingressgateways", - args: []string{ - "--provider=google", - "--source=istio-gateway", - "--istio-ingress-gateway=istio-system/istio-ingressgateway", - "--istio-ingress-gateway=istio-other/istio-otheringressgateway", - }, - envVars: map[string]string{}, - expected: multipleIstioIngressGatewaysConfig, - }, - { - title: "override everything via environment variables with multiple istio ingress gateway load balancer services", - args: []string{}, - envVars: map[string]string{ - "EXTERNAL_DNS_PROVIDER": "google", - "EXTERNAL_DNS_SOURCE": "istio-gateway", - "EXTERNAL_DNS_ISTIO_INGRESS_GATEWAY": "istio-system/istio-ingressgateway\nistio-other/istio-otheringressgateway", - }, - expected: multipleIstioIngressGatewaysConfig, - }, } { t.Run(ti.title, func(t *testing.T) { originalEnv := setEnv(t, ti.envVars) diff --git a/source/gateway.go b/source/gateway.go index 17071be33c..50e77253b6 100644 --- a/source/gateway.go +++ b/source/gateway.go @@ -22,6 +22,11 @@ import ( "sort" "strings" "text/template" + "time" + + kubeinformers "k8s.io/client-go/informers" + coreinformers "k8s.io/client-go/informers/core/v1" + "k8s.io/client-go/tools/cache" log "github.com/sirupsen/logrus" @@ -29,6 +34,7 @@ import ( istiomodel "istio.io/istio/pilot/pkg/model" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" "github.com/kubernetes-sigs/external-dns/endpoint" "k8s.io/client-go/kubernetes" @@ -38,21 +44,20 @@ import ( // The gateway implementation uses the spec.servers.hosts values for the hostnames. // Use targetAnnotationKey to explicitly set Endpoint. type gatewaySource struct { - kubeClient kubernetes.Interface - istioClient istiomodel.ConfigStore - istioIngressGatewayServices []string - namespace string - annotationFilter string - fqdnTemplate *template.Template - combineFQDNAnnotation bool - ignoreHostnameAnnotation bool + kubeClient kubernetes.Interface + istioClient istiomodel.ConfigStore + namespace string + annotationFilter string + fqdnTemplate *template.Template + combineFQDNAnnotation bool + ignoreHostnameAnnotation bool + serviceInformer coreinformers.ServiceInformer } // NewIstioGatewaySource creates a new gatewaySource with the given config. func NewIstioGatewaySource( kubeClient kubernetes.Interface, istioClient istiomodel.ConfigStore, - istioIngressGatewayServices []string, namespace string, annotationFilter string, fqdnTemplate string, @@ -63,11 +68,6 @@ func NewIstioGatewaySource( tmpl *template.Template err error ) - for _, lbService := range istioIngressGatewayServices { - if _, _, err = parseIngressGateway(lbService); err != nil { - return nil, err - } - } if fqdnTemplate != "" { tmpl, err = template.New("endpoint").Funcs(template.FuncMap{ @@ -78,15 +78,40 @@ func NewIstioGatewaySource( } } + // Use shared informers to listen for add/update/delete of services/pods/nodes in the specified namespace. + // Set resync period to 0, to prevent processing when nothing has changed + informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0, kubeinformers.WithNamespace(namespace)) + serviceInformer := informerFactory.Core().V1().Services() + + // Add default resource event handlers to properly initialize informer. + serviceInformer.Informer().AddEventHandler( + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + log.Debug("service added") + }, + }, + ) + + // TODO informer is not explicitly stopped since controller is not passing in its channel. + informerFactory.Start(wait.NeverStop) + + // wait for the local cache to be populated. + err = wait.Poll(time.Second, 60*time.Second, func() (bool, error) { + return serviceInformer.Informer().HasSynced() == true, nil + }) + if err != nil { + return nil, fmt.Errorf("failed to sync cache: %v", err) + } + return &gatewaySource{ - kubeClient: kubeClient, - istioClient: istioClient, - istioIngressGatewayServices: istioIngressGatewayServices, - namespace: namespace, - annotationFilter: annotationFilter, - fqdnTemplate: tmpl, - combineFQDNAnnotation: combineFqdnAnnotation, - ignoreHostnameAnnotation: ignoreHostnameAnnotation, + kubeClient: kubeClient, + istioClient: istioClient, + namespace: namespace, + annotationFilter: annotationFilter, + fqdnTemplate: tmpl, + combineFQDNAnnotation: combineFqdnAnnotation, + ignoreHostnameAnnotation: ignoreHostnameAnnotation, + serviceInformer: serviceInformer, }, nil } @@ -168,7 +193,7 @@ func (sc *gatewaySource) endpointsFromTemplate(config *istiomodel.Config) ([]*en targets := getTargetsFromTargetAnnotation(config.Annotations) if len(targets) == 0 { - targets, err = sc.targetsFromIstioIngressGatewayServices() + targets, err = sc.targetsFromGatewayConfig(config) if err != nil { return nil, err } @@ -223,22 +248,30 @@ func (sc *gatewaySource) setResourceLabel(config istiomodel.Config, endpoints [] } } -func (sc *gatewaySource) targetsFromIstioIngressGatewayServices() (targets endpoint.Targets, err error) { - for _, lbService := range sc.istioIngressGatewayServices { - lbNamespace, lbName, err := parseIngressGateway(lbService) - if err != nil { - return nil, err - } - if svc, err := sc.kubeClient.CoreV1().Services(lbNamespace).Get(lbName, metav1.GetOptions{}); err != nil { - log.Warn(err) - } else { - for _, lb := range svc.Status.LoadBalancer.Ingress { - if lb.IP != "" { - targets = append(targets, lb.IP) - } - if lb.Hostname != "" { - targets = append(targets, lb.Hostname) - } +func (sc *gatewaySource) targetsFromGatewayConfig(config *istiomodel.Config) (targets endpoint.Targets, err error) { + gateway := config.Spec.(*istionetworking.Gateway) + labelSelector, err := metav1.ParseToLabelSelector(labels.Set(gateway.Selector).String()) + if err != nil { + return nil, err + } + selector, err := metav1.LabelSelectorAsSelector(labelSelector) + if err != nil { + return nil, err + } + + services, err := sc.serviceInformer.Lister().Services(sc.namespace).List(selector) + if err != nil { + log.Error(err) + return + } + + for _, service := range services { + for _, lb := range service.Status.LoadBalancer.Ingress { + if lb.IP != "" { + targets = append(targets, lb.IP) + } + if lb.Hostname != "" { + targets = append(targets, lb.Hostname) } } } @@ -258,7 +291,7 @@ func (sc *gatewaySource) endpointsFromGatewayConfig(config istiomodel.Config) ([ targets := getTargetsFromTargetAnnotation(config.Annotations) if len(targets) == 0 { - targets, err = sc.targetsFromIstioIngressGatewayServices() + targets, err = sc.targetsFromGatewayConfig(&config) if err != nil { return nil, err } diff --git a/source/gateway_test.go b/source/gateway_test.go index 2544160bb3..00a26d271f 100644 --- a/source/gateway_test.go +++ b/source/gateway_test.go @@ -68,16 +68,15 @@ func (suite *GatewaySuite) SetupTest() { }).Service(), } - for _, loadBalancer := range suite.lbServices { - _, err = fakeKubernetesClient.CoreV1().Services(loadBalancer.Namespace).Create(loadBalancer) + for _, service := range suite.lbServices { + _, err = fakeKubernetesClient.CoreV1().Services(service.Namespace).Create(service) suite.NoError(err, "should succeed") } suite.source, err = NewIstioGatewaySource( fakeKubernetesClient, fakeIstioClient, - []string{"istio-system/istio-ingressgateway"}, - "default", + "", "", "{{.Name}}", false, @@ -150,7 +149,6 @@ func TestNewIstioGatewaySource(t *testing.T) { _, err := NewIstioGatewaySource( fake.NewSimpleClientset(), NewFakeConfigStore(), - []string{"istio-system/istio-ingressgateway"}, "", ti.annotationFilter, ti.fqdnTemplate, @@ -436,6 +434,7 @@ func testGatewayEndpoints(t *testing.T) { { ips: []string{"8.8.8.8"}, hostnames: []string{"lb.com"}, + namespace: "testing1", }, }, configItems: []fakeGatewayConfig{ @@ -1082,14 +1081,10 @@ func testGatewayEndpoints(t *testing.T) { fakeKubernetesClient := fake.NewSimpleClientset() - var fakeLoadBalancerList []string for _, lb := range ti.lbServices { - lbService := lb.Service() - _, err := fakeKubernetesClient.CoreV1().Services(lbService.Namespace).Create(lbService) - if err != nil { - require.NoError(t, err) - } - fakeLoadBalancerList = append(fakeLoadBalancerList, lbService.Namespace+"/"+lbService.Name) + service := lb.Service() + _, err := fakeKubernetesClient.CoreV1().Services(service.Namespace).Create(service) + require.NoError(t, err) } fakeIstioClient := NewFakeConfigStore() @@ -1101,7 +1096,6 @@ func testGatewayEndpoints(t *testing.T) { gatewaySource, err := NewIstioGatewaySource( fakeKubernetesClient, fakeIstioClient, - fakeLoadBalancerList, ti.targetNamespace, ti.annotationFilter, ti.fqdnTemplate, @@ -1127,21 +1121,18 @@ func newTestGatewaySource(loadBalancerList []fakeIngressGatewayService) (*gatewa fakeKubernetesClient := fake.NewSimpleClientset() fakeIstioClient := NewFakeConfigStore() - var lbList []string for _, lb := range loadBalancerList { - lbService := lb.Service() - _, err := fakeKubernetesClient.CoreV1().Services(lbService.Namespace).Create(lbService) + service := lb.Service() + _, err := fakeKubernetesClient.CoreV1().Services(service.Namespace).Create(service) if err != nil { return nil, err } - lbList = append(lbList, lbService.Namespace+"/"+lbService.Name) } src, err := NewIstioGatewaySource( fakeKubernetesClient, fakeIstioClient, - lbList, - "default", + "", "", "{{.Name}}", false, @@ -1198,6 +1189,7 @@ type fakeGatewayConfig struct { name string annotations map[string]string dnsnames [][]string + selector map[string]string } func (c fakeGatewayConfig) Config() istiomodel.Config { @@ -1211,6 +1203,8 @@ func (c fakeGatewayConfig) Config() istiomodel.Config { }) } + gw.Selector = c.selector + config := istiomodel.Config{ ConfigMeta: istiomodel.ConfigMeta{ Namespace: c.namespace, diff --git a/source/store.go b/source/store.go index e42ec5ba1b..eafa2a421b 100644 --- a/source/store.go +++ b/source/store.go @@ -181,7 +181,7 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err if err != nil { return nil, err } - return NewIstioGatewaySource(kubernetesClient, istioClient, cfg.IstioIngressGatewayServices, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation) + return NewIstioGatewaySource(kubernetesClient, istioClient, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation) case "cloudfoundry": cfClient, err := p.CloudFoundryClient(cfg.CFAPIEndpoint, cfg.CFUsername, cfg.CFPassword) if err != nil { From 95624432b771cafd1a93ffaaa9b4f32baacb5a12 Mon Sep 17 00:00:00 2001 From: Yury Tsarev Date: Fri, 27 Dec 2019 15:20:24 +0100 Subject: [PATCH 75/79] Update CRD source doc with RBAC, fix CRD manifest * Add RBAC piece of documentation * Remove `status:` to avoid validation failure Otherwise it fails with ``` $ kubectl apply -f crd-manifest.yaml error: error validating "crd-manifest.yaml": error validating data: ValidationError(CustomResourceDefinition.status): missing required field "storedVersions" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionStatus; ``` --- docs/contributing/crd-source.md | 12 ++++++++++++ docs/contributing/crd-source/crd-manifest.yaml | 5 ----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/contributing/crd-source.md b/docs/contributing/crd-source.md index e326d39356..7ff9c1252a 100644 --- a/docs/contributing/crd-source.md +++ b/docs/contributing/crd-source.md @@ -106,3 +106,15 @@ INFO[0000] Connected to cluster at https://192.168.99.100:8443 INFO[0000] CREATE: foo.bar.com 180 IN A 192.168.99.216 INFO[0000] CREATE: foo.bar.com 0 IN TXT "heritage=external-dns,external-dns/owner=default" ``` + +### RBAC configuration + +If you use RBAC, extend the `external-dns` ClusterRole with: +``` +- apiGroups: ["externaldns.k8s.io"] + resources: ["dnsendpoints"] + verbs: ["get","watch","list"] +- apiGroups: ["externaldns.k8s.io"] + resources: ["dnsendpoints/status"] + verbs: ["*"] +``` diff --git a/docs/contributing/crd-source/crd-manifest.yaml b/docs/contributing/crd-source/crd-manifest.yaml index 00b52f34c3..8429286900 100644 --- a/docs/contributing/crd-source/crd-manifest.yaml +++ b/docs/contributing/crd-source/crd-manifest.yaml @@ -60,8 +60,3 @@ spec: type: integer type: object version: v1alpha1 -status: - acceptedNames: - kind: "" - plural: "" - conditions: null From e7435721843e10b9f2cc30a4538b30654e0b429c Mon Sep 17 00:00:00 2001 From: Raffaele Di Fazio Date: Fri, 3 Jan 2020 21:20:49 +0100 Subject: [PATCH 76/79] Remove incubator references in README --- README.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/README.md b/README.md index 5be92cc9a2..81519c4be4 100644 --- a/README.md +++ b/README.md @@ -315,18 +315,6 @@ ExternalDNS is an effort to unify the following similar projects in order to bri * Zalando's [Mate](https://github.com/linki/mate) * Molecule Software's [route53-kubernetes](https://github.com/wearemolecule/route53-kubernetes) -## Kubernetes Incubator - -This is a [Kubernetes Incubator project](https://github.com/kubernetes/community/blob/master/incubator.md). -The project was established 2017-Feb-9 (initial announcement [here](https://groups.google.com/forum/#!searchin/kubernetes-dev/external$20dns%7Csort:relevance/kubernetes-dev/2wGQUB0fUuE/9OXz01i2BgAJ)). -The incubator team for the project is: - -* Sponsor: sig-network -* Champion: Tim Hockin (@thockin) -* SIG: sig-network - -For more information about sig-network, such as meeting times and agenda, check out the [community site](https://github.com/kubernetes/community/tree/master/sig-network). - ### Code of conduct Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). From 084ea67be0019b4b8662dc2059f9747548c6b86d Mon Sep 17 00:00:00 2001 From: David Grizzanti Date: Mon, 6 Jan 2020 09:14:45 -0500 Subject: [PATCH 77/79] Update vinyldns docs Make registry txt usage more clear --- docs/tutorials/vinyldns.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/vinyldns.md b/docs/tutorials/vinyldns.md index d8b6df8650..c6e2ee7eca 100644 --- a/docs/tutorials/vinyldns.md +++ b/docs/tutorials/vinyldns.md @@ -42,6 +42,10 @@ nginx 10.0.0.115 34.x.x.x 80:30543/TCP 2m Connect your `kubectl` client to the cluster you want to test ExternalDNS with. Then apply one of the following manifests file to deploy ExternalDNS. +**Note for examples below** + +When using `registry=txt` option, make sure to also use the `txt-prefix` and `txt-owner-id` options as well. If you try to create a `TXT` record in VinylDNS without a prefix, it will try to create a `TXT` record with the same name as your actual DNS record and fail (creating a stranded record `external-dns` cannot manage). + ### Manifest (for clusters without RBAC enabled) ```yaml @@ -64,6 +68,9 @@ spec: - --provider=vinyldns - --source=service - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. + - --registry=txt + - --txt-owner-id=grizz + - --txt-prefix=txt- env: - name: VINYLDNS_HOST value: "YOUR_VINYLDNS_HOST" @@ -132,6 +139,9 @@ spec: - --provider=vinyldns - --source=service - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. + - --registry=txt + - --txt-owner-id=grizz + - --txt-prefix=txt- env: env: - name: VINYLDNS_HOST @@ -161,7 +171,7 @@ export VINYLDNS_SECRET_KEY= --domain-filter=elements.capsps.comcast.net. \ --zone-id-filter=20e8bfd2-3a70-4e1b-8e11-c9c1948528d3 \ --registry=txt \ - --txt-owner-id=grizz- \ + --txt-owner-id=grizz \ --txt-prefix=txt- \ --namespace=default \ --once \ From 41ba7f1ff5149f5c19e36ebaf9b02a2574324ebd Mon Sep 17 00:00:00 2001 From: Tariq Ibrahim Date: Mon, 30 Dec 2019 16:15:37 -0800 Subject: [PATCH 78/79] rename project root package to sigs.k8s.io --- Dockerfile | 4 ++-- Dockerfile.mini | 4 ++-- Makefile | 2 +- controller/controller.go | 8 ++++---- controller/controller_test.go | 10 +++++----- go.mod | 2 +- internal/testutils/endpoint.go | 2 +- internal/testutils/endpoint_test.go | 2 +- internal/testutils/mock_source.go | 2 +- main.go | 14 +++++++------- pkg/apis/externaldns/validation/validation.go | 2 +- pkg/apis/externaldns/validation/validation_test.go | 2 +- plan/conflict.go | 2 +- plan/conflict_test.go | 3 ++- plan/plan.go | 2 +- plan/plan_test.go | 5 +++-- plan/policy_test.go | 2 +- provider/alibaba_cloud.go | 5 +++-- provider/alibaba_cloud_test.go | 4 ++-- provider/aws.go | 5 +++-- provider/aws_sd.go | 7 ++++--- provider/aws_sd_test.go | 7 ++++--- provider/aws_test.go | 7 ++++--- provider/azure.go | 4 ++-- provider/azure_private_dns.go | 4 ++-- provider/azure_privatedns_test.go | 4 ++-- provider/azure_test.go | 8 ++++---- provider/cloudflare.go | 6 +++--- provider/cloudflare_test.go | 5 +++-- provider/coredns.go | 4 ++-- provider/coredns_test.go | 4 ++-- provider/designate.go | 6 +++--- provider/designate_test.go | 5 +++-- provider/digital_ocean.go | 4 ++-- provider/digital_ocean_test.go | 7 +++---- provider/dnsimple.go | 5 +++-- provider/dnsimple_test.go | 5 +++-- provider/dyn.go | 4 ++-- provider/dyn_test.go | 2 +- provider/exoscale.go | 5 +++-- provider/exoscale_test.go | 5 +++-- provider/google.go | 9 +++------ provider/google_test.go | 13 +++++-------- provider/infoblox.go | 5 +++-- provider/infoblox_test.go | 5 +++-- provider/inmemory.go | 4 ++-- provider/inmemory_test.go | 8 ++++---- provider/linode.go | 7 +++---- provider/linode_test.go | 5 +++-- provider/ns1.go | 5 ++--- provider/ns1_test.go | 5 +++-- provider/oci.go | 4 ++-- provider/oci_test.go | 4 ++-- provider/pdns.go | 13 ++++++------- provider/pdns_test.go | 6 ++---- provider/provider.go | 4 ++-- provider/rcode0.go | 5 +++-- provider/rcode0_test.go | 5 +++-- provider/rdns.go | 7 +++---- provider/rdns_test.go | 4 ++-- provider/rfc2136.go | 4 ++-- provider/rfc2136_test.go | 5 +++-- provider/transip.go | 5 +++-- provider/transip_test.go | 3 ++- provider/vinyldns.go | 5 +++-- provider/vinyldns_test.go | 5 +++-- registry/aws_sd_registry.go | 6 +++--- registry/aws_sd_registry_test.go | 7 ++++--- registry/noop.go | 6 +++--- registry/noop_test.go | 10 +++++----- registry/registry.go | 5 +++-- registry/txt.go | 10 +++++----- registry/txt_test.go | 10 +++++----- source/cloudfoundry.go | 3 ++- source/compatibility.go | 3 ++- source/connector.go | 3 ++- source/connector_test.go | 3 ++- source/crd.go | 3 ++- source/crd_test.go | 3 ++- source/dedup_source.go | 2 +- source/dedup_source_test.go | 4 ++-- source/empty.go | 2 +- source/fake.go | 2 +- source/fake_test.go | 2 +- source/gateway.go | 12 +++++------- source/gateway_test.go | 12 +++++------- source/ingress.go | 4 ++-- source/ingress_test.go | 9 ++++----- source/ingressroute.go | 3 ++- source/ingressroute_test.go | 2 +- source/multi_source.go | 2 +- source/multi_source_test.go | 6 +++--- source/node.go | 2 +- source/node_test.go | 3 ++- source/service.go | 13 +++++-------- source/service_test.go | 12 +++++------- source/shared_test.go | 2 +- source/source.go | 2 +- source/source_test.go | 3 ++- source/store.go | 3 +-- 100 files changed, 260 insertions(+), 249 deletions(-) diff --git a/Dockerfile b/Dockerfile index 07e2e61fc7..5f6f268d77 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ # builder image FROM golang:1.13 as builder -WORKDIR /github.com/kubernetes-sigs/external-dns +WORKDIR /sigs.k8s.io/external-dns COPY . . RUN go mod vendor && \ @@ -29,7 +29,7 @@ LABEL maintainer="Team Teapot @ Zalando SE " RUN apk add --no-cache ca-certificates && \ update-ca-certificates -COPY --from=builder /github.com/kubernetes-sigs/external-dns/build/external-dns /bin/external-dns +COPY --from=builder /sigs.k8s.io/external-dns/build/external-dns /bin/external-dns # Run as UID for nobody since k8s pod securityContext runAsNonRoot can't resolve the user ID: # https://github.com/kubernetes/kubernetes/issues/40958 diff --git a/Dockerfile.mini b/Dockerfile.mini index 1475c2416a..1fa4ac3701 100644 --- a/Dockerfile.mini +++ b/Dockerfile.mini @@ -14,7 +14,7 @@ FROM golang:1.13 as builder -WORKDIR /github.com/kubernetes-sigs/external-dns +WORKDIR /sigs.k8s.io/external-dns COPY . . RUN apt-get update && \ @@ -27,7 +27,7 @@ RUN apt-get update && \ FROM gcr.io/distroless/static COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -COPY --from=builder /github.com/kubernetes-sigs/external-dns/build/external-dns /bin/external-dns +COPY --from=builder /sigs.k8s.io/external-dns/build/external-dns /bin/external-dns # Run as UID for nobody since k8s pod securityContext runAsNonRoot can't resolve the user ID: # https://github.com/kubernetes/kubernetes/issues/40958 diff --git a/Makefile b/Makefile index 48db48cad8..6c1fc875cb 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ SOURCES = $(shell find . -name '*.go') IMAGE ?= registry.opensource.zalan.do/teapot/$(BINARY) VERSION ?= $(shell git describe --tags --always --dirty) BUILD_FLAGS ?= -v -LDFLAGS ?= -X github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns.Version=$(VERSION) -w -s +LDFLAGS ?= -X sigs.k8s.io/external-dns/pkg/apis/externaldns.Version=$(VERSION) -w -s build: build/$(BINARY) diff --git a/controller/controller.go b/controller/controller.go index f6c88e9f40..aa12b6eddb 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -23,10 +23,10 @@ import ( "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/kubernetes-sigs/external-dns/provider" - "github.com/kubernetes-sigs/external-dns/registry" - "github.com/kubernetes-sigs/external-dns/source" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" + "sigs.k8s.io/external-dns/registry" + "sigs.k8s.io/external-dns/source" ) var ( diff --git a/controller/controller_test.go b/controller/controller_test.go index 3d0b0ecfa5..7bebe395e8 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -22,11 +22,11 @@ import ( "reflect" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/kubernetes-sigs/external-dns/provider" - "github.com/kubernetes-sigs/external-dns/registry" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" + "sigs.k8s.io/external-dns/registry" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/go.mod b/go.mod index 7b858af448..227d4f4be5 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/kubernetes-sigs/external-dns +module sigs.k8s.io/external-dns go 1.13 diff --git a/internal/testutils/endpoint.go b/internal/testutils/endpoint.go index 2ba552491b..bf2f8634f5 100644 --- a/internal/testutils/endpoint.go +++ b/internal/testutils/endpoint.go @@ -20,7 +20,7 @@ import ( "reflect" "sort" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) /** test utility functions for endpoints verifications */ diff --git a/internal/testutils/endpoint_test.go b/internal/testutils/endpoint_test.go index 27120f2f6e..ffbb54fb2a 100644 --- a/internal/testutils/endpoint_test.go +++ b/internal/testutils/endpoint_test.go @@ -20,7 +20,7 @@ import ( "fmt" "sort" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) func ExampleSameEndpoints() { diff --git a/internal/testutils/mock_source.go b/internal/testutils/mock_source.go index 6a9db805ff..1c601ae913 100644 --- a/internal/testutils/mock_source.go +++ b/internal/testutils/mock_source.go @@ -19,7 +19,7 @@ package testutils import ( "github.com/stretchr/testify/mock" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) // MockSource returns mock endpoints. diff --git a/main.go b/main.go index f0aa9b708b..5ebcf1f87c 100644 --- a/main.go +++ b/main.go @@ -27,13 +27,13 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth" - "github.com/kubernetes-sigs/external-dns/controller" - "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns" - "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns/validation" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/kubernetes-sigs/external-dns/provider" - "github.com/kubernetes-sigs/external-dns/registry" - "github.com/kubernetes-sigs/external-dns/source" + "sigs.k8s.io/external-dns/controller" + "sigs.k8s.io/external-dns/pkg/apis/externaldns" + "sigs.k8s.io/external-dns/pkg/apis/externaldns/validation" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" + "sigs.k8s.io/external-dns/registry" + "sigs.k8s.io/external-dns/source" ) func main() { diff --git a/pkg/apis/externaldns/validation/validation.go b/pkg/apis/externaldns/validation/validation.go index 6ca2814284..c4e09f9eb0 100644 --- a/pkg/apis/externaldns/validation/validation.go +++ b/pkg/apis/externaldns/validation/validation.go @@ -20,7 +20,7 @@ import ( "errors" "fmt" - "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns" + "sigs.k8s.io/external-dns/pkg/apis/externaldns" ) // ValidateConfig performs validation on the Config object diff --git a/pkg/apis/externaldns/validation/validation_test.go b/pkg/apis/externaldns/validation/validation_test.go index 5f7fe6e40c..a228c50657 100644 --- a/pkg/apis/externaldns/validation/validation_test.go +++ b/pkg/apis/externaldns/validation/validation_test.go @@ -19,7 +19,7 @@ package validation import ( "testing" - "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns" + "sigs.k8s.io/external-dns/pkg/apis/externaldns" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/plan/conflict.go b/plan/conflict.go index f01a724bd3..9b1f29cfe6 100644 --- a/plan/conflict.go +++ b/plan/conflict.go @@ -19,7 +19,7 @@ package plan import ( "sort" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) // ConflictResolver is used to make a decision in case of two or more different kubernetes resources diff --git a/plan/conflict_test.go b/plan/conflict_test.go index 14ae83cae0..ff2005223b 100644 --- a/plan/conflict_test.go +++ b/plan/conflict_test.go @@ -19,8 +19,9 @@ package plan import ( "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/suite" + + "sigs.k8s.io/external-dns/endpoint" ) var _ ConflictResolver = PerResource{} diff --git a/plan/plan.go b/plan/plan.go index 17c5f4a958..acfb63d37a 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) // Plan can convert a list of desired and current records to a series of create, diff --git a/plan/plan_test.go b/plan/plan_test.go index 63d5750ebc..b51f1b89c6 100644 --- a/plan/plan_test.go +++ b/plan/plan_test.go @@ -19,10 +19,11 @@ package plan import ( "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" ) type PlanTestSuite struct { diff --git a/plan/policy_test.go b/plan/policy_test.go index c214526269..e91e05173b 100644 --- a/plan/policy_test.go +++ b/plan/policy_test.go @@ -20,7 +20,7 @@ import ( "reflect" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) // TestApply tests that applying a policy results in the correct set of changes. diff --git a/provider/alibaba_cloud.go b/provider/alibaba_cloud.go index 97856f734c..1418c902dc 100644 --- a/provider/alibaba_cloud.go +++ b/provider/alibaba_cloud.go @@ -28,10 +28,11 @@ import ( "github.com/aliyun/alibaba-cloud-sdk-go/services/alidns" "github.com/aliyun/alibaba-cloud-sdk-go/services/pvtz" "github.com/denverdino/aliyungo/metadata" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" yaml "gopkg.in/yaml.v2" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/alibaba_cloud_test.go b/provider/alibaba_cloud_test.go index 55a57df5e4..87b629bef1 100644 --- a/provider/alibaba_cloud_test.go +++ b/provider/alibaba_cloud_test.go @@ -22,9 +22,9 @@ import ( "github.com/aliyun/alibaba-cloud-sdk-go/services/alidns" "github.com/aliyun/alibaba-cloud-sdk-go/services/pvtz" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/plan" ) type MockAlibabaCloudDNSAPI struct { diff --git a/provider/aws.go b/provider/aws.go index b06ff3662a..e2d92c26ee 100644 --- a/provider/aws.go +++ b/provider/aws.go @@ -28,10 +28,11 @@ import ( "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/route53" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/linki/instrumented_http" log "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/aws_sd.go b/provider/aws_sd.go index 330db7528d..6bc6fc0db1 100644 --- a/provider/aws_sd.go +++ b/provider/aws_sd.go @@ -31,11 +31,12 @@ import ( "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" sd "github.com/aws/aws-sdk-go/service/servicediscovery" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/pkg/apis/externaldns" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/linki/instrumented_http" log "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/pkg/apis/externaldns" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/aws_sd_test.go b/provider/aws_sd_test.go index 1f2d2ec83c..6ac5c136b9 100644 --- a/provider/aws_sd_test.go +++ b/provider/aws_sd_test.go @@ -26,11 +26,12 @@ import ( "github.com/aws/aws-sdk-go/aws" sd "github.com/aws/aws-sdk-go/service/servicediscovery" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/plan" ) // Compile time check for interface conformance diff --git a/provider/aws_test.go b/provider/aws_test.go index d47329a842..afd3119385 100644 --- a/provider/aws_test.go +++ b/provider/aws_test.go @@ -27,12 +27,13 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/azure.go b/provider/azure.go index d3a1638027..962d89e0c0 100644 --- a/provider/azure.go +++ b/provider/azure.go @@ -32,8 +32,8 @@ import ( "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/to" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/azure_private_dns.go b/provider/azure_private_dns.go index 45563321ca..5ffb40f942 100644 --- a/provider/azure_private_dns.go +++ b/provider/azure_private_dns.go @@ -29,8 +29,8 @@ import ( "github.com/Azure/go-autorest/autorest/azure/auth" "github.com/Azure/go-autorest/autorest/to" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type azurePrivateDNSConfig struct { diff --git a/provider/azure_privatedns_test.go b/provider/azure_privatedns_test.go index e64b3fc600..c3eeff4bb0 100644 --- a/provider/azure_privatedns_test.go +++ b/provider/azure_privatedns_test.go @@ -25,8 +25,8 @@ import ( "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/to" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) // mockPrivateZonesClient implements the methods of the Azure Private DNS Zones Client which are used in the Azure Private DNS Provider diff --git a/provider/azure_test.go b/provider/azure_test.go index 878880af02..0382360c07 100644 --- a/provider/azure_test.go +++ b/provider/azure_test.go @@ -24,11 +24,11 @@ import ( "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/to" - - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/plan" ) // mockZonesClient implements the methods of the Azure DNS Zones Client which are used in the Azure Provider diff --git a/provider/cloudflare.go b/provider/cloudflare.go index 7921949cd6..3fd1318713 100644 --- a/provider/cloudflare.go +++ b/provider/cloudflare.go @@ -27,9 +27,9 @@ import ( cloudflare "github.com/cloudflare/cloudflare-go" log "github.com/sirupsen/logrus" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/kubernetes-sigs/external-dns/source" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/source" ) const ( diff --git a/provider/cloudflare_test.go b/provider/cloudflare_test.go index c2cb67e660..4f29f66153 100644 --- a/provider/cloudflare_test.go +++ b/provider/cloudflare_test.go @@ -23,10 +23,11 @@ import ( "testing" cloudflare "github.com/cloudflare/cloudflare-go" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type mockCloudFlareClient struct{} diff --git a/provider/coredns.go b/provider/coredns.go index a30541d454..3c64189430 100644 --- a/provider/coredns.go +++ b/provider/coredns.go @@ -33,8 +33,8 @@ import ( etcdcv3 "github.com/coreos/etcd/clientv3" log "github.com/sirupsen/logrus" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) func init() { diff --git a/provider/coredns_test.go b/provider/coredns_test.go index 2f4cc10ec1..3fd64a47cb 100644 --- a/provider/coredns_test.go +++ b/provider/coredns_test.go @@ -21,8 +21,8 @@ import ( "strings" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const defaultCoreDNSPrefix = "/skydns/" diff --git a/provider/designate.go b/provider/designate.go index 3ab6cb8bab..1144beb5f6 100644 --- a/provider/designate.go +++ b/provider/designate.go @@ -32,9 +32,9 @@ import ( "github.com/gophercloud/gophercloud/pagination" log "github.com/sirupsen/logrus" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/pkg/tlsutils" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/pkg/tlsutils" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/designate_test.go b/provider/designate_test.go index 202ae6350b..9d1675d84b 100644 --- a/provider/designate_test.go +++ b/provider/designate_test.go @@ -31,8 +31,9 @@ import ( "github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets" "github.com/gophercloud/gophercloud/openstack/dns/v2/zones" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) var lastGeneratedDesignateID int32 diff --git a/provider/digital_ocean.go b/provider/digital_ocean.go index fb9849dd3b..b14c9a5adc 100644 --- a/provider/digital_ocean.go +++ b/provider/digital_ocean.go @@ -26,8 +26,8 @@ import ( log "github.com/sirupsen/logrus" "golang.org/x/oauth2" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/digital_ocean_test.go b/provider/digital_ocean_test.go index 40461ad692..34e77ca692 100644 --- a/provider/digital_ocean_test.go +++ b/provider/digital_ocean_test.go @@ -23,12 +23,11 @@ import ( "testing" "github.com/digitalocean/godo" - - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type mockDigitalOceanInterface interface { diff --git a/provider/dnsimple.go b/provider/dnsimple.go index 74b7f6e117..bb953f1df1 100644 --- a/provider/dnsimple.go +++ b/provider/dnsimple.go @@ -24,9 +24,10 @@ import ( "strings" "github.com/dnsimple/dnsimple-go/dnsimple" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const dnsimpleRecordTTL = 3600 // Default TTL of 1 hour if not set (DNSimple's default) diff --git a/provider/dnsimple_test.go b/provider/dnsimple_test.go index 4838a0b940..42149609f4 100644 --- a/provider/dnsimple_test.go +++ b/provider/dnsimple_test.go @@ -25,11 +25,12 @@ import ( "strconv" "github.com/dnsimple/dnsimple-go/dnsimple" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) var mockProvider dnsimpleProvider diff --git a/provider/dyn.go b/provider/dyn.go index a44e4cc91f..29afac0a7b 100644 --- a/provider/dyn.go +++ b/provider/dyn.go @@ -29,8 +29,8 @@ import ( "github.com/nesv/go-dynect/dynect" "github.com/sanyu/dynectsoap/dynectsoap" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/dyn_test.go b/provider/dyn_test.go index f748148c2b..bf8724a330 100644 --- a/provider/dyn_test.go +++ b/provider/dyn_test.go @@ -24,7 +24,7 @@ import ( "github.com/nesv/go-dynect/dynect" "github.com/stretchr/testify/assert" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) func TestDynMerge_NoUpdateOnTTL0Changes(t *testing.T) { diff --git a/provider/exoscale.go b/provider/exoscale.go index 27c4dadb3d..d709137cb5 100644 --- a/provider/exoscale.go +++ b/provider/exoscale.go @@ -21,9 +21,10 @@ import ( "strings" "github.com/exoscale/egoscale" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) // EgoscaleClientI for replaceable implementation diff --git a/provider/exoscale_test.go b/provider/exoscale_test.go index caae497ae1..fd6e313c30 100644 --- a/provider/exoscale_test.go +++ b/provider/exoscale_test.go @@ -22,9 +22,10 @@ import ( "testing" "github.com/exoscale/egoscale" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type createRecordExoscale struct { diff --git a/provider/google.go b/provider/google.go index d798f8e613..2721b4278a 100644 --- a/provider/google.go +++ b/provider/google.go @@ -26,17 +26,14 @@ import ( "cloud.google.com/go/compute/metadata" "github.com/linki/instrumented_http" log "github.com/sirupsen/logrus" - - dns "google.golang.org/api/dns/v1" - "golang.org/x/net/context" "golang.org/x/oauth2/google" - + dns "google.golang.org/api/dns/v1" googleapi "google.golang.org/api/googleapi" "google.golang.org/api/option" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/google_test.go b/provider/google_test.go index 06bde5d39a..f45acd5b4f 100644 --- a/provider/google_test.go +++ b/provider/google_test.go @@ -23,17 +23,14 @@ import ( "strings" "testing" - dns "google.golang.org/api/dns/v1" - + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "golang.org/x/net/context" - - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" - + dns "google.golang.org/api/dns/v1" "google.golang.org/api/googleapi" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) var ( diff --git a/provider/infoblox.go b/provider/infoblox.go index 8f9f1a6b92..60e4ab6608 100644 --- a/provider/infoblox.go +++ b/provider/infoblox.go @@ -25,9 +25,10 @@ import ( "strings" ibclient "github.com/infobloxopen/infoblox-go-client" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) // InfobloxConfig clarifies the method signature diff --git a/provider/infoblox_test.go b/provider/infoblox_test.go index c4c821ba4c..7f96497ce5 100644 --- a/provider/infoblox_test.go +++ b/provider/infoblox_test.go @@ -25,9 +25,10 @@ import ( "testing" ibclient "github.com/infobloxopen/infoblox-go-client" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type mockIBConnector struct { diff --git a/provider/inmemory.go b/provider/inmemory.go index e78525e1cb..e8a42d6e4f 100644 --- a/provider/inmemory.go +++ b/provider/inmemory.go @@ -23,8 +23,8 @@ import ( log "github.com/sirupsen/logrus" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) var ( diff --git a/provider/inmemory_test.go b/provider/inmemory_test.go index 94ebf17704..b31fd2c080 100644 --- a/provider/inmemory_test.go +++ b/provider/inmemory_test.go @@ -20,12 +20,12 @@ import ( "context" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/plan" ) var ( diff --git a/provider/linode.go b/provider/linode.go index 53c9760dc0..cba9dcbad2 100644 --- a/provider/linode.go +++ b/provider/linode.go @@ -22,15 +22,14 @@ import ( "net/http" "os" "strconv" + "strings" "github.com/linode/linodego" log "github.com/sirupsen/logrus" "golang.org/x/oauth2" - "strings" - - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) // LinodeDomainClient interface to ease testing diff --git a/provider/linode_test.go b/provider/linode_test.go index 32f255b87c..c033f70c66 100644 --- a/provider/linode_test.go +++ b/provider/linode_test.go @@ -21,12 +21,13 @@ import ( "os" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/linode/linodego" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type MockDomainClient struct { diff --git a/provider/ns1.go b/provider/ns1.go index 924c13301d..b203be7975 100644 --- a/provider/ns1.go +++ b/provider/ns1.go @@ -25,12 +25,11 @@ import ( "strings" log "github.com/sirupsen/logrus" - api "gopkg.in/ns1/ns1-go.v2/rest" "gopkg.in/ns1/ns1-go.v2/rest/model/dns" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/ns1_test.go b/provider/ns1_test.go index 756fa2da73..f5bc2b9448 100644 --- a/provider/ns1_test.go +++ b/provider/ns1_test.go @@ -23,13 +23,14 @@ import ( "os" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" api "gopkg.in/ns1/ns1-go.v2/rest" "gopkg.in/ns1/ns1-go.v2/rest/model/dns" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type MockNS1DomainClient struct { diff --git a/provider/oci.go b/provider/oci.go index 431a17a140..933bf67de0 100644 --- a/provider/oci.go +++ b/provider/oci.go @@ -27,8 +27,8 @@ import ( log "github.com/sirupsen/logrus" yaml "gopkg.in/yaml.v2" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ociRecordTTL = 300 diff --git a/provider/oci_test.go b/provider/oci_test.go index 985998bebc..bf04928f40 100644 --- a/provider/oci_test.go +++ b/provider/oci_test.go @@ -26,8 +26,8 @@ import ( "github.com/pkg/errors" "github.com/stretchr/testify/require" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type mockOCIDNSClient struct{} diff --git a/provider/pdns.go b/provider/pdns.go index 8553b021d5..684cc5548d 100644 --- a/provider/pdns.go +++ b/provider/pdns.go @@ -19,23 +19,22 @@ package provider import ( "bytes" "context" + "crypto/tls" "encoding/json" "errors" "math" + "net" "net/http" "sort" "strings" "time" + pgo "github.com/ffledgling/pdns-go" log "github.com/sirupsen/logrus" - "crypto/tls" - "net" - - pgo "github.com/ffledgling/pdns-go" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/pkg/tlsutils" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/pkg/tlsutils" + "sigs.k8s.io/external-dns/plan" ) type pdnsChangeType string diff --git a/provider/pdns_test.go b/provider/pdns_test.go index cd40dbc655..8c7db1b638 100644 --- a/provider/pdns_test.go +++ b/provider/pdns_test.go @@ -19,17 +19,15 @@ package provider import ( "context" "errors" - - //"fmt" "net/http" "strings" "testing" + pgo "github.com/ffledgling/pdns-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - pgo "github.com/ffledgling/pdns-go" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) // FIXME: What do we do about labels? diff --git a/provider/provider.go b/provider/provider.go index 1d55ec5927..96876d7818 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -21,8 +21,8 @@ import ( "net" "strings" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) // Provider defines the interface DNS providers should implement. diff --git a/provider/rcode0.go b/provider/rcode0.go index f37c870985..8741b25997 100644 --- a/provider/rcode0.go +++ b/provider/rcode0.go @@ -23,10 +23,11 @@ import ( "os" "strings" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" rc0 "github.com/nic-at/rc0go" log "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) // RcodeZeroProvider implements the DNS provider for RcodeZero Anycast DNS. diff --git a/provider/rcode0_test.go b/provider/rcode0_test.go index dc5dc1a955..9c10b594f3 100644 --- a/provider/rcode0_test.go +++ b/provider/rcode0_test.go @@ -22,10 +22,11 @@ import ( "os" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" rc0 "github.com/nic-at/rc0go" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/rdns.go b/provider/rdns.go index cb7ccc2eca..5826da8d6d 100644 --- a/provider/rdns.go +++ b/provider/rdns.go @@ -29,13 +29,12 @@ import ( "strings" "time" - log "github.com/sirupsen/logrus" - "github.com/coreos/etcd/clientv3" "github.com/pkg/errors" + log "github.com/sirupsen/logrus" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/rdns_test.go b/provider/rdns_test.go index 57fe9f272b..5276fffcb5 100644 --- a/provider/rdns_test.go +++ b/provider/rdns_test.go @@ -27,8 +27,8 @@ import ( "github.com/coreos/etcd/mvcc/mvccpb" "github.com/stretchr/testify/assert" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type fakeEtcdv3Client struct { diff --git a/provider/rfc2136.go b/provider/rfc2136.go index ab33da1ffe..ca17ba62de 100644 --- a/provider/rfc2136.go +++ b/provider/rfc2136.go @@ -28,8 +28,8 @@ import ( "github.com/pkg/errors" log "github.com/sirupsen/logrus" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) // rfc2136 provider type diff --git a/provider/rfc2136_test.go b/provider/rfc2136_test.go index 6233891b20..dc4abe7676 100644 --- a/provider/rfc2136_test.go +++ b/provider/rfc2136_test.go @@ -21,11 +21,12 @@ import ( "strings" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/miekg/dns" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type rfc2136Stub struct { diff --git a/provider/transip.go b/provider/transip.go index 8a09ea5a75..c3f8f7b169 100644 --- a/provider/transip.go +++ b/provider/transip.go @@ -6,11 +6,12 @@ import ( "fmt" "strings" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" "github.com/transip/gotransip" transip "github.com/transip/gotransip/domain" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/transip_test.go b/provider/transip_test.go index 5a4450dac6..960c57b6c2 100644 --- a/provider/transip_test.go +++ b/provider/transip_test.go @@ -3,9 +3,10 @@ package provider import ( "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" transip "github.com/transip/gotransip/domain" + + "sigs.k8s.io/external-dns/endpoint" ) func TestTransIPDnsEntriesAreEqual(t *testing.T) { diff --git a/provider/vinyldns.go b/provider/vinyldns.go index dc485ab190..c0f3f0d7a7 100644 --- a/provider/vinyldns.go +++ b/provider/vinyldns.go @@ -22,10 +22,11 @@ import ( "os" "strings" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" "github.com/vinyldns/go-vinyldns/vinyldns" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) const ( diff --git a/provider/vinyldns_test.go b/provider/vinyldns_test.go index 70eacc0385..ada49071de 100644 --- a/provider/vinyldns_test.go +++ b/provider/vinyldns_test.go @@ -22,11 +22,12 @@ import ( "os" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/vinyldns/go-vinyldns/vinyldns" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) type mockVinyldnsZoneInterface struct { diff --git a/registry/aws_sd_registry.go b/registry/aws_sd_registry.go index b73ed97726..1422db0b9b 100644 --- a/registry/aws_sd_registry.go +++ b/registry/aws_sd_registry.go @@ -20,9 +20,9 @@ import ( "context" "errors" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/kubernetes-sigs/external-dns/provider" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" ) // AWSSDRegistry implements registry interface with ownership information associated via the Description field of SD Service diff --git a/registry/aws_sd_registry_test.go b/registry/aws_sd_registry_test.go index 953c2cc8bb..0658877eb9 100644 --- a/registry/aws_sd_registry_test.go +++ b/registry/aws_sd_registry_test.go @@ -20,11 +20,12 @@ import ( "context" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" - "github.com/kubernetes-sigs/external-dns/plan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/plan" ) type inMemoryProvider struct { diff --git a/registry/noop.go b/registry/noop.go index d6b04abcfa..1a49b8ed03 100644 --- a/registry/noop.go +++ b/registry/noop.go @@ -19,9 +19,9 @@ package registry import ( "context" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/kubernetes-sigs/external-dns/provider" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" ) // NoopRegistry implements registry interface without ownership directly propagating changes to dns provider diff --git a/registry/noop_test.go b/registry/noop_test.go index 01954576f3..b56b8eecaf 100644 --- a/registry/noop_test.go +++ b/registry/noop_test.go @@ -20,13 +20,13 @@ import ( "context" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/kubernetes-sigs/external-dns/provider" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" ) var _ Registry = &NoopRegistry{} diff --git a/registry/registry.go b/registry/registry.go index bf01dd8980..be87d20468 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -19,9 +19,10 @@ package registry import ( "context" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" log "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" ) // Registry is an interface which should enables ownership concept in external-dns diff --git a/registry/txt.go b/registry/txt.go index c97ac9bf84..544355b4d5 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -19,15 +19,15 @@ package registry import ( "context" "errors" - "time" - "fmt" "strings" + "time" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/kubernetes-sigs/external-dns/provider" log "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" ) // TXTRegistry implements registry interface with ownership implemented via associated TXT records diff --git a/registry/txt_test.go b/registry/txt_test.go index 3c1238a7c5..c5920ad7e2 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -22,13 +22,13 @@ import ( "testing" "time" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" - "github.com/kubernetes-sigs/external-dns/plan" - "github.com/kubernetes-sigs/external-dns/provider" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" ) const ( diff --git a/source/cloudfoundry.go b/source/cloudfoundry.go index e136860055..eb3566994e 100644 --- a/source/cloudfoundry.go +++ b/source/cloudfoundry.go @@ -20,7 +20,8 @@ import ( "net/url" cfclient "github.com/cloudfoundry-community/go-cfclient" - "github.com/kubernetes-sigs/external-dns/endpoint" + + "sigs.k8s.io/external-dns/endpoint" ) type cloudfoundrySource struct { diff --git a/source/compatibility.go b/source/compatibility.go index 069f699185..aa86c1c3f1 100644 --- a/source/compatibility.go +++ b/source/compatibility.go @@ -19,8 +19,9 @@ package source import ( "strings" - "github.com/kubernetes-sigs/external-dns/endpoint" v1 "k8s.io/api/core/v1" + + "sigs.k8s.io/external-dns/endpoint" ) const ( diff --git a/source/connector.go b/source/connector.go index 4adadea5ce..7b657e8476 100644 --- a/source/connector.go +++ b/source/connector.go @@ -21,8 +21,9 @@ import ( "net" "time" - "github.com/kubernetes-sigs/external-dns/endpoint" log "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/endpoint" ) const ( diff --git a/source/connector_test.go b/source/connector_test.go index f4cd673f58..7e00aef6a6 100644 --- a/source/connector_test.go +++ b/source/connector_test.go @@ -21,9 +21,10 @@ import ( "net" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" + + "sigs.k8s.io/external-dns/endpoint" ) type ConnectorSuite struct { diff --git a/source/crd.go b/source/crd.go index 66c464c7bd..a373d0af8d 100644 --- a/source/crd.go +++ b/source/crd.go @@ -21,7 +21,6 @@ import ( "os" "strings" - "github.com/kubernetes-sigs/external-dns/endpoint" log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -30,6 +29,8 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + + "sigs.k8s.io/external-dns/endpoint" ) // crdSource is an implementation of Source that provides endpoints by listing diff --git a/source/crd_test.go b/source/crd_test.go index 6f1ed19a5e..ce8e76c7cd 100644 --- a/source/crd_test.go +++ b/source/crd_test.go @@ -26,7 +26,6 @@ import ( "strings" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -35,6 +34,8 @@ import ( "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/rest" "k8s.io/client-go/rest/fake" + + "sigs.k8s.io/external-dns/endpoint" ) type CRDSuite struct { diff --git a/source/dedup_source.go b/source/dedup_source.go index ac32b159c7..08f76574cc 100644 --- a/source/dedup_source.go +++ b/source/dedup_source.go @@ -19,7 +19,7 @@ package source import ( log "github.com/sirupsen/logrus" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) // dedupSource is a Source that removes duplicate endpoints from its wrapped source. diff --git a/source/dedup_source_test.go b/source/dedup_source_test.go index 222b8f6f81..fee8549214 100644 --- a/source/dedup_source_test.go +++ b/source/dedup_source_test.go @@ -19,8 +19,8 @@ package source import ( "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" ) // Validates that dedupSource is a Source diff --git a/source/empty.go b/source/empty.go index 591a75c5dc..cd7ed89314 100644 --- a/source/empty.go +++ b/source/empty.go @@ -16,7 +16,7 @@ limitations under the License. package source -import "github.com/kubernetes-sigs/external-dns/endpoint" +import "sigs.k8s.io/external-dns/endpoint" // emptySource is a Source that returns no endpoints. type emptySource struct{} diff --git a/source/fake.go b/source/fake.go index be3f55af13..f3f037b9a3 100644 --- a/source/fake.go +++ b/source/fake.go @@ -26,7 +26,7 @@ import ( "net" "time" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) // fakeSource is an implementation of Source that provides dummy endpoints for diff --git a/source/fake_test.go b/source/fake_test.go index 77a254ca6e..a45a6d98b4 100644 --- a/source/fake_test.go +++ b/source/fake_test.go @@ -21,7 +21,7 @@ import ( "regexp" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) func generateTestEndpoints() []*endpoint.Endpoint { diff --git a/source/gateway.go b/source/gateway.go index 50e77253b6..7ce56cfeb5 100644 --- a/source/gateway.go +++ b/source/gateway.go @@ -24,20 +24,18 @@ import ( "text/template" "time" - kubeinformers "k8s.io/client-go/informers" - coreinformers "k8s.io/client-go/informers/core/v1" - "k8s.io/client-go/tools/cache" - log "github.com/sirupsen/logrus" - istionetworking "istio.io/api/networking/v1alpha3" istiomodel "istio.io/istio/pilot/pkg/model" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/wait" - - "github.com/kubernetes-sigs/external-dns/endpoint" + kubeinformers "k8s.io/client-go/informers" + coreinformers "k8s.io/client-go/informers/core/v1" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + + "sigs.k8s.io/external-dns/endpoint" ) // gatewaySource is an implementation of Source for Istio Gateway objects. diff --git a/source/gateway_test.go b/source/gateway_test.go index 00a26d271f..c397e5be08 100644 --- a/source/gateway_test.go +++ b/source/gateway_test.go @@ -17,23 +17,21 @@ limitations under the License. package source import ( - "testing" - - istionetworking "istio.io/api/networking/v1alpha3" - istiomodel "istio.io/istio/pilot/pkg/model" - - "github.com/kubernetes-sigs/external-dns/endpoint" - "strconv" "sync" + "testing" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + istionetworking "istio.io/api/networking/v1alpha3" + istiomodel "istio.io/istio/pilot/pkg/model" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" + + "sigs.k8s.io/external-dns/endpoint" ) // This is a compile-time validation that gatewaySource is a Source. diff --git a/source/ingress.go b/source/ingress.go index bff985af7a..370a35f2a1 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -22,10 +22,8 @@ import ( "sort" "strings" "text/template" - "time" - "github.com/kubernetes-sigs/external-dns/endpoint" log "github.com/sirupsen/logrus" "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -35,6 +33,8 @@ import ( extinformers "k8s.io/client-go/informers/extensions/v1beta1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" + + "sigs.k8s.io/external-dns/endpoint" ) const ( diff --git a/source/ingress_test.go b/source/ingress_test.go index ae2d560d73..cf9d2d50a8 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -20,17 +20,16 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" v1 "k8s.io/api/core/v1" "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes/fake" - "github.com/kubernetes-sigs/external-dns/endpoint" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" + "sigs.k8s.io/external-dns/endpoint" ) // Validates that ingressSource is a Source diff --git a/source/ingressroute.go b/source/ingressroute.go index 82b42d8916..77455ecb7a 100644 --- a/source/ingressroute.go +++ b/source/ingressroute.go @@ -28,7 +28,6 @@ import ( contour "github.com/heptio/contour/apis/generated/clientset/versioned" contourinformers "github.com/heptio/contour/apis/generated/informers/externalversions" extinformers "github.com/heptio/contour/apis/generated/informers/externalversions/contour/v1beta1" - "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/pkg/errors" log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -36,6 +35,8 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" + + "sigs.k8s.io/external-dns/endpoint" ) // ingressRouteSource is an implementation of Source for Heptio Contour IngressRoute objects. diff --git a/source/ingressroute_test.go b/source/ingressroute_test.go index 6bf466e46a..0f52120c9f 100644 --- a/source/ingressroute_test.go +++ b/source/ingressroute_test.go @@ -29,7 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" fakeKube "k8s.io/client-go/kubernetes/fake" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) // This is a compile-time validation that ingressRouteSource is a Source. diff --git a/source/multi_source.go b/source/multi_source.go index 360c9c87ff..efd8916cb5 100644 --- a/source/multi_source.go +++ b/source/multi_source.go @@ -16,7 +16,7 @@ limitations under the License. package source -import "github.com/kubernetes-sigs/external-dns/endpoint" +import "sigs.k8s.io/external-dns/endpoint" // multiSource is a Source that merges the endpoints of its nested Sources. type multiSource struct { diff --git a/source/multi_source_test.go b/source/multi_source_test.go index 2102c514a2..59584d6af7 100644 --- a/source/multi_source_test.go +++ b/source/multi_source_test.go @@ -20,11 +20,11 @@ import ( "errors" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" - "github.com/kubernetes-sigs/external-dns/internal/testutils" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" ) func TestMultiSource(t *testing.T) { diff --git a/source/node.go b/source/node.go index 4364074f3b..8d9fd7c798 100644 --- a/source/node.go +++ b/source/node.go @@ -33,7 +33,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) type nodeSource struct { diff --git a/source/node_test.go b/source/node_test.go index 8ac2858514..231f4d8a10 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -3,12 +3,13 @@ package source import ( "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" + + "sigs.k8s.io/external-dns/endpoint" ) func TestNodeSource(t *testing.T) { diff --git a/source/service.go b/source/service.go index 4a70b4c39f..ee8d7ce882 100644 --- a/source/service.go +++ b/source/service.go @@ -22,22 +22,19 @@ import ( "sort" "strings" "text/template" - - kubeinformers "k8s.io/client-go/informers" - coreinformers "k8s.io/client-go/informers/core/v1" - "k8s.io/client-go/tools/cache" + "time" log "github.com/sirupsen/logrus" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/wait" + kubeinformers "k8s.io/client-go/informers" + coreinformers "k8s.io/client-go/informers/core/v1" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" - "time" - - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) const ( diff --git a/source/service_test.go b/source/service_test.go index a83d1fd334..3fbda307b8 100644 --- a/source/service_test.go +++ b/source/service_test.go @@ -21,17 +21,15 @@ import ( "testing" "time" - "k8s.io/apimachinery/pkg/util/wait" - + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes/fake" - "github.com/kubernetes-sigs/external-dns/endpoint" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" + "sigs.k8s.io/external-dns/endpoint" ) type ServiceSuite struct { diff --git a/source/shared_test.go b/source/shared_test.go index 3118143329..d7043a82b9 100644 --- a/source/shared_test.go +++ b/source/shared_test.go @@ -21,7 +21,7 @@ import ( "strings" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) // test helper functions diff --git a/source/source.go b/source/source.go index a2b265587d..a82db8f76d 100644 --- a/source/source.go +++ b/source/source.go @@ -23,7 +23,7 @@ import ( "strconv" "strings" - "github.com/kubernetes-sigs/external-dns/endpoint" + "sigs.k8s.io/external-dns/endpoint" ) const ( diff --git a/source/source_test.go b/source/source_test.go index 874336f249..a434c84706 100644 --- a/source/source_test.go +++ b/source/source_test.go @@ -20,8 +20,9 @@ import ( "fmt" "testing" - "github.com/kubernetes-sigs/external-dns/endpoint" "github.com/stretchr/testify/assert" + + "sigs.k8s.io/external-dns/endpoint" ) func TestGetTTLFromAnnotations(t *testing.T) { diff --git a/source/store.go b/source/store.go index eafa2a421b..586068068e 100644 --- a/source/store.go +++ b/source/store.go @@ -21,9 +21,8 @@ import ( "net/http" "os" "strings" - "time" - "sync" + "time" "github.com/cloudfoundry-community/go-cfclient" contour "github.com/heptio/contour/apis/generated/clientset/versioned" From 779e7a978070491a4f2437de944c1cc963e9bd57 Mon Sep 17 00:00:00 2001 From: Martin Linkhorst Date: Tue, 7 Jan 2020 11:38:44 +0100 Subject: [PATCH 79/79] fixme: temporarily move cloudbuild to configured path --- cloudbuild.yaml => ci/postsubmit/push-to-staging/cloudbuild.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cloudbuild.yaml => ci/postsubmit/push-to-staging/cloudbuild.yaml (100%) diff --git a/cloudbuild.yaml b/ci/postsubmit/push-to-staging/cloudbuild.yaml similarity index 100% rename from cloudbuild.yaml rename to ci/postsubmit/push-to-staging/cloudbuild.yaml