Add unit test for zone addition to all dnsproviders. Fixes #27785

This commit is contained in:
Quinton Hoole 2016-06-21 16:11:27 -07:00
parent 9122e745b6
commit 37ce95e107
8 changed files with 112 additions and 19 deletions

View File

@ -29,6 +29,8 @@ type Zones interface {
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)

View File

@ -32,7 +32,7 @@ import (
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 dnsprovider.GetDnsProvider(ProviderName, strings.NewReader("\n[global]\nproject-id = federation0-cluster00"))
return newFakeInterface() // Use this to stub out the entire cloud service
}
@ -68,16 +68,23 @@ func TestMain(m *testing.M) {
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, supported := interface_.Zones()
if supported {
t.Logf("Got zones %v\n", z)
} else {
t.Fatalf("Zones interface not supported by interface %v", interface_)
}
z := zones(t)
zones, err := z.List()
if err != nil {
t.Fatalf("Failed to list zones: %v", err)
@ -139,6 +146,28 @@ func TestZonesList(t *testing.T) {
firstZone(t)
}
/* 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)))

View File

@ -31,6 +31,7 @@ type Route53API interface {
ChangeResourceRecordSets(*route53.ChangeResourceRecordSetsInput) (*route53.ChangeResourceRecordSetsOutput, error)
ListHostedZones(*route53.ListHostedZonesInput) (*route53.ListHostedZonesOutput, 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.
@ -110,3 +111,14 @@ func (r *Route53APIStub) CreateHostedZone(input *route53.CreateHostedZoneInput)
}
return &route53.CreateHostedZoneOutput{HostedZone: r.zones[*input.Name]}, 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
}

View File

@ -48,7 +48,8 @@ func (zones Zones) List() ([]dnsprovider.Zone, error) {
func (zones Zones) Add(zone dnsprovider.Zone) (dnsprovider.Zone, error) {
dnsName := zone.Name()
input := route53.CreateHostedZoneInput{Name: &dnsName}
callerReference := string(util.NewUUID())
input := route53.CreateHostedZoneInput{Name: &dnsName, CallerReference: &callerReference}
output, err := zones.interface_.service.CreateHostedZone(&input)
if err != nil {
return nil, err
@ -56,6 +57,15 @@ func (zones Zones) Add(zone dnsprovider.Zone) (dnsprovider.Zone, error) {
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(util.NewUUID())
managedZone := route53.HostedZone{Id: &id, Name: &name}

View File

@ -29,7 +29,7 @@ import (
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.
// i, err := dnsprovider.GetDnsProvider(ProviderName, strings.NewReader("\n[global]\nproject-id = federation0-cluster00"))
// return dnsprovider.GetDnsProvider(ProviderName, strings.NewReader("\n[global]\nproject-id = federation0-cluster00"))
return NewFakeInterface() // Use this to stub out the entire cloud service
}
@ -46,17 +46,23 @@ func TestMain(m *testing.M) {
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, 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()
zones, err := zones(t).List()
if err != nil {
t.Fatalf("Failed to list zones: %v", err)
} else {
@ -117,6 +123,30 @@ func TestZonesList(t *testing.T) {
firstZone(t)
}
/* 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)))

View File

@ -28,5 +28,5 @@ var _ interfaces.ManagedZonesDeleteCall = ManagedZonesDeleteCall{}
type ManagedZonesDeleteCall struct{ impl *dns.ManagedZonesDeleteCall }
func (call ManagedZonesDeleteCall) Do(opts ...googleapi.CallOption) error {
return call.Do(opts...)
return call.impl.Do(opts...)
}

View File

@ -17,6 +17,8 @@ limitations under the License.
package internal
import (
"strings"
dns "google.golang.org/api/dns/v1"
"k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns/internal/interfaces"
"k8s.io/kubernetes/pkg/util"
@ -28,7 +30,7 @@ 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)}
return &ManagedZonesCreateCall{m.impl.Create(project, managedzone.(*ManagedZone).impl)}
}
func (m *ManagedZonesService) Delete(project, managedZone string) interfaces.ManagedZonesDeleteCall {
@ -44,5 +46,6 @@ func (m *ManagedZonesService) List(project string) interfaces.ManagedZonesListCa
}
func (m *ManagedZonesService) NewManagedZone(dnsName string) interfaces.ManagedZone {
return &ManagedZone{impl: &dns.ManagedZone{Name: string(util.NewUUID()), DnsName: dnsName}}
name := "x" + strings.Replace(string(util.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}}
}

View File

@ -51,6 +51,13 @@ func (zones Zones) Add(zone dnsprovider.Zone) (dnsprovider.Zone, error) {
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