From 29cd6c633e834e42eb35527e41e0f37ae5d13abc Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 15 Nov 2017 02:39:22 -0500 Subject: [PATCH 1/6] Add copy of k8s.io/kubernetes/federation/pkg/dnsprovider/ --- dnsprovider/pkg/dnsprovider/README.md | 9 + dnsprovider/pkg/dnsprovider/dns.go | 114 +++++++ dnsprovider/pkg/dnsprovider/dns_test.go | 96 ++++++ dnsprovider/pkg/dnsprovider/doc.go | 21 ++ dnsprovider/pkg/dnsprovider/plugins.go | 109 +++++++ .../providers/aws/route53/interface.go | 39 +++ .../providers/aws/route53/route53.go | 72 +++++ .../providers/aws/route53/route53_test.go | 295 ++++++++++++++++++ .../providers/aws/route53/rrchangeset.go | 134 ++++++++ .../providers/aws/route53/rrset.go | 63 ++++ .../providers/aws/route53/rrsets.go | 106 +++++++ .../providers/aws/route53/stubs/route53api.go | 133 ++++++++ .../dnsprovider/providers/aws/route53/zone.go | 56 ++++ .../providers/aws/route53/zones.go | 73 +++++ .../dnsprovider/providers/coredns/coredns.go | 95 ++++++ .../providers/coredns/coredns_test.go | 270 ++++++++++++++++ .../providers/coredns/interface.go | 41 +++ .../providers/coredns/rrchangeset.go | 148 +++++++++ .../dnsprovider/providers/coredns/rrset.go | 49 +++ .../dnsprovider/providers/coredns/rrsets.go | 114 +++++++ .../providers/coredns/stubs/corednsapi.go | 85 +++++ .../pkg/dnsprovider/providers/coredns/zone.go | 42 +++ .../dnsprovider/providers/coredns/zones.go | 49 +++ .../providers/google/clouddns/clouddns.go | 116 +++++++ .../google/clouddns/clouddns_test.go | 273 ++++++++++++++++ .../providers/google/clouddns/interface.go | 43 +++ .../google/clouddns/internal/change.go | 43 +++ .../clouddns/internal/changes_create_call.go | 34 ++ .../clouddns/internal/changes_service.go | 43 +++ .../google/clouddns/internal/clouddns.go | 35 +++ .../internal/interfaces/interfaces.go | 212 +++++++++++++ .../google/clouddns/internal/managed_zone.go | 39 +++ .../internal/managed_zone_create_call.go | 33 ++ .../internal/managed_zones_delete_call.go | 32 ++ .../internal/managed_zones_get_call.go | 33 ++ .../internal/managed_zones_list_call.go | 38 +++ .../internal/managed_zones_list_response.go | 35 +++ .../internal/managed_zones_service.go | 51 +++ .../google/clouddns/internal/rrset.go | 32 ++ .../clouddns/internal/rrsets_list_call.go | 53 ++++ .../clouddns/internal/rrsets_list_response.go | 38 +++ .../clouddns/internal/rrsets_service.go | 43 +++ .../google/clouddns/internal/service.go | 49 +++ .../google/clouddns/internal/stubs/change.go | 36 +++ .../internal/stubs/changes_create_call.go | 67 ++++ .../internal/stubs/changes_service.go | 34 ++ .../clouddns/internal/stubs/clouddns.go | 33 ++ .../clouddns/internal/stubs/managed_zone.go | 41 +++ .../stubs/managed_zone_create_call.go | 52 +++ .../stubs/managed_zones_delete_call.go | 53 ++++ .../internal/stubs/managed_zones_get_call.go | 42 +++ .../internal/stubs/managed_zones_list_call.go | 59 ++++ .../stubs/managed_zones_list_response.go | 28 ++ .../internal/stubs/managed_zones_service.go | 46 +++ .../google/clouddns/internal/stubs/rrset.go | 34 ++ .../internal/stubs/rrsets_list_call.go | 52 +++ .../internal/stubs/rrsets_list_response.go | 30 ++ .../clouddns/internal/stubs/rrsets_service.go | 83 +++++ .../google/clouddns/internal/stubs/service.go | 54 ++++ .../providers/google/clouddns/rrchangeset.go | 124 ++++++++ .../providers/google/clouddns/rrset.go | 53 ++++ .../providers/google/clouddns/rrsets.go | 94 ++++++ .../providers/google/clouddns/zone.go | 48 +++ .../providers/google/clouddns/zones.go | 68 ++++ .../pkg/dnsprovider/rrstype/rrstype.go | 28 ++ .../pkg/dnsprovider/tests/commontests.go | 194 ++++++++++++ 66 files changed, 4841 insertions(+) create mode 100644 dnsprovider/pkg/dnsprovider/README.md create mode 100644 dnsprovider/pkg/dnsprovider/dns.go create mode 100644 dnsprovider/pkg/dnsprovider/dns_test.go create mode 100644 dnsprovider/pkg/dnsprovider/doc.go create mode 100644 dnsprovider/pkg/dnsprovider/plugins.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/interface.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/route53.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/route53_test.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/rrset.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/rrsets.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs/route53api.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/zone.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/zones.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/interface.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/zone.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/zones.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/interface.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/change.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/clouddns.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/service.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/clouddns.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrset.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrsets.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/zone.go create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/zones.go create mode 100644 dnsprovider/pkg/dnsprovider/rrstype/rrstype.go create mode 100644 dnsprovider/pkg/dnsprovider/tests/commontests.go diff --git a/dnsprovider/pkg/dnsprovider/README.md b/dnsprovider/pkg/dnsprovider/README.md new file mode 100644 index 0000000000000..e60022d1138cd --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/README.md @@ -0,0 +1,9 @@ +This is a (partial) copy of federation/pkg/dnsprovider from k8s.io/kubernetes. + +Changes made here should be submitted upstream. + +Reasons for doing this: + +* Ability to fix bugs quickly +* We want to stop vendoring k8s.io/kubernetes +* The federation code is likely to move somewhere else in future diff --git a/dnsprovider/pkg/dnsprovider/dns.go b/dnsprovider/pkg/dnsprovider/dns.go new file mode 100644 index 0000000000000..b707280e1d5c4 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/dns.go @@ -0,0 +1,114 @@ +/* +Copyright 2016 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 dnsprovider + +import ( + "reflect" + + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +// Interface is an abstract, pluggable interface for DNS providers. +type Interface interface { + // Zones returns the provider's Zones interface, or false if not supported. + Zones() (Zones, bool) +} + +type Zones interface { + // List returns the managed Zones, or an error if the list operation failed. + List() ([]Zone, error) + // Add creates and returns a new managed zone, or an error if the operation failed + Add(Zone) (Zone, error) + // Remove deletes a managed zone, or returns an error if the operation failed. + Remove(Zone) error + // New allocates a new Zone, which can then be passed to Add() + // Arguments are as per the Zone interface below. + New(name string) (Zone, error) +} + +type Zone interface { + // Name returns the name of the zone, e.g. "example.com" + Name() string + // ID returns the unique provider identifier for the zone + ID() string + // ResourceRecordSets returns the provider's ResourceRecordSets interface, or false if not supported. + ResourceRecordSets() (ResourceRecordSets, bool) +} + +type ResourceRecordSets interface { + // List returns the ResourceRecordSets of the Zone, or an error if the list operation failed. + List() ([]ResourceRecordSet, error) + // Get returns the ResourceRecordSet list with the name in the Zone. + // This is a list because there might be multiple records of different + // types for a given name. If the named resource record sets do not + // exist, but no error occurred, the returned record set will be empty + // and error will be nil. + Get(name string) ([]ResourceRecordSet, error) + // New allocates a new ResourceRecordSet, which can then be passed to ResourceRecordChangeset Add() or Remove() + // Arguments are as per the ResourceRecordSet interface below. + New(name string, rrdatas []string, ttl int64, rrstype rrstype.RrsType) ResourceRecordSet + // StartChangeset begins a new batch operation of changes against the Zone + StartChangeset() ResourceRecordChangeset + // Zone returns the parent zone + Zone() Zone +} + +// ResourceRecordChangeset accumulates a set of changes, that can then be applied with Apply +type ResourceRecordChangeset interface { + // Add adds the creation of a ResourceRecordSet in the Zone to the changeset + Add(ResourceRecordSet) ResourceRecordChangeset + // Remove adds the removal of a ResourceRecordSet in the Zone to the changeset + // The supplied ResourceRecordSet must match one of the existing recordsets (obtained via List()) exactly. + Remove(ResourceRecordSet) ResourceRecordChangeset + // Upsert adds an "create or update" operation for the ResourceRecordSet in the Zone to the changeset + // Note: the implementation may translate this into a Remove followed by an Add operation. + // If you have the pre-image, it will likely be more efficient to call Remove and Add. + Upsert(ResourceRecordSet) ResourceRecordChangeset + // Apply applies the accumulated operations to the Zone. + Apply() error + // IsEmpty returns true if there are no accumulated operations. + IsEmpty() bool + // ResourceRecordSets returns the parent ResourceRecordSets + ResourceRecordSets() ResourceRecordSets +} + +type ResourceRecordSet interface { + // Name returns the name of the ResourceRecordSet, e.g. "www.example.com". + Name() string + // Rrdatas returns the Resource Record Datas of the record set. + Rrdatas() []string + // Ttl returns the time-to-live of the record set, in seconds. + Ttl() int64 + // Type returns the type of the record set (A, CNAME, SRV, etc) + Type() rrstype.RrsType +} + +/* ResourceRecordSetsEquivalent compares two ResourceRecordSets for semantic equivalence. + Go's equality operator doesn't work the way we want it to in this case, + hence the need for this function. + More specifically (from the Go spec): + "Two struct values are equal if their corresponding non-blank fields are equal." + In our case, there may be some private internal member variables that may not be not equal, + but we want the two structs to be considered equivalent anyway, if the fields exposed + via their interfaces are equal. +*/ +func ResourceRecordSetsEquivalent(r1, r2 ResourceRecordSet) bool { + if r1.Name() == r2.Name() && reflect.DeepEqual(r1.Rrdatas(), r2.Rrdatas()) && r1.Ttl() == r2.Ttl() && r1.Type() == r2.Type() { + return true + } + return false +} diff --git a/dnsprovider/pkg/dnsprovider/dns_test.go b/dnsprovider/pkg/dnsprovider/dns_test.go new file mode 100644 index 0000000000000..b5a2344c35b21 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/dns_test.go @@ -0,0 +1,96 @@ +/* +Copyright 2016 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 dnsprovider + +import ( + "testing" + + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +// Compile time interface check +var _ ResourceRecordSet = record{} + +type record struct { + name string + rrdatas []string + ttl int64 + type_ string +} + +func (r record) Name() string { + return r.name +} + +func (r record) Ttl() int64 { + return r.ttl +} + +func (r record) Rrdatas() []string { + return r.rrdatas +} + +func (r record) Type() rrstype.RrsType { + return rrstype.RrsType(r.type_) +} + +const testDNSZone string = "foo.com" + +var testData = []struct { + inputs [2]record + expectedOutput bool +}{ + { + [2]record{ + {"foo", []string{"1.2.3.4", "5,6,7,8"}, 180, "A"}, // Identical + {"foo", []string{"1.2.3.4", "5,6,7,8"}, 180, "A"}}, true, + }, + { + [2]record{ + {"foo", []string{"1.2.3.4", "5,6,7,8"}, 180, "A"}, // Identical except Name + {"bar", []string{"1.2.3.4", "5,6,7,8"}, 180, "A"}}, false, + }, + { + [2]record{ + {"foo", []string{"1.2.3.4", "5,6,7,8"}, 180, "A"}, // Identical except Rrdata + {"foo", []string{"1.2.3.4", "5,6,7,9"}, 180, "A"}}, false, + }, + { + [2]record{ + {"foo", []string{"1.2.3.4", "5,6,7,8"}, 180, "A"}, // Identical except Rrdata ordering reversed + {"foo", []string{"5,6,7,8", "1.2.3.4"}, 180, "A"}}, false, + }, + { + [2]record{ + {"foo", []string{"1.2.3.4", "5,6,7,8"}, 180, "A"}, // Identical except TTL + {"foo", []string{"1.2.3.4", "5,6,7,8"}, 150, "A"}}, false, + }, + { + [2]record{ + {"foo", []string{"1.2.3.4", "5,6,7,8"}, 180, "A"}, // Identical except Type + {"foo", []string{"1.2.3.4", "5,6,7,8"}, 180, "CNAME"}}, false, + }, +} + +func TestEquivalent(t *testing.T) { + for _, test := range testData { + output := ResourceRecordSetsEquivalent(test.inputs[0], test.inputs[1]) + if output != test.expectedOutput { + t.Errorf("Expected equivalence comparison of %q and %q to yield %v, but it vielded %v", test.inputs[0], test.inputs[1], test.expectedOutput, output) + } + } +} diff --git a/dnsprovider/pkg/dnsprovider/doc.go b/dnsprovider/pkg/dnsprovider/doc.go new file mode 100644 index 0000000000000..201c57a0502c9 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2016 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. +*/ + +/* +dnsprovider supplies interfaces for dns service providers (e.g. Google Cloud DNS, AWS route53, etc). +Implementations exist in the providers sub-package +*/ +package dnsprovider // import "k8s.io/kubernetes/federation/pkg/dnsprovider" diff --git a/dnsprovider/pkg/dnsprovider/plugins.go b/dnsprovider/pkg/dnsprovider/plugins.go new file mode 100644 index 0000000000000..affaf404e3c5a --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/plugins.go @@ -0,0 +1,109 @@ +/* +Copyright 2016 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 dnsprovider + +import ( + "fmt" + "io" + "os" + "sync" + + "github.com/golang/glog" +) + +// Factory is a function that returns a dnsprovider.Interface. +// The config parameter provides an io.Reader handler to the factory in +// order to load specific configurations. If no configuration is provided +// the parameter is nil. +type Factory func(config io.Reader) (Interface, error) + +// All registered dns providers. +var providersMutex sync.Mutex +var providers = make(map[string]Factory) + +// RegisterDnsProvider registers a dnsprovider.Factory by name. This +// is expected to happen during startup. +func RegisterDnsProvider(name string, cloud Factory) { + providersMutex.Lock() + defer providersMutex.Unlock() + if _, found := providers[name]; found { + glog.Fatalf("DNS provider %q was registered twice", name) + } + glog.V(1).Infof("Registered DNS provider %q", name) + providers[name] = cloud +} + +// GetDnsProvider creates an instance of the named DNS provider, or nil if +// the name is not known. The error return is only used if the named provider +// was known but failed to initialize. The config parameter specifies the +// io.Reader handler of the configuration file for the DNS provider, or nil +// for no configuration. +func GetDnsProvider(name string, config io.Reader) (Interface, error) { + providersMutex.Lock() + defer providersMutex.Unlock() + f, found := providers[name] + if !found { + return nil, nil + } + return f(config) +} + +// Returns a list of registered dns providers. +func RegisteredDnsProviders() []string { + registeredProviders := make([]string, len(providers)) + i := 0 + for provider := range providers { + registeredProviders[i] = provider + i = i + 1 + } + return registeredProviders +} + +// InitDnsProvider creates an instance of the named DNS provider. +func InitDnsProvider(name string, configFilePath string) (Interface, error) { + var dns Interface + var err error + + if name == "" { + glog.Info("No DNS provider specified.") + return nil, nil + } + + if configFilePath != "" { + var config *os.File + config, err = os.Open(configFilePath) + if err != nil { + return nil, fmt.Errorf("Couldn't open DNS provider configuration %s: %#v", configFilePath, err) + } + + defer config.Close() + dns, err = GetDnsProvider(name, config) + } else { + // Pass explicit nil so plugins can actually check for nil. See + // "Why is my nil error value not equal to nil?" in golang.org/doc/faq. + dns, err = GetDnsProvider(name, nil) + } + + if err != nil { + return nil, fmt.Errorf("could not init DNS provider %q: %v", name, err) + } + if dns == nil { + return nil, fmt.Errorf("unknown DNS provider %q", name) + } + + return dns, nil +} diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/interface.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/interface.go new file mode 100644 index 0000000000000..b5f171887286d --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/interface.go @@ -0,0 +1,39 @@ +/* +Copyright 2016 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 route53 + +import ( + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/stubs" +) + +// Compile time check for interface adherence +var _ dnsprovider.Interface = Interface{} + +type Interface struct { + service stubs.Route53API +} + +// New builds an Interface, with a specified Route53API implementation. +// This is useful for testing purposes, but also if we want an instance with with custom AWS options. +func New(service stubs.Route53API) *Interface { + return &Interface{service} +} + +func (i Interface) Zones() (zones dnsprovider.Zones, supported bool) { + return Zones{&i}, true +} diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53.go new file mode 100644 index 0000000000000..4e440f7a3da75 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53.go @@ -0,0 +1,72 @@ +/* +Copyright 2016 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. +*/ + +// route53 is the implementation of pkg/dnsprovider interface for AWS Route53 +package route53 + +import ( + "io" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/route53" + "github.com/golang/glog" + "k8s.io/kubernetes/federation/pkg/dnsprovider" +) + +const ( + ProviderName = "aws-route53" +) + +func init() { + dnsprovider.RegisterDnsProvider(ProviderName, func(config io.Reader) (dnsprovider.Interface, error) { + return newRoute53(config) + }) +} + +// route53HandlerLogger is a request handler for aws-sdk-go that logs route53 requests +func route53HandlerLogger(req *request.Request) { + service := req.ClientInfo.ServiceName + + name := "?" + if req.Operation != nil { + name = req.Operation.Name + } + + glog.V(4).Infof("AWS request: %s %s", service, name) +} + +// newRoute53 creates a new instance of an AWS Route53 DNS Interface. +func newRoute53(config io.Reader) (*Interface, error) { + // Connect to AWS Route53 - TODO: Do more sophisticated auth + + awsConfig := aws.NewConfig() + + // This avoids a confusing error message when we fail to get credentials + // e.g. https://github.com/kubernetes/kops/issues/605 + awsConfig = awsConfig.WithCredentialsChainVerboseErrors(true) + + svc := route53.New(session.New(), awsConfig) + + // Add our handler that will log requests + svc.Handlers.Sign.PushFrontNamed(request.NamedHandler{ + Name: "k8s/logger", + Fn: route53HandlerLogger, + }) + + return New(svc), nil +} diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53_test.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53_test.go new file mode 100644 index 0000000000000..19d8967fdeb01 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53_test.go @@ -0,0 +1,295 @@ +/* +Copyright 2016 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 route53 + +import ( + "flag" + "fmt" + "os" + "testing" + + "k8s.io/kubernetes/federation/pkg/dnsprovider" + route53testing "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/stubs" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/route53" + "k8s.io/kubernetes/federation/pkg/dnsprovider/tests" +) + +func newTestInterface() (dnsprovider.Interface, error) { + // Use this to test the real cloud service. + // return dnsprovider.GetDnsProvider(ProviderName, strings.NewReader("\n[global]\nproject-id = federation0-cluster00")) + return newFakeInterface() // Use this to stub out the entire cloud service +} + +func newFakeInterface() (dnsprovider.Interface, error) { + var service route53testing.Route53API + service = route53testing.NewRoute53APIStub() + iface := New(service) + // Add a fake zone to test against. + params := &route53.CreateHostedZoneInput{ + CallerReference: aws.String("Nonce"), // Required + Name: aws.String("example.com"), // Required + } + _, err := iface.service.CreateHostedZone(params) + if err != nil { + return nil, err + } + return iface, nil +} + +var interface_ dnsprovider.Interface + +func TestMain(m *testing.M) { + fmt.Printf("Parsing flags.\n") + flag.Parse() + var err error + fmt.Printf("Getting new test interface.\n") + interface_, err = newTestInterface() + if err != nil { + fmt.Printf("Error creating interface: %v", err) + os.Exit(1) + } + fmt.Printf("Running tests...\n") + os.Exit(m.Run()) +} + +// zones returns the zones interface for the configured dns provider account/project, +// or fails if it can't be found +func zones(t *testing.T) dnsprovider.Zones { + zonesInterface, supported := interface_.Zones() + if !supported { + t.Fatalf("Zones interface not supported by interface %v", interface_) + } else { + t.Logf("Got zones %v\n", zonesInterface) + } + return zonesInterface +} + +// firstZone returns the first zone for the configured dns provider account/project, +// or fails if it can't be found +func firstZone(t *testing.T) dnsprovider.Zone { + t.Logf("Getting zones") + z := zones(t) + zones, err := z.List() + if err != nil { + t.Fatalf("Failed to list zones: %v", err) + } else { + t.Logf("Got zone list: %v\n", zones) + } + if len(zones) < 1 { + t.Fatalf("Zone listing returned %d, expected >= %d", len(zones), 1) + } else { + t.Logf("Got at least 1 zone in list:%v\n", zones[0]) + } + return zones[0] +} + +/* rrs returns the ResourceRecordSets interface for a given zone */ +func rrs(t *testing.T, zone dnsprovider.Zone) (r dnsprovider.ResourceRecordSets) { + rrsets, supported := zone.ResourceRecordSets() + if !supported { + t.Fatalf("ResourceRecordSets interface not supported by zone %v", zone) + return r + } + return rrsets +} + +func listRrsOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets) []dnsprovider.ResourceRecordSet { + rrset, err := rrsets.List() + if err != nil { + t.Fatalf("Failed to list recordsets: %v", err) + } else { + if len(rrset) < 0 { + t.Fatalf("Record set length=%d, expected >=0", len(rrset)) + } else { + t.Logf("Got %d recordsets: %v", len(rrset), rrset) + } + } + return rrset +} + +func getExampleRrs(zone dnsprovider.Zone) dnsprovider.ResourceRecordSet { + rrsets, _ := zone.ResourceRecordSets() + return rrsets.New("www11."+zone.Name(), []string{"10.10.10.10", "169.20.20.20"}, 180, rrstype.A) +} + +func getInvalidRrs(zone dnsprovider.Zone) dnsprovider.ResourceRecordSet { + rrsets, _ := zone.ResourceRecordSets() + return rrsets.New("www12."+zone.Name(), []string{"rubbish", "rubbish"}, 180, rrstype.A) +} + +func addRrsetOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets, rrset dnsprovider.ResourceRecordSet) { + err := rrsets.StartChangeset().Add(rrset).Apply() + if err != nil { + t.Fatalf("Failed to add recordsets: %v", err) + } +} + +/* TestZonesList verifies that listing of zones succeeds */ +func TestZonesList(t *testing.T) { + firstZone(t) +} + +/* TestZonesID verifies that the id of the zone is returned with the prefix removed */ +func TestZonesID(t *testing.T) { + zone := firstZone(t) + + // Check /hostedzone/ prefix is removed + zoneID := zone.ID() + if zoneID != zone.Name() { + t.Fatalf("Unexpected zone id: %q", zoneID) + } +} + +/* TestZoneAddSuccess verifies that addition of a valid managed DNS zone succeeds */ +func TestZoneAddSuccess(t *testing.T) { + testZoneName := "ubernetes.testing" + z := zones(t) + input, err := z.New(testZoneName) + if err != nil { + t.Errorf("Failed to allocate new zone object %s: %v", testZoneName, err) + } + zone, err := z.Add(input) + if err != nil { + t.Errorf("Failed to create new managed DNS zone %s: %v", testZoneName, err) + } + defer func(zone dnsprovider.Zone) { + if zone != nil { + if err := z.Remove(zone); err != nil { + t.Errorf("Failed to delete zone %v: %v", zone, err) + } + } + }(zone) + t.Logf("Successfully added managed DNS zone: %v", zone) +} + +/* TestResourceRecordSetsList verifies that listing of RRS's succeeds */ +func TestResourceRecordSetsList(t *testing.T) { + listRrsOrFail(t, rrs(t, firstZone(t))) +} + +/* TestResourceRecordSetsAddSuccess verifies that addition of a valid RRS succeeds */ +func TestResourceRecordSetsAddSuccess(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + set := getExampleRrs(zone) + addRrsetOrFail(t, sets, set) + defer sets.StartChangeset().Remove(set).Apply() + t.Logf("Successfully added resource record set: %v", set) +} + +/* TestResourceRecordSetsAdditionVisible verifies that added RRS is visible after addition */ +func TestResourceRecordSetsAdditionVisible(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + defer sets.StartChangeset().Remove(rrset).Apply() + t.Logf("Successfully added resource record set: %v", rrset) + found := false + for _, record := range listRrsOrFail(t, sets) { + if record.Name() == rrset.Name() { + found = true + break + } + } + if !found { + t.Errorf("Failed to find added resource record set %s", rrset.Name()) + } +} + +/* TestResourceRecordSetsAddDuplicateFail verifies that addition of a duplicate RRS fails */ +func TestResourceRecordSetsAddDuplicateFail(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + defer sets.StartChangeset().Remove(rrset).Apply() + t.Logf("Successfully added resource record set: %v", rrset) + // Try to add it again, and verify that the call fails. + err := sets.StartChangeset().Add(rrset).Apply() + if err == nil { + defer sets.StartChangeset().Remove(rrset).Apply() + t.Errorf("Should have failed to add duplicate resource record %v, but succeeded instead.", rrset) + } else { + t.Logf("Correctly failed to add duplicate resource record %v: %v", rrset, err) + } +} + +/* TestResourceRecordSetsRemove verifies that the removal of an existing RRS succeeds */ +func TestResourceRecordSetsRemove(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + err := sets.StartChangeset().Remove(rrset).Apply() + if err != nil { + // Try again to clean up. + defer sets.StartChangeset().Remove(rrset).Apply() + t.Errorf("Failed to remove resource record set %v after adding", rrset) + } else { + t.Logf("Successfully removed resource set %v after adding", rrset) + } +} + +/* TestResourceRecordSetsRemoveGone verifies that a removed RRS no longer exists */ +func TestResourceRecordSetsRemoveGone(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + err := sets.StartChangeset().Remove(rrset).Apply() + if err != nil { + // Try again to clean up. + defer sets.StartChangeset().Remove(rrset).Apply() + t.Errorf("Failed to remove resource record set %v after adding", rrset) + } else { + t.Logf("Successfully removed resource set %v after adding", rrset) + } + // Check that it's gone + list := listRrsOrFail(t, sets) + found := false + for _, set := range list { + if set.Name() == rrset.Name() { + found = true + break + } + } + if found { + t.Errorf("Deleted resource record set %v is still present", rrset) + } +} + +/* TestResourceRecordSetsReplace verifies that replacing an RRS works */ +func TestResourceRecordSetsReplace(t *testing.T) { + zone := firstZone(t) + tests.CommonTestResourceRecordSetsReplace(t, zone) +} + +/* TestResourceRecordSetsReplaceAll verifies that we can remove an RRS and create one with a different name*/ +func TestResourceRecordSetsReplaceAll(t *testing.T) { + zone := firstZone(t) + tests.CommonTestResourceRecordSetsReplaceAll(t, zone) +} + +/* TestResourceRecordSetsDifferentTypes verifies that we can add records of the same name but different types */ +func TestResourceRecordSetsDifferentTypes(t *testing.T) { + zone := firstZone(t) + tests.CommonTestResourceRecordSetsDifferentTypes(t, zone) +} diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go new file mode 100644 index 0000000000000..7727159fa32b4 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go @@ -0,0 +1,134 @@ +/* +Copyright 2016 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 route53 + +import ( + "bytes" + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/route53" + "github.com/golang/glog" + "k8s.io/kubernetes/federation/pkg/dnsprovider" +) + +// Compile time check for interface adherence +var _ dnsprovider.ResourceRecordChangeset = &ResourceRecordChangeset{} + +type ResourceRecordChangeset struct { + zone *Zone + rrsets *ResourceRecordSets + + additions []dnsprovider.ResourceRecordSet + removals []dnsprovider.ResourceRecordSet + upserts []dnsprovider.ResourceRecordSet +} + +func (c *ResourceRecordChangeset) Add(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { + c.additions = append(c.additions, rrset) + return c +} + +func (c *ResourceRecordChangeset) Remove(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { + c.removals = append(c.removals, rrset) + return c +} + +func (c *ResourceRecordChangeset) Upsert(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { + c.upserts = append(c.upserts, rrset) + return c +} + +// buildChange converts a dnsprovider.ResourceRecordSet to a route53.Change request +func buildChange(action string, rrs dnsprovider.ResourceRecordSet) *route53.Change { + change := &route53.Change{ + Action: aws.String(action), + ResourceRecordSet: &route53.ResourceRecordSet{ + Name: aws.String(rrs.Name()), + Type: aws.String(string(rrs.Type())), + TTL: aws.Int64(rrs.Ttl()), + }, + } + + for _, rrdata := range rrs.Rrdatas() { + rr := &route53.ResourceRecord{ + Value: aws.String(rrdata), + } + change.ResourceRecordSet.ResourceRecords = append(change.ResourceRecordSet.ResourceRecords, rr) + } + return change +} + +func (c *ResourceRecordChangeset) Apply() error { + hostedZoneID := c.zone.impl.Id + + var changes []*route53.Change + + for _, removal := range c.removals { + change := buildChange(route53.ChangeActionDelete, removal) + changes = append(changes, change) + } + + for _, addition := range c.additions { + change := buildChange(route53.ChangeActionCreate, addition) + changes = append(changes, change) + } + + for _, upsert := range c.upserts { + change := buildChange(route53.ChangeActionUpsert, upsert) + changes = append(changes, change) + } + + if len(changes) == 0 { + return nil + } + + if glog.V(8) { + var sb bytes.Buffer + for _, change := range changes { + sb.WriteString(fmt.Sprintf("\t%s %s %s\n", aws.StringValue(change.Action), aws.StringValue(change.ResourceRecordSet.Type), aws.StringValue(change.ResourceRecordSet.Name))) + } + + glog.V(8).Infof("Route53 Changeset:\n%s", sb.String()) + } + + service := c.zone.zones.interface_.service + + request := &route53.ChangeResourceRecordSetsInput{ + ChangeBatch: &route53.ChangeBatch{ + Changes: changes, + }, + HostedZoneId: hostedZoneID, + } + + _, err := service.ChangeResourceRecordSets(request) + if err != nil { + // Cast err to awserr.Error to get the Code and + // Message from an error. + return err + } + return nil +} + +func (c *ResourceRecordChangeset) IsEmpty() bool { + return len(c.removals) == 0 && len(c.additions) == 0 +} + +// ResourceRecordSets returns the parent ResourceRecordSets +func (c *ResourceRecordChangeset) ResourceRecordSets() dnsprovider.ResourceRecordSets { + return c.rrsets +} diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrset.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrset.go new file mode 100644 index 0000000000000..cee6fcc3425ae --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrset.go @@ -0,0 +1,63 @@ +/* +Copyright 2016 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 route53 + +import ( + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/route53" +) + +// Compile time check for interface adherence +var _ dnsprovider.ResourceRecordSet = ResourceRecordSet{} + +type ResourceRecordSet struct { + impl *route53.ResourceRecordSet + rrsets *ResourceRecordSets +} + +func (rrset ResourceRecordSet) Name() string { + return aws.StringValue(rrset.impl.Name) +} + +func (rrset ResourceRecordSet) Rrdatas() []string { + // Sigh - need to unpack the strings out of the route53 ResourceRecords + result := make([]string, len(rrset.impl.ResourceRecords)) + for i, record := range rrset.impl.ResourceRecords { + result[i] = aws.StringValue(record.Value) + } + return result +} + +func (rrset ResourceRecordSet) Ttl() int64 { + return aws.Int64Value(rrset.impl.TTL) +} + +func (rrset ResourceRecordSet) Type() rrstype.RrsType { + return rrstype.RrsType(aws.StringValue(rrset.impl.Type)) +} + +// Route53ResourceRecordSet returns the route53 ResourceRecordSet object for the ResourceRecordSet +// This is a "back door" that allows for limited access to the ResourceRecordSet, +// without having to requery it, so that we can expose AWS specific functionality. +// Using this method should be avoided where possible; instead prefer to add functionality +// to the cross-provider ResourceRecordSet interface. +func (rrset ResourceRecordSet) Route53ResourceRecordSet() *route53.ResourceRecordSet { + return rrset.impl +} diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrsets.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrsets.go new file mode 100644 index 0000000000000..67470c8778fc4 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrsets.go @@ -0,0 +1,106 @@ +/* +Copyright 2016 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 route53 + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/route53" + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +// Compile time check for interface adherence +var _ dnsprovider.ResourceRecordSets = ResourceRecordSets{} + +type ResourceRecordSets struct { + zone *Zone +} + +func (rrsets ResourceRecordSets) List() ([]dnsprovider.ResourceRecordSet, error) { + input := route53.ListResourceRecordSetsInput{ + HostedZoneId: rrsets.zone.impl.Id, + } + + var list []dnsprovider.ResourceRecordSet + err := rrsets.zone.zones.interface_.service.ListResourceRecordSetsPages(&input, func(page *route53.ListResourceRecordSetsOutput, lastPage bool) bool { + for _, rrset := range page.ResourceRecordSets { + list = append(list, &ResourceRecordSet{rrset, &rrsets}) + } + return true + }) + if err != nil { + return nil, err + } + return list, nil +} + +func (rrsets ResourceRecordSets) Get(name string) ([]dnsprovider.ResourceRecordSet, error) { + // This list implementation is very similar to the one implemented in + // the List() method above, but it restricts the retrieved list to + // the records whose name match the given `name`. + input := route53.ListResourceRecordSetsInput{ + HostedZoneId: rrsets.zone.impl.Id, + StartRecordName: aws.String(name), + } + + var list []dnsprovider.ResourceRecordSet + err := rrsets.zone.zones.interface_.service.ListResourceRecordSetsPages(&input, func(page *route53.ListResourceRecordSetsOutput, lastPage bool) bool { + for _, rrset := range page.ResourceRecordSets { + if aws.StringValue(rrset.Name) != name { + return false + } + list = append(list, &ResourceRecordSet{rrset, &rrsets}) + } + return true + }) + if err != nil { + return nil, err + } + + return list, nil +} + +func (r ResourceRecordSets) StartChangeset() dnsprovider.ResourceRecordChangeset { + return &ResourceRecordChangeset{ + zone: r.zone, + rrsets: &r, + } +} + +func (r ResourceRecordSets) New(name string, rrdatas []string, ttl int64, rrstype rrstype.RrsType) dnsprovider.ResourceRecordSet { + rrstypeStr := string(rrstype) + rrs := &route53.ResourceRecordSet{ + Name: &name, + Type: &rrstypeStr, + TTL: &ttl, + } + for _, rrdata := range rrdatas { + rrs.ResourceRecords = append(rrs.ResourceRecords, &route53.ResourceRecord{ + Value: aws.String(rrdata), + }) + } + + return ResourceRecordSet{ + rrs, + &r, + } +} + +// Zone returns the parent zone +func (rrset ResourceRecordSets) Zone() dnsprovider.Zone { + return rrset.zone +} diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs/route53api.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs/route53api.go new file mode 100644 index 0000000000000..b09155a6da038 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs/route53api.go @@ -0,0 +1,133 @@ +/* +Copyright 2016 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. +*/ + +/* internal implements a stub for the AWS Route53 API, used primarily for unit testing purposes */ +package stubs + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/route53" +) + +// Compile time check for interface conformance +var _ Route53API = &Route53APIStub{} + +/* Route53API is the subset of the AWS Route53 API that we actually use. Add methods as required. Signatures must match exactly. */ +type Route53API interface { + ListResourceRecordSetsPages(input *route53.ListResourceRecordSetsInput, fn func(p *route53.ListResourceRecordSetsOutput, lastPage bool) (shouldContinue bool)) error + ChangeResourceRecordSets(*route53.ChangeResourceRecordSetsInput) (*route53.ChangeResourceRecordSetsOutput, error) + ListHostedZonesPages(input *route53.ListHostedZonesInput, fn func(p *route53.ListHostedZonesOutput, lastPage bool) (shouldContinue bool)) error + CreateHostedZone(*route53.CreateHostedZoneInput) (*route53.CreateHostedZoneOutput, error) + DeleteHostedZone(*route53.DeleteHostedZoneInput) (*route53.DeleteHostedZoneOutput, error) +} + +// Route53APIStub is a minimal implementation of Route53API, used primarily for unit testing. +// See http://http://docs.aws.amazon.com/sdk-for-go/api/service/route53.html for descriptions +// of all of its methods. +type Route53APIStub struct { + zones map[string]*route53.HostedZone + recordSets map[string]map[string][]*route53.ResourceRecordSet +} + +// NewRoute53APIStub returns an initialized Route53APIStub +func NewRoute53APIStub() *Route53APIStub { + return &Route53APIStub{ + zones: make(map[string]*route53.HostedZone), + recordSets: make(map[string]map[string][]*route53.ResourceRecordSet), + } +} + +func (r *Route53APIStub) ListResourceRecordSetsPages(input *route53.ListResourceRecordSetsInput, fn func(p *route53.ListResourceRecordSetsOutput, lastPage bool) (shouldContinue bool)) error { + output := route53.ListResourceRecordSetsOutput{} // TODO: Support optional input args. + if len(r.recordSets) <= 0 { + output.ResourceRecordSets = []*route53.ResourceRecordSet{} + } else if _, ok := r.recordSets[*input.HostedZoneId]; !ok { + output.ResourceRecordSets = []*route53.ResourceRecordSet{} + } else { + for _, rrsets := range r.recordSets[*input.HostedZoneId] { + for _, rrset := range rrsets { + output.ResourceRecordSets = append(output.ResourceRecordSets, rrset) + } + } + } + lastPage := true + fn(&output, lastPage) + return nil +} + +func (r *Route53APIStub) ChangeResourceRecordSets(input *route53.ChangeResourceRecordSetsInput) (*route53.ChangeResourceRecordSetsOutput, error) { + output := &route53.ChangeResourceRecordSetsOutput{} + recordSets, ok := r.recordSets[*input.HostedZoneId] + if !ok { + recordSets = make(map[string][]*route53.ResourceRecordSet) + } + + for _, change := range input.ChangeBatch.Changes { + key := *change.ResourceRecordSet.Name + "::" + *change.ResourceRecordSet.Type + switch *change.Action { + case route53.ChangeActionCreate: + if _, found := recordSets[key]; found { + return nil, fmt.Errorf("Attempt to create duplicate rrset %s", key) // TODO: Return AWS errors with codes etc + } + recordSets[key] = append(recordSets[key], change.ResourceRecordSet) + case route53.ChangeActionDelete: + if _, found := recordSets[key]; !found { + return nil, fmt.Errorf("Attempt to delete non-existent rrset %s", key) // TODO: Check other fields too + } + delete(recordSets, key) + case route53.ChangeActionUpsert: + // TODO - not used yet + } + } + r.recordSets[*input.HostedZoneId] = recordSets + return output, nil // TODO: We should ideally return status etc, but we don't' use that yet. +} + +func (r *Route53APIStub) ListHostedZonesPages(input *route53.ListHostedZonesInput, fn func(p *route53.ListHostedZonesOutput, lastPage bool) (shouldContinue bool)) error { + output := &route53.ListHostedZonesOutput{} + for _, zone := range r.zones { + output.HostedZones = append(output.HostedZones, zone) + } + lastPage := true + fn(output, lastPage) + return nil +} + +func (r *Route53APIStub) CreateHostedZone(input *route53.CreateHostedZoneInput) (*route53.CreateHostedZoneOutput, error) { + name := aws.StringValue(input.Name) + id := "/hostedzone/" + name + if _, ok := r.zones[id]; ok { + return nil, fmt.Errorf("Error creating hosted DNS zone: %s already exists", id) + } + r.zones[id] = &route53.HostedZone{ + Id: aws.String(id), + Name: aws.String(name), + } + return &route53.CreateHostedZoneOutput{HostedZone: r.zones[id]}, nil +} + +func (r *Route53APIStub) DeleteHostedZone(input *route53.DeleteHostedZoneInput) (*route53.DeleteHostedZoneOutput, error) { + if _, ok := r.zones[*input.Id]; !ok { + return nil, fmt.Errorf("Error deleting hosted DNS zone: %s does not exist", *input.Id) + } + if len(r.recordSets[*input.Id]) > 0 { + return nil, fmt.Errorf("Error deleting hosted DNS zone: %s has resource records", *input.Id) + } + delete(r.zones, *input.Id) + return &route53.DeleteHostedZoneOutput{}, nil +} diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/zone.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/zone.go new file mode 100644 index 0000000000000..7d82783ba09c0 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/zone.go @@ -0,0 +1,56 @@ +/* +Copyright 2016 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 route53 + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/route53" + "k8s.io/kubernetes/federation/pkg/dnsprovider" +) + +// Compile time check for interface adherence +var _ dnsprovider.Zone = &Zone{} + +type Zone struct { + impl *route53.HostedZone + zones *Zones +} + +func (zone *Zone) Name() string { + return aws.StringValue(zone.impl.Name) +} + +func (zone *Zone) ID() string { + id := aws.StringValue(zone.impl.Id) + id = strings.TrimPrefix(id, "/hostedzone/") + return id +} + +func (zone *Zone) ResourceRecordSets() (dnsprovider.ResourceRecordSets, bool) { + return &ResourceRecordSets{zone}, true +} + +// Route53HostedZone returns the route53 HostedZone object for the zone. +// This is a "back door" that allows for limited access to the HostedZone, +// without having to requery it, so that we can expose AWS specific functionality. +// Using this method should be avoided where possible; instead prefer to add functionality +// to the cross-provider Zone interface. +func (zone *Zone) Route53HostedZone() *route53.HostedZone { + return zone.impl +} diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/zones.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/zones.go new file mode 100644 index 0000000000000..4cb9e9c5585c7 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/zones.go @@ -0,0 +1,73 @@ +/* +Copyright 2016 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 route53 + +import ( + "github.com/aws/aws-sdk-go/service/route53" + + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/kubernetes/federation/pkg/dnsprovider" +) + +// Compile time check for interface adherence +var _ dnsprovider.Zones = Zones{} + +type Zones struct { + interface_ *Interface +} + +func (zones Zones) List() ([]dnsprovider.Zone, error) { + var zoneList []dnsprovider.Zone + + input := route53.ListHostedZonesInput{} + err := zones.interface_.service.ListHostedZonesPages(&input, func(page *route53.ListHostedZonesOutput, lastPage bool) bool { + for _, zone := range page.HostedZones { + zoneList = append(zoneList, &Zone{zone, &zones}) + } + return true + }) + if err != nil { + return []dnsprovider.Zone{}, err + } + return zoneList, nil +} + +func (zones Zones) Add(zone dnsprovider.Zone) (dnsprovider.Zone, error) { + dnsName := zone.Name() + callerReference := string(uuid.NewUUID()) + input := route53.CreateHostedZoneInput{Name: &dnsName, CallerReference: &callerReference} + output, err := zones.interface_.service.CreateHostedZone(&input) + if err != nil { + return nil, err + } + return &Zone{output.HostedZone, &zones}, nil +} + +func (zones Zones) Remove(zone dnsprovider.Zone) error { + zoneId := zone.(*Zone).impl.Id + input := route53.DeleteHostedZoneInput{Id: zoneId} + _, err := zones.interface_.service.DeleteHostedZone(&input) + if err != nil { + return err + } + return nil +} +func (zones Zones) New(name string) (dnsprovider.Zone, error) { + id := string(uuid.NewUUID()) + managedZone := route53.HostedZone{Id: &id, Name: &name} + return &Zone{&managedZone, &zones}, nil +} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go new file mode 100644 index 0000000000000..ba39ba5fb1c75 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go @@ -0,0 +1,95 @@ +/* +Copyright 2016 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 coredns is the implementation of pkg/dnsprovider interface for CoreDNS +package coredns + +import ( + "fmt" + etcdc "github.com/coreos/etcd/client" + "github.com/golang/glog" + "gopkg.in/gcfg.v1" + "io" + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "strconv" + "strings" +) + +// "coredns" should be used to use this DNS provider +const ( + ProviderName = "coredns" +) + +// Config to override defaults +type Config struct { + Global struct { + EtcdEndpoints string `gcfg:"etcd-endpoints"` + DNSZones string `gcfg:"zones"` + CoreDNSEndpoints string `gcfg:"coredns-endpoints"` + } +} + +func init() { + dnsprovider.RegisterDnsProvider(ProviderName, func(config io.Reader) (dnsprovider.Interface, error) { + return newCoreDNSProviderInterface(config) + }) +} + +// newCoreDnsProviderInterface creates a new instance of an CoreDNS DNS Interface. +func newCoreDNSProviderInterface(config io.Reader) (*Interface, error) { + etcdEndpoints := "http://federation-dns-server-etcd:2379" + etcdPathPrefix := "skydns" + dnsZones := "" + + // Possibly override defaults with config below + if config != nil { + var cfg Config + if err := gcfg.ReadInto(&cfg, config); err != nil { + glog.Errorf("Couldn't read config: %v", err) + return nil, err + } + etcdEndpoints = cfg.Global.EtcdEndpoints + dnsZones = cfg.Global.DNSZones + } + glog.Infof("Using CoreDNS DNS provider") + + if dnsZones == "" { + return nil, fmt.Errorf("Need to provide at least one DNS Zone") + } + + etcdCfg := etcdc.Config{ + Endpoints: strings.Split(etcdEndpoints, ","), + Transport: etcdc.DefaultTransport, + } + + c, err := etcdc.New(etcdCfg) + if err != nil { + return nil, fmt.Errorf("Create etcd client from the config failed") + } + etcdKeysAPI := etcdc.NewKeysAPI(c) + + intf := newInterfaceWithStub(etcdKeysAPI) + intf.etcdPathPrefix = etcdPathPrefix + zoneList := strings.Split(dnsZones, ",") + + intf.zones = Zones{intf: intf} + for index, zoneName := range zoneList { + zone := Zone{domain: zoneName, id: strconv.Itoa(index), zones: &intf.zones} + intf.zones.zoneList = append(intf.zones.zoneList, zone) + } + + return intf, nil +} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go new file mode 100644 index 0000000000000..39012573fd35a --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go @@ -0,0 +1,270 @@ +/* +Copyright 2016 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 coredns + +import ( + "flag" + "fmt" + "os" + "strconv" + "testing" + + "k8s.io/kubernetes/federation/pkg/dnsprovider" + corednstesting "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/stubs" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + + "k8s.io/kubernetes/federation/pkg/dnsprovider/tests" + "strings" +) + +func newTestInterface() (dnsprovider.Interface, error) { + // Use this to test the real cloud service. + // return dnsprovider.GetDnsProvider(ProviderName, strings.NewReader("\n[global]\nproject-id = federation0-cluster00")) + return newFakeInterface() // Use this to stub out the entire cloud service +} + +func newFakeInterface() (dnsprovider.Interface, error) { + var service corednstesting.EtcdKeysAPI + service = corednstesting.NewEtcdKeysAPIStub() + intf := newInterfaceWithStub(service) + intf.etcdPathPrefix = "skydns" + + zoneList := strings.Split("example.com,federation.io", ",") + intf.zones = Zones{intf: intf} + for index, zoneName := range zoneList { + zone := Zone{domain: zoneName, id: strconv.Itoa(index), zones: &intf.zones} + intf.zones.zoneList = append(intf.zones.zoneList, zone) + } + + return intf, nil +} + +var intf dnsprovider.Interface + +func TestMain(m *testing.M) { + fmt.Printf("Parsing flags.\n") + flag.Parse() + var err error + fmt.Printf("Getting new test interface.\n") + intf, err = newTestInterface() + if err != nil { + fmt.Printf("Error creating interface: %v", err) + os.Exit(1) + } + fmt.Printf("Running tests...\n") + os.Exit(m.Run()) +} + +// zones returns the zones interface for the configured dns provider account/project, +// or fails if it can't be found +func zones(t *testing.T) dnsprovider.Zones { + zonesInterface, supported := intf.Zones() + if !supported { + t.Fatalf("Zones interface not supported by interface %v", intf) + } else { + t.Logf("Got zones %v\n", zonesInterface) + } + return zonesInterface +} + +// firstZone returns the first zone for the configured dns provider account/project, +// or fails if it can't be found +func firstZone(t *testing.T) dnsprovider.Zone { + t.Logf("Getting zones") + z := zones(t) + zones, err := z.List() + if err != nil { + t.Fatalf("Failed to list zones: %v", err) + } else { + t.Logf("Got zone list: %v\n", zones) + } + if len(zones) < 1 { + t.Fatalf("Zone listing returned %d, expected >= %d", len(zones), 1) + } else { + t.Logf("Got at least 1 zone in list:%v\n", zones[0]) + } + return zones[0] +} + +/* rrs returns the ResourceRecordSets interface for a given zone */ +func rrs(t *testing.T, zone dnsprovider.Zone) (r dnsprovider.ResourceRecordSets) { + rrsets, supported := zone.ResourceRecordSets() + if !supported { + t.Fatalf("ResourceRecordSets interface not supported by zone %v", zone) + return r + } + return rrsets +} + +func listRrsOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets) []dnsprovider.ResourceRecordSet { + rrset, err := rrsets.List() + if err != nil { + t.Fatalf("Failed to list recordsets: %v", err) + } else { + if len(rrset) < 0 { + t.Fatalf("Record set length=%d, expected >=0", len(rrset)) + } else { + t.Logf("Got %d recordsets: %v", len(rrset), rrset) + } + } + return rrset +} + +func getRrOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets, name string) []dnsprovider.ResourceRecordSet { + rrsetList, err := rrsets.Get(name) + if err != nil { + t.Fatalf("Failed to get recordset: %v", err) + } else if len(rrsetList) == 0 { + t.Logf("Did not Get recordset: %v", name) + } else { + t.Logf("Got recordsets: %v", rrsetList) + } + return rrsetList +} + +func getExampleRrs(zone dnsprovider.Zone) dnsprovider.ResourceRecordSet { + rrsets, _ := zone.ResourceRecordSets() + return rrsets.New("www11."+zone.Name(), []string{"10.10.10.10", "169.20.20.20"}, 180, rrstype.A) +} + +func addRrsetOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets, rrset dnsprovider.ResourceRecordSet) { + err := rrsets.StartChangeset().Add(rrset).Apply() + if err != nil { + t.Fatalf("Failed to add recordsets: %v", err) + } +} + +/* TestZonesList verifies that listing of zones succeeds */ +func TestZonesList(t *testing.T) { + firstZone(t) +} + +/* TestZonesID verifies that the id of the zone is unique */ +func TestZonesID(t *testing.T) { + zone := firstZone(t) + + zoneID := zone.ID() + if zoneID != "0" { + t.Fatalf("Unexpected zone id: %q", zoneID) + } +} + +/* TestResourceRecordSetsGet verifies that getting of RRS succeeds */ +func TestResourceRecordSetsGet(t *testing.T) { + getRrOrFail(t, rrs(t, firstZone(t)), "example.com") +} + +/* TestResourceRecordSetsAddSuccess verifies that addition of a valid RRS succeeds */ +func TestResourceRecordSetsAddSuccess(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + set := getExampleRrs(zone) + addRrsetOrFail(t, sets, set) + defer sets.StartChangeset().Remove(set).Apply() + t.Logf("Successfully added resource record set: %v", set) + if sets.Zone().ID() != zone.ID() { + t.Errorf("Zone for rrset does not match expected") + } +} + +/* TestResourceRecordSetsAdditionVisible verifies that added RRS is visible after addition */ +func TestResourceRecordSetsAdditionVisible(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + defer sets.StartChangeset().Remove(rrset).Apply() + t.Logf("Successfully added resource record set: %v", rrset) + + record := getRrOrFail(t, sets, rrset.Name()) + if record == nil { + t.Errorf("Failed to find added resource record set %s", rrset.Name()) + } +} + +/* TestResourceRecordSetsAddDuplicateFail verifies that addition of a duplicate RRS fails */ +func TestResourceRecordSetsAddDuplicateFail(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + defer sets.StartChangeset().Remove(rrset).Apply() + t.Logf("Successfully added resource record set: %v", rrset) + // Try to add it again, and verify that the call fails. + err := sets.StartChangeset().Add(rrset).Apply() + if err == nil { + defer sets.StartChangeset().Remove(rrset).Apply() + t.Errorf("Should have failed to add duplicate resource record %v, but succeeded instead.", rrset) + } else { + t.Logf("Correctly failed to add duplicate resource record %v: %v", rrset, err) + } +} + +/* TestResourceRecordSetsRemove verifies that the removal of an existing RRS succeeds */ +func TestResourceRecordSetsRemove(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + err := sets.StartChangeset().Remove(rrset).Apply() + if err != nil { + // Try again to clean up. + defer sets.StartChangeset().Remove(rrset).Apply() + t.Errorf("Failed to remove resource record set %v after adding", rrset) + } else { + t.Logf("Successfully removed resource set %v after adding", rrset) + } +} + +/* TestResourceRecordSetsRemoveGone verifies that a removed RRS no longer exists */ +func TestResourceRecordSetsRemoveGone(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + err := sets.StartChangeset().Remove(rrset).Apply() + if err != nil { + // Try again to clean up. + defer sets.StartChangeset().Remove(rrset).Apply() + t.Errorf("Failed to remove resource record set %v after adding", rrset) + } else { + t.Logf("Successfully removed resource set %v after adding", rrset) + } + + record := getRrOrFail(t, sets, rrset.Name()) + if record != nil { + t.Errorf("Deleted resource record set %v is still present", rrset) + } +} + +/* TestResourceRecordSetsReplace verifies that replacing an RRS works */ +func TestResourceRecordSetsReplace(t *testing.T) { + zone := firstZone(t) + tests.CommonTestResourceRecordSetsReplace(t, zone) +} + +/* TestResourceRecordSetsReplaceAll verifies that we can remove an RRS and create one with a different name */ +func TestResourceRecordSetsReplaceAll(t *testing.T) { + zone := firstZone(t) + tests.CommonTestResourceRecordSetsReplaceAll(t, zone) +} + +/* TestResourceRecordSetsDifferentTypes verifies that we can add records with same name, but different types */ +func TestResourceRecordSetsDifferentTypes(t *testing.T) { + zone := firstZone(t) + tests.CommonTestResourceRecordSetsDifferentTypes(t, zone) +} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go b/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go new file mode 100644 index 0000000000000..d579fd4725c6a --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go @@ -0,0 +1,41 @@ +/* +Copyright 2016 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 coredns + +import ( + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/stubs" +) + +// Compile time check for interface adherence +var _ dnsprovider.Interface = Interface{} + +type Interface struct { + etcdKeysAPI stubs.EtcdKeysAPI + etcdPathPrefix string + zones Zones +} + +// newInterfaceWithStub facilitates stubbing out the underlying etcd +// library for testing purposes. It returns an provider-independent interface. +func newInterfaceWithStub(etcdKeysAPI stubs.EtcdKeysAPI) *Interface { + return &Interface{etcdKeysAPI: etcdKeysAPI} +} + +func (i Interface) Zones() (dnsprovider.Zones, bool) { + return i.zones, true +} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go b/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go new file mode 100644 index 0000000000000..a2f4bab5160bd --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go @@ -0,0 +1,148 @@ +/* +Copyright 2016 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 coredns + +import ( + "encoding/json" + "fmt" + "hash/fnv" + + etcdc "github.com/coreos/etcd/client" + dnsmsg "github.com/miekg/coredns/middleware/etcd/msg" + "golang.org/x/net/context" + "k8s.io/kubernetes/federation/pkg/dnsprovider" +) + +// Compile time check for interface adherence +var _ dnsprovider.ResourceRecordChangeset = &ResourceRecordChangeset{} + +type ChangeSetType string + +const ( + ADDITION = ChangeSetType("ADDITION") + DELETION = ChangeSetType("DELETION") + UPSERT = ChangeSetType("UPSERT") +) + +type ChangeSet struct { + cstype ChangeSetType + rrset dnsprovider.ResourceRecordSet +} + +type ResourceRecordChangeset struct { + zone *Zone + rrsets *ResourceRecordSets + + changeset []ChangeSet +} + +func (c *ResourceRecordChangeset) Add(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { + c.changeset = append(c.changeset, ChangeSet{cstype: ADDITION, rrset: rrset}) + return c +} + +func (c *ResourceRecordChangeset) Remove(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { + c.changeset = append(c.changeset, ChangeSet{cstype: DELETION, rrset: rrset}) + return c +} + +func (c *ResourceRecordChangeset) IsEmpty() bool { + return len(c.changeset) == 0 +} + +func (c *ResourceRecordChangeset) Upsert(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { + c.changeset = append(c.changeset, ChangeSet{cstype: UPSERT, rrset: rrset}) + return c +} + +func (c *ResourceRecordChangeset) Apply() error { + ctx := context.Background() + etcdPathPrefix := c.zone.zones.intf.etcdPathPrefix + getOpts := &etcdc.GetOptions{} + setOpts := &etcdc.SetOptions{} + deleteOpts := &etcdc.DeleteOptions{ + Recursive: true, + } + + for _, changeset := range c.changeset { + switch changeset.cstype { + case ADDITION, UPSERT: + checkNotExists := changeset.cstype == ADDITION + + // TODO: I think the semantics of the other providers are different; they operate at the record level, not the individual rrdata level + // In other words: we should insert/replace all the records for the key + for _, rrdata := range changeset.rrset.Rrdatas() { + b, err := json.Marshal(&dnsmsg.Service{Host: rrdata, TTL: uint32(changeset.rrset.Ttl()), Group: changeset.rrset.Name()}) + if err != nil { + return err + } + recordValue := string(b) + recordLabel := getHash(rrdata) + recordKey := buildDNSNameString(changeset.rrset.Name(), recordLabel) + + if checkNotExists { + response, err := c.zone.zones.intf.etcdKeysAPI.Get(ctx, dnsmsg.Path(recordKey, etcdPathPrefix), getOpts) + if err == nil && response != nil { + return fmt.Errorf("Key already exist, key: %v", recordKey) + } + } + + _, err = c.zone.zones.intf.etcdKeysAPI.Set(ctx, dnsmsg.Path(recordKey, etcdPathPrefix), recordValue, setOpts) + if err != nil { + return err + } + } + + case DELETION: + // TODO: I think the semantics of the other providers are different; they operate at the record level, not the individual rrdata level + // In other words: we should delete all the records for the key, only if it matches exactly + for _, rrdata := range changeset.rrset.Rrdatas() { + recordLabel := getHash(rrdata) + recordKey := buildDNSNameString(changeset.rrset.Name(), recordLabel) + _, err := c.zone.zones.intf.etcdKeysAPI.Delete(ctx, dnsmsg.Path(recordKey, etcdPathPrefix), deleteOpts) + if err != nil { + return err + } + } + // TODO: We need to cleanup empty dirs in etcd + } + } + return nil +} + +// ResourceRecordSets returns the parent ResourceRecordSets +func (c *ResourceRecordChangeset) ResourceRecordSets() dnsprovider.ResourceRecordSets { + return c.rrsets +} + +func getHash(text string) string { + h := fnv.New32a() + h.Write([]byte(text)) + return fmt.Sprintf("%x", h.Sum32()) +} + +func buildDNSNameString(labels ...string) string { + var res string + for _, label := range labels { + if res == "" { + res = label + } else { + res = fmt.Sprintf("%s.%s", label, res) + } + } + return res +} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go b/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go new file mode 100644 index 0000000000000..394303667ef6e --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go @@ -0,0 +1,49 @@ +/* +Copyright 2016 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 coredns + +import ( + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +// Compile time check for interface adherence +var _ dnsprovider.ResourceRecordSet = ResourceRecordSet{} + +type ResourceRecordSet struct { + name string + rrdatas []string + ttl int64 + rrsType rrstype.RrsType + rrsets *ResourceRecordSets +} + +func (rrset ResourceRecordSet) Name() string { + return rrset.name +} + +func (rrset ResourceRecordSet) Rrdatas() []string { + return rrset.rrdatas +} + +func (rrset ResourceRecordSet) Ttl() int64 { + return rrset.ttl +} + +func (rrset ResourceRecordSet) Type() rrstype.RrsType { + return rrset.rrsType +} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go b/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go new file mode 100644 index 0000000000000..dbd85cab35c94 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go @@ -0,0 +1,114 @@ +/* +Copyright 2016 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 coredns + +import ( + "encoding/json" + "fmt" + etcdc "github.com/coreos/etcd/client" + "github.com/golang/glog" + dnsmsg "github.com/miekg/coredns/middleware/etcd/msg" + "golang.org/x/net/context" + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "net" +) + +// Compile time check for interface adherence +var _ dnsprovider.ResourceRecordSets = ResourceRecordSets{} + +type ResourceRecordSets struct { + zone *Zone +} + +func (rrsets ResourceRecordSets) List() ([]dnsprovider.ResourceRecordSet, error) { + var list []dnsprovider.ResourceRecordSet + return list, fmt.Errorf("OperationNotSupported") +} + +func (rrsets ResourceRecordSets) Get(name string) ([]dnsprovider.ResourceRecordSet, error) { + getOpts := &etcdc.GetOptions{ + Recursive: true, + } + etcdPathPrefix := rrsets.zone.zones.intf.etcdPathPrefix + response, err := rrsets.zone.zones.intf.etcdKeysAPI.Get(context.Background(), dnsmsg.Path(name, etcdPathPrefix), getOpts) + if err != nil { + if etcdc.IsKeyNotFound(err) { + glog.V(2).Infof("Subdomain %q does not exist", name) + return nil, nil + } + return nil, fmt.Errorf("Failed to get service from etcd, err: %v", err) + } + if emptyResponse(response) { + glog.V(2).Infof("Subdomain %q does not exist in etcd", name) + return nil, nil + } + + var list []dnsprovider.ResourceRecordSet + + for _, node := range response.Node.Nodes { + service := dnsmsg.Service{} + err = json.Unmarshal([]byte(node.Value), &service) + if err != nil { + return nil, fmt.Errorf("Failed to unmarshall json data, err: %v", err) + } + + rrset := ResourceRecordSet{name: name, rrdatas: []string{}, rrsets: &rrsets} + ip := net.ParseIP(service.Host) + switch { + case ip == nil: + rrset.rrsType = rrstype.CNAME + case ip.To4() != nil: + rrset.rrsType = rrstype.A + case ip.To16() != nil: + rrset.rrsType = rrstype.AAAA + default: + // Cannot occur + } + rrset.rrdatas = append(rrset.rrdatas, service.Host) + rrset.ttl = int64(service.TTL) + list = append(list, rrset) + } + + return list, nil +} + +func (rrsets ResourceRecordSets) StartChangeset() dnsprovider.ResourceRecordChangeset { + return &ResourceRecordChangeset{ + zone: rrsets.zone, + rrsets: &rrsets, + } +} + +func (rrsets ResourceRecordSets) New(name string, rrdatas []string, ttl int64, rrsType rrstype.RrsType) dnsprovider.ResourceRecordSet { + return ResourceRecordSet{ + name: name, + rrdatas: rrdatas, + ttl: ttl, + rrsType: rrsType, + rrsets: &rrsets, + } +} + +// Zone returns the parent zone +func (rrset ResourceRecordSets) Zone() dnsprovider.Zone { + return rrset.zone +} + +func emptyResponse(resp *etcdc.Response) bool { + return resp == nil || resp.Node == nil || (len(resp.Node.Value) == 0 && len(resp.Node.Nodes) == 0) +} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go b/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go new file mode 100644 index 0000000000000..4e392257bb3cf --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go @@ -0,0 +1,85 @@ +/* +Copyright 2016 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 stubs implements a stub for the EtcdKeysAPI, used primarily for unit testing purposes +package stubs + +import ( + "strings" + + etcd "github.com/coreos/etcd/client" + "golang.org/x/net/context" +) + +// Compile time check for interface conformance +var _ EtcdKeysAPI = &EtcdKeysAPIStub{} + +type EtcdKeysAPI interface { + Set(context context.Context, key, value string, options *etcd.SetOptions) (*etcd.Response, error) + Get(context context.Context, key string, options *etcd.GetOptions) (*etcd.Response, error) + Delete(context context.Context, key string, options *etcd.DeleteOptions) (*etcd.Response, error) +} + +type EtcdKeysAPIStub struct { + writes map[string]string +} + +// NewEtcdKeysAPIStub returns an initialized EtcdKeysAPIStub +func NewEtcdKeysAPIStub() *EtcdKeysAPIStub { + return &EtcdKeysAPIStub{make(map[string]string)} +} + +func (ec *EtcdKeysAPIStub) Set(context context.Context, key, value string, options *etcd.SetOptions) (*etcd.Response, error) { + ec.writes[key] = value + return nil, nil +} + +func (ec *EtcdKeysAPIStub) Delete(context context.Context, key string, options *etcd.DeleteOptions) (*etcd.Response, error) { + for p := range ec.writes { + if (options.Recursive && strings.HasPrefix(p, key)) || (!options.Recursive && p == key) { + delete(ec.writes, p) + } + } + return nil, nil +} + +func (ec *EtcdKeysAPIStub) Get(context context.Context, key string, options *etcd.GetOptions) (*etcd.Response, error) { + nodes := ec.GetAll(key) + if len(nodes) == 0 { + return nil, nil + } + if len(nodes) == 1 && nodes[key] != "" { + return &etcd.Response{Node: &etcd.Node{Key: key, Value: nodes[key], Dir: false}}, nil + } + + node := &etcd.Node{Key: key, Dir: true, Nodes: etcd.Nodes{}} + for k, v := range nodes { + n := &etcd.Node{Key: k, Value: v} + node.Nodes = append(node.Nodes, n) + } + return &etcd.Response{Node: node}, nil +} + +func (ec *EtcdKeysAPIStub) GetAll(key string) map[string]string { + nodes := make(map[string]string) + key = strings.ToLower(key) + for path := range ec.writes { + if strings.HasPrefix(path, key) { + nodes[path] = ec.writes[path] + } + } + return nodes +} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go b/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go new file mode 100644 index 0000000000000..66cb7bb487903 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go @@ -0,0 +1,42 @@ +/* +Copyright 2016 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 coredns + +import ( + "k8s.io/kubernetes/federation/pkg/dnsprovider" +) + +// Compile time check for interface adherence +var _ dnsprovider.Zone = Zone{} + +type Zone struct { + domain string + id string + zones *Zones +} + +func (zone Zone) Name() string { + return zone.domain +} + +func (zone Zone) ID() string { + return zone.id +} + +func (zone Zone) ResourceRecordSets() (dnsprovider.ResourceRecordSets, bool) { + return &ResourceRecordSets{zone: &zone}, true +} diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go b/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go new file mode 100644 index 0000000000000..14e34d96652e0 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go @@ -0,0 +1,49 @@ +/* +Copyright 2016 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 coredns + +import ( + "fmt" + "k8s.io/kubernetes/federation/pkg/dnsprovider" +) + +// Compile time check for interface adherence +var _ dnsprovider.Zones = Zones{} + +type Zones struct { + intf *Interface + zoneList []Zone +} + +func (zones Zones) List() ([]dnsprovider.Zone, error) { + var zoneList []dnsprovider.Zone + for _, zone := range zones.zoneList { + zoneList = append(zoneList, zone) + } + return zoneList, nil +} + +func (zones Zones) Add(zone dnsprovider.Zone) (dnsprovider.Zone, error) { + return &Zone{}, fmt.Errorf("OperationNotSupported") +} + +func (zones Zones) Remove(zone dnsprovider.Zone) error { + return fmt.Errorf("OperationNotSupported") +} +func (zones Zones) New(name string) (dnsprovider.Zone, error) { + return &Zone{}, fmt.Errorf("OperationNotSupported") +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns.go new file mode 100644 index 0000000000000..0242087b1fa4c --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns.go @@ -0,0 +1,116 @@ +/* +Copyright 2016 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. +*/ + +// clouddns is the implementation of pkg/dnsprovider interface for Google Cloud DNS +package clouddns + +import ( + "io" + + "cloud.google.com/go/compute/metadata" + "github.com/golang/glog" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + compute "google.golang.org/api/compute/v1" + dns "google.golang.org/api/dns/v1" + gcfg "gopkg.in/gcfg.v1" + + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs" + "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" +) + +const ( + ProviderName = "google-clouddns" +) + +func init() { + dnsprovider.RegisterDnsProvider(ProviderName, func(config io.Reader) (dnsprovider.Interface, error) { + return newCloudDns(config) + }) +} + +type Config struct { + Global struct { + TokenURL string `gcfg:"token-url"` + TokenBody string `gcfg:"token-body"` + ProjectID string `gcfg:"project-id"` + } +} + +// newCloudDns creates a new instance of a Google Cloud DNS Interface. +func newCloudDns(config io.Reader) (*Interface, error) { + projectID, _ := metadata.ProjectID() // On error we get an empty string, which is fine for now. + var tokenSource oauth2.TokenSource + // Possibly override defaults with config below + if config != nil { + var cfg Config + if err := gcfg.ReadInto(&cfg, config); err != nil { + glog.Errorf("Couldn't read config: %v", err) + return nil, err + } + glog.Infof("Using Google Cloud DNS provider config %+v", cfg) + if cfg.Global.ProjectID != "" { + projectID = cfg.Global.ProjectID + } + if cfg.Global.TokenURL != "" { + tokenSource = gce.NewAltTokenSource(cfg.Global.TokenURL, cfg.Global.TokenBody) + } + } + return CreateInterface(projectID, tokenSource) +} + +// CreateInterface creates a clouddns.Interface object using the specified parameters. +// If no tokenSource is specified, uses oauth2.DefaultTokenSource. +func CreateInterface(projectID string, tokenSource oauth2.TokenSource) (*Interface, error) { + if tokenSource == nil { + var err error + tokenSource, err = google.DefaultTokenSource( + oauth2.NoContext, + compute.CloudPlatformScope, + compute.ComputeScope) + glog.Infof("Using DefaultTokenSource %#v", tokenSource) + if err != nil { + return nil, err + } + } else { + glog.Infof("Using existing Token Source %#v", tokenSource) + } + + oauthClient := oauth2.NewClient(oauth2.NoContext, tokenSource) + + service, err := dns.New(oauthClient) + if err != nil { + glog.Errorf("Failed to get Cloud DNS client: %v", err) + } + glog.Infof("Successfully got DNS service: %v\n", service) + return newInterfaceWithStub(projectID, internal.NewService(service)), nil +} + +// NewFakeInterface returns a fake clouddns interface, useful for unit testing purposes. +func NewFakeInterface() (dnsprovider.Interface, error) { + service := stubs.NewService() + interface_ := newInterfaceWithStub("", service) + zones := service.ManagedZones_ + // Add a fake zone to test against. + zone := &stubs.ManagedZone{Service: zones, Name_: "example.com", Rrsets: []stubs.ResourceRecordSet{}, Id_: 1} + call := zones.Create(interface_.project(), zone) + if _, err := call.Do(); err != nil { + return nil, err + } + return interface_, nil +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go new file mode 100644 index 0000000000000..705bb145d55d2 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go @@ -0,0 +1,273 @@ +/* +Copyright 2016 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 clouddns + +import ( + "flag" + "fmt" + "os" + "testing" + + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kubernetes/federation/pkg/dnsprovider/tests" +) + +func newTestInterface() (dnsprovider.Interface, error) { + // Use this to test the real cloud service - insert appropriate project-id. Default token source will be used. See + // https://github.com/golang/oauth2/blob/master/google/default.go for details. + // return dnsprovider.GetDnsProvider(ProviderName, strings.NewReader("\n[global]\nproject-id = federation0-cluster00")) + return NewFakeInterface() // Use this to stub out the entire cloud service +} + +var interface_ dnsprovider.Interface + +func TestMain(m *testing.M) { + flag.Parse() + var err error + interface_, err = newTestInterface() + if err != nil { + fmt.Printf("Error creating interface: %v", err) + os.Exit(1) + } + os.Exit(m.Run()) +} + +// zones returns the zones interface for the configured dns provider account/project, +// or fails if it can't be found +func zones(t *testing.T) dnsprovider.Zones { + zonesInterface, supported := interface_.Zones() + if !supported { + t.Fatalf("Zones interface not supported by interface %v", interface_) + } else { + t.Logf("Got zones %v\n", zonesInterface) + } + return zonesInterface +} + +// firstZone returns the first zone for the configured dns provider account/project, +// or fails if it can't be found +func firstZone(t *testing.T) dnsprovider.Zone { + t.Logf("Getting zones") + zones, err := zones(t).List() + if err != nil { + t.Fatalf("Failed to list zones: %v", err) + } else { + t.Logf("Got zone list: %v\n", zones) + } + if len(zones) < 1 { + t.Fatalf("Zone listing returned %d, expected >= %d", len(zones), 1) + } else { + t.Logf("Got at least 1 zone in list:%v\n", zones[0]) + } + return zones[0] +} + +/* rrs returns the ResourceRecordSets interface for a given zone */ +func rrs(t *testing.T, zone dnsprovider.Zone) (r dnsprovider.ResourceRecordSets) { + rrsets, supported := zone.ResourceRecordSets() + if !supported { + t.Fatalf("ResourceRecordSets interface not supported by zone %v", zone) + return r + } + return rrsets +} + +func listRrsOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets) []dnsprovider.ResourceRecordSet { + rrset, err := rrsets.List() + if err != nil { + t.Fatalf("Failed to list recordsets: %v", err) + } else { + if len(rrset) < 0 { + t.Fatalf("Record set length=%d, expected >=0", len(rrset)) + } else { + t.Logf("Got %d recordsets: %v", len(rrset), rrset) + } + } + return rrset +} + +func getExampleRrs(zone dnsprovider.Zone) dnsprovider.ResourceRecordSet { + rrsets, _ := zone.ResourceRecordSets() + return rrsets.New("www11."+zone.Name(), []string{"10.10.10.10", "169.20.20.20"}, 180, rrstype.A) +} + +func getInvalidRrs(zone dnsprovider.Zone) dnsprovider.ResourceRecordSet { + rrsets, _ := zone.ResourceRecordSets() + return rrsets.New("www12."+zone.Name(), []string{"rubbish", "rubbish"}, 180, rrstype.A) +} + +func addRrsetOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets, rrset dnsprovider.ResourceRecordSet) { + err := rrsets.StartChangeset().Add(rrset).Apply() + if err != nil { + t.Fatalf("Failed to add recordsets: %v", err) + } +} + +/* TestZonesList verifies that listing of zones succeeds */ +func TestZonesList(t *testing.T) { + firstZone(t) +} + +/* TestZonesID verifies that the id of the zone is returned with the prefix removed */ +func TestZonesID(t *testing.T) { + zone := firstZone(t) + + zoneID := zone.ID() + if zoneID != "1" { + t.Fatalf("Unexpected zone id: %q", zoneID) + } +} + +/* TestZoneAddSuccess verifies that addition of a valid managed DNS zone succeeds */ +func TestZoneAddSuccess(t *testing.T) { + testZoneName := "ubernetesv2.test." + t.Logf("Getting zones") + z := zones(t) + t.Logf("Got zones, making new Zone") + input, err := z.New(testZoneName) + if err != nil { + t.Errorf("Failed to allocate new zone object %s: %v", testZoneName, err) + } + zone, err := z.Add(input) + if err != nil { + t.Errorf("Failed to create new managed DNS zone %s: %v", testZoneName, err) + } + defer func(zone dnsprovider.Zone) { + if zone != nil { + if err := z.Remove(zone); err != nil { + t.Errorf("Failed to delete zone %v: %v", zone, err) + } + } + }(zone) + t.Logf("Successfully added managed DNS zone: %v", zone) +} + +/* TestResourceRecordSetsList verifies that listing of RRS's succeeds */ +func TestResourceRecordSetsList(t *testing.T) { + listRrsOrFail(t, rrs(t, firstZone(t))) +} + +/* TestResourceRecordSetsAddSuccess verifies that addition of a valid RRS succeeds */ +func TestResourceRecordSetsAddSuccess(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + set := getExampleRrs(zone) + addRrsetOrFail(t, sets, set) + defer sets.StartChangeset().Remove(set).Apply() + t.Logf("Successfully added resource record set: %v", set) +} + +/* TestResourceRecordSetsAdditionVisible verifies that added RRS is visible after addition */ +func TestResourceRecordSetsAdditionVisible(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + defer sets.StartChangeset().Remove(rrset).Apply() + t.Logf("Successfully added resource record set: %v", rrset) + found := false + for _, record := range listRrsOrFail(t, sets) { + if record.Name() == rrset.Name() { + found = true + break + } + } + if !found { + t.Errorf("Failed to find added resource record set %s", rrset.Name()) + } +} + +/* TestResourceRecordSetsAddDuplicateFail verifies that addition of a duplicate RRS fails */ +func TestResourceRecordSetsAddDuplicateFail(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + defer sets.StartChangeset().Remove(rrset).Apply() + t.Logf("Successfully added resource record set: %v", rrset) + // Try to add it again, and verify that the call fails. + err := sets.StartChangeset().Add(rrset).Apply() + if err == nil { + defer sets.StartChangeset().Remove(rrset).Apply() + t.Errorf("Should have failed to add duplicate resource record %v, but succeeded instead.", rrset) + } else { + t.Logf("Correctly failed to add duplicate resource record %v: %v", rrset, err) + } +} + +/* TestResourceRecordSetsRemove verifies that the removal of an existing RRS succeeds */ +func TestResourceRecordSetsRemove(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + err := sets.StartChangeset().Remove(rrset).Apply() + if err != nil { + // Try again to clean up. + defer sets.StartChangeset().Remove(rrset).Apply() + t.Errorf("Failed to remove resource record set %v after adding: %v", rrset, err) + } else { + t.Logf("Successfully removed resource set %v after adding", rrset) + } +} + +/* TestResourceRecordSetsRemoveGone verifies that a removed RRS no longer exists */ +func TestResourceRecordSetsRemoveGone(t *testing.T) { + zone := firstZone(t) + sets := rrs(t, zone) + rrset := getExampleRrs(zone) + addRrsetOrFail(t, sets, rrset) + err := sets.StartChangeset().Remove(rrset).Apply() + if err != nil { + // Try again to clean up. + defer sets.StartChangeset().Remove(rrset).Apply() + t.Errorf("Failed to remove resource record set %v after adding: %v", rrset, err) + } else { + t.Logf("Successfully removed resource set %v after adding", rrset) + } + // Check that it's gone + list := listRrsOrFail(t, sets) + found := false + for _, set := range list { + if set.Name() == rrset.Name() { + found = true + break + } + } + if found { + t.Errorf("Deleted resource record set %v is still present", rrset) + } +} + +/* TestResourceRecordSetsReplace verifies that replacing an RRS works */ +func TestResourceRecordSetsReplace(t *testing.T) { + zone := firstZone(t) + tests.CommonTestResourceRecordSetsReplace(t, zone) +} + +/* TestResourceRecordSetsReplaceAll verifies that we can remove an RRS and create one with a different name*/ +func TestResourceRecordSetsReplaceAll(t *testing.T) { + zone := firstZone(t) + tests.CommonTestResourceRecordSetsReplaceAll(t, zone) +} + +/* TestResourceRecordSetsDifferentType verifies that we can add records of the same name but different types */ +func TestResourceRecordSetsDifferentTypes(t *testing.T) { + zone := firstZone(t) + tests.CommonTestResourceRecordSetsDifferentTypes(t, zone) +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/interface.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/interface.go new file mode 100644 index 0000000000000..6fca4eb84c1ef --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2016 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 clouddns + +import ( + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +var _ dnsprovider.Interface = Interface{} + +type Interface struct { + project_ string + service interfaces.Service +} + +// newInterfaceWithStub facilitates stubbing out the underlying Google Cloud DNS +// library for testing purposes. It returns an provider-independent interface. +func newInterfaceWithStub(project string, service interfaces.Service) *Interface { + return &Interface{project, service} +} + +func (i Interface) Zones() (zones dnsprovider.Zones, supported bool) { + return Zones{i.service.ManagedZones(), &i}, true +} + +func (i Interface) project() string { + return i.project_ +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/change.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/change.go new file mode 100644 index 0000000000000..e229a7954d785 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/change.go @@ -0,0 +1,43 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.Change = Change{} + +type Change struct{ impl *dns.Change } + +func (c Change) Additions() (rrsets []interfaces.ResourceRecordSet) { + rrsets = make([]interfaces.ResourceRecordSet, len(c.impl.Additions)) + for index, addition := range c.impl.Additions { + rrsets[index] = interfaces.ResourceRecordSet(&ResourceRecordSet{addition}) + } + return rrsets +} + +func (c Change) Deletions() (rrsets []interfaces.ResourceRecordSet) { + rrsets = make([]interfaces.ResourceRecordSet, len(c.impl.Deletions)) + for index, deletion := range c.impl.Deletions { + rrsets[index] = interfaces.ResourceRecordSet(&ResourceRecordSet{deletion}) + } + return rrsets +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go new file mode 100644 index 0000000000000..b1a8310bcd45a --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go @@ -0,0 +1,34 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "google.golang.org/api/googleapi" + + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ChangesCreateCall = ChangesCreateCall{} + +type ChangesCreateCall struct{ impl *dns.ChangesCreateCall } + +func (c ChangesCreateCall) Do(opts ...googleapi.CallOption) (interfaces.Change, error) { + ch, err := c.impl.Do(opts...) + return &Change{ch}, err +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go new file mode 100644 index 0000000000000..887ed9df2721f --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go @@ -0,0 +1,43 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ChangesService = ChangesService{} + +type ChangesService struct{ impl *dns.ChangesService } + +func (c ChangesService) Create(project string, managedZone string, change interfaces.Change) interfaces.ChangesCreateCall { + return &ChangesCreateCall{c.impl.Create(project, managedZone, change.(*Change).impl)} +} + +func (c ChangesService) NewChange(additions, deletions []interfaces.ResourceRecordSet) interfaces.Change { + adds := make([]*dns.ResourceRecordSet, len(additions)) + deletes := make([]*dns.ResourceRecordSet, len(deletions)) + for i, a := range additions { + adds[i] = a.(*ResourceRecordSet).impl + } + for i, d := range deletions { + deletes[i] = d.(*ResourceRecordSet).impl + } + return &Change{&dns.Change{Additions: adds, Deletions: deletes}} +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/clouddns.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/clouddns.go new file mode 100644 index 0000000000000..3c8f8c5339557 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/clouddns.go @@ -0,0 +1,35 @@ +/* +Copyright 2016 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 internal + +// Implementation of internal/interfaces/* on top of Google Cloud DNS API. +// See https://godoc.org/google.golang.org/api/dns/v1 for details +// This facilitates stubbing out Google Cloud DNS for unit testing. +// Only the parts of the API that we use are included. +// Others can be added as needed. + +import dns "google.golang.org/api/dns/v1" + +type ( + Project struct{ impl *dns.Project } + + ProjectsGetCall struct{ impl *dns.ProjectsGetCall } + + ProjectsService struct{ impl *dns.ProjectsService } + + Quota struct{ impl *dns.Quota } +) diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go new file mode 100644 index 0000000000000..7d9f1663984e5 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go @@ -0,0 +1,212 @@ +/* +Copyright 2016 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 interfaces + +import ( + "context" + + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +// Interfaces to directly mirror the Google Cloud DNS API structures. +// See https://godoc.org/google.golang.org/api/dns/v1 for details +// This facilitates stubbing out Google Cloud DNS for unit testing. +// Only the parts of the API that we use are included. +// Others can be added as needed. + +type ( + Change interface { + Additions() []ResourceRecordSet + Deletions() []ResourceRecordSet + // Id() string // TODO: Add as needed + // Kind() string // TODO: Add as needed + // StartTime() string // TODO: Add as needed + // Status() string // TODO: Add as needed + } + + ChangesCreateCall interface { + // Context(ctx context.Context) *ChangesCreateCall // TODO: Add as needed + Do(opts ...googleapi.CallOption) (Change, error) + // Fields(s ...googleapi.Field) *ChangesCreateCall // TODO: Add as needed + } + + ChangesGetCall interface { + // Context(ctx context.Context) *ChangesGetCall // TODO: Add as needed + Do(opts ...googleapi.CallOption) (*Change, error) + // Fields(s ...googleapi.Field) *ChangesGetCall // TODO: Add as needed + // IfNoneMatch(entityTag string) *ChangesGetCall // TODO: Add as needed + } + + ChangesListCall interface { + // Context(ctx context.Context) *ChangesListCall // TODO: Add as needed + Do(opts ...googleapi.CallOption) (*ChangesListResponse, error) + // Fields(s ...googleapi.Field) *ChangesListCall // TODO: Add as needed + // IfNoneMatch(entityTag string) *ChangesListCall // TODO: Add as needed + // MaxResults(maxResults int64) *ChangesListCall // TODO: Add as needed + // PageToken(pageToken string) *ChangesListCall // TODO: Add as needed + // Pages(ctx context.Context, f func(*ChangesListResponse) error) error // TODO: Add as needed + // SortBy(sortBy string) *ChangesListCall // TODO: Add as needed + // SortOrder(sortOrder string) *ChangesListCall // TODO: Add as needed + } + + ChangesListResponse interface { + // Changes() []*Change // TODO: Add as needed + // Kind() string // TODO: Add as needed + // NextPageToken() string // TODO: Add as needed + // ServerResponse() googleapi.ServerResponse // TODO: Add as needed + // ForceSendFields() []string // TODO: Add as needed + } + + ChangesService interface { + // Create(project string, managedZone string, change *Change) *ChangesCreateCall // TODO: Add as needed + Create(project string, managedZone string, change Change) ChangesCreateCall + NewChange(additions, deletions []ResourceRecordSet) Change + + // Get(project string, managedZone string, changeId string) *ChangesGetCall // TODO: Add as needed + // List(project string, managedZone string) *ChangesListCall // TODO: Add as needed + } + + ManagedZone interface { + // CreationTime() string // TODO: Add as needed + // Description() string // TODO: Add as needed + DnsName() string + Id() uint64 + // Kind() string // TODO: Add as needed + Name() string + // NameServerSet() string // TODO: Add as needed + // NameServers() []string // TODO: Add as needed + // ServerResponse() googleapi.ServerResponse // TODO: Add as needed + // ForceSendFields() []string // TODO: Add as needed + } + + ManagedZonesCreateCall interface { + // Context(ctx context.Context) *ManagedZonesCreateCall // TODO: Add as needed + Do(opts ...googleapi.CallOption) (ManagedZone, error) + // Fields(s ...googleapi.Field) *ManagedZonesCreateCall // TODO: Add as needed + } + + ManagedZonesDeleteCall interface { + // Context(ctx context.Context) *ManagedZonesDeleteCall // TODO: Add as needed + Do(opts ...googleapi.CallOption) error + // Fields(s ...googleapi.Field) *ManagedZonesDeleteCall // TODO: Add as needed + } + + ManagedZonesGetCall interface { + // Context(ctx context.Context) *ManagedZonesGetCall // TODO: Add as needed + Do(opts ...googleapi.CallOption) (ManagedZone, error) + // Fields(s ...googleapi.Field) *ManagedZonesGetCall // TODO: Add as needed + // IfNoneMatch(entityTag string) *ManagedZonesGetCall // TODO: Add as needed + } + + ManagedZonesListCall interface { + // Context(ctx context.Context) *ManagedZonesListCall // TODO: Add as needed + DnsName(dnsName string) ManagedZonesListCall + Do(opts ...googleapi.CallOption) (ManagedZonesListResponse, error) + // Fields(s ...googleapi.Field) *ManagedZonesListCall // TODO: Add as needed + // IfNoneMatch(entityTag string) *ManagedZonesListCall // TODO: Add as needed + // MaxResults(maxResults int64) *ManagedZonesListCall // TODO: Add as needed + // PageToken(pageToken string) *ManagedZonesListCall // TODO: Add as needed + // Pages(ctx context.Context, f func(*ManagedZonesListResponse) error) error // TODO: Add as needed + } + + ManagedZonesListResponse interface { + // Kind() string // TODO: Add as needed + // ManagedZones() []*ManagedZone // TODO: Add as needed + ManagedZones() []ManagedZone + // NextPageToken string // TODO: Add as needed + // ServerResponse() googleapi.ServerResponse // TODO: Add as needed + // ForceSendFields() []string // TODO: Add as needed + } + + ManagedZonesService interface { + // NewManagedZonesService(s *Service) *ManagedZonesService // TODO: Add to service if needed + Create(project string, managedZone ManagedZone) ManagedZonesCreateCall + Delete(project string, managedZone string) ManagedZonesDeleteCall + Get(project string, managedZone string) ManagedZonesGetCall + List(project string) ManagedZonesListCall + NewManagedZone(dnsName string) ManagedZone + } + + Project interface { + // Id() string // TODO: Add as needed + // Kind() string // TODO: Add as needed + // Number() uint64 // TODO: Add as needed + // Quota() *Quota // TODO: Add as needed + // ServerResponse() googleapi.ServerResponse // TODO: Add as needed + // ForceSendFields() []string // TODO: Add as needed + } + + ProjectsGetCall interface { + // TODO: Add as needed + } + + ProjectsService interface { + // TODO: Add as needed + } + + Quota interface { + // TODO: Add as needed + } + + ResourceRecordSet interface { + // Kind() string // TODO: Add as needed + Name() string + Rrdatas() []string + Ttl() int64 + Type() string + // ForceSendFields []string // TODO: Add as needed + } + + ResourceRecordSetsListCall interface { + // Context(ctx context.Context) *ResourceRecordSetsListCall // TODO: Add as needed + Do(opts ...googleapi.CallOption) (ResourceRecordSetsListResponse, error) + Pages(ctx context.Context, f func(ResourceRecordSetsListResponse) error) error + // Fields(s ...googleapi.Field) *ResourceRecordSetsListCall // TODO: Add as needed + // IfNoneMatch(entityTag string) *ResourceRecordSetsListCall // TODO: Add as needed + // MaxResults(maxResults int64) *ResourceRecordSetsListCall // TODO: Add as needed + Name(name string) ResourceRecordSetsListCall + // PageToken(pageToken string) *ResourceRecordSetsListCall // TODO: Add as needed + Type(type_ string) ResourceRecordSetsListCall + } + + ResourceRecordSetsListResponse interface { + // Kind() string // TODO: Add as needed + // NextPageToken() string // TODO: Add as needed + Rrsets() []ResourceRecordSet + // ServerResponse() googleapi.ServerResponse // TODO: Add as needed + // ForceSendFields() []string // TODO: Add as needed + } + + ResourceRecordSetsService interface { + List(project string, managedZone string) ResourceRecordSetsListCall + // Get returns a list of resources records with the matching name + Get(project, managedZone, name string) ResourceRecordSetsListCall + // NewResourceRecordSetsService(s *Service) *ResourceRecordSetsService // TODO: add to service as needed + NewResourceRecordSet(name string, rrdatas []string, ttl int64, type_ rrstype.RrsType) ResourceRecordSet + } + + Service interface { + // BasePath() string // TODO: Add as needed + // UserAgent() string // TODO: Add as needed + Changes() ChangesService + ManagedZones() ManagedZonesService + Projects() ProjectsService + ResourceRecordSets() ResourceRecordSetsService + } + // New(client *http.Client) (*Service, error) // TODO: Add as needed +) diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go new file mode 100644 index 0000000000000..862897743f9fb --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go @@ -0,0 +1,39 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZone = ManagedZone{} + +type ManagedZone struct{ impl *dns.ManagedZone } + +func (m ManagedZone) Name() string { + return m.impl.Name +} + +func (m ManagedZone) Id() uint64 { + return m.impl.Id +} + +func (m ManagedZone) DnsName() string { + return m.impl.DnsName +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go new file mode 100644 index 0000000000000..133cd145b48fc --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go @@ -0,0 +1,33 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesCreateCall = ManagedZonesCreateCall{} + +type ManagedZonesCreateCall struct{ impl *dns.ManagedZonesCreateCall } + +func (call ManagedZonesCreateCall) Do(opts ...googleapi.CallOption) (interfaces.ManagedZone, error) { + m, err := call.impl.Do(opts...) + return &ManagedZone{m}, err +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go new file mode 100644 index 0000000000000..2e96763e010c1 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go @@ -0,0 +1,32 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesDeleteCall = ManagedZonesDeleteCall{} + +type ManagedZonesDeleteCall struct{ impl *dns.ManagedZonesDeleteCall } + +func (call ManagedZonesDeleteCall) Do(opts ...googleapi.CallOption) error { + return call.impl.Do(opts...) +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go new file mode 100644 index 0000000000000..2a6cadfed99b5 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go @@ -0,0 +1,33 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesGetCall = ManagedZonesGetCall{} + +type ManagedZonesGetCall struct{ impl *dns.ManagedZonesGetCall } + +func (call ManagedZonesGetCall) Do(opts ...googleapi.CallOption) (interfaces.ManagedZone, error) { + m, err := call.impl.Do(opts...) + return &ManagedZone{m}, err +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go new file mode 100644 index 0000000000000..b704104647741 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go @@ -0,0 +1,38 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesListCall = &ManagedZonesListCall{} + +type ManagedZonesListCall struct{ impl *dns.ManagedZonesListCall } + +func (call *ManagedZonesListCall) Do(opts ...googleapi.CallOption) (interfaces.ManagedZonesListResponse, error) { + response, err := call.impl.Do(opts...) + return &ManagedZonesListResponse{response}, err +} + +func (call *ManagedZonesListCall) DnsName(dnsName string) interfaces.ManagedZonesListCall { + call.impl.DnsName(dnsName) + return call +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go new file mode 100644 index 0000000000000..b254f5eb56ea1 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go @@ -0,0 +1,35 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesListResponse = &ManagedZonesListResponse{} + +type ManagedZonesListResponse struct{ impl *dns.ManagedZonesListResponse } + +func (response *ManagedZonesListResponse) ManagedZones() []interfaces.ManagedZone { + zones := make([]interfaces.ManagedZone, len(response.impl.ManagedZones)) + for i, z := range response.impl.ManagedZones { + zones[i] = &ManagedZone{z} + } + return zones +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go new file mode 100644 index 0000000000000..2ea9e2484f903 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go @@ -0,0 +1,51 @@ +/* +Copyright 2016 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 internal + +import ( + "strings" + + dns "google.golang.org/api/dns/v1" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesService = &ManagedZonesService{} + +type ManagedZonesService struct{ impl *dns.ManagedZonesService } + +func (m *ManagedZonesService) Create(project string, managedzone interfaces.ManagedZone) interfaces.ManagedZonesCreateCall { + return &ManagedZonesCreateCall{m.impl.Create(project, managedzone.(*ManagedZone).impl)} +} + +func (m *ManagedZonesService) Delete(project, managedZone string) interfaces.ManagedZonesDeleteCall { + return &ManagedZonesDeleteCall{m.impl.Delete(project, managedZone)} +} + +func (m *ManagedZonesService) Get(project, managedZone string) interfaces.ManagedZonesGetCall { + return &ManagedZonesGetCall{m.impl.Get(project, managedZone)} +} + +func (m *ManagedZonesService) List(project string) interfaces.ManagedZonesListCall { + return &ManagedZonesListCall{m.impl.List(project)} +} + +func (m *ManagedZonesService) NewManagedZone(dnsName string) interfaces.ManagedZone { + name := "x" + strings.Replace(string(uuid.NewUUID()), "-", "", -1)[0:30] // Unique name, strip out the "-" chars to shorten it, start with a lower case alpha, and truncate to Cloud DNS 32 character limit + return &ManagedZone{impl: &dns.ManagedZone{Name: name, Description: "Kubernetes Federated Service", DnsName: dnsName}} +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go new file mode 100644 index 0000000000000..2b7c0ce24e545 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go @@ -0,0 +1,32 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ResourceRecordSet = ResourceRecordSet{} + +type ResourceRecordSet struct{ impl *dns.ResourceRecordSet } + +func (r ResourceRecordSet) Name() string { return r.impl.Name } +func (r ResourceRecordSet) Rrdatas() []string { return r.impl.Rrdatas } +func (r ResourceRecordSet) Ttl() int64 { return r.impl.Ttl } +func (r ResourceRecordSet) Type() string { return r.impl.Type } diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go new file mode 100644 index 0000000000000..f497ebcfbce7e --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go @@ -0,0 +1,53 @@ +/* +Copyright 2016 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 internal + +import ( + "context" + + dns "google.golang.org/api/dns/v1" + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ResourceRecordSetsListCall = &ResourceRecordSetsListCall{} + +type ResourceRecordSetsListCall struct { + impl *dns.ResourceRecordSetsListCall +} + +func (call *ResourceRecordSetsListCall) Do(opts ...googleapi.CallOption) (interfaces.ResourceRecordSetsListResponse, error) { + response, err := call.impl.Do(opts...) + return &ResourceRecordSetsListResponse{response}, err +} + +func (call *ResourceRecordSetsListCall) Pages(ctx context.Context, f func(interfaces.ResourceRecordSetsListResponse) error) error { + return call.impl.Pages(ctx, func(page *dns.ResourceRecordSetsListResponse) error { + return f(&ResourceRecordSetsListResponse{page}) + }) +} + +func (call *ResourceRecordSetsListCall) Name(name string) interfaces.ResourceRecordSetsListCall { + call.impl.Name(name) + return call +} + +func (call *ResourceRecordSetsListCall) Type(type_ string) interfaces.ResourceRecordSetsListCall { + call.impl.Type(type_) + return call +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go new file mode 100644 index 0000000000000..a6ff28df8f938 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go @@ -0,0 +1,38 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ResourceRecordSetsListResponse = &ResourceRecordSetsListResponse{} + +type ResourceRecordSetsListResponse struct { + impl *dns.ResourceRecordSetsListResponse +} + +func (response *ResourceRecordSetsListResponse) Rrsets() []interfaces.ResourceRecordSet { + rrsets := make([]interfaces.ResourceRecordSet, len(response.impl.Rrsets)) + for i, rrset := range response.impl.Rrsets { + rrsets[i] = &ResourceRecordSet{rrset} + } + return rrsets + +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go new file mode 100644 index 0000000000000..a971fd7513cef --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go @@ -0,0 +1,43 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +// Compile time check for interface adherence +var _ interfaces.ResourceRecordSetsService = &ResourceRecordSetsService{} + +type ResourceRecordSetsService struct { + impl *dns.ResourceRecordSetsService +} + +func (service ResourceRecordSetsService) List(project string, managedZone string) interfaces.ResourceRecordSetsListCall { + return &ResourceRecordSetsListCall{service.impl.List(project, managedZone)} +} + +func (service ResourceRecordSetsService) Get(project, managedZone, name string) interfaces.ResourceRecordSetsListCall { + return &ResourceRecordSetsListCall{service.impl.List(project, managedZone).Name(name)} +} + +func (service ResourceRecordSetsService) NewResourceRecordSet(name string, rrdatas []string, ttl int64, type_ rrstype.RrsType) interfaces.ResourceRecordSet { + rrset := dns.ResourceRecordSet{Name: name, Rrdatas: rrdatas, Ttl: ttl, Type: string(type_)} + return &ResourceRecordSet{&rrset} +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/service.go new file mode 100644 index 0000000000000..8ac5e63b74e32 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/service.go @@ -0,0 +1,49 @@ +/* +Copyright 2016 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 internal + +import ( + dns "google.golang.org/api/dns/v1" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.Service = &Service{} + +type Service struct { + impl *dns.Service +} + +func NewService(service *dns.Service) *Service { + return &Service{service} +} + +func (s *Service) Changes() interfaces.ChangesService { + return &ChangesService{s.impl.Changes} +} + +func (s *Service) ManagedZones() interfaces.ManagedZonesService { + return &ManagedZonesService{s.impl.ManagedZones} +} + +func (s *Service) Projects() interfaces.ProjectsService { + return &ProjectsService{s.impl.Projects} +} + +func (s *Service) ResourceRecordSets() interfaces.ResourceRecordSetsService { + return &ResourceRecordSetsService{s.impl.ResourceRecordSets} +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go new file mode 100644 index 0000000000000..83e5d94796739 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go @@ -0,0 +1,36 @@ +/* +Copyright 2016 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 stubs + +import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + +// Compile time check for interface adherence +var _ interfaces.Change = &Change{} + +type Change struct { + Service *ChangesService + Additions_ []interfaces.ResourceRecordSet + Deletions_ []interfaces.ResourceRecordSet +} + +func (c *Change) Additions() (rrsets []interfaces.ResourceRecordSet) { + return c.Additions_ +} + +func (c *Change) Deletions() (rrsets []interfaces.ResourceRecordSet) { + return c.Deletions_ +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go new file mode 100644 index 0000000000000..ab27a12f75e4d --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go @@ -0,0 +1,67 @@ +/* +Copyright 2016 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 stubs + +import ( + "fmt" + + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ChangesCreateCall = ChangesCreateCall{} + +type ChangesCreateCall struct { + Service *ChangesService + Project string + Zone string + Change interfaces.Change + Error error // Use this to over-ride response if necessary +} + +func hashKey(set interfaces.ResourceRecordSet) string { + return fmt.Sprintf("%s-%d-%s", set.Name(), set.Ttl(), string(set.Type())) +} + +func (c ChangesCreateCall) Do(opts ...googleapi.CallOption) (interfaces.Change, error) { + if c.Error != nil { + return nil, c.Error + } + zone := (c.Service.Service.ManagedZones_.Impl[c.Project][c.Zone]).(*ManagedZone) + rrsets := map[string]ResourceRecordSet{} // compute the new state + for _, set := range zone.Rrsets { + rrsets[hashKey(set)] = set + } + for _, del := range c.Change.Deletions() { + if _, found := rrsets[hashKey(del)]; !found { + return nil, fmt.Errorf("Attempt to delete non-existent rrset %v", del) + } + delete(rrsets, hashKey(del)) + } + for _, add := range c.Change.Additions() { + if _, found := rrsets[hashKey(add)]; found { + return nil, fmt.Errorf("Attempt to insert duplicate rrset %v", add) + } + rrsets[hashKey(add)] = add.(ResourceRecordSet) + } + zone.Rrsets = []ResourceRecordSet{} + for _, rrset := range rrsets { + zone.Rrsets = append(zone.Rrsets, rrset) + } + return c.Change, nil +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go new file mode 100644 index 0000000000000..39b8bd14f217d --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go @@ -0,0 +1,34 @@ +/* +Copyright 2016 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 stubs + +import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + +// Compile time check for interface adherence +var _ interfaces.ChangesService = &ChangesService{} + +type ChangesService struct { + Service *Service +} + +func (c *ChangesService) Create(project string, managedZone string, change interfaces.Change) interfaces.ChangesCreateCall { + return &ChangesCreateCall{c, project, managedZone, change, nil} +} + +func (c *ChangesService) NewChange(additions, deletions []interfaces.ResourceRecordSet) interfaces.Change { + return &Change{c, additions, deletions} +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/clouddns.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/clouddns.go new file mode 100644 index 0000000000000..e870ee4091e77 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/clouddns.go @@ -0,0 +1,33 @@ +/* +Copyright 2016 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 stubs + +// Implementation of internal/interfaces/* on top of Google Cloud DNS API. +// See https://godoc.org/google.golang.org/api/dns/v1 for details +// This facilitates stubbing out Google Cloud DNS for unit testing. +// Only the parts of the API that we use are included. +// Others can be added as needed. + +import dns "google.golang.org/api/dns/v1" + +type ( + // TODO: We don't need these yet, so they remain unimplemented. Add later as required. + Project struct{ impl *dns.Project } + ProjectsGetCall struct{ impl *dns.ProjectsGetCall } + ProjectsService struct{ impl *dns.ProjectsService } + Quota struct{ impl *dns.Quota } +) diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go new file mode 100644 index 0000000000000..2096da400bdac --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go @@ -0,0 +1,41 @@ +/* +Copyright 2016 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 stubs + +import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + +// Compile time check for interface adherence +var _ interfaces.ManagedZone = ManagedZone{} + +type ManagedZone struct { + Service *ManagedZonesService + Name_ string + Id_ uint64 + Rrsets []ResourceRecordSet +} + +func (m ManagedZone) Name() string { + return m.Name_ +} + +func (m ManagedZone) Id() uint64 { + return m.Id_ +} + +func (m ManagedZone) DnsName() string { + return m.Name_ // Don't bother storing a separate DNS name +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go new file mode 100644 index 0000000000000..f35f585cb51bc --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go @@ -0,0 +1,52 @@ +/* +Copyright 2016 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 stubs + +import ( + "fmt" + + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesCreateCall = ManagedZonesCreateCall{} + +type ManagedZonesCreateCall struct { + Error *error // Use to override response for testing + Service *ManagedZonesService + Project string + ManagedZone interfaces.ManagedZone +} + +func (call ManagedZonesCreateCall) Do(opts ...googleapi.CallOption) (interfaces.ManagedZone, error) { + if call.Error != nil { + return nil, *call.Error + } + if call.Service.Impl[call.Project][call.ManagedZone.DnsName()] != nil { + return nil, fmt.Errorf("Error - attempt to create duplicate zone %s in project %s.", + call.ManagedZone.DnsName(), call.Project) + } + if call.Service.Impl == nil { + call.Service.Impl = map[string]map[string]interfaces.ManagedZone{} + } + if call.Service.Impl[call.Project] == nil { + call.Service.Impl[call.Project] = map[string]interfaces.ManagedZone{} + } + call.Service.Impl[call.Project][call.ManagedZone.DnsName()] = call.ManagedZone + return call.ManagedZone, nil +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go new file mode 100644 index 0000000000000..c518e76ebad81 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go @@ -0,0 +1,53 @@ +/* +Copyright 2016 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 stubs + +import ( + "fmt" + + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesDeleteCall = ManagedZonesDeleteCall{} + +type ManagedZonesDeleteCall struct { + Service *ManagedZonesService + Project string + ZoneName string + Error *error // Use this to override response for testing if required +} + +func (call ManagedZonesDeleteCall) Do(opts ...googleapi.CallOption) error { + if call.Error != nil { // Return the override value + return *call.Error + } else { // Just try to delete it from the in-memory array. + project, ok := call.Service.Impl[call.Project] + if ok { + zone, ok := project[call.ZoneName] + if ok { + delete(project, zone.Name()) + return nil + } else { + return fmt.Errorf("Failed to find zone %s in project %s to delete it", call.ZoneName, call.Project) + } + } else { + return fmt.Errorf("Failed to find project %s to delete zone %s from it", call.Project, call.ZoneName) + } + } +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go new file mode 100644 index 0000000000000..f2923c3abd35b --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go @@ -0,0 +1,42 @@ +/* +Copyright 2016 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 stubs + +import ( + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesGetCall = ManagedZonesGetCall{} + +type ManagedZonesGetCall struct { + Service *ManagedZonesService + Project string + ZoneName string + Response interfaces.ManagedZone // Use this to override response if required + Error *error // Use this to override response if required + DnsName_ string +} + +func (call ManagedZonesGetCall) Do(opts ...googleapi.CallOption) (interfaces.ManagedZone, error) { + if call.Response != nil { + return call.Response, *call.Error + } else { + return call.Service.Impl[call.Project][call.ZoneName], nil + } +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go new file mode 100644 index 0000000000000..4b7156ffbc53c --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go @@ -0,0 +1,59 @@ +/* +Copyright 2016 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 stubs + +import ( + "fmt" + + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesListCall = &ManagedZonesListCall{} + +type ManagedZonesListCall struct { + Service *ManagedZonesService + Project string + Response *interfaces.ManagedZonesListResponse // Use this to override response if required + Error *error // Use this to override response if required + DnsName_ string +} + +func (call *ManagedZonesListCall) Do(opts ...googleapi.CallOption) (interfaces.ManagedZonesListResponse, error) { + if call.Response != nil { + return *call.Response, *call.Error + } else { + proj, projectFound := call.Service.Impl[call.Project] + if !projectFound { + return nil, fmt.Errorf("Project %s not found.", call.Project) + } + if call.DnsName_ != "" { + return &ManagedZonesListResponse{[]interfaces.ManagedZone{proj[call.DnsName_]}}, nil + } + list := []interfaces.ManagedZone{} + for _, zone := range proj { + list = append(list, zone) + } + return &ManagedZonesListResponse{list}, nil + } +} + +func (call *ManagedZonesListCall) DnsName(dnsName string) interfaces.ManagedZonesListCall { + call.DnsName_ = dnsName + return call +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go new file mode 100644 index 0000000000000..095cae2ba80a2 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go @@ -0,0 +1,28 @@ +/* +Copyright 2016 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 stubs + +import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesListResponse = &ManagedZonesListResponse{} + +type ManagedZonesListResponse struct{ ManagedZones_ []interfaces.ManagedZone } + +func (response *ManagedZonesListResponse) ManagedZones() []interfaces.ManagedZone { + return response.ManagedZones_ +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go new file mode 100644 index 0000000000000..5b8513f2f73b1 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go @@ -0,0 +1,46 @@ +/* +Copyright 2016 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 stubs + +import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + +// Compile time check for interface adherence +var _ interfaces.ManagedZonesService = &ManagedZonesService{} + +type ManagedZonesService struct { + Impl map[string]map[string]interfaces.ManagedZone +} + +func (m *ManagedZonesService) Create(project string, managedzone interfaces.ManagedZone) interfaces.ManagedZonesCreateCall { + return &ManagedZonesCreateCall{nil, m, project, managedzone.(*ManagedZone)} +} + +func (m *ManagedZonesService) Delete(project string, managedZone string) interfaces.ManagedZonesDeleteCall { + return &ManagedZonesDeleteCall{m, project, managedZone, nil} +} + +func (m *ManagedZonesService) Get(project string, managedZone string) interfaces.ManagedZonesGetCall { + return &ManagedZonesGetCall{m, project, managedZone, nil, nil, ""} +} + +func (m *ManagedZonesService) List(project string) interfaces.ManagedZonesListCall { + return &ManagedZonesListCall{m, project, nil, nil, ""} +} + +func (m *ManagedZonesService) NewManagedZone(dnsName string) interfaces.ManagedZone { + return &ManagedZone{Service: m, Name_: dnsName} +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go new file mode 100644 index 0000000000000..3412775c17cee --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go @@ -0,0 +1,34 @@ +/* +Copyright 2016 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 stubs + +import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + +// Compile time check for interface adherence +var _ interfaces.ResourceRecordSet = ResourceRecordSet{} + +type ResourceRecordSet struct { + Name_ string + Rrdatas_ []string + Ttl_ int64 + Type_ string +} + +func (r ResourceRecordSet) Name() string { return r.Name_ } +func (r ResourceRecordSet) Rrdatas() []string { return r.Rrdatas_ } +func (r ResourceRecordSet) Ttl() int64 { return r.Ttl_ } +func (r ResourceRecordSet) Type() string { return r.Type_ } diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go new file mode 100644 index 0000000000000..8695142bff5de --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go @@ -0,0 +1,52 @@ +/* +Copyright 2016 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 stubs + +import ( + "context" + + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ interfaces.ResourceRecordSetsListCall = &ResourceRecordSetsListCall{} + +type ResourceRecordSetsListCall struct { + Response_ *ResourceRecordSetsListResponse + Err_ error + Name_ string + Type_ string +} + +func (call *ResourceRecordSetsListCall) Do(opts ...googleapi.CallOption) (interfaces.ResourceRecordSetsListResponse, error) { + return call.Response_, call.Err_ +} + +func (call *ResourceRecordSetsListCall) Pages(ctx context.Context, f func(interfaces.ResourceRecordSetsListResponse) error) error { + return f(call.Response_) +} + +func (call *ResourceRecordSetsListCall) Name(name string) interfaces.ResourceRecordSetsListCall { + call.Name_ = name + return call +} + +func (call *ResourceRecordSetsListCall) Type(type_ string) interfaces.ResourceRecordSetsListCall { + call.Type_ = type_ + return call +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go new file mode 100644 index 0000000000000..a60d8dceffb18 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go @@ -0,0 +1,30 @@ +/* +Copyright 2016 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 stubs + +import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + +// Compile time check for interface adherence +var _ interfaces.ResourceRecordSetsListResponse = &ResourceRecordSetsListResponse{} + +type ResourceRecordSetsListResponse struct { + impl []interfaces.ResourceRecordSet +} + +func (response *ResourceRecordSetsListResponse) Rrsets() []interfaces.ResourceRecordSet { + return response.impl +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go new file mode 100644 index 0000000000000..13e50d8b03b63 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go @@ -0,0 +1,83 @@ +/* +Copyright 2016 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 stubs + +import ( + "fmt" + + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +// Compile time check for interface adherence +var _ interfaces.ResourceRecordSetsService = &ResourceRecordSetsService{} + +type ResourceRecordSetsService struct { + Service *Service + ListCall interfaces.ResourceRecordSetsListCall // Use to override response if required for testing +} + +func (s ResourceRecordSetsService) managedZone(project, managedZone string) (*ManagedZone, error) { + p := s.Service.ManagedZones_.Impl[project] + if p == nil { + return nil, fmt.Errorf("Project not found: %s", project) + } + z := s.Service.ManagedZones_.Impl[project][managedZone] + if z == nil { + return nil, fmt.Errorf("Zone %s not found in project %s", managedZone, project) + } + return z.(*ManagedZone), nil +} + +func (s ResourceRecordSetsService) List(project string, managedZone string) interfaces.ResourceRecordSetsListCall { + if s.ListCall != nil { + return s.ListCall + } + zone, err := s.managedZone(project, managedZone) + if err != nil { + return &ResourceRecordSetsListCall{Err_: err} + } + + response := &ResourceRecordSetsListResponse{} + for _, set := range zone.Rrsets { + response.impl = append(response.impl, set) + } + return &ResourceRecordSetsListCall{Response_: response} +} + +func (s ResourceRecordSetsService) Get(project, managedZone, name string) interfaces.ResourceRecordSetsListCall { + if s.ListCall != nil { + return s.ListCall + } + zone, err := s.managedZone(project, managedZone) + if err != nil { + return &ResourceRecordSetsListCall{Err_: err} + } + + response := &ResourceRecordSetsListResponse{} + for _, set := range zone.Rrsets { + if set.Name_ == name { + response.impl = append(response.impl, set) + } + } + return &ResourceRecordSetsListCall{Response_: response} +} + +func (service ResourceRecordSetsService) NewResourceRecordSet(name string, rrdatas []string, ttl int64, type_ rrstype.RrsType) interfaces.ResourceRecordSet { + rrset := ResourceRecordSet{Name_: name, Rrdatas_: rrdatas, Ttl_: ttl, Type_: string(type_)} + return rrset +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go new file mode 100644 index 0000000000000..561678cf93656 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go @@ -0,0 +1,54 @@ +/* +Copyright 2016 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 stubs + +import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + +// Compile time check for interface adherence +var _ interfaces.Service = &Service{} + +type Service struct { + Changes_ *ChangesService + ManagedZones_ *ManagedZonesService + Projects_ *ProjectsService + Rrsets_ *ResourceRecordSetsService +} + +func NewService() *Service { + s := &Service{} + s.Changes_ = &ChangesService{s} + s.ManagedZones_ = &ManagedZonesService{} + s.Projects_ = &ProjectsService{} + s.Rrsets_ = &ResourceRecordSetsService{s, nil} + return s +} + +func (s *Service) Changes() interfaces.ChangesService { + return s.Changes_ +} + +func (s *Service) ManagedZones() interfaces.ManagedZonesService { + return s.ManagedZones_ +} + +func (s *Service) Projects() interfaces.ProjectsService { + return s.Projects_ +} + +func (s *Service) ResourceRecordSets() interfaces.ResourceRecordSetsService { + return s.Rrsets_ +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go new file mode 100644 index 0000000000000..c81d03dd237b5 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go @@ -0,0 +1,124 @@ +/* +Copyright 2016 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 clouddns + +import ( + "fmt" + + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ dnsprovider.ResourceRecordChangeset = &ResourceRecordChangeset{} + +type ResourceRecordChangeset struct { + rrsets *ResourceRecordSets + + additions []dnsprovider.ResourceRecordSet + removals []dnsprovider.ResourceRecordSet + upserts []dnsprovider.ResourceRecordSet +} + +func (c *ResourceRecordChangeset) Add(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { + c.additions = append(c.additions, rrset) + return c +} + +func (c *ResourceRecordChangeset) Remove(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { + c.removals = append(c.removals, rrset) + return c +} + +func (c *ResourceRecordChangeset) Upsert(rrset dnsprovider.ResourceRecordSet) dnsprovider.ResourceRecordChangeset { + c.upserts = append(c.upserts, rrset) + return c +} + +func (c *ResourceRecordChangeset) Apply() error { + rrsets := c.rrsets + + service := rrsets.zone.zones.interface_.service.Changes() + + var additions []interfaces.ResourceRecordSet + for _, r := range c.additions { + additions = append(additions, r.(ResourceRecordSet).impl) + } + var deletions []interfaces.ResourceRecordSet + for _, r := range c.removals { + deletions = append(deletions, r.(ResourceRecordSet).impl) + } + + if len(c.upserts) != 0 { + // TODO: We could maybe tweak this to fetch just the records we care about + // although not clear when this would be a win. N=1 obviously so though... + before, err := c.rrsets.List() + if err != nil { + return fmt.Errorf("error fetching recordset images for upsert operation: %v", err) + } + + upsertMap := make(map[string]dnsprovider.ResourceRecordSet) + for _, upsert := range c.upserts { + key := string(upsert.Type()) + "::" + upsert.Name() + upsertMap[key] = upsert + } + + for _, b := range before { + key := string(b.Type()) + "::" + b.Name() + upsert := upsertMap[key] + if upsert == nil { + continue + } + + deletions = append(deletions, b.(ResourceRecordSet).impl) + additions = append(additions, upsert.(ResourceRecordSet).impl) + + // Mark as seen + delete(upsertMap, key) + } + + // Anything left in the map must be an addition + for _, upsert := range upsertMap { + additions = append(additions, upsert.(ResourceRecordSet).impl) + } + } + + change := service.NewChange(additions, deletions) + newChange, err := service.Create(rrsets.project(), rrsets.zone.impl.Name(), change).Do() + if err != nil { + return err + } + newAdditions := newChange.Additions() + if len(newAdditions) != len(additions) { + return fmt.Errorf("Internal error when adding resource record set. Call succeeded but number of records returned is incorrect. Records sent=%d, records returned=%d, additions:%v", len(additions), len(newAdditions), c.additions) + } + newDeletions := newChange.Deletions() + if len(newDeletions) != len(deletions) { + return fmt.Errorf("Internal error when deleting resource record set. Call succeeded but number of records returned is incorrect. Records sent=%d, records returned=%d, deletions:%v", len(deletions), len(newDeletions), c.removals) + } + + return nil +} + +func (c *ResourceRecordChangeset) IsEmpty() bool { + return len(c.additions) == 0 && len(c.removals) == 0 +} + +// ResourceRecordSets returns the parent ResourceRecordSets +func (c *ResourceRecordChangeset) ResourceRecordSets() dnsprovider.ResourceRecordSets { + return c.rrsets +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrset.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrset.go new file mode 100644 index 0000000000000..f357e1c9e7c50 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrset.go @@ -0,0 +1,53 @@ +/* +Copyright 2016 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 clouddns + +import ( + "fmt" + + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +// Compile time check for interface adherence +var _ dnsprovider.ResourceRecordSet = ResourceRecordSet{} + +type ResourceRecordSet struct { + impl interfaces.ResourceRecordSet + rrsets *ResourceRecordSets +} + +func (rrset ResourceRecordSet) String() string { + return fmt.Sprintf("<(clouddns) %q type=%s rrdatas=%q ttl=%v>", rrset.Name(), rrset.Type(), rrset.Rrdatas(), rrset.Ttl()) +} + +func (rrset ResourceRecordSet) Name() string { + return rrset.impl.Name() +} + +func (rrset ResourceRecordSet) Rrdatas() []string { + return rrset.impl.Rrdatas() +} + +func (rrset ResourceRecordSet) Ttl() int64 { + return rrset.impl.Ttl() +} + +func (rrset ResourceRecordSet) Type() rrstype.RrsType { + return rrstype.RrsType(rrset.impl.Type()) +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrsets.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrsets.go new file mode 100644 index 0000000000000..db9411c766158 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrsets.go @@ -0,0 +1,94 @@ +/* +Copyright 2016 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 clouddns + +import ( + "context" + + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +// Compile time check for interface adherence +var _ dnsprovider.ResourceRecordSets = ResourceRecordSets{} + +type ResourceRecordSets struct { + zone *Zone + impl interfaces.ResourceRecordSetsService +} + +// List returns a list of resource records in the given project and +// managed zone. +// !!CAUTION!! Your memory might explode if you have a huge number of +// records in your managed zone. +func (rrsets ResourceRecordSets) List() ([]dnsprovider.ResourceRecordSet, error) { + var list []dnsprovider.ResourceRecordSet + + ctx := context.Background() + + call := rrsets.impl.List(rrsets.project(), rrsets.zone.impl.Name()) + err := call.Pages(ctx, func(page interfaces.ResourceRecordSetsListResponse) error { + for _, rrset := range page.Rrsets() { + list = append(list, ResourceRecordSet{rrset, &rrsets}) + } + return nil + }) + if err != nil { + return nil, err + } + + return list, nil +} + +func (rrsets ResourceRecordSets) Get(name string) ([]dnsprovider.ResourceRecordSet, error) { + var list []dnsprovider.ResourceRecordSet + + ctx := context.Background() + + call := rrsets.impl.Get(rrsets.project(), rrsets.zone.impl.Name(), name) + err := call.Pages(ctx, func(page interfaces.ResourceRecordSetsListResponse) error { + for _, rrset := range page.Rrsets() { + list = append(list, ResourceRecordSet{rrset, &rrsets}) + } + return nil + }) + if err != nil { + return nil, err + } + + return list, nil +} + +func (r ResourceRecordSets) StartChangeset() dnsprovider.ResourceRecordChangeset { + return &ResourceRecordChangeset{ + rrsets: &r, + } +} + +func (r ResourceRecordSets) New(name string, rrdatas []string, ttl int64, rrstype rrstype.RrsType) dnsprovider.ResourceRecordSet { + return ResourceRecordSet{r.impl.NewResourceRecordSet(name, rrdatas, ttl, rrstype), &r} +} + +func (rrsets ResourceRecordSets) project() string { + return rrsets.zone.project() +} + +// Zone returns the parent zone +func (rrset ResourceRecordSets) Zone() dnsprovider.Zone { + return rrset.zone +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zone.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zone.go new file mode 100644 index 0000000000000..97e775f90f7be --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zone.go @@ -0,0 +1,48 @@ +/* +Copyright 2016 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 clouddns + +import ( + "strconv" + + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ dnsprovider.Zone = &Zone{} + +type Zone struct { + impl interfaces.ManagedZone + zones *Zones +} + +func (zone *Zone) Name() string { + return zone.impl.DnsName() +} + +func (zone *Zone) ID() string { + return strconv.FormatUint(zone.impl.Id(), 10) +} + +func (zone *Zone) ResourceRecordSets() (dnsprovider.ResourceRecordSets, bool) { + return &ResourceRecordSets{zone, zone.zones.interface_.service.ResourceRecordSets()}, true +} + +func (zone Zone) project() string { + return zone.zones.project() +} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zones.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zones.go new file mode 100644 index 0000000000000..62d56aef48686 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zones.go @@ -0,0 +1,68 @@ +/* +Copyright 2016 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 clouddns + +import ( + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +) + +// Compile time check for interface adherence +var _ dnsprovider.Zones = Zones{} + +type Zones struct { + impl interfaces.ManagedZonesService + interface_ *Interface +} + +func (zones Zones) List() ([]dnsprovider.Zone, error) { + response, err := zones.impl.List(zones.project()).Do() + if err != nil { + return nil, err + } + managedZones := response.ManagedZones() + zoneList := make([]dnsprovider.Zone, len(managedZones)) + for i, zone := range managedZones { + zoneList[i] = &Zone{zone, &zones} + } + return zoneList, nil +} + +func (zones Zones) Add(zone dnsprovider.Zone) (dnsprovider.Zone, error) { + managedZone := zones.impl.NewManagedZone(zone.Name()) + response, err := zones.impl.Create(zones.project(), managedZone).Do() + if err != nil { + return nil, err + } + return &Zone{response, &zones}, nil +} + +func (zones Zones) Remove(zone dnsprovider.Zone) error { + if err := zones.impl.Delete(zones.project(), zone.(*Zone).impl.Name()).Do(); err != nil { + return err + } + return nil +} + +func (zones Zones) New(name string) (dnsprovider.Zone, error) { + managedZone := zones.impl.NewManagedZone(name) + return &Zone{managedZone, &zones}, nil +} + +func (zones Zones) project() string { + return zones.interface_.project() +} diff --git a/dnsprovider/pkg/dnsprovider/rrstype/rrstype.go b/dnsprovider/pkg/dnsprovider/rrstype/rrstype.go new file mode 100644 index 0000000000000..acf9e90b31226 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/rrstype/rrstype.go @@ -0,0 +1,28 @@ +/* +Copyright 2016 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 rrstype + +type ( + RrsType string +) + +const ( + A = RrsType("A") + AAAA = RrsType("AAAA") + CNAME = RrsType("CNAME") + // TODO: Add other types as required +) diff --git a/dnsprovider/pkg/dnsprovider/tests/commontests.go b/dnsprovider/pkg/dnsprovider/tests/commontests.go new file mode 100644 index 0000000000000..6e1584ad86fc4 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/tests/commontests.go @@ -0,0 +1,194 @@ +/* +Copyright 2016 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 tests + +import ( + "reflect" + "testing" + + "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" +) + +/* CommonTestResourceRecordSetsReplace verifies that replacing an RRS works */ +func CommonTestResourceRecordSetsReplace(t *testing.T, zone dnsprovider.Zone) { + rrsets, _ := zone.ResourceRecordSets() + + sets := rrs(t, zone) + rrset := rrsets.New("alpha.test.com", []string{"8.8.4.4"}, 40, rrstype.A) + addRrsetOrFail(t, sets, rrset) + defer sets.StartChangeset().Remove(rrset).Apply() + + // Replace the record (change ttl and rrdatas) + newRrset := rrsets.New("alpha.test.com", []string{"8.8.8.8"}, 80, rrstype.A) + err := sets.StartChangeset().Add(newRrset).Remove(rrset).Apply() + if err != nil { + t.Errorf("Failed to replace resource record set %v -> %v: %v", rrset, newRrset, err) + } else { + defer sets.StartChangeset().Remove(newRrset).Apply() + t.Logf("Correctly replaced resource record %v -> %v", rrset, newRrset) + } + + // Check that the record was updated + assertHasRecord(t, sets, newRrset) +} + +/* CommonTestResourceRecordSetsReplaceAll verifies that we can remove an RRS and create one with a different name*/ +func CommonTestResourceRecordSetsReplaceAll(t *testing.T, zone dnsprovider.Zone) { + rrsets, _ := zone.ResourceRecordSets() + + sets := rrs(t, zone) + rrset := rrsets.New("alpha.test.com", []string{"8.8.4.4"}, 40, rrstype.A) + addRrsetOrFail(t, sets, rrset) + defer sets.StartChangeset().Remove(rrset).Apply() + + newRrset := rrsets.New("beta.test.com", []string{"8.8.8.8"}, 80, rrstype.A) + + // Try to add it again, and verify that the call fails. + err := sets.StartChangeset().Add(newRrset).Remove(rrset).Apply() + if err != nil { + t.Errorf("Failed to replace resource record set %v -> %v: %v", rrset, newRrset, err) + } else { + defer sets.StartChangeset().Remove(newRrset).Apply() + t.Logf("Correctly replaced resource record %v -> %v", rrset, newRrset) + } + + // Check that it was updated + assertHasRecord(t, sets, newRrset) + assertNotHasRecord(t, sets, rrset.Name(), rrset.Type()) +} + +/* CommonTestResourceRecordSetsDifferentType verifies that we can add records of the same name but different types */ +func CommonTestResourceRecordSetsDifferentTypes(t *testing.T, zone dnsprovider.Zone) { + rrsets, _ := zone.ResourceRecordSets() + + sets := rrs(t, zone) + rrset := rrsets.New("alpha.test.com", []string{"8.8.4.4"}, 40, rrstype.A) + addRrsetOrFail(t, sets, rrset) + defer sets.StartChangeset().Remove(rrset).Apply() + + aaaaRrset := rrsets.New("alpha.test.com", []string{"2001:4860:4860::8888"}, 80, rrstype.AAAA) + + // Add the resource with the same name but different type + err := sets.StartChangeset().Add(aaaaRrset).Apply() + if err != nil { + t.Errorf("Failed to add resource record set %v: %v", aaaaRrset, err) + } + defer sets.StartChangeset().Remove(aaaaRrset).Apply() + + // Check that both records exist + assertHasRecord(t, sets, aaaaRrset) + assertHasRecord(t, sets, rrset) +} + +/* rrs returns the ResourceRecordSets interface for a given zone */ +func rrs(t *testing.T, zone dnsprovider.Zone) (r dnsprovider.ResourceRecordSets) { + rrsets, supported := zone.ResourceRecordSets() + if !supported { + t.Fatalf("ResourceRecordSets interface not supported by zone %v", zone) + return r + } + return rrsets +} + +func getRrOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets, name string) []dnsprovider.ResourceRecordSet { + rrsetList, err := rrsets.Get(name) + if err != nil { + t.Fatalf("Failed to get recordset: %v", err) + } else if len(rrsetList) == 0 { + t.Logf("Did not Get recordset: %v", name) + } else { + t.Logf("Got recordset: %v", rrsetList[0].Name()) + } + return rrsetList +} + +// assertHasRecord tests that rrsets has a record equivalent to rrset +func assertHasRecord(t *testing.T, rrsets dnsprovider.ResourceRecordSets, rrset dnsprovider.ResourceRecordSet) { + var found dnsprovider.ResourceRecordSet + + rrs, err := rrsets.List() + if err != nil { + if err.Error() == "OperationNotSupported" { + foundList := getRrOrFail(t, rrsets, rrset.Name()) + for i, elem := range foundList { + if elem.Name() == rrset.Name() && elem.Type() == rrset.Type() { + found = foundList[i] + break + } + } + } else { + t.Fatalf("Failed to list recordsets: %v", err) + } + } else { + if len(rrs) < 0 { + t.Fatalf("Record set length=%d, expected >=0", len(rrs)) + } else { + t.Logf("Got %d recordsets: %v", len(rrs), rrs) + } + + for _, r := range rrs { + if r.Name() != rrset.Name() || r.Type() != rrset.Type() { + continue + } + + if found != nil { + t.Errorf("found duplicate resource record set: %q and %q", r, found) + } + found = r + } + } + + if found == nil { + t.Errorf("resource record set %v not found", rrset) + } else { + assertEquivalent(t, found, rrset) + } +} + +// assertNotHasRecord tests that rrsets does not have a record matching name and type +func assertNotHasRecord(t *testing.T, rrsets dnsprovider.ResourceRecordSets, name string, rrstype rrstype.RrsType) { + found := getRrOrFail(t, rrsets, name) + if found != nil { + t.Errorf("resource record set found unexpectedly: %v", found) + } +} + +// assertEquivalent tests that l is equal to r, for the methods in ResourceRecordSet +func assertEquivalent(t *testing.T, l, r dnsprovider.ResourceRecordSet) { + if l.Name() != r.Name() { + t.Errorf("resource record sets not equal %v vs %v", l, r) + } + if l.Type() != r.Type() { + t.Errorf("resource record sets not equal %v vs %v", l, r) + } + if l.Ttl() != r.Ttl() { + t.Errorf("resource record sets not equal %v vs %v", l, r) + } + if !reflect.DeepEqual(l.Rrdatas(), r.Rrdatas()) { + t.Errorf("resource record sets not equal %v vs %v", l, r) + } +} + +func addRrsetOrFail(t *testing.T, rrsets dnsprovider.ResourceRecordSets, rrset dnsprovider.ResourceRecordSet) { + err := rrsets.StartChangeset().Add(rrset).Apply() + if err != nil { + t.Fatalf("Failed to add recordset %v: %v", rrset, err) + } else { + t.Logf("Successfully added resource record set: %v", rrset) + } +} From efca80a2b6f072ad0f05d7cd7c0a98c02e560f27 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 15 Nov 2017 02:52:50 -0500 Subject: [PATCH 2/6] Fixup import paths & bazel --- dnsprovider/{pkg/dnsprovider => }/README.md | 0 dnsprovider/pkg/dnsprovider/BUILD.bazel | 24 +++++++++++ dnsprovider/pkg/dnsprovider/dns.go | 2 +- dnsprovider/pkg/dnsprovider/dns_test.go | 2 +- dnsprovider/pkg/dnsprovider/doc.go | 2 +- .../providers/aws/route53/BUILD.bazel | 42 ++++++++++++++++++ .../providers/aws/route53/interface.go | 4 +- .../providers/aws/route53/route53.go | 2 +- .../providers/aws/route53/route53_test.go | 8 ++-- .../providers/aws/route53/rrchangeset.go | 2 +- .../providers/aws/route53/rrset.go | 4 +- .../providers/aws/route53/rrsets.go | 4 +- .../providers/aws/route53/stubs/BUILD.bazel | 12 ++++++ .../dnsprovider/providers/aws/route53/zone.go | 2 +- .../providers/aws/route53/zones.go | 2 +- .../dnsprovider/providers/coredns/BUILD.bazel | 39 +++++++++++++++++ .../dnsprovider/providers/coredns/coredns.go | 2 +- .../providers/coredns/coredns_test.go | 8 ++-- .../providers/coredns/interface.go | 4 +- .../providers/coredns/rrchangeset.go | 2 +- .../dnsprovider/providers/coredns/rrset.go | 4 +- .../dnsprovider/providers/coredns/rrsets.go | 4 +- .../providers/coredns/stubs/BUILD.bazel | 12 ++++++ .../pkg/dnsprovider/providers/coredns/zone.go | 2 +- .../dnsprovider/providers/coredns/zones.go | 2 +- .../providers/google/clouddns/BUILD.bazel | 43 +++++++++++++++++++ .../providers/google/clouddns/clouddns.go | 6 +-- .../google/clouddns/clouddns_test.go | 6 +-- .../providers/google/clouddns/interface.go | 4 +- .../google/clouddns/internal/BUILD.bazel | 32 ++++++++++++++ .../google/clouddns/internal/change.go | 2 +- .../clouddns/internal/changes_create_call.go | 2 +- .../clouddns/internal/changes_service.go | 2 +- .../clouddns/internal/interfaces/BUILD.bazel | 12 ++++++ .../internal/interfaces/interfaces.go | 2 +- .../google/clouddns/internal/managed_zone.go | 2 +- .../internal/managed_zone_create_call.go | 2 +- .../internal/managed_zones_delete_call.go | 2 +- .../internal/managed_zones_get_call.go | 2 +- .../internal/managed_zones_list_call.go | 2 +- .../internal/managed_zones_list_response.go | 2 +- .../internal/managed_zones_service.go | 2 +- .../google/clouddns/internal/rrset.go | 2 +- .../clouddns/internal/rrsets_list_call.go | 2 +- .../clouddns/internal/rrsets_list_response.go | 2 +- .../clouddns/internal/rrsets_service.go | 4 +- .../google/clouddns/internal/service.go | 2 +- .../clouddns/internal/stubs/BUILD.bazel | 31 +++++++++++++ .../google/clouddns/internal/stubs/change.go | 2 +- .../internal/stubs/changes_create_call.go | 2 +- .../internal/stubs/changes_service.go | 2 +- .../clouddns/internal/stubs/managed_zone.go | 2 +- .../stubs/managed_zone_create_call.go | 2 +- .../stubs/managed_zones_delete_call.go | 2 +- .../internal/stubs/managed_zones_get_call.go | 2 +- .../internal/stubs/managed_zones_list_call.go | 2 +- .../stubs/managed_zones_list_response.go | 2 +- .../internal/stubs/managed_zones_service.go | 2 +- .../google/clouddns/internal/stubs/rrset.go | 2 +- .../internal/stubs/rrsets_list_call.go | 2 +- .../internal/stubs/rrsets_list_response.go | 2 +- .../clouddns/internal/stubs/rrsets_service.go | 4 +- .../google/clouddns/internal/stubs/service.go | 2 +- .../providers/google/clouddns/rrchangeset.go | 4 +- .../providers/google/clouddns/rrset.go | 6 +-- .../providers/google/clouddns/rrsets.go | 6 +-- .../providers/google/clouddns/zone.go | 4 +- .../providers/google/clouddns/zones.go | 4 +- .../pkg/dnsprovider/rrstype/BUILD.bazel | 8 ++++ dnsprovider/pkg/dnsprovider/tests/BUILD.bazel | 12 ++++++ .../pkg/dnsprovider/tests/commontests.go | 4 +- 71 files changed, 353 insertions(+), 86 deletions(-) rename dnsprovider/{pkg/dnsprovider => }/README.md (100%) create mode 100644 dnsprovider/pkg/dnsprovider/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/providers/coredns/stubs/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/rrstype/BUILD.bazel create mode 100644 dnsprovider/pkg/dnsprovider/tests/BUILD.bazel diff --git a/dnsprovider/pkg/dnsprovider/README.md b/dnsprovider/README.md similarity index 100% rename from dnsprovider/pkg/dnsprovider/README.md rename to dnsprovider/README.md diff --git a/dnsprovider/pkg/dnsprovider/BUILD.bazel b/dnsprovider/pkg/dnsprovider/BUILD.bazel new file mode 100644 index 0000000000000..bd6fc0d278109 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/BUILD.bazel @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "dns.go", + "doc.go", + "plugins.go", + ], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider", + visibility = ["//visibility:public"], + deps = [ + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//vendor/github.com/golang/glog:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["dns_test.go"], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider", + library = ":go_default_library", + deps = ["//dnsprovider/pkg/dnsprovider/rrstype:go_default_library"], +) diff --git a/dnsprovider/pkg/dnsprovider/dns.go b/dnsprovider/pkg/dnsprovider/dns.go index b707280e1d5c4..adebdac1378d8 100644 --- a/dnsprovider/pkg/dnsprovider/dns.go +++ b/dnsprovider/pkg/dnsprovider/dns.go @@ -19,7 +19,7 @@ package dnsprovider import ( "reflect" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) // Interface is an abstract, pluggable interface for DNS providers. diff --git a/dnsprovider/pkg/dnsprovider/dns_test.go b/dnsprovider/pkg/dnsprovider/dns_test.go index b5a2344c35b21..599c87db2821b 100644 --- a/dnsprovider/pkg/dnsprovider/dns_test.go +++ b/dnsprovider/pkg/dnsprovider/dns_test.go @@ -19,7 +19,7 @@ package dnsprovider import ( "testing" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) // Compile time interface check diff --git a/dnsprovider/pkg/dnsprovider/doc.go b/dnsprovider/pkg/dnsprovider/doc.go index 201c57a0502c9..a1410798d21c1 100644 --- a/dnsprovider/pkg/dnsprovider/doc.go +++ b/dnsprovider/pkg/dnsprovider/doc.go @@ -18,4 +18,4 @@ limitations under the License. dnsprovider supplies interfaces for dns service providers (e.g. Google Cloud DNS, AWS route53, etc). Implementations exist in the providers sub-package */ -package dnsprovider // import "k8s.io/kubernetes/federation/pkg/dnsprovider" +package dnsprovider // import "k8s.io/kops/dnsprovider/pkg/dnsprovider" diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/aws/route53/BUILD.bazel new file mode 100644 index 0000000000000..0d4783d40303c --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/BUILD.bazel @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "interface.go", + "route53.go", + "rrchangeset.go", + "rrset.go", + "rrsets.go", + "zone.go", + "zones.go", + ], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53", + visibility = ["//visibility:public"], + deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//vendor/github.com/aws/aws-sdk-go/aws:go_default_library", + "//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library", + "//vendor/github.com/aws/aws-sdk-go/aws/session:go_default_library", + "//vendor/github.com/aws/aws-sdk-go/service/route53:go_default_library", + "//vendor/github.com/golang/glog:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["route53_test.go"], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53", + library = ":go_default_library", + deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//dnsprovider/pkg/dnsprovider/tests:go_default_library", + "//vendor/github.com/aws/aws-sdk-go/aws:go_default_library", + "//vendor/github.com/aws/aws-sdk-go/service/route53:go_default_library", + ], +) diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/interface.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/interface.go index b5f171887286d..60c5a35785ecd 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/interface.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/interface.go @@ -17,8 +17,8 @@ limitations under the License. package route53 import ( - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/stubs" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53.go index 4e440f7a3da75..34f1364a96609 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53.go @@ -25,7 +25,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/route53" "github.com/golang/glog" - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) const ( diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53_test.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53_test.go index 19d8967fdeb01..c4e912870f820 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53_test.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/route53_test.go @@ -22,13 +22,13 @@ import ( "os" "testing" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - route53testing "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/stubs" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + route53testing "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" - "k8s.io/kubernetes/federation/pkg/dnsprovider/tests" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/tests" ) func newTestInterface() (dnsprovider.Interface, error) { diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go index 7727159fa32b4..3e51c54304c5b 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go @@ -23,7 +23,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" "github.com/golang/glog" - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrset.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrset.go index cee6fcc3425ae..c14e67ef26cf0 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrset.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrset.go @@ -17,8 +17,8 @@ limitations under the License. package route53 import ( - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrsets.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrsets.go index 67470c8778fc4..b66a3824bee25 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrsets.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrsets.go @@ -19,8 +19,8 @@ package route53 import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs/BUILD.bazel new file mode 100644 index 0000000000000..e54a0efddfaba --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["route53api.go"], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/aws/aws-sdk-go/aws:go_default_library", + "//vendor/github.com/aws/aws-sdk-go/service/route53:go_default_library", + ], +) diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/zone.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/zone.go index 7d82783ba09c0..7373a3c77ba36 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/zone.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/zone.go @@ -21,7 +21,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/zones.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/zones.go index 4cb9e9c5585c7..802901f1077b8 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/zones.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/zones.go @@ -20,7 +20,7 @@ import ( "github.com/aws/aws-sdk-go/service/route53" "k8s.io/apimachinery/pkg/util/uuid" - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/coredns/BUILD.bazel new file mode 100644 index 0000000000000..735424e8eae18 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/BUILD.bazel @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "coredns.go", + "interface.go", + "rrchangeset.go", + "rrset.go", + "rrsets.go", + "zone.go", + "zones.go", + ], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns", + visibility = ["//visibility:public"], + deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/coredns/stubs:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//vendor/github.com/coreos/etcd/client:go_default_library", + "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/miekg/coredns/middleware/etcd/msg:go_default_library", + "//vendor/golang.org/x/net/context:go_default_library", + "//vendor/gopkg.in/gcfg.v1:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["coredns_test.go"], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns", + library = ":go_default_library", + deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/coredns/stubs:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//dnsprovider/pkg/dnsprovider/tests:go_default_library", + ], +) diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go index ba39ba5fb1c75..6748dcc657408 100644 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns.go @@ -23,7 +23,7 @@ import ( "github.com/golang/glog" "gopkg.in/gcfg.v1" "io" - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "strconv" "strings" ) diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go index 39012573fd35a..c6a121cae4ddf 100644 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/coredns_test.go @@ -23,11 +23,11 @@ import ( "strconv" "testing" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - corednstesting "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/stubs" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + corednstesting "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns/stubs" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" - "k8s.io/kubernetes/federation/pkg/dnsprovider/tests" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/tests" "strings" ) diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go b/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go index d579fd4725c6a..c2c3f7bb23393 100644 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/interface.go @@ -17,8 +17,8 @@ limitations under the License. package coredns import ( - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/stubs" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns/stubs" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go b/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go index a2f4bab5160bd..d5a4161cacc1d 100644 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/rrchangeset.go @@ -24,7 +24,7 @@ import ( etcdc "github.com/coreos/etcd/client" dnsmsg "github.com/miekg/coredns/middleware/etcd/msg" "golang.org/x/net/context" - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go b/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go index 394303667ef6e..580f23671f560 100644 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/rrset.go @@ -17,8 +17,8 @@ limitations under the License. package coredns import ( - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go b/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go index dbd85cab35c94..2594ab41831c0 100644 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/rrsets.go @@ -23,8 +23,8 @@ import ( "github.com/golang/glog" dnsmsg "github.com/miekg/coredns/middleware/etcd/msg" "golang.org/x/net/context" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" "net" ) diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/BUILD.bazel new file mode 100644 index 0000000000000..753112bcf5e89 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/stubs/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["corednsapi.go"], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns/stubs", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/coreos/etcd/client:go_default_library", + "//vendor/golang.org/x/net/context:go_default_library", + ], +) diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go b/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go index 66cb7bb487903..b280ae6d167e0 100644 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/zone.go @@ -17,7 +17,7 @@ limitations under the License. package coredns import ( - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go b/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go index 14e34d96652e0..5c2d079813aed 100644 --- a/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go +++ b/dnsprovider/pkg/dnsprovider/providers/coredns/zones.go @@ -18,7 +18,7 @@ package coredns import ( "fmt" - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/BUILD.bazel new file mode 100644 index 0000000000000..6a9295b7f9da5 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/BUILD.bazel @@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "clouddns.go", + "interface.go", + "rrchangeset.go", + "rrset.go", + "rrsets.go", + "zone.go", + "zones.go", + ], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns", + visibility = ["//visibility:public"], + deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//vendor/cloud.google.com/go/compute/metadata:go_default_library", + "//vendor/github.com/golang/glog:go_default_library", + "//vendor/golang.org/x/oauth2:go_default_library", + "//vendor/golang.org/x/oauth2/google:go_default_library", + "//vendor/google.golang.org/api/compute/v1:go_default_library", + "//vendor/google.golang.org/api/dns/v1:go_default_library", + "//vendor/gopkg.in/gcfg.v1:go_default_library", + "//vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["clouddns_test.go"], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns", + library = ":go_default_library", + deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//dnsprovider/pkg/dnsprovider/tests:go_default_library", + ], +) diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns.go index 0242087b1fa4c..ca6cac843b473 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns.go @@ -28,9 +28,9 @@ import ( dns "google.golang.org/api/dns/v1" gcfg "gopkg.in/gcfg.v1" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs" "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" ) diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go index 705bb145d55d2..bb5e5350c36c1 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go @@ -22,9 +22,9 @@ import ( "os" "testing" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" - "k8s.io/kubernetes/federation/pkg/dnsprovider/tests" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/tests" ) func newTestInterface() (dnsprovider.Interface, error) { diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/interface.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/interface.go index 6fca4eb84c1ef..2b7da3dc3dae9 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/interface.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/interface.go @@ -17,8 +17,8 @@ limitations under the License. package clouddns import ( - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) var _ dnsprovider.Interface = Interface{} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/BUILD.bazel new file mode 100644 index 0000000000000..d9d14c1014fe2 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/BUILD.bazel @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "change.go", + "changes_create_call.go", + "changes_service.go", + "clouddns.go", + "managed_zone.go", + "managed_zone_create_call.go", + "managed_zones_delete_call.go", + "managed_zones_get_call.go", + "managed_zones_list_call.go", + "managed_zones_list_response.go", + "managed_zones_service.go", + "rrset.go", + "rrsets_list_call.go", + "rrsets_list_response.go", + "rrsets_service.go", + "service.go", + ], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal", + visibility = ["//visibility:public"], + deps = [ + "//dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//vendor/google.golang.org/api/dns/v1:go_default_library", + "//vendor/google.golang.org/api/googleapi:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library", + ], +) diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/change.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/change.go index e229a7954d785..9aea828607caf 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/change.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/change.go @@ -18,7 +18,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go index b1a8310bcd45a..1819d490671dc 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go @@ -20,7 +20,7 @@ import ( dns "google.golang.org/api/dns/v1" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go index 887ed9df2721f..f5a128ac72d99 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go @@ -18,7 +18,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/BUILD.bazel new file mode 100644 index 0000000000000..210b07b24b2d7 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["interfaces.go"], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces", + visibility = ["//dnsprovider/pkg/dnsprovider/providers/google/clouddns:__subpackages__"], + deps = [ + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//vendor/google.golang.org/api/googleapi:go_default_library", + ], +) diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go index 7d9f1663984e5..2fa2c2098c236 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go @@ -20,7 +20,7 @@ import ( "context" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) // Interfaces to directly mirror the Google Cloud DNS API structures. diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go index 862897743f9fb..6e7ef4fcf3e26 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go @@ -18,7 +18,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go index 133cd145b48fc..019ef9f039cde 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go @@ -19,7 +19,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go index 2e96763e010c1..da69e24e5a6aa 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go @@ -19,7 +19,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go index 2a6cadfed99b5..f355d5cc697f9 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go @@ -19,7 +19,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go index b704104647741..1ac212887a386 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go @@ -19,7 +19,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go index b254f5eb56ea1..86a74b1063f93 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go @@ -18,7 +18,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go index 2ea9e2484f903..e7240380213b9 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go @@ -21,7 +21,7 @@ import ( dns "google.golang.org/api/dns/v1" "k8s.io/apimachinery/pkg/util/uuid" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go index 2b7c0ce24e545..67cf759befba3 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go @@ -18,7 +18,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go index f497ebcfbce7e..b0414700db084 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go @@ -21,7 +21,7 @@ import ( dns "google.golang.org/api/dns/v1" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go index a6ff28df8f938..62ed278bd56bf 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go @@ -18,7 +18,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go index a971fd7513cef..1c741f1b89e36 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go @@ -18,8 +18,8 @@ package internal import ( dns "google.golang.org/api/dns/v1" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/service.go index 8ac5e63b74e32..0090b1705a513 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/service.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/service.go @@ -18,7 +18,7 @@ package internal import ( dns "google.golang.org/api/dns/v1" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/BUILD.bazel b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/BUILD.bazel new file mode 100644 index 0000000000000..86c3f71516fbc --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/BUILD.bazel @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "change.go", + "changes_create_call.go", + "changes_service.go", + "clouddns.go", + "managed_zone.go", + "managed_zone_create_call.go", + "managed_zones_delete_call.go", + "managed_zones_get_call.go", + "managed_zones_list_call.go", + "managed_zones_list_response.go", + "managed_zones_service.go", + "rrset.go", + "rrsets_list_call.go", + "rrsets_list_response.go", + "rrsets_service.go", + "service.go", + ], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs", + visibility = ["//dnsprovider/pkg/dnsprovider/providers/google/clouddns:__subpackages__"], + deps = [ + "//dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + "//vendor/google.golang.org/api/dns/v1:go_default_library", + "//vendor/google.golang.org/api/googleapi:go_default_library", + ], +) diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go index 83e5d94796739..b0f76ab710851 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go @@ -16,7 +16,7 @@ limitations under the License. package stubs -import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +import "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" // Compile time check for interface adherence var _ interfaces.Change = &Change{} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go index ab27a12f75e4d..712b715332b71 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go @@ -20,7 +20,7 @@ import ( "fmt" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go index 39b8bd14f217d..e2397dcc2fd6e 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go @@ -16,7 +16,7 @@ limitations under the License. package stubs -import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +import "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" // Compile time check for interface adherence var _ interfaces.ChangesService = &ChangesService{} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go index 2096da400bdac..b769b640f9bde 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go @@ -16,7 +16,7 @@ limitations under the License. package stubs -import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +import "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" // Compile time check for interface adherence var _ interfaces.ManagedZone = ManagedZone{} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go index f35f585cb51bc..fe680468cf080 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go @@ -20,7 +20,7 @@ import ( "fmt" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go index c518e76ebad81..d1341b2a2e2e8 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go @@ -20,7 +20,7 @@ import ( "fmt" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go index f2923c3abd35b..ebd5adc81b92b 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go @@ -18,7 +18,7 @@ package stubs import ( "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go index 4b7156ffbc53c..36b16bc6e74bf 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go @@ -20,7 +20,7 @@ import ( "fmt" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go index 095cae2ba80a2..1f3278400e7b5 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go @@ -16,7 +16,7 @@ limitations under the License. package stubs -import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +import "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" // Compile time check for interface adherence var _ interfaces.ManagedZonesListResponse = &ManagedZonesListResponse{} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go index 5b8513f2f73b1..df27f401ffee1 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go @@ -16,7 +16,7 @@ limitations under the License. package stubs -import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +import "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" // Compile time check for interface adherence var _ interfaces.ManagedZonesService = &ManagedZonesService{} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go index 3412775c17cee..eba1abec0a4c5 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go @@ -16,7 +16,7 @@ limitations under the License. package stubs -import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +import "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" // Compile time check for interface adherence var _ interfaces.ResourceRecordSet = ResourceRecordSet{} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go index 8695142bff5de..8403d46c3b753 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go @@ -20,7 +20,7 @@ import ( "context" "google.golang.org/api/googleapi" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go index a60d8dceffb18..1f907d419984d 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go @@ -16,7 +16,7 @@ limitations under the License. package stubs -import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +import "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" // Compile time check for interface adherence var _ interfaces.ResourceRecordSetsListResponse = &ResourceRecordSetsListResponse{} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go index 13e50d8b03b63..08a195a04ddcc 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go @@ -19,8 +19,8 @@ package stubs import ( "fmt" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go index 561678cf93656..7708695cb2e2e 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go @@ -16,7 +16,7 @@ limitations under the License. package stubs -import "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" +import "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" // Compile time check for interface adherence var _ interfaces.Service = &Service{} diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go index c81d03dd237b5..0dbbe712960d3 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go @@ -19,8 +19,8 @@ package clouddns import ( "fmt" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrset.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrset.go index f357e1c9e7c50..0a3f706892e39 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrset.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrset.go @@ -19,9 +19,9 @@ package clouddns import ( "fmt" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrsets.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrsets.go index db9411c766158..8a6c303942af9 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrsets.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/rrsets.go @@ -19,9 +19,9 @@ package clouddns import ( "context" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zone.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zone.go index 97e775f90f7be..fc8e1c09a1539 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zone.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zone.go @@ -19,8 +19,8 @@ package clouddns import ( "strconv" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zones.go b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zones.go index 62d56aef48686..7fd81286d2cdf 100644 --- a/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zones.go +++ b/dnsprovider/pkg/dnsprovider/providers/google/clouddns/zones.go @@ -17,8 +17,8 @@ limitations under the License. package clouddns import ( - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces" ) // Compile time check for interface adherence diff --git a/dnsprovider/pkg/dnsprovider/rrstype/BUILD.bazel b/dnsprovider/pkg/dnsprovider/rrstype/BUILD.bazel new file mode 100644 index 0000000000000..11a144014168f --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/rrstype/BUILD.bazel @@ -0,0 +1,8 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["rrstype.go"], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype", + visibility = ["//visibility:public"], +) diff --git a/dnsprovider/pkg/dnsprovider/tests/BUILD.bazel b/dnsprovider/pkg/dnsprovider/tests/BUILD.bazel new file mode 100644 index 0000000000000..c89a65ce54462 --- /dev/null +++ b/dnsprovider/pkg/dnsprovider/tests/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["commontests.go"], + importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/tests", + visibility = ["//visibility:public"], + deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", + ], +) diff --git a/dnsprovider/pkg/dnsprovider/tests/commontests.go b/dnsprovider/pkg/dnsprovider/tests/commontests.go index 6e1584ad86fc4..70027757c86a9 100644 --- a/dnsprovider/pkg/dnsprovider/tests/commontests.go +++ b/dnsprovider/pkg/dnsprovider/tests/commontests.go @@ -20,8 +20,8 @@ import ( "reflect" "testing" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) /* CommonTestResourceRecordSetsReplace verifies that replacing an RRS works */ From f03cc5dbd9e3dcedd75e3a75e2d91a60ab486dcf Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 15 Nov 2017 03:00:14 -0500 Subject: [PATCH 3/6] Update dnsprovider imports to use our version --- dns-controller/cmd/dns-controller/BUILD.bazel | 8 ++++---- dns-controller/cmd/dns-controller/main.go | 8 ++++---- dns-controller/pkg/dns/BUILD.bazel | 6 +++--- dns-controller/pkg/dns/dnscache.go | 2 +- dns-controller/pkg/dns/dnscontroller.go | 6 +++--- dns-controller/pkg/dns/zonespec.go | 2 +- pkg/resources/digitalocean/BUILD.bazel | 2 +- pkg/resources/digitalocean/cloud.go | 2 +- pkg/resources/digitalocean/dns/BUILD.bazel | 6 +++--- pkg/resources/digitalocean/dns/dns.go | 4 ++-- pkg/resources/digitalocean/dns/dns_test.go | 2 +- pkg/resources/gce/BUILD.bazel | 2 +- pkg/resources/gce/gce.go | 2 +- protokube/cmd/protokube/BUILD.bazel | 8 ++++---- protokube/cmd/protokube/main.go | 8 ++++---- protokube/pkg/gossip/dns/provider/BUILD.bazel | 4 ++-- protokube/pkg/gossip/dns/provider/changeset.go | 2 +- protokube/pkg/gossip/dns/provider/provider.go | 2 +- protokube/pkg/gossip/dns/provider/rrset.go | 4 ++-- protokube/pkg/gossip/dns/provider/zone.go | 4 ++-- protokube/pkg/gossip/dns/provider/zones.go | 2 +- upup/pkg/fi/BUILD.bazel | 2 +- upup/pkg/fi/cloud.go | 2 +- upup/pkg/fi/cloudup/BUILD.bazel | 6 +++--- upup/pkg/fi/cloudup/awsup/BUILD.bazel | 4 ++-- upup/pkg/fi/cloudup/awsup/aws_cloud.go | 4 ++-- upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go | 4 ++-- upup/pkg/fi/cloudup/baremetal/BUILD.bazel | 2 +- upup/pkg/fi/cloudup/baremetal/cloud.go | 2 +- upup/pkg/fi/cloudup/dns.go | 4 ++-- upup/pkg/fi/cloudup/dnstasks/BUILD.bazel | 2 +- upup/pkg/fi/cloudup/dnstasks/dnszone.go | 2 +- upup/pkg/fi/cloudup/gce/BUILD.bazel | 4 ++-- upup/pkg/fi/cloudup/gce/gce_cloud.go | 4 ++-- upup/pkg/fi/cloudup/gce/mock_gce_cloud.go | 4 ++-- upup/pkg/fi/cloudup/openstack/BUILD.bazel | 3 +-- upup/pkg/fi/cloudup/openstack/cloud.go | 2 +- upup/pkg/fi/cloudup/utils.go | 4 ++-- upup/pkg/fi/cloudup/vsphere/BUILD.bazel | 4 ++-- upup/pkg/fi/cloudup/vsphere/vsphere_cloud.go | 4 ++-- upup/pkg/fi/context.go | 2 +- 41 files changed, 75 insertions(+), 76 deletions(-) diff --git a/dns-controller/cmd/dns-controller/BUILD.bazel b/dns-controller/cmd/dns-controller/BUILD.bazel index 876946357007a..62560f3a07abc 100644 --- a/dns-controller/cmd/dns-controller/BUILD.bazel +++ b/dns-controller/cmd/dns-controller/BUILD.bazel @@ -8,6 +8,10 @@ go_library( deps = [ "//dns-controller/pkg/dns:go_default_library", "//dns-controller/pkg/watchers:go_default_library", + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/aws/route53:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/coredns:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/google/clouddns:go_default_library", "//protokube/pkg/gossip:go_default_library", "//protokube/pkg/gossip/dns:go_default_library", "//protokube/pkg/gossip/dns/provider:go_default_library", @@ -16,10 +20,6 @@ go_library( "//vendor/github.com/spf13/pflag:go_default_library", "//vendor/k8s.io/client-go/kubernetes:go_default_library", "//vendor/k8s.io/client-go/rest:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns:go_default_library", ], ) diff --git a/dns-controller/cmd/dns-controller/main.go b/dns-controller/cmd/dns-controller/main.go index ac6b7d4f9d61c..5ac1a9672a69c 100644 --- a/dns-controller/cmd/dns-controller/main.go +++ b/dns-controller/cmd/dns-controller/main.go @@ -30,14 +30,14 @@ import ( "k8s.io/client-go/rest" "k8s.io/kops/dns-controller/pkg/dns" "k8s.io/kops/dns-controller/pkg/watchers" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + _ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53" + k8scoredns "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns" + _ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns" "k8s.io/kops/protokube/pkg/gossip" gossipdns "k8s.io/kops/protokube/pkg/gossip/dns" gossipdnsprovider "k8s.io/kops/protokube/pkg/gossip/dns/provider" "k8s.io/kops/protokube/pkg/gossip/mesh" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - _ "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53" - k8scoredns "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns" - _ "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns" ) var ( diff --git a/dns-controller/pkg/dns/BUILD.bazel b/dns-controller/pkg/dns/BUILD.bazel index ba973111ddb3b..16c3cf281c361 100644 --- a/dns-controller/pkg/dns/BUILD.bazel +++ b/dns-controller/pkg/dns/BUILD.bazel @@ -13,10 +13,10 @@ go_library( visibility = ["//visibility:public"], deps = [ "//dns-controller/pkg/util:go_default_library", + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/coredns:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", "//vendor/github.com/golang/glog:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype:go_default_library", ], ) diff --git a/dns-controller/pkg/dns/dnscache.go b/dns-controller/pkg/dns/dnscache.go index 57e591e2f93e2..1817673d5bb0f 100644 --- a/dns-controller/pkg/dns/dnscache.go +++ b/dns-controller/pkg/dns/dnscache.go @@ -22,7 +22,7 @@ import ( "time" "github.com/golang/glog" - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) // dnsCache is a wrapper around the DNS provider, adding some caching diff --git a/dns-controller/pkg/dns/dnscontroller.go b/dns-controller/pkg/dns/dnscontroller.go index a2eeb2f28934c..96ba1fca7bedb 100644 --- a/dns-controller/pkg/dns/dnscontroller.go +++ b/dns-controller/pkg/dns/dnscontroller.go @@ -28,9 +28,9 @@ import ( "sync/atomic" "k8s.io/kops/dns-controller/pkg/util" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - k8scoredns "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + k8scoredns "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) var zoneListCacheValidity = time.Minute * 15 diff --git a/dns-controller/pkg/dns/zonespec.go b/dns-controller/pkg/dns/zonespec.go index 435e2f2c6704a..2e91e7ff20339 100644 --- a/dns-controller/pkg/dns/zonespec.go +++ b/dns-controller/pkg/dns/zonespec.go @@ -21,7 +21,7 @@ import ( "strings" "github.com/golang/glog" - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) type ZoneSpec struct { diff --git a/pkg/resources/digitalocean/BUILD.bazel b/pkg/resources/digitalocean/BUILD.bazel index 25d3381591fe5..61be673013ea9 100644 --- a/pkg/resources/digitalocean/BUILD.bazel +++ b/pkg/resources/digitalocean/BUILD.bazel @@ -10,6 +10,7 @@ go_library( importpath = "k8s.io/kops/pkg/resources/digitalocean", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", "//pkg/apis/kops:go_default_library", "//pkg/cloudinstances:go_default_library", "//pkg/resources:go_default_library", @@ -19,6 +20,5 @@ go_library( "//vendor/github.com/golang/glog:go_default_library", "//vendor/golang.org/x/oauth2:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", ], ) diff --git a/pkg/resources/digitalocean/cloud.go b/pkg/resources/digitalocean/cloud.go index 7696f45525cb3..2587c8aacd6cb 100644 --- a/pkg/resources/digitalocean/cloud.go +++ b/pkg/resources/digitalocean/cloud.go @@ -27,11 +27,11 @@ import ( "fmt" "k8s.io/api/core/v1" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/cloudinstances" "k8s.io/kops/pkg/resources/digitalocean/dns" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kubernetes/federation/pkg/dnsprovider" ) // TokenSource implements oauth2.TokenSource diff --git a/pkg/resources/digitalocean/dns/BUILD.bazel b/pkg/resources/digitalocean/dns/BUILD.bazel index db485552ea84e..962b12d51b15b 100644 --- a/pkg/resources/digitalocean/dns/BUILD.bazel +++ b/pkg/resources/digitalocean/dns/BUILD.bazel @@ -6,11 +6,11 @@ go_library( importpath = "k8s.io/kops/pkg/resources/digitalocean/dns", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", "//vendor/github.com/digitalocean/godo:go_default_library", "//vendor/github.com/digitalocean/godo/context:go_default_library", "//vendor/github.com/golang/glog:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype:go_default_library", ], ) @@ -21,8 +21,8 @@ go_test( importpath = "k8s.io/kops/pkg/resources/digitalocean/dns", library = ":go_default_library", deps = [ + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", "//vendor/github.com/digitalocean/godo:go_default_library", "//vendor/github.com/digitalocean/godo/context:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype:go_default_library", ], ) diff --git a/pkg/resources/digitalocean/dns/dns.go b/pkg/resources/digitalocean/dns/dns.go index 46ab37eb5f591..f608d323e7c6d 100644 --- a/pkg/resources/digitalocean/dns/dns.go +++ b/pkg/resources/digitalocean/dns/dns.go @@ -24,8 +24,8 @@ import ( "github.com/golang/glog" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) const ipPlaceholder = "203.0.113.123" diff --git a/pkg/resources/digitalocean/dns/dns_test.go b/pkg/resources/digitalocean/dns/dns_test.go index 25a8dec96a325..be72d23325c89 100644 --- a/pkg/resources/digitalocean/dns/dns_test.go +++ b/pkg/resources/digitalocean/dns/dns_test.go @@ -26,7 +26,7 @@ import ( "github.com/digitalocean/godo" "github.com/digitalocean/godo/context" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" ) type fakeDomainService struct { diff --git a/pkg/resources/gce/BUILD.bazel b/pkg/resources/gce/BUILD.bazel index 47fd3d8c3e5f9..33066c5ae87f4 100644 --- a/pkg/resources/gce/BUILD.bazel +++ b/pkg/resources/gce/BUILD.bazel @@ -9,13 +9,13 @@ go_library( importpath = "k8s.io/kops/pkg/resources/gce", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", "//pkg/resources:go_default_library", "//upup/pkg/fi:go_default_library", "//upup/pkg/fi/cloudup/gce:go_default_library", "//vendor/github.com/golang/glog:go_default_library", "//vendor/google.golang.org/api/compute/v0.beta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", ], ) diff --git a/pkg/resources/gce/gce.go b/pkg/resources/gce/gce.go index 26573844128aa..263dde00a1c99 100644 --- a/pkg/resources/gce/gce.go +++ b/pkg/resources/gce/gce.go @@ -24,10 +24,10 @@ import ( "github.com/golang/glog" compute "google.golang.org/api/compute/v0.beta" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/pkg/resources" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/gce" - "k8s.io/kubernetes/federation/pkg/dnsprovider" ) type gceListFn func() ([]*resources.Resource, error) diff --git a/protokube/cmd/protokube/BUILD.bazel b/protokube/cmd/protokube/BUILD.bazel index fa99f9d314f14..66acacda3500e 100644 --- a/protokube/cmd/protokube/BUILD.bazel +++ b/protokube/cmd/protokube/BUILD.bazel @@ -7,16 +7,16 @@ go_library( visibility = ["//visibility:private"], deps = [ "//dns-controller/pkg/dns:go_default_library", + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/aws/route53:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/coredns:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/google/clouddns:go_default_library", "//protokube/pkg/gossip:go_default_library", "//protokube/pkg/gossip/dns:go_default_library", "//protokube/pkg/gossip/mesh:go_default_library", "//protokube/pkg/protokube:go_default_library", "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns:go_default_library", ], ) diff --git a/protokube/cmd/protokube/main.go b/protokube/cmd/protokube/main.go index d599f7eb27983..db32d7039166a 100644 --- a/protokube/cmd/protokube/main.go +++ b/protokube/cmd/protokube/main.go @@ -27,17 +27,17 @@ import ( "strings" "k8s.io/kops/dns-controller/pkg/dns" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/protokube/pkg/gossip" gossipdns "k8s.io/kops/protokube/pkg/gossip/dns" "k8s.io/kops/protokube/pkg/gossip/mesh" "k8s.io/kops/protokube/pkg/protokube" - "k8s.io/kubernetes/federation/pkg/dnsprovider" // Load DNS plugins "github.com/golang/glog" "github.com/spf13/pflag" - _ "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53" - k8scoredns "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns" - _ "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns" + _ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53" + k8scoredns "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns" + _ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns" ) var ( diff --git a/protokube/pkg/gossip/dns/provider/BUILD.bazel b/protokube/pkg/gossip/dns/provider/BUILD.bazel index e69a83bd052c6..4c13ef96710d2 100644 --- a/protokube/pkg/gossip/dns/provider/BUILD.bazel +++ b/protokube/pkg/gossip/dns/provider/BUILD.bazel @@ -13,8 +13,8 @@ go_library( importpath = "k8s.io/kops/protokube/pkg/gossip/dns/provider", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", "//protokube/pkg/gossip/dns:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype:go_default_library", ], ) diff --git a/protokube/pkg/gossip/dns/provider/changeset.go b/protokube/pkg/gossip/dns/provider/changeset.go index 6151231b851c8..afd0baf2888f5 100644 --- a/protokube/pkg/gossip/dns/provider/changeset.go +++ b/protokube/pkg/gossip/dns/provider/changeset.go @@ -17,7 +17,7 @@ limitations under the License. package provider import ( - "k8s.io/kubernetes/federation/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" ) type resourceRecordChangeset struct { diff --git a/protokube/pkg/gossip/dns/provider/provider.go b/protokube/pkg/gossip/dns/provider/provider.go index 2fe0f06512353..cd5b4028611d6 100644 --- a/protokube/pkg/gossip/dns/provider/provider.go +++ b/protokube/pkg/gossip/dns/provider/provider.go @@ -17,8 +17,8 @@ limitations under the License. package provider import ( + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/protokube/pkg/gossip/dns" - "k8s.io/kubernetes/federation/pkg/dnsprovider" ) type Provider struct { diff --git a/protokube/pkg/gossip/dns/provider/rrset.go b/protokube/pkg/gossip/dns/provider/rrset.go index 7aeedc0e4c37c..8fc9267397c16 100644 --- a/protokube/pkg/gossip/dns/provider/rrset.go +++ b/protokube/pkg/gossip/dns/provider/rrset.go @@ -17,9 +17,9 @@ limitations under the License. package provider import ( + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" "k8s.io/kops/protokube/pkg/gossip/dns" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" ) const defaultTTL = 60 diff --git a/protokube/pkg/gossip/dns/provider/zone.go b/protokube/pkg/gossip/dns/provider/zone.go index aa4b711b8a3ce..e84adf510ad26 100644 --- a/protokube/pkg/gossip/dns/provider/zone.go +++ b/protokube/pkg/gossip/dns/provider/zone.go @@ -19,9 +19,9 @@ package provider import ( "fmt" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" "k8s.io/kops/protokube/pkg/gossip/dns" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" ) type zone struct { diff --git a/protokube/pkg/gossip/dns/provider/zones.go b/protokube/pkg/gossip/dns/provider/zones.go index 0d1459cd38b06..edfd5887b281f 100644 --- a/protokube/pkg/gossip/dns/provider/zones.go +++ b/protokube/pkg/gossip/dns/provider/zones.go @@ -19,8 +19,8 @@ package provider import ( "fmt" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/protokube/pkg/gossip/dns" - "k8s.io/kubernetes/federation/pkg/dnsprovider" ) type zones struct { diff --git a/upup/pkg/fi/BUILD.bazel b/upup/pkg/fi/BUILD.bazel index f3f66d6ad7cd5..57e37b86f4b18 100644 --- a/upup/pkg/fi/BUILD.bazel +++ b/upup/pkg/fi/BUILD.bazel @@ -41,6 +41,7 @@ go_library( importpath = "k8s.io/kops/upup/pkg/fi", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", "//pkg/acls:go_default_library", "//pkg/apis/kops:go_default_library", "//pkg/assets:go_default_library", @@ -58,7 +59,6 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/api/validation:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", ], ) diff --git a/upup/pkg/fi/cloud.go b/upup/pkg/fi/cloud.go index 7416175e546f1..e7a7b8f452718 100644 --- a/upup/pkg/fi/cloud.go +++ b/upup/pkg/fi/cloud.go @@ -18,9 +18,9 @@ package fi import ( "k8s.io/api/core/v1" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/cloudinstances" - "k8s.io/kubernetes/federation/pkg/dnsprovider" ) type Cloud interface { diff --git a/upup/pkg/fi/cloudup/BUILD.bazel b/upup/pkg/fi/cloudup/BUILD.bazel index 0bda75dab5eb8..b3a7ceabe5612 100644 --- a/upup/pkg/fi/cloudup/BUILD.bazel +++ b/upup/pkg/fi/cloudup/BUILD.bazel @@ -26,6 +26,9 @@ go_library( "//:go_default_library", "//channels/pkg/api:go_default_library", "//dns-controller/pkg/dns:go_default_library", + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/aws/route53:go_default_library", + "//dnsprovider/pkg/dnsprovider/rrstype:go_default_library", "//pkg/apis/kops:go_default_library", "//pkg/apis/kops/registry:go_default_library", "//pkg/apis/kops/util:go_default_library", @@ -68,9 +71,6 @@ go_library( "//vendor/github.com/golang/glog:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype:go_default_library", ], ) diff --git a/upup/pkg/fi/cloudup/awsup/BUILD.bazel b/upup/pkg/fi/cloudup/awsup/BUILD.bazel index c0a80e7b25951..db7f63174e7c3 100644 --- a/upup/pkg/fi/cloudup/awsup/BUILD.bazel +++ b/upup/pkg/fi/cloudup/awsup/BUILD.bazel @@ -16,6 +16,8 @@ go_library( importpath = "k8s.io/kops/upup/pkg/fi/cloudup/awsup", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/aws/route53:go_default_library", "//pkg/apis/kops:go_default_library", "//pkg/apis/kops/model:go_default_library", "//pkg/cloudinstances:go_default_library", @@ -38,8 +40,6 @@ go_library( "//vendor/github.com/golang/glog:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53:go_default_library", "//vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/aws:go_default_library", ], ) diff --git a/upup/pkg/fi/cloudup/awsup/aws_cloud.go b/upup/pkg/fi/cloudup/awsup/aws_cloud.go index 491dccb4dd104..bb09c3075f984 100644 --- a/upup/pkg/fi/cloudup/awsup/aws_cloud.go +++ b/upup/pkg/fi/cloudup/awsup/aws_cloud.go @@ -40,12 +40,12 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + dnsproviderroute53 "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops/model" "k8s.io/kops/pkg/cloudinstances" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - dnsproviderroute53 "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53" k8s_aws "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" ) diff --git a/upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go b/upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go index 030f9c85154d7..0ca31f5ad345c 100644 --- a/upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go +++ b/upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go @@ -29,11 +29,11 @@ import ( "github.com/aws/aws-sdk-go/service/route53/route53iface" "github.com/golang/glog" "k8s.io/api/core/v1" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + dnsproviderroute53 "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/cloudinstances" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - dnsproviderroute53 "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53" ) type MockAWSCloud struct { diff --git a/upup/pkg/fi/cloudup/baremetal/BUILD.bazel b/upup/pkg/fi/cloudup/baremetal/BUILD.bazel index cd9d14064d26e..4c5fa536ce6e4 100644 --- a/upup/pkg/fi/cloudup/baremetal/BUILD.bazel +++ b/upup/pkg/fi/cloudup/baremetal/BUILD.bazel @@ -9,11 +9,11 @@ go_library( importpath = "k8s.io/kops/upup/pkg/fi/cloudup/baremetal", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", "//pkg/apis/kops:go_default_library", "//pkg/cloudinstances:go_default_library", "//upup/pkg/fi:go_default_library", "//vendor/github.com/golang/glog:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", ], ) diff --git a/upup/pkg/fi/cloudup/baremetal/cloud.go b/upup/pkg/fi/cloudup/baremetal/cloud.go index 70c252a456d65..cca9b0a654682 100644 --- a/upup/pkg/fi/cloudup/baremetal/cloud.go +++ b/upup/pkg/fi/cloudup/baremetal/cloud.go @@ -22,10 +22,10 @@ import ( "github.com/golang/glog" "k8s.io/api/core/v1" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/cloudinstances" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kubernetes/federation/pkg/dnsprovider" ) type Cloud struct { diff --git a/upup/pkg/fi/cloudup/dns.go b/upup/pkg/fi/cloudup/dns.go index cbaa222ecc501..aadf891efa864 100644 --- a/upup/pkg/fi/cloudup/dns.go +++ b/upup/pkg/fi/cloudup/dns.go @@ -24,13 +24,13 @@ import ( "github.com/golang/glog" "k8s.io/kops/dns-controller/pkg/dns" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype" "k8s.io/kops/pkg/apis/kops" kopsdns "k8s.io/kops/pkg/dns" "k8s.io/kops/pkg/featureflag" "k8s.io/kops/pkg/model" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype" ) const ( diff --git a/upup/pkg/fi/cloudup/dnstasks/BUILD.bazel b/upup/pkg/fi/cloudup/dnstasks/BUILD.bazel index d4262daada039..94c9d86873301 100644 --- a/upup/pkg/fi/cloudup/dnstasks/BUILD.bazel +++ b/upup/pkg/fi/cloudup/dnstasks/BUILD.bazel @@ -6,8 +6,8 @@ go_library( importpath = "k8s.io/kops/upup/pkg/fi/cloudup/dnstasks", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", "//upup/pkg/fi:go_default_library", "//vendor/github.com/golang/glog:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", ], ) diff --git a/upup/pkg/fi/cloudup/dnstasks/dnszone.go b/upup/pkg/fi/cloudup/dnstasks/dnszone.go index af708fd91257c..91a353de522e7 100644 --- a/upup/pkg/fi/cloudup/dnstasks/dnszone.go +++ b/upup/pkg/fi/cloudup/dnstasks/dnszone.go @@ -22,8 +22,8 @@ import ( "strings" "github.com/golang/glog" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kubernetes/federation/pkg/dnsprovider" ) // DNSZone is a zone object in a dns provider diff --git a/upup/pkg/fi/cloudup/gce/BUILD.bazel b/upup/pkg/fi/cloudup/gce/BUILD.bazel index 0b69a6304e21d..2c98a2e9f7e62 100644 --- a/upup/pkg/fi/cloudup/gce/BUILD.bazel +++ b/upup/pkg/fi/cloudup/gce/BUILD.bazel @@ -17,6 +17,8 @@ go_library( importpath = "k8s.io/kops/upup/pkg/fi/cloudup/gce", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/google/clouddns:go_default_library", "//pkg/apis/kops:go_default_library", "//pkg/cloudinstances:go_default_library", "//protokube/pkg/etcd:go_default_library", @@ -31,7 +33,5 @@ go_library( "//vendor/google.golang.org/api/storage/v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns:go_default_library", ], ) diff --git a/upup/pkg/fi/cloudup/gce/gce_cloud.go b/upup/pkg/fi/cloudup/gce/gce_cloud.go index 9031ec331ce74..e2c80a1b76ab3 100644 --- a/upup/pkg/fi/cloudup/gce/gce_cloud.go +++ b/upup/pkg/fi/cloudup/gce/gce_cloud.go @@ -30,10 +30,10 @@ import ( "google.golang.org/api/iam/v1" oauth2 "google.golang.org/api/oauth2/v2" "google.golang.org/api/storage/v1" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns" ) type GCECloud interface { diff --git a/upup/pkg/fi/cloudup/gce/mock_gce_cloud.go b/upup/pkg/fi/cloudup/gce/mock_gce_cloud.go index 39707d0ca6d49..c77f6439ca781 100644 --- a/upup/pkg/fi/cloudup/gce/mock_gce_cloud.go +++ b/upup/pkg/fi/cloudup/gce/mock_gce_cloud.go @@ -24,11 +24,11 @@ import ( "google.golang.org/api/iam/v1" "google.golang.org/api/storage/v1" "k8s.io/api/core/v1" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + dnsproviderclouddns "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/cloudinstances" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - dnsproviderclouddns "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns" ) // mockGCECloud is a mock implementation of GCECloud for testing diff --git a/upup/pkg/fi/cloudup/openstack/BUILD.bazel b/upup/pkg/fi/cloudup/openstack/BUILD.bazel index dcb6e4b65e674..308f6681ac012 100644 --- a/upup/pkg/fi/cloudup/openstack/BUILD.bazel +++ b/upup/pkg/fi/cloudup/openstack/BUILD.bazel @@ -9,6 +9,7 @@ go_library( importpath = "k8s.io/kops/upup/pkg/fi/cloudup/openstack", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", "//pkg/apis/kops:go_default_library", "//pkg/cloudinstances:go_default_library", "//upup/pkg/fi:go_default_library", @@ -18,7 +19,5 @@ go_library( "//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", ], ) diff --git a/upup/pkg/fi/cloudup/openstack/cloud.go b/upup/pkg/fi/cloudup/openstack/cloud.go index bee8abf85609d..2790d1cdd9928 100644 --- a/upup/pkg/fi/cloudup/openstack/cloud.go +++ b/upup/pkg/fi/cloudup/openstack/cloud.go @@ -26,11 +26,11 @@ import ( cinder "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/cloudinstances" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/util/pkg/vfs" - "k8s.io/kubernetes/federation/pkg/dnsprovider" ) const TagNameEtcdClusterPrefix = "k8s.io/etcd/" diff --git a/upup/pkg/fi/cloudup/utils.go b/upup/pkg/fi/cloudup/utils.go index 5d203bf212229..2782f4fd78e65 100644 --- a/upup/pkg/fi/cloudup/utils.go +++ b/upup/pkg/fi/cloudup/utils.go @@ -21,6 +21,8 @@ import ( "strings" "github.com/golang/glog" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/awsup" @@ -29,8 +31,6 @@ import ( "k8s.io/kops/upup/pkg/fi/cloudup/gce" "k8s.io/kops/upup/pkg/fi/cloudup/openstack" "k8s.io/kops/upup/pkg/fi/cloudup/vsphere" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53" ) func BuildCloud(cluster *kops.Cluster) (fi.Cloud, error) { diff --git a/upup/pkg/fi/cloudup/vsphere/BUILD.bazel b/upup/pkg/fi/cloudup/vsphere/BUILD.bazel index 72b45fa3e9352..58c775ef43716 100644 --- a/upup/pkg/fi/cloudup/vsphere/BUILD.bazel +++ b/upup/pkg/fi/cloudup/vsphere/BUILD.bazel @@ -11,6 +11,8 @@ go_library( importpath = "k8s.io/kops/upup/pkg/fi/cloudup/vsphere", visibility = ["//visibility:public"], deps = [ + "//dnsprovider/pkg/dnsprovider:go_default_library", + "//dnsprovider/pkg/dnsprovider/providers/coredns:go_default_library", "//pkg/apis/kops:go_default_library", "//pkg/cloudinstances:go_default_library", "//upup/pkg/fi:go_default_library", @@ -25,7 +27,5 @@ go_library( "//vendor/github.com/vmware/govmomi/vim25/soap:go_default_library", "//vendor/github.com/vmware/govmomi/vim25/types:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider:go_default_library", - "//vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns:go_default_library", ], ) diff --git a/upup/pkg/fi/cloudup/vsphere/vsphere_cloud.go b/upup/pkg/fi/cloudup/vsphere/vsphere_cloud.go index 24f84e63321fc..2f481a9c5b4a1 100644 --- a/upup/pkg/fi/cloudup/vsphere/vsphere_cloud.go +++ b/upup/pkg/fi/cloudup/vsphere/vsphere_cloud.go @@ -37,11 +37,11 @@ import ( "github.com/vmware/govmomi/vim25/soap" "github.com/vmware/govmomi/vim25/types" "k8s.io/api/core/v1" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" + k8scoredns "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/cloudinstances" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kubernetes/federation/pkg/dnsprovider" - k8scoredns "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns" ) // VSphereCloud represents a vSphere cloud instance. diff --git a/upup/pkg/fi/context.go b/upup/pkg/fi/context.go index 11ea288bf13bd..2c99e2bd90409 100644 --- a/upup/pkg/fi/context.go +++ b/upup/pkg/fi/context.go @@ -26,9 +26,9 @@ import ( "time" "github.com/golang/glog" + "k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/util/pkg/vfs" - "k8s.io/kubernetes/federation/pkg/dnsprovider" ) type Context struct { From 84449a38521469fd1b33363de9556dde8e6f115c Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 15 Nov 2017 03:02:47 -0500 Subject: [PATCH 4/6] Fix simple IsEmpty logic bug in route53 --- .../pkg/dnsprovider/providers/aws/route53/rrchangeset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go index 3e51c54304c5b..2782abc5ddd9c 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go @@ -125,7 +125,7 @@ func (c *ResourceRecordChangeset) Apply() error { } func (c *ResourceRecordChangeset) IsEmpty() bool { - return len(c.removals) == 0 && len(c.additions) == 0 + return len(c.removals) == 0 && len(c.additions) == 0 && len(c.upserts) == 0 } // ResourceRecordSets returns the parent ResourceRecordSets From 94452eb648b95a931a6c87707e5fe503552b803e Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 15 Nov 2017 03:12:50 -0500 Subject: [PATCH 5/6] Batch route53 requests to stay under the route53 limit --- .../providers/aws/route53/rrchangeset.go | 98 +++++++++++++------ 1 file changed, 70 insertions(+), 28 deletions(-) diff --git a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go index 2782abc5ddd9c..e3f443c0fd3a4 100644 --- a/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go +++ b/dnsprovider/pkg/dnsprovider/providers/aws/route53/rrchangeset.go @@ -76,51 +76,93 @@ func buildChange(action string, rrs dnsprovider.ResourceRecordSet) *route53.Chan func (c *ResourceRecordChangeset) Apply() error { hostedZoneID := c.zone.impl.Id - var changes []*route53.Change - + removals := make(map[string]*route53.Change) for _, removal := range c.removals { - change := buildChange(route53.ChangeActionDelete, removal) - changes = append(changes, change) + removals[string(removal.Type())+"::"+removal.Name()] = buildChange(route53.ChangeActionDelete, removal) } + additions := make(map[string]*route53.Change) for _, addition := range c.additions { - change := buildChange(route53.ChangeActionCreate, addition) - changes = append(changes, change) + additions[string(addition.Type())+"::"+addition.Name()] = buildChange(route53.ChangeActionCreate, addition) } + upserts := make(map[string]*route53.Change) for _, upsert := range c.upserts { - change := buildChange(route53.ChangeActionUpsert, upsert) - changes = append(changes, change) + upserts[string(upsert.Type())+"::"+upsert.Name()] = buildChange(route53.ChangeActionUpsert, upsert) } - if len(changes) == 0 { - return nil + doneKeys := make(map[string]bool) + + keys := make(map[string]bool) + for k := range removals { + keys[k] = true + } + for k := range additions { + keys[k] = true + } + for k := range upserts { + keys[k] = true } - if glog.V(8) { - var sb bytes.Buffer - for _, change := range changes { - sb.WriteString(fmt.Sprintf("\t%s %s %s\n", aws.StringValue(change.Action), aws.StringValue(change.ResourceRecordSet.Type), aws.StringValue(change.ResourceRecordSet.Name))) + for { + // Limit batch size + maxBatchSize := 900 + + var batch []*route53.Change + // We group the changes so that changes with the same key are in the same batch + for k := range keys { + if doneKeys[k] { + continue + } + + if len(batch)+3 >= maxBatchSize { + break + } + + if change := removals[k]; change != nil { + batch = append(batch, change) + } + if change := additions[k]; change != nil { + batch = append(batch, change) + } + if change := upserts[k]; change != nil { + batch = append(batch, change) + } + doneKeys[k] = true } - glog.V(8).Infof("Route53 Changeset:\n%s", sb.String()) - } + if len(batch) == 0 { + // Nothing left to do + break + } - service := c.zone.zones.interface_.service + if glog.V(8) { + var sb bytes.Buffer + for _, change := range batch { + sb.WriteString(fmt.Sprintf("\t%s %s %s\n", aws.StringValue(change.Action), aws.StringValue(change.ResourceRecordSet.Type), aws.StringValue(change.ResourceRecordSet.Name))) + } - request := &route53.ChangeResourceRecordSetsInput{ - ChangeBatch: &route53.ChangeBatch{ - Changes: changes, - }, - HostedZoneId: hostedZoneID, - } + glog.V(8).Infof("Route53 Changeset:\n%s", sb.String()) + } - _, err := service.ChangeResourceRecordSets(request) - if err != nil { - // Cast err to awserr.Error to get the Code and - // Message from an error. - return err + service := c.zone.zones.interface_.service + + request := &route53.ChangeResourceRecordSetsInput{ + ChangeBatch: &route53.ChangeBatch{ + Changes: batch, + }, + HostedZoneId: hostedZoneID, + } + + // The aws-sdk-go does backoff for PriorRequestNotComplete + _, err := service.ChangeResourceRecordSets(request) + if err != nil { + // Cast err to awserr.Error to get the Code and + // Message from an error. + return err + } } + return nil } From 1cceb8ed9e591ba98268a9f087fded41b47c4052 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 13 Dec 2017 21:32:21 -0500 Subject: [PATCH 6/6] Update hack/.packages --- hack/.packages | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hack/.packages b/hack/.packages index 19e23bd01bbae..c3a1c470548ee 100644 --- a/hack/.packages +++ b/hack/.packages @@ -15,6 +15,17 @@ k8s.io/kops/dns-controller/cmd/dns-controller k8s.io/kops/dns-controller/pkg/dns k8s.io/kops/dns-controller/pkg/util k8s.io/kops/dns-controller/pkg/watchers +k8s.io/kops/dnsprovider/pkg/dnsprovider +k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53 +k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53/stubs +k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns +k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/coredns/stubs +k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns +k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal +k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/interfaces +k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns/internal/stubs +k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype +k8s.io/kops/dnsprovider/pkg/dnsprovider/tests k8s.io/kops/examples/kops-api-example k8s.io/kops/federation k8s.io/kops/federation/model