Commit 64204965 authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #26049 from quinton-hoole/2016-05-22-aws-route53-dnsprovider

Automatic merge from submit-queue AWS Route53 dnsprovider Still needs unit tests, and some other cleanup. Review not urgent, but feel free to make a first pass. Only need to look at the last two commits. The prior commits will go in as #26020. This will need to be rebased against #26020 once that merges. It's a bare minimum implementation, only what's required for Ubernetes Federated Services (managing basic A and CNAME records). More functionality (health checks, geolocation etc) can be fairly easily added as required. It also requires github.com/aws/aws-sdk-go/service/route53 to be vendored into godeps, which I haven't managed to do successfully yet (Oh Godep!) cc: @justinsb FYI
parents 48771537 5b421842
...@@ -165,6 +165,11 @@ ...@@ -165,6 +165,11 @@
"Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/restxml",
"Comment": "v1.0.8",
"Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
"Comment": "v1.0.8", "Comment": "v1.0.8",
"Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
...@@ -200,6 +205,11 @@ ...@@ -200,6 +205,11 @@
"Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc" "Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/route53",
"Comment": "v1.0.8",
"Rev": "c924893c38ecc04b18d7aab8a7aa561cb8b4c4cc"
},
{
"ImportPath": "github.com/beorn7/perks/quantile", "ImportPath": "github.com/beorn7/perks/quantile",
"Rev": "3ac7bf7a47d159a033b107610db8a1b6575507a4" "Rev": "3ac7bf7a47d159a033b107610db8a1b6575507a4"
}, },
......
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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/testing"
)
// Compile time check for interface adeherence
var _ dnsprovider.Interface = Interface{}
type Interface struct {
service testing.Route53API
}
// newInterfaceWithStub facilitates stubbing out the underlying AWS Route53
// library for testing purposes. It returns an provider-independent interface.
func newInterfaceWithStub(service testing.Route53API) *Interface {
return &Interface{service}
}
func (i Interface) Zones() (zones dnsprovider.Zones, supported bool) {
return Zones{&i}, true
}
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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"
"k8s.io/kubernetes/federation/pkg/dnsprovider"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/route53"
)
const (
ProviderName = "aws-route53"
)
func init() {
dnsprovider.RegisterDnsProvider(ProviderName, func(config io.Reader) (dnsprovider.Interface, error) {
return newRoute53(config)
})
}
// 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
svc := route53.New(session.New())
return newInterfaceWithStub(svc), nil
}
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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/testing"
"k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53"
)
func newTestInterface() (dnsprovider.Interface, error) {
// Use this to test the real cloud service.
// i, err := 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 := newInterfaceWithStub(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())
}
// 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, supported := interface_.Zones()
if supported {
t.Logf("Got zones %v\n", z)
} else {
t.Fatalf("Zones interface not supported by interface %v", interface_)
}
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) dnsprovider.ResourceRecordSet {
result, err := rrsets.Add(rrset)
if err != nil {
t.Fatalf("Failed to add recordsets: %v", err)
}
return result
}
/* TestResourceRecordSetsList verifies that listing of zones succeeds */
func TestZonesList(t *testing.T) {
firstZone(t)
}
/* 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 := addRrsetOrFail(t, sets, getExampleRrs(zone))
defer sets.Remove(set)
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)
set := addRrsetOrFail(t, sets, rrset)
defer sets.Remove(set)
t.Logf("Successfully added resource record set: %v", set)
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)
set := addRrsetOrFail(t, sets, rrset)
defer sets.Remove(set)
t.Logf("Successfully added resource record set: %v", set)
// Try to add it again, and verify that the call fails.
rrs, err := sets.Add(rrset)
if err == nil {
defer sets.Remove(rrs)
t.Errorf("Should have failed to add duplicate resource record %v, but succeeded instead.", set)
} else {
t.Logf("Correctly failed to add duplicate resource record %v: %v", set, 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)
set := addRrsetOrFail(t, sets, rrset)
err := sets.Remove(set)
if err != nil {
// Try again to clean up.
defer sets.Remove(rrset)
t.Errorf("Failed to remove resource record set %v after adding", rrset)
} else {
t.Logf("Successfully removed resource set %v after adding", set)
}
}
/* TestResourceRecordSetsRemoveGone verifies that a removed RRS no longer exists */
func TestResourceRecordSetsRemoveGone(t *testing.T) {
zone := firstZone(t)
sets := rrs(t, zone)
rrset := getExampleRrs(zone)
set := addRrsetOrFail(t, sets, rrset)
err := sets.Remove(set)
if err != nil {
// Try again to clean up.
defer sets.Remove(rrset)
t.Errorf("Failed to remove resource record set %v after adding", rrset)
} else {
t.Logf("Successfully removed resource set %v after adding", set)
}
// 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)
}
}
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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/service/route53"
)
// Compile time check for interface adeherence
var _ dnsprovider.ResourceRecordSet = ResourceRecordSet{}
type ResourceRecordSet struct {
impl *route53.ResourceRecordSet
rrsets *ResourceRecordSets
}
func (rrset ResourceRecordSet) Name() string {
return *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] = *record.Value
}
return result
}
func (rrset ResourceRecordSet) Ttl() int64 {
return *rrset.impl.TTL
}
func (rrset ResourceRecordSet) Type() rrstype.RrsType {
return rrstype.RrsType(*rrset.impl.Type)
}
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 adeherence
var _ dnsprovider.ResourceRecordSets = ResourceRecordSets{}
type ResourceRecordSets struct {
zone *Zone
}
func (rrsets ResourceRecordSets) List() ([]dnsprovider.ResourceRecordSet, error) {
input := route53.ListResourceRecordSetsInput{
HostedZoneId: rrsets.zone.impl.Id,
}
response, err := rrsets.zone.zones.interface_.service.ListResourceRecordSets(&input)
// TODO: Handle truncated responses
if err != nil {
return nil, err
}
list := make([]dnsprovider.ResourceRecordSet, len(response.ResourceRecordSets))
for i, rrset := range response.ResourceRecordSets {
list[i] = &ResourceRecordSet{rrset, &rrsets}
}
return list, nil
}
func (rrsets ResourceRecordSets) Add(rrset dnsprovider.ResourceRecordSet) (dnsprovider.ResourceRecordSet, error) {
service := rrsets.zone.zones.interface_.service
input := getChangeResourceRecordSetsInput("CREATE", rrset.Name(), string(rrset.Type()), *rrset.(ResourceRecordSet).rrsets.zone.impl.Id, rrset.Rrdatas(), rrset.Ttl())
_, err := service.ChangeResourceRecordSets(input)
if err != nil {
// Cast err to awserr.Error to get the Code and
// Message from an error.
return nil, err
}
return ResourceRecordSet{input.ChangeBatch.Changes[0].ResourceRecordSet, &rrsets}, nil
}
func (rrsets ResourceRecordSets) Remove(rrset dnsprovider.ResourceRecordSet) error {
input := getChangeResourceRecordSetsInput("DELETE", rrset.Name(), string(rrset.Type()), *rrset.(ResourceRecordSet).rrsets.zone.impl.Id, rrset.Rrdatas(), rrset.Ttl())
_, err := rrsets.zone.zones.interface_.service.ChangeResourceRecordSets(input)
if err != nil {
// Cast err to awserr.Error to get the Code and
// Message from an error.
return err
}
return nil
}
func getChangeResourceRecordSetsInput(action, name, type_, hostedZoneId string, rrdatas []string, ttl int64) *route53.ChangeResourceRecordSetsInput {
input := &route53.ChangeResourceRecordSetsInput{
ChangeBatch: &route53.ChangeBatch{ // Required
Changes: []*route53.Change{ // Required
{ // Required
Action: aws.String(action), // Required
ResourceRecordSet: &route53.ResourceRecordSet{ // Required
Name: aws.String(name), // Required
Type: aws.String(type_), // Required
/*
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("DNSName"), // Required
EvaluateTargetHealth: aws.Bool(true), // Required
HostedZoneId: aws.String("ResourceId"), // Required
},
Failover: aws.String("ResourceRecordSetFailover"),
GeoLocation: &route53.GeoLocation{
ContinentCode: aws.String("GeoLocationContinentCode"),
CountryCode: aws.String("GeoLocationCountryCode"),
SubdivisionCode: aws.String("GeoLocationSubdivisionCode"),
},
HealthCheckId: aws.String("HealthCheckId"),
Region: aws.String("ResourceRecordSetRegion"),
*/
ResourceRecords: []*route53.ResourceRecord{
{ // Required
Value: aws.String(rrdatas[0]), // Required
},
// More values...
},
/*
SetIdentifier: aws.String("ResourceRecordSetIdentifier"),
*/
TTL: aws.Int64(ttl),
/*
TrafficPolicyInstanceId: aws.String("TrafficPolicyInstanceId"),
Weight: aws.Int64(1),
*/
},
},
// More values...
},
},
HostedZoneId: aws.String(hostedZoneId), // Required
}
return input
}
func (rrsets ResourceRecordSets) New(name string, rrdatas []string, ttl int64, rrstype rrstype.RrsType) dnsprovider.ResourceRecordSet {
rrstypeStr := string(rrstype)
return ResourceRecordSet{
&route53.ResourceRecordSet{
Name: &name,
Type: &rrstypeStr,
TTL: &ttl,
ResourceRecords: []*route53.ResourceRecord{
{
Value: &rrdatas[0],
},
},
}, // TODO: Add remaining rrdatas
&rrsets,
}
}
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 testing
import (
"fmt"
"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 {
ListResourceRecordSets(*route53.ListResourceRecordSetsInput) (*route53.ListResourceRecordSetsOutput, error)
ChangeResourceRecordSets(*route53.ChangeResourceRecordSetsInput) (*route53.ChangeResourceRecordSetsOutput, error)
ListHostedZones(*route53.ListHostedZonesInput) (*route53.ListHostedZonesOutput, error)
CreateHostedZone(*route53.CreateHostedZoneInput) (*route53.CreateHostedZoneOutput, 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 it's methods.
type Route53APIStub struct {
zones map[string]*route53.HostedZone
recordSets map[string]map[string][]*route53.ResourceRecordSet
}
// NewRoute53APIStub returns an initlialized Route53APIStub
func NewRoute53APIStub() *Route53APIStub {
return &Route53APIStub{
zones: make(map[string]*route53.HostedZone),
recordSets: make(map[string]map[string][]*route53.ResourceRecordSet),
}
}
func (r *Route53APIStub) ListResourceRecordSets(input *route53.ListResourceRecordSetsInput) (*route53.ListResourceRecordSetsOutput, 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)
}
}
}
return &output, 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 {
switch *change.Action {
case route53.ChangeActionCreate:
if _, found := recordSets[*change.ResourceRecordSet.Name]; found {
return nil, fmt.Errorf("Attempt to create duplicate rrset %s", change.ResourceRecordSet.Name) // TODO: Return AWS errors with codes etc
}
recordSets[*change.ResourceRecordSet.Name] = append(recordSets[*change.ResourceRecordSet.Name], change.ResourceRecordSet)
case route53.ChangeActionDelete:
if _, found := recordSets[*change.ResourceRecordSet.Name]; !found {
return nil, fmt.Errorf("Attempt to delete non-existant rrset %s", change.ResourceRecordSet.Name) // TODO: Check other fields too
}
delete(recordSets, *change.ResourceRecordSet.Name)
case route53.ChangeActionUpsert:
// TODO - not used yet
}
}
r.recordSets[*input.HostedZoneId] = recordSets
return output, nil // TODO: We should ideally return status etc, but we dont' use that yet.
}
func (r *Route53APIStub) ListHostedZones(*route53.ListHostedZonesInput) (*route53.ListHostedZonesOutput, error) {
output := &route53.ListHostedZonesOutput{}
for _, zone := range r.zones {
output.HostedZones = append(output.HostedZones, zone)
}
return output, nil
}
func (r *Route53APIStub) CreateHostedZone(input *route53.CreateHostedZoneInput) (*route53.CreateHostedZoneOutput, error) {
if _, ok := r.zones[*input.Name]; ok {
return nil, fmt.Errorf("Error creating hosted DNS zone: %s already exists", input.Name)
}
r.zones[*input.Name] = &route53.HostedZone{
Id: input.Name,
Name: input.Name,
}
return &route53.CreateHostedZoneOutput{HostedZone: r.zones[*input.Name]}, nil
}
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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/kubernetes/federation/pkg/dnsprovider"
)
// Compile time check for interface adeherence
var _ dnsprovider.Zone = &Zone{}
type Zone struct {
impl *route53.HostedZone
zones *Zones
}
func (zone *Zone) Name() string {
return *zone.impl.Name
}
func (zone *Zone) ResourceRecordSets() (dnsprovider.ResourceRecordSets, bool) {
return &ResourceRecordSets{zone}, true
}
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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/kubernetes/federation/pkg/dnsprovider"
)
// Compile time check for interface adeherence
var _ dnsprovider.Zones = Zones{}
type Zones struct {
interface_ *Interface
}
func (zones Zones) List() ([]dnsprovider.Zone, error) {
input := route53.ListHostedZonesInput{}
response, err := zones.interface_.service.ListHostedZones(&input)
if err != nil {
return []dnsprovider.Zone{}, err
}
hostedZones := response.HostedZones
// TODO: Handle result truncation
// https://docs.aws.amazon.com/sdk-for-go/api/service/route53/Route53.html#ListHostedZones-instance_method
zoneList := make([]dnsprovider.Zone, len(hostedZones))
for i, zone := range hostedZones {
zoneList[i] = &Zone{zone, &zones}
}
return zoneList, nil
}
// Package restxml provides RESTful XML serialisation of AWS
// requests and responses.
package restxml
//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/rest-xml.json build_test.go
//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-xml.json unmarshal_test.go
import (
"bytes"
"encoding/xml"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/query"
"github.com/aws/aws-sdk-go/private/protocol/rest"
"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
)
// Build builds a request payload for the REST XML protocol.
func Build(r *request.Request) {
rest.Build(r)
if t := rest.PayloadType(r.Params); t == "structure" || t == "" {
var buf bytes.Buffer
err := xmlutil.BuildXML(r.Params, xml.NewEncoder(&buf))
if err != nil {
r.Error = awserr.New("SerializationError", "failed to encode rest XML request", err)
return
}
r.SetBufferBody(buf.Bytes())
}
}
// Unmarshal unmarshals a payload response for the REST XML protocol.
func Unmarshal(r *request.Request) {
if t := rest.PayloadType(r.Data); t == "structure" || t == "" {
defer r.HTTPResponse.Body.Close()
decoder := xml.NewDecoder(r.HTTPResponse.Body)
err := xmlutil.UnmarshalXML(r.Data, decoder, "")
if err != nil {
r.Error = awserr.New("SerializationError", "failed to decode REST XML response", err)
return
}
} else {
rest.Unmarshal(r)
}
}
// UnmarshalMeta unmarshals response headers for the REST XML protocol.
func UnmarshalMeta(r *request.Request) {
rest.UnmarshalMeta(r)
}
// UnmarshalError unmarshals a response error for the REST XML protocol.
func UnmarshalError(r *request.Request) {
query.UnmarshalError(r)
}
This source diff could not be displayed because it is too large. You can view the blob instead.
package route53
import (
"regexp"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/request"
)
func init() {
initClient = func(c *client.Client) {
c.Handlers.Build.PushBack(sanitizeURL)
}
}
var reSanitizeURL = regexp.MustCompile(`\/%2F\w+%2F`)
func sanitizeURL(r *request.Request) {
r.HTTPRequest.URL.Opaque =
reSanitizeURL.ReplaceAllString(r.HTTPRequest.URL.Opaque, "/")
}
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
package route53
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/restxml"
"github.com/aws/aws-sdk-go/private/signer/v4"
)
// Route53 is a client for Route 53.
//The service client's operations are safe to be used concurrently.
// It is not safe to mutate any of the client's properties though.
type Route53 struct {
*client.Client
}
// Used for custom client initialization logic
var initClient func(*client.Client)
// Used for custom request initialization logic
var initRequest func(*request.Request)
// A ServiceName is the name of the service the client will make API calls to.
const ServiceName = "route53"
// New creates a new instance of the Route53 client with a session.
// If additional configuration is needed for the client instance use the optional
// aws.Config parameter to add your extra config.
//
// Example:
// // Create a Route53 client from just a session.
// svc := route53.New(mySession)
//
// // Create a Route53 client with additional configuration
// svc := route53.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *Route53 {
c := p.ClientConfig(ServiceName, cfgs...)
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
}
// newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *Route53 {
svc := &Route53{
Client: client.New(
cfg,
metadata.ClientInfo{
ServiceName: ServiceName,
SigningRegion: signingRegion,
Endpoint: endpoint,
APIVersion: "2013-04-01",
},
handlers,
),
}
// Handlers
svc.Handlers.Sign.PushBack(v4.Sign)
svc.Handlers.Build.PushBack(restxml.Build)
svc.Handlers.Unmarshal.PushBack(restxml.Unmarshal)
svc.Handlers.UnmarshalMeta.PushBack(restxml.UnmarshalMeta)
svc.Handlers.UnmarshalError.PushBack(restxml.UnmarshalError)
// Run custom client initialization if present
if initClient != nil {
initClient(svc.Client)
}
return svc
}
// newRequest creates a new request for a Route53 operation and runs any
// custom request initialization.
func (c *Route53) newRequest(op *request.Operation, params, data interface{}) *request.Request {
req := c.NewRequest(op, params, data)
// Run custom request initialization if present
if initRequest != nil {
initRequest(req)
}
return req
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment