mirror of https://github.com/kubernetes/kops.git
openstack designate dns provider
This commit is contained in:
parent
9573ed45c0
commit
83365a992a
|
@ -0,0 +1,27 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"designate.go",
|
||||
"interface.go",
|
||||
"rrchangeset.go",
|
||||
"rrset.go",
|
||||
"rrsets.go",
|
||||
"zone.go",
|
||||
"zones.go",
|
||||
],
|
||||
importpath = "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/openstack/designate",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//dnsprovider/pkg/dnsprovider:go_default_library",
|
||||
"//dnsprovider/pkg/dnsprovider/rrstype:go_default_library",
|
||||
"//util/pkg/vfs:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,67 @@
|
|||
package designate
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/gophercloud/gophercloud/openstack"
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
||||
"k8s.io/kops/util/pkg/vfs"
|
||||
)
|
||||
|
||||
const (
|
||||
// ProviderName is the name of this DNS provider
|
||||
ProviderName = "openstack-designate"
|
||||
)
|
||||
|
||||
func init() {
|
||||
dnsprovider.RegisterDnsProvider(ProviderName, func(config io.Reader) (dnsprovider.Interface, error) {
|
||||
return newDesignate(config)
|
||||
})
|
||||
}
|
||||
|
||||
func newDesignate(_ io.Reader) (*Interface, error) {
|
||||
oc := vfs.OpenstackConfig{}
|
||||
ao, err := oc.GetCredential()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/*
|
||||
pc, err := openstack.AuthenticatedClient(ao)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building openstack authenticated client: %v", err)
|
||||
}*/
|
||||
|
||||
provider, err := openstack.NewClient(ao.IdentityEndpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building openstack provider client: %v", err)
|
||||
}
|
||||
|
||||
tlsconfig := &tls.Config{}
|
||||
tlsconfig.InsecureSkipVerify = true
|
||||
transport := &http.Transport{TLSClientConfig: tlsconfig}
|
||||
provider.HTTPClient = http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
glog.V(2).Info("authenticating to keystone")
|
||||
|
||||
err = openstack.Authenticate(provider, ao)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building openstack authenticated client: %v", err)
|
||||
}
|
||||
|
||||
endpointOpt, err := oc.GetServiceConfig("Designate")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sc, err := openstack.NewDNSV2(provider, endpointOpt)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
return New(sc), nil
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package designate
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
||||
)
|
||||
|
||||
var _ dnsprovider.Interface = Interface{}
|
||||
|
||||
type Interface struct {
|
||||
sc *gophercloud.ServiceClient
|
||||
}
|
||||
|
||||
// New builds an Interface, with a specified Designate implementation.
|
||||
// This is useful for testing purposes, but also if we want an instance with custom OpenStack options.
|
||||
func New(sc *gophercloud.ServiceClient) *Interface {
|
||||
return &Interface{sc}
|
||||
}
|
||||
|
||||
func (i Interface) Zones() (zones dnsprovider.Zones, supported bool) {
|
||||
return Zones{&i}, true
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
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 designate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets"
|
||||
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (c *ResourceRecordChangeset) Apply() error {
|
||||
zoneID := c.zone.impl.ID
|
||||
|
||||
for _, removal := range c.removals {
|
||||
rrID, err := c.nameToID(removal.Name())
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
err = recordsets.Delete(c.zone.zones.iface.sc, zoneID, rrID).ExtractErr()
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for _, addition := range c.additions {
|
||||
opts := recordsets.CreateOpts{
|
||||
Name: addition.Name(),
|
||||
TTL: int(addition.Ttl()),
|
||||
Type: string(addition.Type()),
|
||||
Records: addition.Rrdatas(),
|
||||
}
|
||||
_, err := recordsets.Create(c.zone.zones.iface.sc, zoneID, opts).Extract()
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for _, upsert := range c.upserts {
|
||||
rrID, err := c.nameToID(upsert.Name())
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
uopts := recordsets.UpdateOpts{
|
||||
TTL: int(upsert.Ttl()),
|
||||
Records: upsert.Rrdatas(),
|
||||
}
|
||||
_, err = recordsets.Update(c.zone.zones.iface.sc, zoneID, rrID, uopts).Extract()
|
||||
if err != nil {
|
||||
copts := recordsets.CreateOpts{
|
||||
Name: upsert.Name(),
|
||||
TTL: int(upsert.Ttl()),
|
||||
Type: string(upsert.Type()),
|
||||
Records: upsert.Rrdatas(),
|
||||
}
|
||||
_, err := recordsets.Create(c.zone.zones.iface.sc, zoneID, copts).Extract()
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ResourceRecordChangeset) IsEmpty() bool {
|
||||
return len(c.removals) == 0 && len(c.additions) == 0 && len(c.upserts) == 0
|
||||
}
|
||||
|
||||
// ResourceRecordSets returns the parent ResourceRecordSets
|
||||
func (c *ResourceRecordChangeset) ResourceRecordSets() dnsprovider.ResourceRecordSets {
|
||||
return c.rrsets
|
||||
}
|
||||
|
||||
func (c *ResourceRecordChangeset) nameToID(name string) (string, error) {
|
||||
opts := recordsets.ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
allPages, err := recordsets.ListByZone(c.zone.zones.iface.sc, c.zone.impl.ID, opts).AllPages()
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
rrs, err := recordsets.ExtractRecordSets(allPages)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
switch len(rrs) {
|
||||
case 0:
|
||||
return "", fmt.Errorf("couldn't find recordset with name: %s, expected 1", name)
|
||||
case 1:
|
||||
return rrs[0].ID, nil
|
||||
default:
|
||||
return "", fmt.Errorf("found multiple recordsets with name: %s, expected 1", name)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
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 designate
|
||||
|
||||
import (
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets"
|
||||
)
|
||||
|
||||
var _ dnsprovider.ResourceRecordSet = ResourceRecordSet{}
|
||||
|
||||
type ResourceRecordSet struct {
|
||||
impl *recordsets.RecordSet
|
||||
rrsets *ResourceRecordSets
|
||||
}
|
||||
|
||||
func (rrset ResourceRecordSet) Name() string {
|
||||
return rrset.impl.Name
|
||||
}
|
||||
|
||||
func (rrset ResourceRecordSet) Rrdatas() []string {
|
||||
return rrset.impl.Records
|
||||
}
|
||||
|
||||
func (rrset ResourceRecordSet) Ttl() int64 {
|
||||
return int64(rrset.impl.TTL)
|
||||
}
|
||||
|
||||
func (rrset ResourceRecordSet) Type() rrstype.RrsType {
|
||||
return rrstype.RrsType(rrset.impl.Type)
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
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 designate
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider/rrstype"
|
||||
)
|
||||
|
||||
var _ dnsprovider.ResourceRecordSets = ResourceRecordSets{}
|
||||
|
||||
type ResourceRecordSets struct {
|
||||
zone *Zone
|
||||
}
|
||||
|
||||
func (rrsets ResourceRecordSets) List() ([]dnsprovider.ResourceRecordSet, error) {
|
||||
var list []dnsprovider.ResourceRecordSet
|
||||
err := recordsets.ListByZone(rrsets.zone.zones.iface.sc, rrsets.zone.impl.ID, nil).EachPage(func(page pagination.Page) (bool, error) {
|
||||
rrs, err := recordsets.ExtractRecordSets(page)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, rr := range rrs {
|
||||
list = append(list, &ResourceRecordSet{&rr, &rrsets})
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
return list, err
|
||||
}
|
||||
|
||||
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`.
|
||||
opts := &recordsets.ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
var list []dnsprovider.ResourceRecordSet
|
||||
err := recordsets.ListByZone(rrsets.zone.zones.iface.sc, rrsets.zone.impl.ID, opts).EachPage(func(page pagination.Page) (bool, error) {
|
||||
rrs, err := recordsets.ExtractRecordSets(page)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, rr := range rrs {
|
||||
list = append(list, &ResourceRecordSet{&rr, &rrsets})
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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 {
|
||||
rrs := &recordsets.RecordSet{
|
||||
Name: name,
|
||||
Type: string(rrstype),
|
||||
TTL: int(ttl),
|
||||
}
|
||||
for _, rrdata := range rrdatas {
|
||||
rrs.Records = append(rrs.Records, string(rrdata))
|
||||
}
|
||||
|
||||
return ResourceRecordSet{
|
||||
rrs,
|
||||
&rrsets,
|
||||
}
|
||||
}
|
||||
|
||||
// Zone returns the parent zone
|
||||
func (rrset ResourceRecordSets) Zone() dnsprovider.Zone {
|
||||
return rrset.zone
|
||||
}
|
|
@ -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 designate
|
||||
|
||||
import (
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/dns/v2/zones"
|
||||
)
|
||||
|
||||
var _ dnsprovider.Zone = &Zone{}
|
||||
|
||||
type Zone struct {
|
||||
impl zones.Zone
|
||||
zones *Zones
|
||||
}
|
||||
|
||||
func (z *Zone) Name() string {
|
||||
return z.impl.Name
|
||||
}
|
||||
|
||||
func (z *Zone) ID() string {
|
||||
return z.impl.ID
|
||||
}
|
||||
|
||||
func (z *Zone) ResourceRecordSets() (dnsprovider.ResourceRecordSets, bool) {
|
||||
return &ResourceRecordSets{z}, true
|
||||
}
|
|
@ -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.
|
||||
*/
|
||||
|
||||
package designate
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud/openstack/dns/v2/zones"
|
||||
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
||||
)
|
||||
|
||||
var _ dnsprovider.Zones = Zones{}
|
||||
|
||||
type Zones struct {
|
||||
iface *Interface
|
||||
}
|
||||
|
||||
func (kzs Zones) List() ([]dnsprovider.Zone, error) {
|
||||
var zoneList []dnsprovider.Zone
|
||||
|
||||
allPages, err := zones.List(kzs.iface.sc, nil).AllPages()
|
||||
if err != nil {
|
||||
return zoneList, err
|
||||
}
|
||||
zs, err := zones.ExtractZones(allPages)
|
||||
if err != nil {
|
||||
return zoneList, err
|
||||
}
|
||||
for _, z := range zs {
|
||||
kz := &Zone{
|
||||
impl: z,
|
||||
zones: &kzs,
|
||||
}
|
||||
zoneList = append(zoneList, kz)
|
||||
}
|
||||
return zoneList, nil
|
||||
}
|
||||
|
||||
func (kzs Zones) Add(zone dnsprovider.Zone) (dnsprovider.Zone, error) {
|
||||
opts := &zones.CreateOpts{Name: zone.Name()}
|
||||
z, err := zones.Create(kzs.iface.sc, opts).Extract()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Zone{
|
||||
impl: *z,
|
||||
zones: &kzs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (kzs Zones) Remove(zone dnsprovider.Zone) error {
|
||||
_, err := zones.Delete(kzs.iface.sc, zone.ID()).Extract()
|
||||
return err
|
||||
}
|
||||
|
||||
func (kzs Zones) New(name string) (dnsprovider.Zone, error) {
|
||||
zone := zones.Zone{Name: name}
|
||||
return &Zone{zone, &kzs}, nil
|
||||
}
|
Loading…
Reference in New Issue