Replace godep with dep
This commit is contained in:
parent
1e7489927c
commit
bf5616c65b
14883 changed files with 3937406 additions and 361781 deletions
47
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/BUILD
generated
vendored
Normal file
47
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
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",
|
||||
],
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider/rrstype:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["dns_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = ["//federation/pkg/dnsprovider/rrstype:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//federation/pkg/dnsprovider/providers/aws/route53:all-srcs",
|
||||
"//federation/pkg/dnsprovider/providers/coredns:all-srcs",
|
||||
"//federation/pkg/dnsprovider/providers/google/clouddns:all-srcs",
|
||||
"//federation/pkg/dnsprovider/rrstype:all-srcs",
|
||||
"//federation/pkg/dnsprovider/tests:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
114
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/dns.go
generated
vendored
Normal file
114
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/dns.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
96
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/dns_test.go
generated
vendored
Normal file
96
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/dns_test.go
generated
vendored
Normal file
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
21
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/doc.go
generated
vendored
Normal file
21
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/doc.go
generated
vendored
Normal file
|
|
@ -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"
|
||||
109
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/plugins.go
generated
vendored
Normal file
109
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/plugins.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
61
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/BUILD
generated
vendored
Normal file
61
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
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",
|
||||
],
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider:go_default_library",
|
||||
"//federation/pkg/dnsprovider/providers/aws/route53/stubs:go_default_library",
|
||||
"//federation/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"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider:go_default_library",
|
||||
"//federation/pkg/dnsprovider/providers/aws/route53/stubs:go_default_library",
|
||||
"//federation/pkg/dnsprovider/rrstype:go_default_library",
|
||||
"//federation/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",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//federation/pkg/dnsprovider/providers/aws/route53/stubs:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
39
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/interface.go
generated
vendored
Normal file
39
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/interface.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
72
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/route53.go
generated
vendored
Normal file
72
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/route53.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
295
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/route53_test.go
generated
vendored
Normal file
295
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/route53_test.go
generated
vendored
Normal file
|
|
@ -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)
|
||||
}
|
||||
134
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/rrchangeset.go
generated
vendored
Normal file
134
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/rrchangeset.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
63
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/rrset.go
generated
vendored
Normal file
63
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/rrset.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
106
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/rrsets.go
generated
vendored
Normal file
106
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/rrsets.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/stubs/BUILD
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/stubs/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["route53api.go"],
|
||||
deps = [
|
||||
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
|
||||
"//vendor/github.com/aws/aws-sdk-go/service/route53:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
133
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/stubs/route53api.go
generated
vendored
Normal file
133
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/stubs/route53api.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
56
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/zone.go
generated
vendored
Normal file
56
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/zone.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
73
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/zones.go
generated
vendored
Normal file
73
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53/zones.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
58
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/BUILD
generated
vendored
Normal file
58
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
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",
|
||||
],
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider:go_default_library",
|
||||
"//federation/pkg/dnsprovider/providers/coredns/stubs:go_default_library",
|
||||
"//federation/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"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider:go_default_library",
|
||||
"//federation/pkg/dnsprovider/providers/coredns/stubs:go_default_library",
|
||||
"//federation/pkg/dnsprovider/rrstype:go_default_library",
|
||||
"//federation/pkg/dnsprovider/tests:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//federation/pkg/dnsprovider/providers/coredns/stubs:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
95
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/coredns.go
generated
vendored
Normal file
95
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/coredns.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
270
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/coredns_test.go
generated
vendored
Normal file
270
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/coredns_test.go
generated
vendored
Normal file
|
|
@ -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)
|
||||
}
|
||||
41
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/interface.go
generated
vendored
Normal file
41
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/interface.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
148
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/rrchangeset.go
generated
vendored
Normal file
148
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/rrchangeset.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
49
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/rrset.go
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/rrset.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
114
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/rrsets.go
generated
vendored
Normal file
114
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/rrsets.go
generated
vendored
Normal file
|
|
@ -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)
|
||||
}
|
||||
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/stubs/BUILD
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/stubs/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["corednsapi.go"],
|
||||
deps = [
|
||||
"//vendor/github.com/coreos/etcd/client:go_default_library",
|
||||
"//vendor/golang.org/x/net/context:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
85
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go
generated
vendored
Normal file
85
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/stubs/corednsapi.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
42
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/zone.go
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/zone.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
49
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/zones.go
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns/zones.go
generated
vendored
Normal file
|
|
@ -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")
|
||||
}
|
||||
62
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/BUILD
generated
vendored
Normal file
62
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
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",
|
||||
],
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider:go_default_library",
|
||||
"//federation/pkg/dnsprovider/providers/google/clouddns/internal:go_default_library",
|
||||
"//federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces:go_default_library",
|
||||
"//federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs:go_default_library",
|
||||
"//federation/pkg/dnsprovider/rrstype:go_default_library",
|
||||
"//pkg/cloudprovider/providers/gce: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",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["clouddns_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider:go_default_library",
|
||||
"//federation/pkg/dnsprovider/rrstype:go_default_library",
|
||||
"//federation/pkg/dnsprovider/tests:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//federation/pkg/dnsprovider/providers/google/clouddns/internal:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
116
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/clouddns.go
generated
vendored
Normal file
116
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/clouddns.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
273
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go
generated
vendored
Normal file
273
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/clouddns_test.go
generated
vendored
Normal file
|
|
@ -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)
|
||||
}
|
||||
43
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/interface.go
generated
vendored
Normal file
43
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/interface.go
generated
vendored
Normal file
|
|
@ -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_
|
||||
}
|
||||
52
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/BUILD
generated
vendored
Normal file
52
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
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",
|
||||
],
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces:go_default_library",
|
||||
"//federation/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",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces:all-srcs",
|
||||
"//federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
43
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/change.go
generated
vendored
Normal file
43
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/change.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
34
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go
generated
vendored
Normal file
34
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/changes_create_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
43
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go
generated
vendored
Normal file
43
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/changes_service.go
generated
vendored
Normal file
|
|
@ -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}}
|
||||
}
|
||||
35
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/clouddns.go
generated
vendored
Normal file
35
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/clouddns.go
generated
vendored
Normal file
|
|
@ -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 }
|
||||
)
|
||||
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/BUILD
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["interfaces.go"],
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider/rrstype:go_default_library",
|
||||
"//vendor/google.golang.org/api/googleapi:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
212
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go
generated
vendored
Normal file
212
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces/interfaces.go
generated
vendored
Normal file
|
|
@ -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
|
||||
)
|
||||
39
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go
generated
vendored
Normal file
39
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
33
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go
generated
vendored
Normal file
33
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zone_create_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
32
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go
generated
vendored
Normal file
32
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_delete_call.go
generated
vendored
Normal file
|
|
@ -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...)
|
||||
}
|
||||
33
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go
generated
vendored
Normal file
33
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_get_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
38
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go
generated
vendored
Normal file
38
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
35
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go
generated
vendored
Normal file
35
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_list_response.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
51
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go
generated
vendored
Normal file
51
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/managed_zones_service.go
generated
vendored
Normal file
|
|
@ -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}}
|
||||
}
|
||||
32
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go
generated
vendored
Normal file
32
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/rrset.go
generated
vendored
Normal file
|
|
@ -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 }
|
||||
53
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go
generated
vendored
Normal file
53
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
38
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go
generated
vendored
Normal file
38
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_list_response.go
generated
vendored
Normal file
|
|
@ -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
|
||||
|
||||
}
|
||||
43
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go
generated
vendored
Normal file
43
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/rrsets_service.go
generated
vendored
Normal file
|
|
@ -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}
|
||||
}
|
||||
49
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/service.go
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/service.go
generated
vendored
Normal file
|
|
@ -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}
|
||||
}
|
||||
47
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/BUILD
generated
vendored
Normal file
47
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
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",
|
||||
],
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces:go_default_library",
|
||||
"//federation/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",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
36
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go
generated
vendored
Normal file
36
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/change.go
generated
vendored
Normal file
|
|
@ -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_
|
||||
}
|
||||
67
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go
generated
vendored
Normal file
67
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_create_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
34
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go
generated
vendored
Normal file
34
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/changes_service.go
generated
vendored
Normal file
|
|
@ -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}
|
||||
}
|
||||
33
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/clouddns.go
generated
vendored
Normal file
33
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/clouddns.go
generated
vendored
Normal file
|
|
@ -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 }
|
||||
)
|
||||
41
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go
generated
vendored
Normal file
41
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
52
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go
generated
vendored
Normal file
52
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zone_create_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
53
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go
generated
vendored
Normal file
53
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_delete_call.go
generated
vendored
Normal file
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
42
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_get_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
59
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go
generated
vendored
Normal file
59
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_list_response.go
generated
vendored
Normal file
|
|
@ -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_
|
||||
}
|
||||
46
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go
generated
vendored
Normal file
46
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/managed_zones_service.go
generated
vendored
Normal file
|
|
@ -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}
|
||||
}
|
||||
34
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go
generated
vendored
Normal file
34
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrset.go
generated
vendored
Normal file
|
|
@ -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_ }
|
||||
52
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go
generated
vendored
Normal file
52
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_call.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
30
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go
generated
vendored
Normal file
30
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_list_response.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
83
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go
generated
vendored
Normal file
83
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/rrsets_service.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
54
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/stubs/service.go
generated
vendored
Normal file
|
|
@ -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_
|
||||
}
|
||||
124
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go
generated
vendored
Normal file
124
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/rrchangeset.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
53
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/rrset.go
generated
vendored
Normal file
53
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/rrset.go
generated
vendored
Normal file
|
|
@ -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())
|
||||
}
|
||||
94
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/rrsets.go
generated
vendored
Normal file
94
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/rrsets.go
generated
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
48
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/zone.go
generated
vendored
Normal file
48
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/zone.go
generated
vendored
Normal file
|
|
@ -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()
|
||||
}
|
||||
68
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/zones.go
generated
vendored
Normal file
68
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/zones.go
generated
vendored
Normal file
|
|
@ -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()
|
||||
}
|
||||
24
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype/BUILD
generated
vendored
Normal file
24
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["rrstype.go"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype/rrstype.go
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype/rrstype.go
generated
vendored
Normal file
|
|
@ -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
|
||||
)
|
||||
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/tests/BUILD
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/tests/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["commontests.go"],
|
||||
deps = [
|
||||
"//federation/pkg/dnsprovider:go_default_library",
|
||||
"//federation/pkg/dnsprovider/rrstype:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
194
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/tests/commontests.go
generated
vendored
Normal file
194
vendor/k8s.io/kubernetes/federation/pkg/dnsprovider/tests/commontests.go
generated
vendored
Normal file
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
86
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/BUILD
generated
vendored
Normal file
86
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"hpa_test.go",
|
||||
"scheduling_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//federation/pkg/federation-controller/util/test:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"adapter.go",
|
||||
"configmap.go",
|
||||
"daemonset.go",
|
||||
"deployment.go",
|
||||
"hpa.go",
|
||||
"namespace.go",
|
||||
"qualifiedname.go",
|
||||
"registry.go",
|
||||
"replicaset.go",
|
||||
"scheduling.go",
|
||||
"secret.go",
|
||||
],
|
||||
deps = [
|
||||
"//federation/apis/federation:go_default_library",
|
||||
"//federation/apis/federation/v1beta1:go_default_library",
|
||||
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
||||
"//federation/pkg/federation-controller/util:go_default_library",
|
||||
"//federation/pkg/federation-controller/util/hpa:go_default_library",
|
||||
"//federation/pkg/federation-controller/util/planner:go_default_library",
|
||||
"//federation/pkg/federation-controller/util/podanalyzer:go_default_library",
|
||||
"//federation/pkg/federation-controller/util/replicapreferences:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/controller/namespace/deletion:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//federation/pkg/federatedtypes/crudtester:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
79
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/adapter.go
generated
vendored
Normal file
79
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/adapter.go
generated
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
kubeclientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
)
|
||||
|
||||
// FederatedTypeAdapter defines operations for interacting with a
|
||||
// federated type. Code written to this interface can then target any
|
||||
// type for which an implementation of this interface exists.
|
||||
type FederatedTypeAdapter interface {
|
||||
Kind() string
|
||||
ObjectType() pkgruntime.Object
|
||||
IsExpectedType(obj interface{}) bool
|
||||
Copy(obj pkgruntime.Object) pkgruntime.Object
|
||||
Equivalent(obj1, obj2 pkgruntime.Object) bool
|
||||
QualifiedName(obj pkgruntime.Object) QualifiedName
|
||||
ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta
|
||||
|
||||
// Fed* operations target the federation control plane
|
||||
FedCreate(obj pkgruntime.Object) (pkgruntime.Object, error)
|
||||
FedDelete(qualifiedName QualifiedName, options *metav1.DeleteOptions) error
|
||||
FedGet(qualifiedName QualifiedName) (pkgruntime.Object, error)
|
||||
FedList(namespace string, options metav1.ListOptions) (pkgruntime.Object, error)
|
||||
FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error)
|
||||
FedWatch(namespace string, options metav1.ListOptions) (watch.Interface, error)
|
||||
|
||||
// The following operations are intended to target a cluster that is a member of a federation
|
||||
ClusterCreate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error)
|
||||
ClusterDelete(client kubeclientset.Interface, qualifiedName QualifiedName, options *metav1.DeleteOptions) error
|
||||
ClusterGet(client kubeclientset.Interface, qualifiedName QualifiedName) (pkgruntime.Object, error)
|
||||
ClusterList(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (pkgruntime.Object, error)
|
||||
ClusterUpdate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error)
|
||||
ClusterWatch(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (watch.Interface, error)
|
||||
|
||||
IsSchedulingAdapter() bool
|
||||
|
||||
NewTestObject(namespace string) pkgruntime.Object
|
||||
}
|
||||
|
||||
// AdapterFactory defines the function signature for factory methods
|
||||
// that create instances of FederatedTypeAdapter. Such methods should
|
||||
// be registered with RegisterAdapterFactory to ensure the type
|
||||
// adapter is discoverable.
|
||||
type AdapterFactory func(client federationclientset.Interface, config *restclient.Config, adapterSpecificArgs map[string]interface{}) FederatedTypeAdapter
|
||||
|
||||
// SetAnnotation sets the given key and value in the given object's ObjectMeta.Annotations map
|
||||
func SetAnnotation(adapter FederatedTypeAdapter, obj pkgruntime.Object, key, value string) {
|
||||
meta := adapter.ObjectMeta(obj)
|
||||
if meta.Annotations == nil {
|
||||
meta.Annotations = make(map[string]string)
|
||||
}
|
||||
meta.Annotations[key] = value
|
||||
}
|
||||
|
||||
// ObjectKey returns a cluster-unique key for the given object
|
||||
func ObjectKey(adapter FederatedTypeAdapter, obj pkgruntime.Object) string {
|
||||
return adapter.QualifiedName(obj).String()
|
||||
}
|
||||
150
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/configmap.go
generated
vendored
Normal file
150
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/configmap.go
generated
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
kubeclientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||
)
|
||||
|
||||
const (
|
||||
ConfigMapKind = "configmap"
|
||||
ConfigMapControllerName = "configmaps"
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterFederatedType(ConfigMapKind, ConfigMapControllerName, []schema.GroupVersionResource{apiv1.SchemeGroupVersion.WithResource(ConfigMapControllerName)}, NewConfigMapAdapter)
|
||||
}
|
||||
|
||||
type ConfigMapAdapter struct {
|
||||
client federationclientset.Interface
|
||||
}
|
||||
|
||||
func NewConfigMapAdapter(client federationclientset.Interface, config *restclient.Config, adapterSpecificArgs map[string]interface{}) FederatedTypeAdapter {
|
||||
return &ConfigMapAdapter{client: client}
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) Kind() string {
|
||||
return ConfigMapKind
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) ObjectType() pkgruntime.Object {
|
||||
return &apiv1.ConfigMap{}
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) IsExpectedType(obj interface{}) bool {
|
||||
_, ok := obj.(*apiv1.ConfigMap)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) Copy(obj pkgruntime.Object) pkgruntime.Object {
|
||||
configmap := obj.(*apiv1.ConfigMap)
|
||||
return &apiv1.ConfigMap{
|
||||
ObjectMeta: util.DeepCopyRelevantObjectMeta(configmap.ObjectMeta),
|
||||
Data: configmap.Data,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) Equivalent(obj1, obj2 pkgruntime.Object) bool {
|
||||
configmap1 := obj1.(*apiv1.ConfigMap)
|
||||
configmap2 := obj2.(*apiv1.ConfigMap)
|
||||
return util.ConfigMapEquivalent(configmap1, configmap2)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) QualifiedName(obj pkgruntime.Object) QualifiedName {
|
||||
configmap := obj.(*apiv1.ConfigMap)
|
||||
return QualifiedName{Namespace: configmap.Namespace, Name: configmap.Name}
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta {
|
||||
return &obj.(*apiv1.ConfigMap).ObjectMeta
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) FedCreate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
configmap := obj.(*apiv1.ConfigMap)
|
||||
return a.client.CoreV1().ConfigMaps(configmap.Namespace).Create(configmap)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) FedDelete(qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return a.client.CoreV1().ConfigMaps(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) FedGet(qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return a.client.CoreV1().ConfigMaps(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) FedList(namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return a.client.CoreV1().ConfigMaps(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
configmap := obj.(*apiv1.ConfigMap)
|
||||
return a.client.CoreV1().ConfigMaps(configmap.Namespace).Update(configmap)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) FedWatch(namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return a.client.CoreV1().ConfigMaps(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) ClusterCreate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
configmap := obj.(*apiv1.ConfigMap)
|
||||
return client.CoreV1().ConfigMaps(configmap.Namespace).Create(configmap)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) ClusterDelete(client kubeclientset.Interface, qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return client.CoreV1().ConfigMaps(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) ClusterGet(client kubeclientset.Interface, qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return client.CoreV1().ConfigMaps(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) ClusterList(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return client.CoreV1().ConfigMaps(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) ClusterUpdate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
configmap := obj.(*apiv1.ConfigMap)
|
||||
return client.CoreV1().ConfigMaps(configmap.Namespace).Update(configmap)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) ClusterWatch(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return client.CoreV1().ConfigMaps(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) IsSchedulingAdapter() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *ConfigMapAdapter) NewTestObject(namespace string) pkgruntime.Object {
|
||||
return &apiv1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "test-configmap-",
|
||||
Namespace: namespace,
|
||||
},
|
||||
Data: map[string]string{
|
||||
"A": "ala ma kota",
|
||||
},
|
||||
}
|
||||
}
|
||||
32
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/crudtester/BUILD
generated
vendored
Normal file
32
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/crudtester/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["crudtester.go"],
|
||||
deps = [
|
||||
"//federation/pkg/federatedtypes:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
247
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/crudtester/crudtester.go
generated
vendored
Normal file
247
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/crudtester/crudtester.go
generated
vendored
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package crudtester
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/kubernetes/federation/pkg/federatedtypes"
|
||||
)
|
||||
|
||||
const (
|
||||
AnnotationTestFederationCRUDUpdate string = "federation.kubernetes.io/test-federation-crud-update"
|
||||
)
|
||||
|
||||
// TestLogger defines operations common across different types of testing
|
||||
type TestLogger interface {
|
||||
Fatalf(format string, args ...interface{})
|
||||
Fatal(msg string)
|
||||
Logf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
// FederatedTypeCRUDTester exercises Create/Read/Update/Delete operations for
|
||||
// federated types via the Federation API and validates that the
|
||||
// results of those operations are propagated to clusters that are
|
||||
// members of a federation.
|
||||
type FederatedTypeCRUDTester struct {
|
||||
tl TestLogger
|
||||
adapter federatedtypes.FederatedTypeAdapter
|
||||
kind string
|
||||
clusterClients []clientset.Interface
|
||||
waitInterval time.Duration
|
||||
// Federation operations will use wait.ForeverTestTimeout. Any
|
||||
// operation that involves member clusters may take longer due to
|
||||
// propagation latency.
|
||||
clusterWaitTimeout time.Duration
|
||||
}
|
||||
|
||||
func NewFederatedTypeCRUDTester(testLogger TestLogger, adapter federatedtypes.FederatedTypeAdapter, clusterClients []clientset.Interface, waitInterval, clusterWaitTimeout time.Duration) *FederatedTypeCRUDTester {
|
||||
return &FederatedTypeCRUDTester{
|
||||
tl: testLogger,
|
||||
adapter: adapter,
|
||||
kind: adapter.Kind(),
|
||||
clusterClients: clusterClients,
|
||||
waitInterval: waitInterval,
|
||||
clusterWaitTimeout: clusterWaitTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FederatedTypeCRUDTester) CheckLifecycle(desiredObject pkgruntime.Object) {
|
||||
obj := c.CheckCreate(desiredObject)
|
||||
c.CheckUpdate(obj)
|
||||
|
||||
// Validate the golden path - removal of dependents
|
||||
orphanDependents := false
|
||||
c.CheckDelete(obj, &orphanDependents)
|
||||
}
|
||||
|
||||
func (c *FederatedTypeCRUDTester) Create(desiredObject pkgruntime.Object) pkgruntime.Object {
|
||||
namespace := c.adapter.ObjectMeta(desiredObject).Namespace
|
||||
resourceMsg := fmt.Sprintf("federated %s", c.kind)
|
||||
if len(namespace) > 0 {
|
||||
resourceMsg = fmt.Sprintf("%s in namespace %q", resourceMsg, namespace)
|
||||
}
|
||||
|
||||
c.tl.Logf("Creating new %s", resourceMsg)
|
||||
|
||||
obj, err := c.adapter.FedCreate(desiredObject)
|
||||
if err != nil {
|
||||
c.tl.Fatalf("Error creating %s: %v", resourceMsg, err)
|
||||
}
|
||||
|
||||
qualifiedName := c.adapter.QualifiedName(obj)
|
||||
c.tl.Logf("Created new federated %s %q", c.kind, qualifiedName)
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
func (c *FederatedTypeCRUDTester) CheckCreate(desiredObject pkgruntime.Object) pkgruntime.Object {
|
||||
obj := c.Create(desiredObject)
|
||||
|
||||
c.CheckPropagation(obj)
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
func (c *FederatedTypeCRUDTester) CheckUpdate(obj pkgruntime.Object) {
|
||||
qualifiedName := c.adapter.QualifiedName(obj)
|
||||
|
||||
var initialAnnotation string
|
||||
meta := c.adapter.ObjectMeta(obj)
|
||||
if meta.Annotations != nil {
|
||||
initialAnnotation = meta.Annotations[AnnotationTestFederationCRUDUpdate]
|
||||
}
|
||||
|
||||
c.tl.Logf("Updating federated %s %q", c.kind, qualifiedName)
|
||||
updatedObj, err := c.updateFedObject(obj)
|
||||
if err != nil {
|
||||
c.tl.Fatalf("Error updating federated %s %q: %v", c.kind, qualifiedName, err)
|
||||
}
|
||||
|
||||
// updateFedObject is expected to have changed the value of the annotation
|
||||
meta = c.adapter.ObjectMeta(updatedObj)
|
||||
updatedAnnotation := meta.Annotations[AnnotationTestFederationCRUDUpdate]
|
||||
if updatedAnnotation == initialAnnotation {
|
||||
c.tl.Fatalf("Federated %s %q not mutated", c.kind, qualifiedName)
|
||||
}
|
||||
|
||||
c.CheckPropagation(updatedObj)
|
||||
}
|
||||
|
||||
func (c *FederatedTypeCRUDTester) CheckDelete(obj pkgruntime.Object, orphanDependents *bool) {
|
||||
qualifiedName := c.adapter.QualifiedName(obj)
|
||||
|
||||
c.tl.Logf("Deleting federated %s %q", c.kind, qualifiedName)
|
||||
err := c.adapter.FedDelete(qualifiedName, &metav1.DeleteOptions{OrphanDependents: orphanDependents})
|
||||
if err != nil {
|
||||
c.tl.Fatalf("Error deleting federated %s %q: %v", c.kind, qualifiedName, err)
|
||||
}
|
||||
|
||||
deletingInCluster := (orphanDependents != nil && *orphanDependents == false)
|
||||
|
||||
waitTimeout := wait.ForeverTestTimeout
|
||||
if deletingInCluster {
|
||||
// May need extra time to delete both federation and cluster resources
|
||||
waitTimeout = c.clusterWaitTimeout
|
||||
}
|
||||
|
||||
// Wait for deletion. The federation resource will only be removed once orphan deletion has been
|
||||
// completed or deemed unnecessary.
|
||||
err = wait.PollImmediate(c.waitInterval, waitTimeout, func() (bool, error) {
|
||||
_, err := c.adapter.FedGet(qualifiedName)
|
||||
if errors.IsNotFound(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, err
|
||||
})
|
||||
if err != nil {
|
||||
c.tl.Fatalf("Error deleting federated %s %q: %v", c.kind, qualifiedName, err)
|
||||
}
|
||||
|
||||
var stateMsg string = "present"
|
||||
if deletingInCluster {
|
||||
stateMsg = "not present"
|
||||
}
|
||||
for _, client := range c.clusterClients {
|
||||
_, err := c.adapter.ClusterGet(client, qualifiedName)
|
||||
switch {
|
||||
case !deletingInCluster && errors.IsNotFound(err):
|
||||
c.tl.Fatalf("Federated %s %q was unexpectedly deleted from a member cluster", c.kind, qualifiedName)
|
||||
case deletingInCluster && err == nil:
|
||||
c.tl.Fatalf("Federated %s %q was unexpectedly orphaned in a member cluster", c.kind, qualifiedName)
|
||||
case err != nil && !errors.IsNotFound(err):
|
||||
c.tl.Fatalf("Error while checking whether %s %q is %s in member clusters: %v", c.kind, qualifiedName, stateMsg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CheckPropagation checks propagation for the crud tester's clients
|
||||
func (c *FederatedTypeCRUDTester) CheckPropagation(obj pkgruntime.Object) {
|
||||
c.CheckPropagationForClients(obj, c.clusterClients, true)
|
||||
}
|
||||
|
||||
// CheckPropagationForClients checks propagation for the provided clients
|
||||
func (c *FederatedTypeCRUDTester) CheckPropagationForClients(obj pkgruntime.Object, clusterClients []clientset.Interface, objExpected bool) {
|
||||
qualifiedName := c.adapter.QualifiedName(obj)
|
||||
|
||||
c.tl.Logf("Waiting for %s %q in %d clusters", c.kind, qualifiedName, len(clusterClients))
|
||||
for _, client := range clusterClients {
|
||||
err := c.waitForResource(client, obj)
|
||||
switch {
|
||||
case err == wait.ErrWaitTimeout:
|
||||
if objExpected {
|
||||
c.tl.Fatalf("Timeout verifying %s %q in a member cluster: %v", c.kind, qualifiedName, err)
|
||||
}
|
||||
case err != nil:
|
||||
c.tl.Fatalf("Failed to verify %s %q in a member cluster: %v", c.kind, qualifiedName, err)
|
||||
case err == nil && !objExpected:
|
||||
c.tl.Fatalf("Found unexpected object %s %q in a member cluster: %v", c.kind, qualifiedName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FederatedTypeCRUDTester) waitForResource(client clientset.Interface, obj pkgruntime.Object) error {
|
||||
qualifiedName := c.adapter.QualifiedName(obj)
|
||||
err := wait.PollImmediate(c.waitInterval, c.clusterWaitTimeout, func() (bool, error) {
|
||||
equivalenceFunc := c.adapter.Equivalent
|
||||
if c.adapter.IsSchedulingAdapter() {
|
||||
schedulingAdapter, ok := c.adapter.(federatedtypes.SchedulingAdapter)
|
||||
if !ok {
|
||||
c.tl.Fatalf("Adapter for kind %q does not properly implement SchedulingAdapter.", c.adapter.Kind())
|
||||
}
|
||||
equivalenceFunc = schedulingAdapter.EquivalentIgnoringSchedule
|
||||
}
|
||||
|
||||
clusterObj, err := c.adapter.ClusterGet(client, qualifiedName)
|
||||
if err == nil && equivalenceFunc(clusterObj, obj) {
|
||||
return true, nil
|
||||
}
|
||||
if errors.IsNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FederatedTypeCRUDTester) updateFedObject(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
err := wait.PollImmediate(c.waitInterval, wait.ForeverTestTimeout, func() (bool, error) {
|
||||
// Target the metadata for simplicity (it's type-agnostic)
|
||||
federatedtypes.SetAnnotation(c.adapter, obj, AnnotationTestFederationCRUDUpdate, "updated")
|
||||
|
||||
_, err := c.adapter.FedUpdate(obj)
|
||||
if errors.IsConflict(err) {
|
||||
// The resource was updated by the federation controller.
|
||||
// Get the latest version and retry.
|
||||
qualifiedName := c.adapter.QualifiedName(obj)
|
||||
obj, err = c.adapter.FedGet(qualifiedName)
|
||||
return false, err
|
||||
}
|
||||
// Be tolerant of a slow server
|
||||
if errors.IsServerTimeout(err) {
|
||||
return false, nil
|
||||
}
|
||||
return (err == nil), err
|
||||
})
|
||||
return obj, err
|
||||
}
|
||||
167
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/daemonset.go
generated
vendored
Normal file
167
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/daemonset.go
generated
vendored
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
extensionsv1 "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
kubeclientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||
)
|
||||
|
||||
const (
|
||||
DaemonSetKind = "daemonset"
|
||||
DaemonSetControllerName = "daemonsets"
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterFederatedType(DaemonSetKind, DaemonSetControllerName, []schema.GroupVersionResource{extensionsv1.SchemeGroupVersion.WithResource(DaemonSetControllerName)}, NewDaemonSetAdapter)
|
||||
}
|
||||
|
||||
type DaemonSetAdapter struct {
|
||||
client federationclientset.Interface
|
||||
}
|
||||
|
||||
func NewDaemonSetAdapter(client federationclientset.Interface, config *restclient.Config, adapterSpecificArgs map[string]interface{}) FederatedTypeAdapter {
|
||||
return &DaemonSetAdapter{client: client}
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) Kind() string {
|
||||
return DaemonSetKind
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) ObjectType() pkgruntime.Object {
|
||||
return &extensionsv1.DaemonSet{}
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) IsExpectedType(obj interface{}) bool {
|
||||
_, ok := obj.(*extensionsv1.DaemonSet)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) Copy(obj pkgruntime.Object) pkgruntime.Object {
|
||||
daemonset := obj.(*extensionsv1.DaemonSet)
|
||||
return &extensionsv1.DaemonSet{
|
||||
ObjectMeta: util.DeepCopyRelevantObjectMeta(daemonset.ObjectMeta),
|
||||
Spec: *(util.DeepCopyApiTypeOrPanic(&daemonset.Spec).(*extensionsv1.DaemonSetSpec)),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) Equivalent(obj1, obj2 pkgruntime.Object) bool {
|
||||
daemonset1 := obj1.(*extensionsv1.DaemonSet)
|
||||
daemonset2 := obj2.(*extensionsv1.DaemonSet)
|
||||
return util.ObjectMetaEquivalent(daemonset1.ObjectMeta, daemonset2.ObjectMeta) && reflect.DeepEqual(daemonset1.Spec, daemonset2.Spec)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) QualifiedName(obj pkgruntime.Object) QualifiedName {
|
||||
daemonset := obj.(*extensionsv1.DaemonSet)
|
||||
return QualifiedName{Namespace: daemonset.Namespace, Name: daemonset.Name}
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta {
|
||||
return &obj.(*extensionsv1.DaemonSet).ObjectMeta
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) FedCreate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
daemonset := obj.(*extensionsv1.DaemonSet)
|
||||
return a.client.Extensions().DaemonSets(daemonset.Namespace).Create(daemonset)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) FedDelete(qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return a.client.Extensions().DaemonSets(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) FedGet(qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return a.client.Extensions().DaemonSets(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) FedList(namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return a.client.Extensions().DaemonSets(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
daemonset := obj.(*extensionsv1.DaemonSet)
|
||||
return a.client.Extensions().DaemonSets(daemonset.Namespace).Update(daemonset)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) FedWatch(namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return a.client.Extensions().DaemonSets(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) ClusterCreate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
daemonset := obj.(*extensionsv1.DaemonSet)
|
||||
return client.Extensions().DaemonSets(daemonset.Namespace).Create(daemonset)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) ClusterDelete(client kubeclientset.Interface, qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return client.Extensions().DaemonSets(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) ClusterGet(client kubeclientset.Interface, qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return client.Extensions().DaemonSets(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) ClusterList(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return client.Extensions().DaemonSets(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) ClusterUpdate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
daemonset := obj.(*extensionsv1.DaemonSet)
|
||||
return client.Extensions().DaemonSets(daemonset.Namespace).Update(daemonset)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) ClusterWatch(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return client.Extensions().DaemonSets(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) IsSchedulingAdapter() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *DaemonSetAdapter) NewTestObject(namespace string) pkgruntime.Object {
|
||||
return &extensionsv1.DaemonSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "test-daemonset-",
|
||||
Namespace: namespace,
|
||||
Labels: map[string]string{"app": "test-daemonset"},
|
||||
},
|
||||
Spec: extensionsv1.DaemonSetSpec{
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"name": "test-pod"},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "test-daemonset",
|
||||
Image: "images/test-daemonset",
|
||||
Ports: []v1.ContainerPort{{ContainerPort: 9376}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
189
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/deployment.go
generated
vendored
Normal file
189
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/deployment.go
generated
vendored
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensionsv1 "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
kubeclientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||
)
|
||||
|
||||
const (
|
||||
DeploymentKind = "deployment"
|
||||
DeploymentControllerName = "deployments"
|
||||
FedDeploymentPreferencesAnnotation = "federation.kubernetes.io/deployment-preferences"
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterFederatedType(DeploymentKind, DeploymentControllerName, []schema.GroupVersionResource{extensionsv1.SchemeGroupVersion.WithResource(DeploymentControllerName)}, NewDeploymentAdapter)
|
||||
}
|
||||
|
||||
type DeploymentAdapter struct {
|
||||
*replicaSchedulingAdapter
|
||||
client federationclientset.Interface
|
||||
}
|
||||
|
||||
func NewDeploymentAdapter(client federationclientset.Interface, config *restclient.Config, adapterSpecificArgs map[string]interface{}) FederatedTypeAdapter {
|
||||
schedulingAdapter := replicaSchedulingAdapter{
|
||||
preferencesAnnotationName: FedDeploymentPreferencesAnnotation,
|
||||
updateStatusFunc: func(obj pkgruntime.Object, schedulingInfo interface{}) error {
|
||||
deployment := obj.(*extensionsv1.Deployment)
|
||||
typedStatus := schedulingInfo.(*ReplicaSchedulingInfo).Status
|
||||
if typedStatus.Replicas != deployment.Status.Replicas || typedStatus.UpdatedReplicas != deployment.Status.UpdatedReplicas ||
|
||||
typedStatus.ReadyReplicas != deployment.Status.ReadyReplicas || typedStatus.AvailableReplicas != deployment.Status.AvailableReplicas {
|
||||
deployment.Status = extensionsv1.DeploymentStatus{
|
||||
Replicas: typedStatus.Replicas,
|
||||
UpdatedReplicas: typedStatus.UpdatedReplicas,
|
||||
ReadyReplicas: typedStatus.ReadyReplicas,
|
||||
AvailableReplicas: typedStatus.AvailableReplicas,
|
||||
}
|
||||
_, err := client.Extensions().Deployments(deployment.Namespace).UpdateStatus(deployment)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return &DeploymentAdapter{&schedulingAdapter, client}
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) Kind() string {
|
||||
return DeploymentKind
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) ObjectType() pkgruntime.Object {
|
||||
return &extensionsv1.Deployment{}
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) IsExpectedType(obj interface{}) bool {
|
||||
_, ok := obj.(*extensionsv1.Deployment)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) Copy(obj pkgruntime.Object) pkgruntime.Object {
|
||||
deployment := obj.(*extensionsv1.Deployment)
|
||||
return fedutil.DeepCopyDeployment(deployment)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) Equivalent(obj1, obj2 pkgruntime.Object) bool {
|
||||
deployment1 := obj1.(*extensionsv1.Deployment)
|
||||
deployment2 := obj2.(*extensionsv1.Deployment)
|
||||
return fedutil.DeploymentEquivalent(deployment1, deployment2)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) QualifiedName(obj pkgruntime.Object) QualifiedName {
|
||||
deployment := obj.(*extensionsv1.Deployment)
|
||||
return QualifiedName{Namespace: deployment.Namespace, Name: deployment.Name}
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta {
|
||||
return &obj.(*extensionsv1.Deployment).ObjectMeta
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) FedCreate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
deployment := obj.(*extensionsv1.Deployment)
|
||||
return a.client.Extensions().Deployments(deployment.Namespace).Create(deployment)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) FedDelete(qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return a.client.Extensions().Deployments(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) FedGet(qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return a.client.Extensions().Deployments(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) FedList(namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return a.client.Extensions().Deployments(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
deployment := obj.(*extensionsv1.Deployment)
|
||||
return a.client.Extensions().Deployments(deployment.Namespace).Update(deployment)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) FedWatch(namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return a.client.Extensions().Deployments(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) ClusterCreate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
deployment := obj.(*extensionsv1.Deployment)
|
||||
return client.Extensions().Deployments(deployment.Namespace).Create(deployment)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) ClusterDelete(client kubeclientset.Interface, qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return client.Extensions().Deployments(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) ClusterGet(client kubeclientset.Interface, qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return client.Extensions().Deployments(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) ClusterList(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return client.Extensions().Deployments(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) ClusterUpdate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
deployment := obj.(*extensionsv1.Deployment)
|
||||
return client.Extensions().Deployments(deployment.Namespace).Update(deployment)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) ClusterWatch(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return client.Extensions().Deployments(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) EquivalentIgnoringSchedule(obj1, obj2 pkgruntime.Object) bool {
|
||||
deployment1 := obj1.(*extensionsv1.Deployment)
|
||||
deployment2 := a.Copy(obj2).(*extensionsv1.Deployment)
|
||||
deployment2.Spec.Replicas = deployment1.Spec.Replicas
|
||||
return fedutil.DeploymentEquivalent(deployment1, deployment2)
|
||||
}
|
||||
|
||||
func (a *DeploymentAdapter) NewTestObject(namespace string) pkgruntime.Object {
|
||||
replicas := int32(3)
|
||||
zero := int64(0)
|
||||
return &extensionsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "test-deployment-",
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: extensionsv1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
Template: apiv1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
Spec: apiv1.PodSpec{
|
||||
TerminationGracePeriodSeconds: &zero,
|
||||
Containers: []apiv1.Container{
|
||||
{
|
||||
Name: "nginx",
|
||||
Image: "nginx",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
1015
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/hpa.go
generated
vendored
Normal file
1015
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/hpa.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
264
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/hpa_test.go
generated
vendored
Normal file
264
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/hpa_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
. "k8s.io/kubernetes/federation/pkg/federation-controller/util/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type replicas struct {
|
||||
min int32
|
||||
max int32
|
||||
}
|
||||
|
||||
func TestGetHpaScheduleState(t *testing.T) {
|
||||
defaultFedHpa := newHpaWithReplicas(NewInt32(1), NewInt32(70), 10)
|
||||
testCases := map[string]struct {
|
||||
fedHpa *autoscalingv1.HorizontalPodAutoscaler
|
||||
localHpas map[string]pkgruntime.Object
|
||||
expectedReplicas map[string]*replicas
|
||||
}{
|
||||
"Distribiutes replicas randomly if no existing hpa in any local cluster": {
|
||||
localHpas: func() map[string]pkgruntime.Object {
|
||||
hpas := make(map[string]pkgruntime.Object)
|
||||
hpas["c1"] = nil
|
||||
hpas["c2"] = nil
|
||||
return hpas
|
||||
}(),
|
||||
},
|
||||
"Cluster with no hpa gets replicas if other clusters have replicas": {
|
||||
localHpas: func() map[string]pkgruntime.Object {
|
||||
hpas := make(map[string]pkgruntime.Object)
|
||||
hpas["c1"] = newHpaWithReplicas(NewInt32(1), NewInt32(70), 10)
|
||||
hpas["c2"] = nil
|
||||
return hpas
|
||||
}(),
|
||||
expectedReplicas: map[string]*replicas{
|
||||
"c1": {
|
||||
min: int32(1),
|
||||
max: int32(9),
|
||||
},
|
||||
"c2": {
|
||||
min: int32(1),
|
||||
max: int32(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
"Cluster needing max replicas gets it if there is another cluster to offer max": {
|
||||
localHpas: func() map[string]pkgruntime.Object {
|
||||
hpa1 := newHpaWithReplicas(NewInt32(1), NewInt32(70), 7)
|
||||
hpa1 = updateHpaStatus(hpa1, NewInt32(50), 5, 5, true)
|
||||
hpa2 := newHpaWithReplicas(NewInt32(1), NewInt32(70), 1)
|
||||
hpa2 = updateHpaStatus(hpa2, NewInt32(70), 1, 1, true)
|
||||
// include third object to ensure, it does not break the test
|
||||
hpa3 := newHpaWithReplicas(NewInt32(1), NewInt32(70), 2)
|
||||
hpa3 = updateHpaStatus(hpa3, NewInt32(70), 1, 1, false)
|
||||
hpas := make(map[string]pkgruntime.Object)
|
||||
hpas["c1"] = hpa1
|
||||
hpas["c2"] = hpa2
|
||||
hpas["c3"] = hpa3
|
||||
return hpas
|
||||
}(),
|
||||
expectedReplicas: map[string]*replicas{
|
||||
"c1": {
|
||||
min: int32(1),
|
||||
max: int32(6),
|
||||
},
|
||||
"c2": {
|
||||
min: int32(1),
|
||||
max: int32(2),
|
||||
},
|
||||
"c3": {
|
||||
min: int32(1),
|
||||
max: int32(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
"Cluster needing max replicas does not get it if there is no cluster offerring max": {
|
||||
localHpas: func() map[string]pkgruntime.Object {
|
||||
hpa1 := newHpaWithReplicas(NewInt32(1), NewInt32(70), 9)
|
||||
hpa1 = updateHpaStatus(hpa1, NewInt32(70), 9, 9, false)
|
||||
hpa2 := newHpaWithReplicas(NewInt32(1), NewInt32(70), 1)
|
||||
hpa2 = updateHpaStatus(hpa2, NewInt32(70), 1, 1, true)
|
||||
hpas := make(map[string]pkgruntime.Object)
|
||||
hpas["c1"] = hpa1
|
||||
hpas["c2"] = hpa2
|
||||
return hpas
|
||||
}(),
|
||||
expectedReplicas: map[string]*replicas{
|
||||
"c1": {
|
||||
min: int32(1),
|
||||
max: int32(9),
|
||||
},
|
||||
"c2": {
|
||||
min: int32(1),
|
||||
max: int32(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
"Cluster which can increase min replicas gets to increase min if there is a cluster offering min": {
|
||||
fedHpa: newHpaWithReplicas(NewInt32(4), NewInt32(70), 10),
|
||||
localHpas: func() map[string]pkgruntime.Object {
|
||||
hpa1 := newHpaWithReplicas(NewInt32(3), NewInt32(70), 6)
|
||||
hpa1 = updateHpaStatus(hpa1, NewInt32(50), 3, 3, true)
|
||||
hpa2 := newHpaWithReplicas(NewInt32(1), NewInt32(70), 4)
|
||||
hpa2 = updateHpaStatus(hpa2, NewInt32(50), 3, 3, true)
|
||||
hpas := make(map[string]pkgruntime.Object)
|
||||
hpas["c1"] = hpa1
|
||||
hpas["c2"] = hpa2
|
||||
return hpas
|
||||
}(),
|
||||
expectedReplicas: map[string]*replicas{
|
||||
"c1": {
|
||||
min: int32(2),
|
||||
max: int32(6),
|
||||
},
|
||||
"c2": {
|
||||
min: int32(2),
|
||||
max: int32(4),
|
||||
},
|
||||
},
|
||||
},
|
||||
"Cluster which can increase min replicas does not increase if there are no clusters offering min": {
|
||||
fedHpa: newHpaWithReplicas(NewInt32(4), NewInt32(70), 10),
|
||||
localHpas: func() map[string]pkgruntime.Object {
|
||||
hpa1 := newHpaWithReplicas(NewInt32(3), NewInt32(70), 6)
|
||||
hpa1 = updateHpaStatus(hpa1, NewInt32(50), 4, 4, true)
|
||||
hpa2 := newHpaWithReplicas(NewInt32(1), NewInt32(70), 4)
|
||||
hpa2 = updateHpaStatus(hpa2, NewInt32(50), 3, 3, true)
|
||||
hpas := make(map[string]pkgruntime.Object)
|
||||
hpas["c1"] = hpa1
|
||||
hpas["c2"] = hpa2
|
||||
return hpas
|
||||
}(),
|
||||
expectedReplicas: map[string]*replicas{
|
||||
"c1": {
|
||||
min: int32(3),
|
||||
max: int32(6),
|
||||
},
|
||||
"c2": {
|
||||
min: int32(1),
|
||||
max: int32(4),
|
||||
},
|
||||
},
|
||||
},
|
||||
"Increasing replicas on fed object increases the same on clusters": {
|
||||
// Existing total of local min, max = 1+1, 5+5 decreasing to below
|
||||
fedHpa: newHpaWithReplicas(NewInt32(4), NewInt32(70), 14),
|
||||
localHpas: func() map[string]pkgruntime.Object {
|
||||
// does not matter if scaleability is true
|
||||
hpas := make(map[string]pkgruntime.Object)
|
||||
hpas["c1"] = newHpaWithReplicas(NewInt32(1), NewInt32(70), 5)
|
||||
hpas["c2"] = newHpaWithReplicas(NewInt32(1), NewInt32(70), 5)
|
||||
return hpas
|
||||
}(),
|
||||
// We dont know which cluster gets how many, but the resultant total should match
|
||||
},
|
||||
"Decreasing replicas on fed object decreases the same on clusters": {
|
||||
// Existing total of local min, max = 2+2, 8+8 decreasing to below
|
||||
fedHpa: newHpaWithReplicas(NewInt32(3), NewInt32(70), 8),
|
||||
localHpas: func() map[string]pkgruntime.Object {
|
||||
// does not matter if scaleability is true
|
||||
hpas := make(map[string]pkgruntime.Object)
|
||||
hpas["c1"] = newHpaWithReplicas(NewInt32(2), NewInt32(70), 8)
|
||||
hpas["c2"] = newHpaWithReplicas(NewInt32(2), NewInt32(70), 8)
|
||||
return hpas
|
||||
}(),
|
||||
// We dont know which cluster gets how many, but the resultant total should match
|
||||
},
|
||||
}
|
||||
|
||||
adapter := &HpaAdapter{
|
||||
scaleForbiddenWindow: ScaleForbiddenWindow,
|
||||
}
|
||||
for testName, testCase := range testCases {
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
if testCase.fedHpa == nil {
|
||||
testCase.fedHpa = defaultFedHpa
|
||||
}
|
||||
scheduledState := adapter.getHpaScheduleState(testCase.fedHpa, testCase.localHpas)
|
||||
checkClusterConditions(t, testCase.fedHpa, scheduledState)
|
||||
if testCase.expectedReplicas != nil {
|
||||
for cluster, replicas := range testCase.expectedReplicas {
|
||||
scheduledReplicas := scheduledState[cluster]
|
||||
assert.Equal(t, replicas.min, scheduledReplicas.min)
|
||||
assert.Equal(t, replicas.max, scheduledReplicas.max)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func updateHpaStatus(hpa *autoscalingv1.HorizontalPodAutoscaler, currentUtilisation *int32, current, desired int32, scaleable bool) *autoscalingv1.HorizontalPodAutoscaler {
|
||||
hpa.Status.CurrentReplicas = current
|
||||
hpa.Status.DesiredReplicas = desired
|
||||
hpa.Status.CurrentCPUUtilizationPercentage = currentUtilisation
|
||||
now := metav1.Now()
|
||||
scaledTime := now
|
||||
if scaleable {
|
||||
// definitely more then ScaleForbiddenWindow time ago
|
||||
scaledTime = metav1.NewTime(now.Time.Add(-2 * ScaleForbiddenWindow))
|
||||
}
|
||||
hpa.Status.LastScaleTime = &scaledTime
|
||||
return hpa
|
||||
}
|
||||
|
||||
func checkClusterConditions(t *testing.T, fedHpa *autoscalingv1.HorizontalPodAutoscaler, scheduled map[string]*replicaNums) {
|
||||
minTotal := int32(0)
|
||||
maxTotal := int32(0)
|
||||
for _, replicas := range scheduled {
|
||||
minTotal += replicas.min
|
||||
maxTotal += replicas.max
|
||||
}
|
||||
|
||||
// - Total of max matches the fed max
|
||||
assert.Equal(t, fedHpa.Spec.MaxReplicas, maxTotal)
|
||||
// - Total of min is not less then fed min
|
||||
assert.Condition(t, func() bool {
|
||||
if *fedHpa.Spec.MinReplicas <= minTotal {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
func newHpaWithReplicas(min, targetUtilisation *int32, max int32) *autoscalingv1.HorizontalPodAutoscaler {
|
||||
return &autoscalingv1.HorizontalPodAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "myhpa",
|
||||
Namespace: apiv1.NamespaceDefault,
|
||||
SelfLink: "/api/mylink",
|
||||
},
|
||||
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
|
||||
Kind: "HorizontalPodAutoscaler",
|
||||
Name: "target-",
|
||||
},
|
||||
MinReplicas: min,
|
||||
MaxReplicas: max,
|
||||
TargetCPUUtilizationPercentage: targetUtilisation,
|
||||
},
|
||||
}
|
||||
}
|
||||
215
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/namespace.go
generated
vendored
Normal file
215
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/namespace.go
generated
vendored
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/dynamic"
|
||||
kubeclientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/record"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/controller/namespace/deletion"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
NamespaceKind = "namespace"
|
||||
NamespaceControllerName = "namespaces"
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterFederatedType(NamespaceKind, NamespaceControllerName, []schema.GroupVersionResource{apiv1.SchemeGroupVersion.WithResource(NamespaceControllerName)}, NewNamespaceAdapter)
|
||||
}
|
||||
|
||||
type NamespaceAdapter struct {
|
||||
client federationclientset.Interface
|
||||
deleter deletion.NamespacedResourcesDeleterInterface
|
||||
}
|
||||
|
||||
func NewNamespaceAdapter(client federationclientset.Interface, config *restclient.Config, adapterSpecificArgs map[string]interface{}) FederatedTypeAdapter {
|
||||
dynamicClientPool := dynamic.NewDynamicClientPool(config)
|
||||
discoverResourcesFunc := client.Discovery().ServerPreferredNamespacedResources
|
||||
deleter := deletion.NewNamespacedResourcesDeleter(
|
||||
client.Core().Namespaces(),
|
||||
dynamicClientPool,
|
||||
nil,
|
||||
discoverResourcesFunc,
|
||||
apiv1.FinalizerKubernetes,
|
||||
false)
|
||||
return &NamespaceAdapter{client: client, deleter: deleter}
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) Kind() string {
|
||||
return NamespaceKind
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) ObjectType() pkgruntime.Object {
|
||||
return &apiv1.Namespace{}
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) IsExpectedType(obj interface{}) bool {
|
||||
_, ok := obj.(*apiv1.Namespace)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) Copy(obj pkgruntime.Object) pkgruntime.Object {
|
||||
namespace := obj.(*apiv1.Namespace)
|
||||
return &apiv1.Namespace{
|
||||
ObjectMeta: util.DeepCopyRelevantObjectMeta(namespace.ObjectMeta),
|
||||
Spec: *(util.DeepCopyApiTypeOrPanic(&namespace.Spec).(*apiv1.NamespaceSpec)),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) Equivalent(obj1, obj2 pkgruntime.Object) bool {
|
||||
return util.ObjectMetaAndSpecEquivalent(obj1, obj2)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) QualifiedName(obj pkgruntime.Object) QualifiedName {
|
||||
namespace := obj.(*apiv1.Namespace)
|
||||
return QualifiedName{Name: namespace.Name}
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta {
|
||||
return &obj.(*apiv1.Namespace).ObjectMeta
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) FedCreate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
namespace := obj.(*apiv1.Namespace)
|
||||
return a.client.CoreV1().Namespaces().Create(namespace)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) FedDelete(qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return a.client.CoreV1().Namespaces().Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) FedGet(qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return a.client.CoreV1().Namespaces().Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) FedList(namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return a.client.CoreV1().Namespaces().List(options)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
namespace := obj.(*apiv1.Namespace)
|
||||
return a.client.CoreV1().Namespaces().Update(namespace)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) FedWatch(namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return a.client.CoreV1().Namespaces().Watch(options)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) ClusterCreate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
namespace := obj.(*apiv1.Namespace)
|
||||
return client.CoreV1().Namespaces().Create(namespace)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) ClusterDelete(client kubeclientset.Interface, qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return client.CoreV1().Namespaces().Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) ClusterGet(client kubeclientset.Interface, qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return client.CoreV1().Namespaces().Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) ClusterList(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return client.CoreV1().Namespaces().List(options)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) ClusterUpdate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
namespace := obj.(*apiv1.Namespace)
|
||||
return client.CoreV1().Namespaces().Update(namespace)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) ClusterWatch(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return client.CoreV1().Namespaces().Watch(options)
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) IsSchedulingAdapter() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *NamespaceAdapter) NewTestObject(namespace string) pkgruntime.Object {
|
||||
return &apiv1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "test-namespace-",
|
||||
},
|
||||
Spec: apiv1.NamespaceSpec{
|
||||
Finalizers: []apiv1.FinalizerName{apiv1.FinalizerKubernetes},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CleanUpNamespace deletes all resources in a given namespace.
|
||||
func (a *NamespaceAdapter) CleanUpNamespace(obj pkgruntime.Object, eventRecorder record.EventRecorder) (pkgruntime.Object, error) {
|
||||
namespace := obj.(*apiv1.Namespace)
|
||||
name := namespace.Name
|
||||
|
||||
// Set Terminating status.
|
||||
updatedNamespace := &apiv1.Namespace{
|
||||
ObjectMeta: namespace.ObjectMeta,
|
||||
Spec: namespace.Spec,
|
||||
Status: apiv1.NamespaceStatus{
|
||||
Phase: apiv1.NamespaceTerminating,
|
||||
},
|
||||
}
|
||||
var err error
|
||||
if namespace.Status.Phase != apiv1.NamespaceTerminating {
|
||||
glog.V(2).Infof("Marking ns %s as terminating", name)
|
||||
eventRecorder.Event(namespace, api.EventTypeNormal, "DeleteNamespace", fmt.Sprintf("Marking for deletion"))
|
||||
_, err = a.FedUpdate(updatedNamespace)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update namespace: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if hasFinalizerInSpec(updatedNamespace, apiv1.FinalizerKubernetes) {
|
||||
// Delete resources in this namespace.
|
||||
err = a.deleter.Delete(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in deleting resources in namespace %s: %v", name, err)
|
||||
}
|
||||
glog.V(2).Infof("Removed kubernetes finalizer from ns %s", name)
|
||||
// Fetch the updated Namespace.
|
||||
obj, err = a.FedGet(QualifiedName{Name: name})
|
||||
updatedNamespace = obj.(*apiv1.Namespace)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in fetching updated namespace %s: %s", name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return updatedNamespace, nil
|
||||
}
|
||||
|
||||
func hasFinalizerInSpec(namespace *apiv1.Namespace, finalizer apiv1.FinalizerName) bool {
|
||||
for i := range namespace.Spec.Finalizers {
|
||||
if namespace.Spec.Finalizers[i] == finalizer {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
41
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/qualifiedname.go
generated
vendored
Normal file
41
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/qualifiedname.go
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// QualifiedName comprises a resource name with an optional namespace.
|
||||
// If namespace is provided, a QualifiedName will be rendered as
|
||||
// "<namespace>/<name>". If not, it will be rendered as "name". This
|
||||
// is intended to allow the FederatedTypeAdapter interface and its
|
||||
// consumers to operate on both namespaces and namespace-qualified
|
||||
// resources.
|
||||
|
||||
type QualifiedName struct {
|
||||
Namespace string
|
||||
Name string
|
||||
}
|
||||
|
||||
// String returns the general purpose string representation
|
||||
func (n QualifiedName) String() string {
|
||||
if len(n.Namespace) == 0 {
|
||||
return n.Name
|
||||
}
|
||||
return fmt.Sprintf("%s/%s", n.Namespace, n.Name)
|
||||
}
|
||||
59
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/registry.go
generated
vendored
Normal file
59
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/registry.go
generated
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// FederatedType configures federation for a kubernetes type
|
||||
type FederatedType struct {
|
||||
Kind string
|
||||
ControllerName string
|
||||
RequiredResources []schema.GroupVersionResource
|
||||
AdapterFactory AdapterFactory
|
||||
}
|
||||
|
||||
var typeRegistry = make(map[string]FederatedType)
|
||||
|
||||
// RegisterFederatedType ensures that configuration for the given kind will be returned by the FederatedTypes method.
|
||||
func RegisterFederatedType(kind, controllerName string, requiredResources []schema.GroupVersionResource, factory AdapterFactory) {
|
||||
_, ok := typeRegistry[kind]
|
||||
if ok {
|
||||
// TODO Is panicking ok given that this is part of a type-registration mechanism
|
||||
panic(fmt.Sprintf("Federated type %q has already been registered", kind))
|
||||
}
|
||||
typeRegistry[kind] = FederatedType{
|
||||
Kind: kind,
|
||||
ControllerName: controllerName,
|
||||
RequiredResources: requiredResources,
|
||||
AdapterFactory: factory,
|
||||
}
|
||||
}
|
||||
|
||||
// FederatedTypes returns a mapping of kind (e.g. "secret") to the
|
||||
// type information required to configure its federation.
|
||||
func FederatedTypes() map[string]FederatedType {
|
||||
// TODO copy RequiredResources to avoid accidental mutation
|
||||
result := make(map[string]FederatedType)
|
||||
for key, value := range typeRegistry {
|
||||
result[key] = value
|
||||
}
|
||||
return result
|
||||
}
|
||||
189
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/replicaset.go
generated
vendored
Normal file
189
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/replicaset.go
generated
vendored
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensionsv1 "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
kubeclientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||
)
|
||||
|
||||
const (
|
||||
ReplicaSetKind = "replicaset"
|
||||
ReplicaSetControllerName = "replicasets"
|
||||
FedReplicaSetPreferencesAnnotation = "federation.kubernetes.io/replica-set-preferences"
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterFederatedType(ReplicaSetKind, ReplicaSetControllerName, []schema.GroupVersionResource{extensionsv1.SchemeGroupVersion.WithResource(ReplicaSetControllerName)}, NewReplicaSetAdapter)
|
||||
}
|
||||
|
||||
type ReplicaSetAdapter struct {
|
||||
*replicaSchedulingAdapter
|
||||
client federationclientset.Interface
|
||||
}
|
||||
|
||||
func NewReplicaSetAdapter(client federationclientset.Interface, config *restclient.Config, adapterSpecificArgs map[string]interface{}) FederatedTypeAdapter {
|
||||
replicaSchedulingAdapter := replicaSchedulingAdapter{
|
||||
preferencesAnnotationName: FedReplicaSetPreferencesAnnotation,
|
||||
updateStatusFunc: func(obj pkgruntime.Object, schedulingInfo interface{}) error {
|
||||
rs := obj.(*extensionsv1.ReplicaSet)
|
||||
typedStatus := schedulingInfo.(*ReplicaSchedulingInfo).Status
|
||||
if typedStatus.Replicas != rs.Status.Replicas || typedStatus.FullyLabeledReplicas != rs.Status.FullyLabeledReplicas ||
|
||||
typedStatus.ReadyReplicas != rs.Status.ReadyReplicas || typedStatus.AvailableReplicas != rs.Status.AvailableReplicas {
|
||||
rs.Status = extensionsv1.ReplicaSetStatus{
|
||||
Replicas: typedStatus.Replicas,
|
||||
FullyLabeledReplicas: typedStatus.Replicas,
|
||||
ReadyReplicas: typedStatus.ReadyReplicas,
|
||||
AvailableReplicas: typedStatus.AvailableReplicas,
|
||||
}
|
||||
_, err := client.Extensions().ReplicaSets(rs.Namespace).UpdateStatus(rs)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return &ReplicaSetAdapter{&replicaSchedulingAdapter, client}
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) Kind() string {
|
||||
return ReplicaSetKind
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) ObjectType() pkgruntime.Object {
|
||||
return &extensionsv1.ReplicaSet{}
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) IsExpectedType(obj interface{}) bool {
|
||||
_, ok := obj.(*extensionsv1.ReplicaSet)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) Copy(obj pkgruntime.Object) pkgruntime.Object {
|
||||
rs := obj.(*extensionsv1.ReplicaSet)
|
||||
return &extensionsv1.ReplicaSet{
|
||||
ObjectMeta: fedutil.DeepCopyRelevantObjectMeta(rs.ObjectMeta),
|
||||
Spec: *fedutil.DeepCopyApiTypeOrPanic(&rs.Spec).(*extensionsv1.ReplicaSetSpec),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) Equivalent(obj1, obj2 pkgruntime.Object) bool {
|
||||
return fedutil.ObjectMetaAndSpecEquivalent(obj1, obj2)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) QualifiedName(obj pkgruntime.Object) QualifiedName {
|
||||
replicaset := obj.(*extensionsv1.ReplicaSet)
|
||||
return QualifiedName{Namespace: replicaset.Namespace, Name: replicaset.Name}
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta {
|
||||
return &obj.(*extensionsv1.ReplicaSet).ObjectMeta
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) FedCreate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
replicaset := obj.(*extensionsv1.ReplicaSet)
|
||||
return a.client.Extensions().ReplicaSets(replicaset.Namespace).Create(replicaset)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) FedDelete(qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return a.client.Extensions().ReplicaSets(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) FedGet(qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return a.client.Extensions().ReplicaSets(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) FedList(namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return a.client.Extensions().ReplicaSets(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
replicaset := obj.(*extensionsv1.ReplicaSet)
|
||||
return a.client.Extensions().ReplicaSets(replicaset.Namespace).Update(replicaset)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) FedWatch(namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return a.client.Extensions().ReplicaSets(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) ClusterCreate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
replicaset := obj.(*extensionsv1.ReplicaSet)
|
||||
return client.Extensions().ReplicaSets(replicaset.Namespace).Create(replicaset)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) ClusterDelete(client kubeclientset.Interface, qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return client.Extensions().ReplicaSets(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) ClusterGet(client kubeclientset.Interface, qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return client.Extensions().ReplicaSets(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) ClusterList(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return client.Extensions().ReplicaSets(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) ClusterUpdate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
replicaset := obj.(*extensionsv1.ReplicaSet)
|
||||
return client.Extensions().ReplicaSets(replicaset.Namespace).Update(replicaset)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) ClusterWatch(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return client.Extensions().ReplicaSets(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) EquivalentIgnoringSchedule(obj1, obj2 pkgruntime.Object) bool {
|
||||
replicaset1 := obj1.(*extensionsv1.ReplicaSet)
|
||||
replicaset2 := a.Copy(obj2).(*extensionsv1.ReplicaSet)
|
||||
replicaset2.Spec.Replicas = replicaset1.Spec.Replicas
|
||||
return fedutil.ObjectMetaAndSpecEquivalent(replicaset1, replicaset2)
|
||||
}
|
||||
|
||||
func (a *ReplicaSetAdapter) NewTestObject(namespace string) pkgruntime.Object {
|
||||
replicas := int32(3)
|
||||
zero := int64(0)
|
||||
return &extensionsv1.ReplicaSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "test-replicaset-",
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: extensionsv1.ReplicaSetSpec{
|
||||
Replicas: &replicas,
|
||||
Template: apiv1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
Spec: apiv1.PodSpec{
|
||||
TerminationGracePeriodSeconds: &zero,
|
||||
Containers: []apiv1.Container{
|
||||
{
|
||||
Name: "nginx",
|
||||
Image: "nginx",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
356
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/scheduling.go
generated
vendored
Normal file
356
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/scheduling.go
generated
vendored
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
fedapi "k8s.io/kubernetes/federation/apis/federation"
|
||||
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||
hpautil "k8s.io/kubernetes/federation/pkg/federation-controller/util/hpa"
|
||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util/planner"
|
||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util/podanalyzer"
|
||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util/replicapreferences"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// ScheduleAction is used by the interface ScheduleObject of SchedulingAdapter
|
||||
// to sync controller reconcile to convey the action type needed for the
|
||||
// particular cluster local object in ScheduleObject
|
||||
type ScheduleAction string
|
||||
|
||||
const (
|
||||
ActionAdd = "add"
|
||||
ActionDelete = "delete"
|
||||
)
|
||||
|
||||
// ReplicaStatus contains the details of status fields from the cluster objects,
|
||||
// which need accumulation to update the status of the federated object.
|
||||
type ReplicaStatus struct {
|
||||
Replicas int32
|
||||
UpdatedReplicas int32
|
||||
FullyLabeledReplicas int32
|
||||
ReadyReplicas int32
|
||||
AvailableReplicas int32
|
||||
}
|
||||
|
||||
// ReplicaScheduleState is the result of adapter specific schedule() function,
|
||||
// which is then used to update objects into clusters.
|
||||
type ReplicaScheduleState struct {
|
||||
isSelected bool
|
||||
replicas int64
|
||||
}
|
||||
|
||||
// ReplicaSchedulingInfo wraps the information that a replica type (rs or deployment)
|
||||
// SchedulingAdapter needs to update objects per a schedule.
|
||||
type ReplicaSchedulingInfo struct {
|
||||
ScheduleState map[string]*ReplicaScheduleState
|
||||
Status ReplicaStatus
|
||||
}
|
||||
|
||||
// SchedulingAdapter defines operations for interacting with a
|
||||
// federated type that requires more complex synchronization logic.
|
||||
type SchedulingAdapter interface {
|
||||
GetSchedule(obj pkgruntime.Object, key string, clusters []*federationapi.Cluster, informer fedutil.FederatedInformer) (interface{}, error)
|
||||
ScheduleObject(cluster *federationapi.Cluster, clusterObj pkgruntime.Object, federationObjCopy pkgruntime.Object, schedulingInfo interface{}) (pkgruntime.Object, ScheduleAction, error)
|
||||
UpdateFederatedStatus(obj pkgruntime.Object, schedulingInfo interface{}) error
|
||||
|
||||
// EquivalentIgnoringSchedule returns whether obj1 and obj2 are
|
||||
// equivalent ignoring differences due to scheduling.
|
||||
EquivalentIgnoringSchedule(obj1, obj2 pkgruntime.Object) bool
|
||||
}
|
||||
|
||||
// replicaSchedulingAdapter is meant to be embedded in other type adapters that require
|
||||
// workload scheduling with actual pod replicas.
|
||||
type replicaSchedulingAdapter struct {
|
||||
preferencesAnnotationName string
|
||||
updateStatusFunc func(pkgruntime.Object, interface{}) error
|
||||
}
|
||||
|
||||
func (a *replicaSchedulingAdapter) IsSchedulingAdapter() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isSelected(names []string, name string) bool {
|
||||
for _, val := range names {
|
||||
if val == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isObjHpaControlled(fedObj pkgruntime.Object) (bool, error) {
|
||||
hpaSelectedClusters, error := hpautil.GetHpaTargetClusterList(fedObj)
|
||||
if error != nil {
|
||||
return false, error
|
||||
}
|
||||
|
||||
if hpaSelectedClusters == nil {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// initializeScheduleState initializes the schedule state for consumption by schedule
|
||||
// functions (schedule or simple schedule). After this initialization the state would
|
||||
// already have information, if only a subset of clusters targetted by hpa, or all clusters
|
||||
// need to be considered by the actual scheduling functions.
|
||||
// The return bool named hpaControlled tells if this object is controlled by hpa or not.
|
||||
func initializeScheduleState(fedObj pkgruntime.Object, clusterNames []string) (map[string]*ReplicaScheduleState, bool, error) {
|
||||
initialState := make(map[string]*ReplicaScheduleState)
|
||||
hpaControlled := false
|
||||
hpaSelectedClusters, error := hpautil.GetHpaTargetClusterList(fedObj)
|
||||
if error != nil {
|
||||
return nil, hpaControlled, error
|
||||
}
|
||||
|
||||
if hpaSelectedClusters != nil {
|
||||
hpaControlled = true
|
||||
}
|
||||
for _, clusterName := range clusterNames {
|
||||
replicaState := ReplicaScheduleState{
|
||||
isSelected: false,
|
||||
replicas: 0,
|
||||
}
|
||||
if hpaControlled {
|
||||
if isSelected(hpaSelectedClusters.Names, clusterName) {
|
||||
replicaState.isSelected = true
|
||||
}
|
||||
}
|
||||
initialState[clusterName] = &replicaState
|
||||
}
|
||||
return initialState, hpaControlled, nil
|
||||
}
|
||||
|
||||
func (a *replicaSchedulingAdapter) GetSchedule(obj pkgruntime.Object, key string, clusters []*federationapi.Cluster, informer fedutil.FederatedInformer) (interface{}, error) {
|
||||
var clusterNames []string
|
||||
for _, cluster := range clusters {
|
||||
clusterNames = append(clusterNames, cluster.Name)
|
||||
}
|
||||
|
||||
// Schedule the pods across the existing clusters.
|
||||
objectGetter := func(clusterName, key string) (interface{}, bool, error) {
|
||||
return informer.GetTargetStore().GetByKey(clusterName, key)
|
||||
}
|
||||
podsGetter := func(clusterName string, obj pkgruntime.Object) (*apiv1.PodList, error) {
|
||||
clientset, err := informer.GetClientsetForCluster(clusterName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selectorObj := reflect.ValueOf(obj).Elem().FieldByName("Spec").FieldByName("Selector").Interface().(*metav1.LabelSelector)
|
||||
selector, err := metav1.LabelSelectorAsSelector(selectorObj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid selector: %v", err)
|
||||
}
|
||||
metadata, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientset.Core().Pods(metadata.GetNamespace()).List(metav1.ListOptions{LabelSelector: selector.String()})
|
||||
}
|
||||
|
||||
initializedState, hpaControlled, err := initializeScheduleState(obj, clusterNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if hpaControlled {
|
||||
state, err := simpleSchedule(initializedState, key, objectGetter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ReplicaSchedulingInfo{
|
||||
ScheduleState: state,
|
||||
Status: ReplicaStatus{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
currentReplicasPerCluster, estimatedCapacity, err := clustersReplicaState(clusterNames, key, objectGetter, podsGetter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fedPref, err := replicapreferences.GetAllocationPreferences(obj, a.preferencesAnnotationName)
|
||||
if err != nil {
|
||||
glog.Infof("Invalid workload-type specific preference, using default. object: %v, err: %v", obj, err)
|
||||
}
|
||||
if fedPref == nil {
|
||||
fedPref = &fedapi.ReplicaAllocationPreferences{
|
||||
Clusters: map[string]fedapi.ClusterPreferences{
|
||||
"*": {Weight: 1},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
plnr := planner.NewPlanner(fedPref)
|
||||
|
||||
return &ReplicaSchedulingInfo{
|
||||
ScheduleState: schedule(plnr, obj, key, clusterNames, currentReplicasPerCluster, estimatedCapacity, initializedState),
|
||||
Status: ReplicaStatus{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *replicaSchedulingAdapter) ScheduleObject(cluster *federationapi.Cluster, clusterObj pkgruntime.Object, federationObjCopy pkgruntime.Object, schedulingInfo interface{}) (pkgruntime.Object, ScheduleAction, error) {
|
||||
typedSchedulingInfo := schedulingInfo.(*ReplicaSchedulingInfo)
|
||||
clusterScheduleState := typedSchedulingInfo.ScheduleState[cluster.Name]
|
||||
|
||||
if clusterObj != nil {
|
||||
schedulingStatusVal := reflect.ValueOf(typedSchedulingInfo).Elem().FieldByName("Status")
|
||||
objStatusVal := reflect.ValueOf(clusterObj).Elem().FieldByName("Status")
|
||||
for i := 0; i < schedulingStatusVal.NumField(); i++ {
|
||||
schedulingStatusField := schedulingStatusVal.Field(i)
|
||||
schedulingStatusFieldName := schedulingStatusVal.Type().Field(i).Name
|
||||
objStatusField := objStatusVal.FieldByName(schedulingStatusFieldName)
|
||||
if objStatusField.IsValid() {
|
||||
current := schedulingStatusField.Int()
|
||||
additional := objStatusField.Int()
|
||||
schedulingStatusField.SetInt(current + additional)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var action ScheduleAction = ""
|
||||
specReplicas := int32(0)
|
||||
// If the cluster has been selected (isSelected = true; for example by hpa)
|
||||
// and the obj does not get any replicas, then it should create one with
|
||||
// 0 replicas (which can then be scaled by hpa in that cluster).
|
||||
// On the other hand we keep the action as "unassigned" if this cluster was
|
||||
// not selected, and let the sync controller decide what to do.
|
||||
if clusterScheduleState.isSelected {
|
||||
specReplicas = int32(clusterScheduleState.replicas)
|
||||
action = ActionAdd
|
||||
}
|
||||
reflect.ValueOf(federationObjCopy).Elem().FieldByName("Spec").FieldByName("Replicas").Set(reflect.ValueOf(&specReplicas))
|
||||
return federationObjCopy, action, nil
|
||||
}
|
||||
|
||||
func (a *replicaSchedulingAdapter) UpdateFederatedStatus(obj pkgruntime.Object, schedulingInfo interface{}) error {
|
||||
return a.updateStatusFunc(obj, schedulingInfo)
|
||||
}
|
||||
|
||||
// simpleSchedule get replicas from only those clusters which are selected (by hpa scheduler).
|
||||
// This aim of this is to ensure that this controller does not update objects, which are
|
||||
// targetted by hpa.
|
||||
func simpleSchedule(scheduleState map[string]*ReplicaScheduleState, key string, objectGetter func(clusterName string, key string) (interface{}, bool, error)) (map[string]*ReplicaScheduleState, error) {
|
||||
for clusterName, state := range scheduleState {
|
||||
// Get and consider replicas only for those clusters which are selected by hpa.
|
||||
if state.isSelected {
|
||||
obj, exists, err := objectGetter(clusterName, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
continue
|
||||
}
|
||||
state.replicas = reflect.ValueOf(obj).Elem().FieldByName("Spec").FieldByName("Replicas").Elem().Int()
|
||||
}
|
||||
}
|
||||
|
||||
return scheduleState, nil
|
||||
}
|
||||
|
||||
func schedule(planner *planner.Planner, obj pkgruntime.Object, key string, clusterNames []string, currentReplicasPerCluster map[string]int64, estimatedCapacity map[string]int64, initialState map[string]*ReplicaScheduleState) map[string]*ReplicaScheduleState {
|
||||
// TODO: integrate real scheduler
|
||||
replicas := reflect.ValueOf(obj).Elem().FieldByName("Spec").FieldByName("Replicas").Elem().Int()
|
||||
scheduleResult, overflow := planner.Plan(replicas, clusterNames, currentReplicasPerCluster, estimatedCapacity, key)
|
||||
|
||||
// Ensure that all current clusters end up in the scheduling result.
|
||||
// initialState, is preinitialized with all isSelected to false.
|
||||
result := initialState
|
||||
for clusterName := range currentReplicasPerCluster {
|
||||
// We consider 0 replicas equaling to no need of creating a new object.
|
||||
// isSchedule remains false in such case.
|
||||
result[clusterName].replicas = 0
|
||||
}
|
||||
|
||||
for clusterName, replicas := range scheduleResult {
|
||||
result[clusterName].isSelected = true
|
||||
result[clusterName].replicas = replicas
|
||||
}
|
||||
for clusterName, replicas := range overflow {
|
||||
result[clusterName].isSelected = true
|
||||
result[clusterName].replicas += replicas
|
||||
}
|
||||
|
||||
if glog.V(4) {
|
||||
buf := bytes.NewBufferString(fmt.Sprintf("Schedule - %q\n", key))
|
||||
sort.Strings(clusterNames)
|
||||
for _, clusterName := range clusterNames {
|
||||
cur := currentReplicasPerCluster[clusterName]
|
||||
target := scheduleResult[clusterName]
|
||||
fmt.Fprintf(buf, "%s: current: %d target: %d", clusterName, cur, target)
|
||||
if over, found := overflow[clusterName]; found {
|
||||
fmt.Fprintf(buf, " overflow: %d", over)
|
||||
}
|
||||
if capacity, found := estimatedCapacity[clusterName]; found {
|
||||
fmt.Fprintf(buf, " capacity: %d", capacity)
|
||||
}
|
||||
fmt.Fprintf(buf, "\n")
|
||||
}
|
||||
glog.V(4).Infof(buf.String())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// clusterReplicaState returns information about the scheduling state of the pods running in the federated clusters.
|
||||
func clustersReplicaState(
|
||||
clusterNames []string,
|
||||
key string,
|
||||
objectGetter func(clusterName string, key string) (interface{}, bool, error),
|
||||
podsGetter func(clusterName string, obj pkgruntime.Object) (*apiv1.PodList, error)) (currentReplicasPerCluster map[string]int64, estimatedCapacity map[string]int64, err error) {
|
||||
|
||||
currentReplicasPerCluster = make(map[string]int64)
|
||||
estimatedCapacity = make(map[string]int64)
|
||||
|
||||
for _, clusterName := range clusterNames {
|
||||
obj, exists, err := objectGetter(clusterName, key)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if !exists {
|
||||
continue
|
||||
}
|
||||
replicas := reflect.ValueOf(obj).Elem().FieldByName("Spec").FieldByName("Replicas").Elem().Int()
|
||||
readyReplicas := reflect.ValueOf(obj).Elem().FieldByName("Status").FieldByName("ReadyReplicas").Int()
|
||||
if replicas == readyReplicas {
|
||||
currentReplicasPerCluster[clusterName] = readyReplicas
|
||||
} else {
|
||||
pods, err := podsGetter(clusterName, obj.(pkgruntime.Object))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
podStatus := podanalyzer.AnalyzePods(pods, time.Now())
|
||||
currentReplicasPerCluster[clusterName] = int64(podStatus.RunningAndReady) // include pending as well?
|
||||
unschedulable := int64(podStatus.Unschedulable)
|
||||
if unschedulable > 0 {
|
||||
estimatedCapacity[clusterName] = replicas - unschedulable
|
||||
}
|
||||
}
|
||||
}
|
||||
return currentReplicasPerCluster, estimatedCapacity, nil
|
||||
}
|
||||
163
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/scheduling_test.go
generated
vendored
Normal file
163
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/scheduling_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensionsv1 "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestClusterReplicaState(t *testing.T) {
|
||||
uncalledPodsGetter := func(clusterName string, obj pkgruntime.Object) (*apiv1.PodList, error) {
|
||||
t.Fatal("podsGetter should not be called when workload objects are all ready.")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
podsByReplicaSet := make(map[pkgruntime.Object][]*apiv1.Pod)
|
||||
podsGetter := func(clusterName string, obj pkgruntime.Object) (*apiv1.PodList, error) {
|
||||
pods, ok := podsByReplicaSet[obj]
|
||||
if !ok {
|
||||
t.Fatalf("No pods found in test data for replica set %v", obj)
|
||||
return nil, fmt.Errorf("Not found")
|
||||
}
|
||||
var podListPods []apiv1.Pod
|
||||
for _, pod := range pods {
|
||||
podListPods = append(podListPods, *pod)
|
||||
}
|
||||
return &apiv1.PodList{Items: podListPods}, nil
|
||||
}
|
||||
|
||||
readyCondition := apiv1.PodCondition{Type: apiv1.PodReady}
|
||||
unschedulableCondition := apiv1.PodCondition{
|
||||
Type: apiv1.PodScheduled,
|
||||
Status: apiv1.ConditionFalse,
|
||||
Reason: apiv1.PodReasonUnschedulable,
|
||||
LastTransitionTime: metav1.NewTime(time.Now().Add(-1 * time.Hour)),
|
||||
}
|
||||
|
||||
one := int64(1)
|
||||
two := int64(2)
|
||||
|
||||
tests := map[string]struct {
|
||||
rs1Replicas int32
|
||||
rs2Replicas int32
|
||||
rs1ReadyReplicas int32
|
||||
rs2ReadyReplicas int32
|
||||
podsGetter func(clusterName string, obj pkgruntime.Object) (*apiv1.PodList, error)
|
||||
pod1Phase apiv1.PodPhase
|
||||
pod1Condition apiv1.PodCondition
|
||||
pod2Phase apiv1.PodPhase
|
||||
pod2Condition apiv1.PodCondition
|
||||
cluster1Replicas *int64
|
||||
cluster2Replicas *int64
|
||||
cluster1UnschedulableReplicas *int64
|
||||
cluster2UnschedulableReplicas *int64
|
||||
}{
|
||||
"All replica sets have an equal number of requested and ready replicas.": {rs1Replicas: 2, rs2Replicas: 2, rs1ReadyReplicas: 2, rs2ReadyReplicas: 2, podsGetter: uncalledPodsGetter, cluster1Replicas: &two, cluster2Replicas: &two},
|
||||
"One replica set has a pending schedulable pod": {rs1Replicas: 2, rs2Replicas: 2, rs1ReadyReplicas: 1, rs2ReadyReplicas: 2, podsGetter: podsGetter, pod1Phase: apiv1.PodRunning, pod1Condition: readyCondition, pod2Phase: apiv1.PodPending, cluster1Replicas: &one, cluster2Replicas: &two},
|
||||
"One replica set has an unschedulable pod": {rs1Replicas: 2, rs2Replicas: 2, rs1ReadyReplicas: 1, rs2ReadyReplicas: 2, podsGetter: podsGetter, pod1Phase: apiv1.PodRunning, pod1Condition: readyCondition, pod2Phase: apiv1.PodPending, pod2Condition: unschedulableCondition, cluster1Replicas: &one, cluster2Replicas: &two, cluster1UnschedulableReplicas: &one},
|
||||
}
|
||||
|
||||
for name, tt := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
clusters := []string{"one", "two"}
|
||||
replicaSetsByCluster := make(map[string]*extensionsv1.ReplicaSet)
|
||||
replicaSetGetter := func(clusterName string, key string) (interface{}, bool, error) {
|
||||
rs, ok := replicaSetsByCluster[clusterName]
|
||||
if !ok {
|
||||
t.Fatalf("No replica set found in test data for %v", clusterName)
|
||||
return nil, false, fmt.Errorf("Not found")
|
||||
}
|
||||
return rs, true, nil
|
||||
}
|
||||
rs1 := newReplicaSetWithReplicas("one", tt.rs1Replicas)
|
||||
rs2 := newReplicaSetWithReplicas("two", tt.rs2Replicas)
|
||||
rs1.Spec.Replicas = &tt.rs1Replicas
|
||||
rs2.Spec.Replicas = &tt.rs2Replicas
|
||||
rs1.Status.ReadyReplicas = tt.rs1ReadyReplicas
|
||||
rs2.Status.ReadyReplicas = tt.rs2ReadyReplicas
|
||||
|
||||
replicaSetsByCluster["one"] = rs1
|
||||
replicaSetsByCluster["two"] = rs2
|
||||
|
||||
pod1 := newPod("one")
|
||||
pod2 := newPod("two")
|
||||
podThree := newPod("three")
|
||||
podFour := newPod("four")
|
||||
|
||||
pod1.Status.Phase = tt.pod1Phase
|
||||
pod2.Status.Phase = tt.pod2Phase
|
||||
pod1.Status.Conditions = []apiv1.PodCondition{tt.pod1Condition}
|
||||
pod2.Status.Conditions = []apiv1.PodCondition{tt.pod2Condition}
|
||||
|
||||
podsByReplicaSet[rs1] = []*apiv1.Pod{pod1, pod2}
|
||||
podsByReplicaSet[rs2] = []*apiv1.Pod{podThree, podFour}
|
||||
|
||||
current, estimatedCapacity, err := clustersReplicaState(clusters, "", replicaSetGetter, tt.podsGetter)
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
wantedCurrent := make(map[string]int64)
|
||||
if tt.cluster1Replicas != nil {
|
||||
wantedCurrent["one"] = *tt.cluster1Replicas
|
||||
}
|
||||
if tt.cluster2Replicas != nil {
|
||||
wantedCurrent["two"] = *tt.cluster2Replicas
|
||||
}
|
||||
assert.Equal(t, wantedCurrent, current)
|
||||
|
||||
wantedEstimatedCapacity := make(map[string]int64)
|
||||
if tt.cluster1UnschedulableReplicas != nil {
|
||||
wantedEstimatedCapacity["one"] = *tt.cluster1UnschedulableReplicas
|
||||
}
|
||||
if tt.cluster2UnschedulableReplicas != nil {
|
||||
wantedEstimatedCapacity["two"] = *tt.cluster2UnschedulableReplicas
|
||||
}
|
||||
assert.Equal(t, wantedEstimatedCapacity, estimatedCapacity)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newReplicaSetWithReplicas(name string, replicas int32) *extensionsv1.ReplicaSet {
|
||||
return &extensionsv1.ReplicaSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
SelfLink: "/api/v1/namespaces/default/replicasets/name",
|
||||
},
|
||||
Spec: extensionsv1.ReplicaSetSpec{
|
||||
Replicas: &replicas,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newPod(name string) *apiv1.Pod {
|
||||
return &apiv1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
}
|
||||
}
|
||||
152
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/secret.go
generated
vendored
Normal file
152
vendor/k8s.io/kubernetes/federation/pkg/federatedtypes/secret.go
generated
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedtypes
|
||||
|
||||
import (
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
kubeclientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||
)
|
||||
|
||||
const (
|
||||
SecretKind = "secret"
|
||||
SecretControllerName = "secrets"
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterFederatedType(SecretKind, SecretControllerName, []schema.GroupVersionResource{apiv1.SchemeGroupVersion.WithResource(SecretControllerName)}, NewSecretAdapter)
|
||||
}
|
||||
|
||||
type SecretAdapter struct {
|
||||
client federationclientset.Interface
|
||||
}
|
||||
|
||||
func NewSecretAdapter(client federationclientset.Interface, config *restclient.Config, adapterSpecificArgs map[string]interface{}) FederatedTypeAdapter {
|
||||
return &SecretAdapter{client: client}
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) Kind() string {
|
||||
return SecretKind
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ObjectType() pkgruntime.Object {
|
||||
return &apiv1.Secret{}
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) IsExpectedType(obj interface{}) bool {
|
||||
_, ok := obj.(*apiv1.Secret)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) Copy(obj pkgruntime.Object) pkgruntime.Object {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return &apiv1.Secret{
|
||||
ObjectMeta: util.DeepCopyRelevantObjectMeta(secret.ObjectMeta),
|
||||
Data: secret.Data,
|
||||
Type: secret.Type,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) Equivalent(obj1, obj2 pkgruntime.Object) bool {
|
||||
secret1 := obj1.(*apiv1.Secret)
|
||||
secret2 := obj2.(*apiv1.Secret)
|
||||
return util.SecretEquivalent(*secret1, *secret2)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) QualifiedName(obj pkgruntime.Object) QualifiedName {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return QualifiedName{Namespace: secret.Namespace, Name: secret.Name}
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta {
|
||||
return &obj.(*apiv1.Secret).ObjectMeta
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedCreate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return a.client.CoreV1().Secrets(secret.Namespace).Create(secret)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedDelete(qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return a.client.CoreV1().Secrets(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedGet(qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return a.client.CoreV1().Secrets(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedList(namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return a.client.CoreV1().Secrets(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return a.client.CoreV1().Secrets(secret.Namespace).Update(secret)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedWatch(namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return a.client.CoreV1().Secrets(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterCreate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return client.CoreV1().Secrets(secret.Namespace).Create(secret)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterDelete(client kubeclientset.Interface, qualifiedName QualifiedName, options *metav1.DeleteOptions) error {
|
||||
return client.CoreV1().Secrets(qualifiedName.Namespace).Delete(qualifiedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterGet(client kubeclientset.Interface, qualifiedName QualifiedName) (pkgruntime.Object, error) {
|
||||
return client.CoreV1().Secrets(qualifiedName.Namespace).Get(qualifiedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterList(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return client.CoreV1().Secrets(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterUpdate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return client.CoreV1().Secrets(secret.Namespace).Update(secret)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterWatch(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return client.CoreV1().Secrets(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) IsSchedulingAdapter() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) NewTestObject(namespace string) pkgruntime.Object {
|
||||
return &apiv1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "test-secret-",
|
||||
Namespace: namespace,
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"A": []byte("ala ma kota"),
|
||||
},
|
||||
Type: apiv1.SecretTypeOpaque,
|
||||
}
|
||||
}
|
||||
32
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/BUILD
generated
vendored
Normal file
32
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["doc.go"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//federation/pkg/federation-controller/cluster:all-srcs",
|
||||
"//federation/pkg/federation-controller/ingress:all-srcs",
|
||||
"//federation/pkg/federation-controller/job:all-srcs",
|
||||
"//federation/pkg/federation-controller/service:all-srcs",
|
||||
"//federation/pkg/federation-controller/sync:all-srcs",
|
||||
"//federation/pkg/federation-controller/util:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
8
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/OWNERS
generated
vendored
Normal file
8
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/OWNERS
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
approvers:
|
||||
- quinton-hoole
|
||||
- nikhiljindal
|
||||
- madhusudancs
|
||||
reviewers:
|
||||
- quinton-hoole
|
||||
- nikhiljindal
|
||||
- madhusudancs
|
||||
65
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/BUILD
generated
vendored
Normal file
65
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["clustercontroller_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//federation/apis/federation/v1beta1:go_default_library",
|
||||
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cluster_client.go",
|
||||
"clustercontroller.go",
|
||||
"doc.go",
|
||||
],
|
||||
deps = [
|
||||
"//federation/apis/federation/v1beta1:go_default_library",
|
||||
"//federation/client/cache:go_default_library",
|
||||
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
||||
"//federation/pkg/federation-controller/util:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
170
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/cluster_client.go
generated
vendored
Normal file
170
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/cluster_client.go
generated
vendored
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
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 cluster
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
federation_v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
)
|
||||
|
||||
const (
|
||||
UserAgentName = "Cluster-Controller"
|
||||
)
|
||||
|
||||
type ClusterClient struct {
|
||||
kubeClient *clientset.Clientset
|
||||
}
|
||||
|
||||
func NewClusterClientSet(c *federation_v1beta1.Cluster) (*ClusterClient, error) {
|
||||
clusterConfig, err := util.BuildClusterConfig(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var clusterClientSet = ClusterClient{}
|
||||
if clusterConfig != nil {
|
||||
clusterClientSet.kubeClient = clientset.NewForConfigOrDie((restclient.AddUserAgent(clusterConfig, UserAgentName)))
|
||||
if clusterClientSet.kubeClient == nil {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
return &clusterClientSet, nil
|
||||
}
|
||||
|
||||
// GetClusterHealthStatus gets the kubernetes cluster health status by requesting "/healthz"
|
||||
func (self *ClusterClient) GetClusterHealthStatus() *federation_v1beta1.ClusterStatus {
|
||||
clusterStatus := federation_v1beta1.ClusterStatus{}
|
||||
currentTime := metav1.Now()
|
||||
newClusterReadyCondition := federation_v1beta1.ClusterCondition{
|
||||
Type: federation_v1beta1.ClusterReady,
|
||||
Status: v1.ConditionTrue,
|
||||
Reason: "ClusterReady",
|
||||
Message: "/healthz responded with ok",
|
||||
LastProbeTime: currentTime,
|
||||
LastTransitionTime: currentTime,
|
||||
}
|
||||
newClusterNotReadyCondition := federation_v1beta1.ClusterCondition{
|
||||
Type: federation_v1beta1.ClusterReady,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "ClusterNotReady",
|
||||
Message: "/healthz responded without ok",
|
||||
LastProbeTime: currentTime,
|
||||
LastTransitionTime: currentTime,
|
||||
}
|
||||
newNodeOfflineCondition := federation_v1beta1.ClusterCondition{
|
||||
Type: federation_v1beta1.ClusterOffline,
|
||||
Status: v1.ConditionTrue,
|
||||
Reason: "ClusterNotReachable",
|
||||
Message: "cluster is not reachable",
|
||||
LastProbeTime: currentTime,
|
||||
LastTransitionTime: currentTime,
|
||||
}
|
||||
newNodeNotOfflineCondition := federation_v1beta1.ClusterCondition{
|
||||
Type: federation_v1beta1.ClusterOffline,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "ClusterReachable",
|
||||
Message: "cluster is reachable",
|
||||
LastProbeTime: currentTime,
|
||||
LastTransitionTime: currentTime,
|
||||
}
|
||||
body, err := self.kubeClient.DiscoveryClient.RESTClient().Get().AbsPath("/healthz").Do().Raw()
|
||||
if err != nil {
|
||||
clusterStatus.Conditions = append(clusterStatus.Conditions, newNodeOfflineCondition)
|
||||
} else {
|
||||
if !strings.EqualFold(string(body), "ok") {
|
||||
clusterStatus.Conditions = append(clusterStatus.Conditions, newClusterNotReadyCondition, newNodeNotOfflineCondition)
|
||||
} else {
|
||||
clusterStatus.Conditions = append(clusterStatus.Conditions, newClusterReadyCondition)
|
||||
}
|
||||
}
|
||||
|
||||
zones, region, err := self.GetClusterZones()
|
||||
if err != nil {
|
||||
glog.Warningf("Failed to get zones and region for cluster with client %v: %v", self, err)
|
||||
} else {
|
||||
clusterStatus.Zones = zones
|
||||
clusterStatus.Region = region
|
||||
}
|
||||
|
||||
return &clusterStatus
|
||||
}
|
||||
|
||||
// GetClusterZones gets the kubernetes cluster zones and region by inspecting labels on nodes in the cluster.
|
||||
func (self *ClusterClient) GetClusterZones() (zones []string, region string, err error) {
|
||||
return getZoneNames(self.kubeClient)
|
||||
}
|
||||
|
||||
// Find the name of the zone in which a Node is running
|
||||
func getZoneNameForNode(node api.Node) (string, error) {
|
||||
for key, value := range node.Labels {
|
||||
if key == kubeletapis.LabelZoneFailureDomain {
|
||||
return value, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("Zone name for node %s not found. No label with key %s",
|
||||
node.Name, kubeletapis.LabelZoneFailureDomain)
|
||||
}
|
||||
|
||||
// Find the name of the region in which a Node is running
|
||||
func getRegionNameForNode(node api.Node) (string, error) {
|
||||
for key, value := range node.Labels {
|
||||
if key == kubeletapis.LabelZoneRegion {
|
||||
return value, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("Region name for node %s not found. No label with key %s",
|
||||
node.Name, kubeletapis.LabelZoneRegion)
|
||||
}
|
||||
|
||||
// Find the names of all zones and the region in which we have nodes in this cluster.
|
||||
func getZoneNames(client *clientset.Clientset) (zones []string, region string, err error) {
|
||||
zoneNames := sets.NewString()
|
||||
nodes, err := client.Core().Nodes().List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to list nodes while getting zone names: %v", err)
|
||||
return nil, "", err
|
||||
}
|
||||
for i, node := range nodes.Items {
|
||||
// TODO: quinton-hoole make this more efficient.
|
||||
// For non-multi-zone clusters the zone will
|
||||
// be identical for all nodes, so we only need to look at one node
|
||||
// For multi-zone clusters we know at build time
|
||||
// which zones are included. Rather get this info from there, because it's cheaper.
|
||||
zoneName, err := getZoneNameForNode(node)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
zoneNames.Insert(zoneName)
|
||||
if i == 0 {
|
||||
region, err = getRegionNameForNode(node)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
return zoneNames.List(), region, nil
|
||||
}
|
||||
209
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/clustercontroller.go
generated
vendored
Normal file
209
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/clustercontroller.go
generated
vendored
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
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 cluster
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
federationv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
clustercache "k8s.io/kubernetes/federation/client/cache"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
)
|
||||
|
||||
type ClusterController struct {
|
||||
// federationClient used to operate cluster
|
||||
federationClient federationclientset.Interface
|
||||
|
||||
// clusterMonitorPeriod is the period for updating status of cluster
|
||||
clusterMonitorPeriod time.Duration
|
||||
|
||||
mu sync.RWMutex
|
||||
knownClusterSet sets.String
|
||||
// clusterClusterStatusMap is a mapping of clusterName and cluster status of last sampling
|
||||
clusterClusterStatusMap map[string]federationv1beta1.ClusterStatus
|
||||
// clusterKubeClientMap is a mapping of clusterName and restclient
|
||||
clusterKubeClientMap map[string]ClusterClient
|
||||
|
||||
// cluster framework and store
|
||||
clusterController cache.Controller
|
||||
clusterStore clustercache.StoreToClusterLister
|
||||
}
|
||||
|
||||
// StartClusterController starts a new cluster controller
|
||||
func StartClusterController(config *restclient.Config, stopChan <-chan struct{}, clusterMonitorPeriod time.Duration) {
|
||||
restclient.AddUserAgent(config, "cluster-controller")
|
||||
client := federationclientset.NewForConfigOrDie(config)
|
||||
controller := newClusterController(client, clusterMonitorPeriod)
|
||||
glog.Infof("Starting cluster controller")
|
||||
controller.Run(stopChan)
|
||||
}
|
||||
|
||||
// newClusterController returns a new cluster controller
|
||||
func newClusterController(federationClient federationclientset.Interface, clusterMonitorPeriod time.Duration) *ClusterController {
|
||||
cc := &ClusterController{
|
||||
knownClusterSet: make(sets.String),
|
||||
federationClient: federationClient,
|
||||
clusterMonitorPeriod: clusterMonitorPeriod,
|
||||
clusterClusterStatusMap: make(map[string]federationv1beta1.ClusterStatus),
|
||||
clusterKubeClientMap: make(map[string]ClusterClient),
|
||||
}
|
||||
cc.clusterStore.Store, cc.clusterController = cache.NewInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
return cc.federationClient.Federation().Clusters().List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
return cc.federationClient.Federation().Clusters().Watch(options)
|
||||
},
|
||||
},
|
||||
&federationv1beta1.Cluster{},
|
||||
controller.NoResyncPeriodFunc(),
|
||||
cache.ResourceEventHandlerFuncs{
|
||||
DeleteFunc: cc.delFromClusterSet,
|
||||
AddFunc: cc.addToClusterSet,
|
||||
},
|
||||
)
|
||||
return cc
|
||||
}
|
||||
|
||||
// delFromClusterSet delete a cluster from clusterSet and
|
||||
// delete the corresponding restclient from the map clusterKubeClientMap
|
||||
func (cc *ClusterController) delFromClusterSet(obj interface{}) {
|
||||
cc.mu.Lock()
|
||||
defer cc.mu.Unlock()
|
||||
cluster := obj.(*federationv1beta1.Cluster)
|
||||
cc.delFromClusterSetByName(cluster.Name)
|
||||
}
|
||||
|
||||
// delFromClusterSetByName delete a cluster from clusterSet by name and
|
||||
// delete the corresponding restclient from the map clusterKubeClientMap.
|
||||
// Caller must make sure that they hold the mutex
|
||||
func (cc *ClusterController) delFromClusterSetByName(clusterName string) {
|
||||
glog.V(1).Infof("ClusterController observed a cluster deletion: %v", clusterName)
|
||||
cc.knownClusterSet.Delete(clusterName)
|
||||
delete(cc.clusterKubeClientMap, clusterName)
|
||||
delete(cc.clusterClusterStatusMap, clusterName)
|
||||
}
|
||||
|
||||
func (cc *ClusterController) addToClusterSet(obj interface{}) {
|
||||
cc.mu.Lock()
|
||||
defer cc.mu.Unlock()
|
||||
cluster := obj.(*federationv1beta1.Cluster)
|
||||
cc.addToClusterSetWithoutLock(cluster)
|
||||
}
|
||||
|
||||
// addToClusterSetWithoutLock inserts the new cluster to clusterSet and create
|
||||
// a corresponding restclient to map clusterKubeClientMap if the cluster is not
|
||||
// known. Caller must make sure that they hold the mutex.
|
||||
func (cc *ClusterController) addToClusterSetWithoutLock(cluster *federationv1beta1.Cluster) {
|
||||
if cc.knownClusterSet.Has(cluster.Name) {
|
||||
return
|
||||
}
|
||||
glog.V(1).Infof("ClusterController observed a new cluster: %v", cluster.Name)
|
||||
cc.knownClusterSet.Insert(cluster.Name)
|
||||
// create the restclient of cluster
|
||||
restClient, err := NewClusterClientSet(cluster)
|
||||
if err != nil || restClient == nil {
|
||||
glog.Errorf("Failed to create corresponding restclient of kubernetes cluster: %v", err)
|
||||
return
|
||||
}
|
||||
cc.clusterKubeClientMap[cluster.Name] = *restClient
|
||||
}
|
||||
|
||||
// Run begins watching and syncing.
|
||||
func (cc *ClusterController) Run(stopChan <-chan struct{}) {
|
||||
defer utilruntime.HandleCrash()
|
||||
go cc.clusterController.Run(stopChan)
|
||||
// monitor cluster status periodically, in phase 1 we just get the health state from "/healthz"
|
||||
go wait.Until(func() {
|
||||
if err := cc.updateClusterStatus(); err != nil {
|
||||
glog.Errorf("Error monitoring cluster status: %v", err)
|
||||
}
|
||||
}, cc.clusterMonitorPeriod, stopChan)
|
||||
}
|
||||
|
||||
// updateClusterStatus checks cluster status and get the metrics from cluster's restapi
|
||||
func (cc *ClusterController) updateClusterStatus() error {
|
||||
clusters, err := cc.federationClient.Federation().Clusters().List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cluster := range clusters.Items {
|
||||
cc.mu.RLock()
|
||||
// skip updating status of the cluster which is not yet added to knownClusterSet.
|
||||
if !cc.knownClusterSet.Has(cluster.Name) {
|
||||
cc.mu.RUnlock()
|
||||
continue
|
||||
}
|
||||
clusterClient, clientFound := cc.clusterKubeClientMap[cluster.Name]
|
||||
clusterStatusOld, statusFound := cc.clusterClusterStatusMap[cluster.Name]
|
||||
cc.mu.RUnlock()
|
||||
|
||||
if !clientFound {
|
||||
glog.Warningf("Failed to get client for cluster %s", cluster.Name)
|
||||
continue
|
||||
}
|
||||
clusterStatusNew := clusterClient.GetClusterHealthStatus()
|
||||
if !statusFound {
|
||||
glog.Infof("There is no status stored for cluster: %v before", cluster.Name)
|
||||
} else {
|
||||
hasTransition := false
|
||||
if len(clusterStatusNew.Conditions) != len(clusterStatusOld.Conditions) {
|
||||
hasTransition = true
|
||||
} else {
|
||||
for i := 0; i < len(clusterStatusNew.Conditions); i++ {
|
||||
if !(strings.EqualFold(string(clusterStatusNew.Conditions[i].Type), string(clusterStatusOld.Conditions[i].Type)) &&
|
||||
strings.EqualFold(string(clusterStatusNew.Conditions[i].Status), string(clusterStatusOld.Conditions[i].Status))) {
|
||||
hasTransition = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !hasTransition {
|
||||
for j := 0; j < len(clusterStatusNew.Conditions); j++ {
|
||||
clusterStatusNew.Conditions[j].LastTransitionTime = clusterStatusOld.Conditions[j].LastTransitionTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cc.mu.Lock()
|
||||
cc.clusterClusterStatusMap[cluster.Name] = *clusterStatusNew
|
||||
cc.mu.Unlock()
|
||||
cluster.Status = *clusterStatusNew
|
||||
cluster, err := cc.federationClient.Federation().Clusters().UpdateStatus(&cluster)
|
||||
if err != nil {
|
||||
glog.Warningf("Failed to update the status of cluster: %v ,error is : %v", cluster.Name, err)
|
||||
// Don't return err here, as we want to continue processing remaining clusters.
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
173
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/clustercontroller_test.go
generated
vendored
Normal file
173
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/clustercontroller_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
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 cluster
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
federationv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
)
|
||||
|
||||
func newCluster(clusterName string, serverUrl string) *federationv1beta1.Cluster {
|
||||
cluster := federationv1beta1.Cluster{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: testapi.Federation.GroupVersion().String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
UID: uuid.NewUUID(),
|
||||
Name: clusterName,
|
||||
},
|
||||
Spec: federationv1beta1.ClusterSpec{
|
||||
ServerAddressByClientCIDRs: []federationv1beta1.ServerAddressByClientCIDR{
|
||||
{
|
||||
ClientCIDR: "0.0.0.0/0",
|
||||
ServerAddress: serverUrl,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return &cluster
|
||||
}
|
||||
|
||||
func newClusterList(cluster *federationv1beta1.Cluster) *federationv1beta1.ClusterList {
|
||||
clusterList := federationv1beta1.ClusterList{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: testapi.Federation.GroupVersion().String()},
|
||||
ListMeta: metav1.ListMeta{
|
||||
SelfLink: "foobar",
|
||||
},
|
||||
Items: []federationv1beta1.Cluster{},
|
||||
}
|
||||
clusterList.Items = append(clusterList.Items, *cluster)
|
||||
return &clusterList
|
||||
}
|
||||
|
||||
// init a fake http handler, simulate a federation apiserver, response the "DELETE" "PUT" "GET" "UPDATE"
|
||||
// when "canBeGotten" is false, means that user can not get the cluster cluster from apiserver
|
||||
func createHttptestFakeHandlerForFederation(clusterList *federationv1beta1.ClusterList, canBeGotten bool) *http.HandlerFunc {
|
||||
fakeHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
clusterListString, _ := json.Marshal(*clusterList)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch r.Method {
|
||||
case "PUT":
|
||||
fmt.Fprintln(w, string(clusterListString))
|
||||
case "GET":
|
||||
if canBeGotten {
|
||||
fmt.Fprintln(w, string(clusterListString))
|
||||
} else {
|
||||
fmt.Fprintln(w, "")
|
||||
}
|
||||
default:
|
||||
fmt.Fprintln(w, "")
|
||||
}
|
||||
})
|
||||
return &fakeHandler
|
||||
}
|
||||
|
||||
// init a fake http handler, simulate a cluster apiserver, response the "/healthz"
|
||||
// when "canBeGotten" is false, means that user can not get response from apiserver
|
||||
func createHttptestFakeHandlerForCluster(canBeGotten bool) *http.HandlerFunc {
|
||||
fakeHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
if canBeGotten {
|
||||
fmt.Fprintln(w, "ok")
|
||||
} else {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
default:
|
||||
fmt.Fprintln(w, "")
|
||||
}
|
||||
})
|
||||
return &fakeHandler
|
||||
}
|
||||
|
||||
func TestUpdateClusterStatusOK(t *testing.T) {
|
||||
clusterName := "foobarCluster"
|
||||
// create dummy httpserver
|
||||
testClusterServer := httptest.NewServer(createHttptestFakeHandlerForCluster(true))
|
||||
defer testClusterServer.Close()
|
||||
federationCluster := newCluster(clusterName, testClusterServer.URL)
|
||||
federationClusterList := newClusterList(federationCluster)
|
||||
|
||||
testFederationServer := httptest.NewServer(createHttptestFakeHandlerForFederation(federationClusterList, true))
|
||||
defer testFederationServer.Close()
|
||||
|
||||
restClientCfg, err := clientcmd.BuildConfigFromFlags(testFederationServer.URL, "")
|
||||
if err != nil {
|
||||
t.Errorf("Failed to build client config")
|
||||
}
|
||||
federationClientSet := federationclientset.NewForConfigOrDie(restclient.AddUserAgent(restClientCfg, "cluster-controller"))
|
||||
|
||||
manager := newClusterController(federationClientSet, 5)
|
||||
manager.addToClusterSet(federationCluster)
|
||||
err = manager.updateClusterStatus()
|
||||
if err != nil {
|
||||
t.Errorf("Failed to Update Cluster Status: %v", err)
|
||||
}
|
||||
clusterStatus, found := manager.clusterClusterStatusMap[clusterName]
|
||||
if !found {
|
||||
t.Errorf("Failed to Update Cluster Status")
|
||||
} else {
|
||||
if (clusterStatus.Conditions[1].Status != v1.ConditionFalse) || (clusterStatus.Conditions[1].Type != federationv1beta1.ClusterOffline) {
|
||||
t.Errorf("Failed to Update Cluster Status")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test races between informer's updates and routine updates of cluster status
|
||||
// Issue https://github.com/kubernetes/kubernetes/issues/49958
|
||||
func TestUpdateClusterRace(t *testing.T) {
|
||||
clusterName := "foobarCluster"
|
||||
// create dummy httpserver
|
||||
testClusterServer := httptest.NewServer(createHttptestFakeHandlerForCluster(true))
|
||||
defer testClusterServer.Close()
|
||||
federationCluster := newCluster(clusterName, testClusterServer.URL)
|
||||
federationClusterList := newClusterList(federationCluster)
|
||||
|
||||
testFederationServer := httptest.NewServer(createHttptestFakeHandlerForFederation(federationClusterList, true))
|
||||
defer testFederationServer.Close()
|
||||
|
||||
restClientCfg, err := clientcmd.BuildConfigFromFlags(testFederationServer.URL, "")
|
||||
if err != nil {
|
||||
t.Errorf("Failed to build client config")
|
||||
}
|
||||
federationClientSet := federationclientset.NewForConfigOrDie(restclient.AddUserAgent(restClientCfg, "cluster-controller"))
|
||||
|
||||
manager := newClusterController(federationClientSet, 1*time.Millisecond)
|
||||
|
||||
stop := make(chan struct{})
|
||||
manager.Run(stop)
|
||||
|
||||
// try to trigger the race in UpdateClusterStatus
|
||||
for i := 0; i < 10; i++ {
|
||||
manager.addToClusterSet(federationCluster)
|
||||
manager.delFromClusterSet(federationCluster)
|
||||
}
|
||||
|
||||
close(stop)
|
||||
}
|
||||
18
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/cluster/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
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 cluster contains code for syncing cluster
|
||||
package cluster // import "k8s.io/kubernetes/federation/pkg/federation-controller/cluster"
|
||||
19
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/doc.go
generated
vendored
Normal file
19
vendor/k8s.io/kubernetes/federation/pkg/federation-controller/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Copyright 2015 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 federation_controller contains code for controllers (like the cluster
|
||||
// controller).
|
||||
package federation_controller // import "k8s.io/kubernetes/federation/pkg/federation-controller"
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue