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=