Merge pull request #15425 from zetaab/designate

openstack designate fixes
This commit is contained in:
Kubernetes Prow Robot 2023-05-18 05:04:33 -07:00 committed by GitHub
commit f6c8a3a0d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 80 additions and 35 deletions

View File

@ -37,6 +37,7 @@ import (
"k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/aws/route53"
_ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/do"
_ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/google/clouddns"
_ "k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/openstack/designate"
"k8s.io/kops/pkg/wellknownports"
"k8s.io/kops/protokube/pkg/gossip"
gossipdns "k8s.io/kops/protokube/pkg/gossip/dns"
@ -66,7 +67,7 @@ func main() {
flags.BoolVar(&watchIngress, "watch-ingress", true, "Configure hostnames found in ingress resources")
flags.StringSliceVar(&gossipSeeds, "gossip-seed", gossipSeeds, "If set, will enable gossip zones and seed using the provided addresses")
flags.StringSliceVarP(&zones, "zone", "z", []string{}, "Configure permitted zones and their mappings")
flags.StringVar(&dnsProviderID, "dns", "aws-route53", "DNS provider we should use (aws-route53, google-clouddns, digitalocean, gossip)")
flags.StringVar(&dnsProviderID, "dns", "aws-route53", "DNS provider we should use (aws-route53, google-clouddns, digitalocean, gossip, openstack-designate)")
flag.StringVar(&gossipProtocol, "gossip-protocol", "mesh", "mesh/memberlist")
flags.StringVar(&gossipListen, "gossip-listen", fmt.Sprintf("0.0.0.0:%d", wellknownports.DNSControllerGossipWeaveMesh), "The address on which to listen if gossip is enabled")
flags.StringVar(&gossipSecret, "gossip-secret", gossipSecret, "Secret to use to secure gossip")

View File

@ -42,17 +42,16 @@ func init() {
func newDesignate(_ io.Reader) (*Interface, error) {
oc := vfs.OpenstackConfig{}
region, err := oc.GetRegion()
if err != nil {
return nil, fmt.Errorf("error finding openstack region: %v", err)
}
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)
@ -76,11 +75,10 @@ func newDesignate(_ io.Reader) (*Interface, error) {
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)
sc, err := openstack.NewDNSV2(provider, gophercloud.EndpointOpts{
Type: "dns",
Region: region,
})
if err != nil {
return nil, fmt.Errorf("error creating a ServiceClient: %v", err)
}

View File

@ -18,18 +18,17 @@ package openstack
import (
"fmt"
"strings"
"k8s.io/kops/pkg/dns"
"github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets"
"github.com/gophercloud/gophercloud/openstack/dns/v2/zones"
"k8s.io/kops/pkg/resources"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
)
const (
typeDNSRecord = "dNSRecord"
typeDNSRecord = "DNSRecord"
)
func (os *clusterDiscoveryOS) ListDNSRecordsets() ([]*resources.Resource, error) {
@ -38,29 +37,31 @@ func (os *clusterDiscoveryOS) ListDNSRecordsets() ([]*resources.Resource, error)
return nil, nil
}
zopts := zones.ListOpts{
Name: os.clusterName,
}
zs, err := os.osCloud.ListDNSZones(zopts)
zs, err := os.osCloud.ListDNSZones(zones.ListOpts{})
if err != nil {
return nil, fmt.Errorf("failed to list dns zones: %s", err)
}
if len(zs) == 0 {
return nil, fmt.Errorf("dns zone not found: %s", os.clusterName)
var clusterZone zones.Zone
for _, zone := range zs {
if strings.HasSuffix(os.clusterName, strings.TrimSuffix(zone.Name, ".")) {
clusterZone = zone
break
}
}
z := zs[0]
if clusterZone.ID == "" {
return nil, fmt.Errorf("failed to find cluster dns zone")
}
rrs, err := os.osCloud.ListDNSRecordsets(z.ID, nil)
rrs, err := os.osCloud.ListDNSRecordsets(clusterZone.ID, nil)
if err != nil {
return nil, fmt.Errorf("failed to extract recordsets pages for zone %s: %v", z.Name, err)
return nil, fmt.Errorf("failed to extract recordsets pages for zone %s: %v", clusterZone.Name, err)
}
var resourceTrackers []*resources.Resource
for _, rr := range rrs {
if rr.Type != "A" {
if rr.Type != "A" || !strings.HasSuffix(strings.TrimSuffix(rr.Name, "."), os.clusterName) {
continue
}
@ -69,8 +70,7 @@ func (os *clusterDiscoveryOS) ListDNSRecordsets() ([]*resources.Resource, error)
ID: rr.ID,
Type: typeDNSRecord,
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
// TODO: not tested and this should have retry similar to what we have in another resources
return recordsets.Delete(cloud.(openstack.OpenstackCloud).DNSClient(), z.ID, rr.ID).ExtractErr()
return os.osCloud.DeleteDNSRecordset(clusterZone.ID, r.ID)
},
Obj: rr,
}

View File

@ -56,6 +56,10 @@ spec:
env:
- name: KUBERNETES_SERVICE_HOST
value: "127.0.0.1"
{{ range $name, $value := DNSControllerEnvs }}
- name: {{ $name }}
value: {{ $value }}
{{ end }}
{{- if .Networking.EgressProxy }}
{{ range $name, $value := ProxyEnv }}
- name: {{ $name }}

View File

@ -252,6 +252,8 @@ type OpenstackCloud interface {
// ListDNSRecordsets will list the DNS recordsets for the given zone id
ListDNSRecordsets(zoneID string, opt recordsets.ListOptsBuilder) ([]recordsets.RecordSet, error)
DeleteDNSRecordset(zoneID string, rrsetID string) error
GetLB(loadbalancerID string) (*loadbalancers.LoadBalancer, error)
GetLBStats(loadbalancerID string) (*loadbalancers.Stats, error)
CreateLB(opt loadbalancers.CreateOptsBuilder) (*loadbalancers.LoadBalancer, error)
@ -412,13 +414,10 @@ func buildClients(provider *gophercloud.ProviderClient, tags map[string]string,
var dnsClient *gophercloud.ServiceClient
if hasDNS {
// TODO: This should be replaced with the environment variable methods as done above
endpointOpt, err := config.GetServiceConfig("Designate")
if err != nil {
return nil, fmt.Errorf("failed to get service config: %w", err)
}
dnsClient, err = openstack.NewDNSV2(provider, endpointOpt)
dnsClient, err = openstack.NewDNSV2(provider, gophercloud.EndpointOpts{
Type: "dns",
Region: region,
})
if err != nil {
return nil, fmt.Errorf("error building dns client: %w", err)
}

View File

@ -54,6 +54,28 @@ func listDNSZones(c OpenstackCloud, opt zones.ListOptsBuilder) ([]zones.Zone, er
}
}
func deleteDNSRecordset(c OpenstackCloud, zoneID string, rrsetID string) error {
done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
err := recordsets.Delete(c.DNSClient(), zoneID, rrsetID).ExtractErr()
if err != nil {
return false, fmt.Errorf("failed to delete dns recordset: %s", err)
}
return true, nil
})
if err != nil {
return err
} else if done {
return nil
} else {
return wait.ErrWaitTimeout
}
}
// DeleteDNSRecordset will delete single DNS recordset in zone
func (c *openstackCloud) DeleteDNSRecordset(zoneID string, rrsetID string) error {
return deleteDNSRecordset(c, zoneID, rrsetID)
}
// ListDNSRecordsets will list DNS recordsets
func (c *openstackCloud) ListDNSRecordsets(zoneID string, opt recordsets.ListOptsBuilder) ([]recordsets.RecordSet, error) {
return listDNSRecordsets(c, zoneID, opt)

View File

@ -405,6 +405,10 @@ func (c *MockCloud) ListDNSRecordsets(zoneID string, opt recordsets.ListOptsBuil
return listDNSRecordsets(c, zoneID, opt)
}
func (c *MockCloud) DeleteDNSRecordset(zoneID string, rrsetID string) error {
return deleteDNSRecordset(c, zoneID, rrsetID)
}
func (c *MockCloud) ListInstances(opt servers.ListOptsBuilder) ([]servers.Server, error) {
return listInstances(c, opt)
}

View File

@ -166,6 +166,7 @@ func (tf *TemplateFunctions) AddTo(dest template.FuncMap, secretStore fi.SecretS
// will return openstack external ccm image location for current kubernetes version
dest["OpenStackCCMTag"] = tf.OpenStackCCMTag
dest["OpenStackCSITag"] = tf.OpenStackCSITag
dest["DNSControllerEnvs"] = tf.DNSControllerEnvs
dest["ProxyEnv"] = tf.ProxyEnv
dest["KopsSystemEnv"] = tf.KopsSystemEnv
@ -610,6 +611,8 @@ func (tf *TemplateFunctions) DNSControllerArgv() ([]string, error) {
argv = append(argv, "--dns=google-clouddns")
case kops.CloudProviderDO:
argv = append(argv, "--dns=digitalocean")
case kops.CloudProviderOpenstack:
argv = append(argv, "--dns=openstack-designate")
default:
return nil, fmt.Errorf("unhandled cloudprovider %q", cluster.Spec.GetCloudProvider())
@ -807,6 +810,20 @@ func (tf *TemplateFunctions) ExternalDNSArgv() ([]string, error) {
return argv, nil
}
func (tf *TemplateFunctions) DNSControllerEnvs() map[string]string {
if tf.Cluster.Spec.GetCloudProvider() != kops.CloudProviderOpenstack {
return nil
}
envs := env.BuildSystemComponentEnvVars(&tf.Cluster.Spec)
out := make(map[string]string)
for k, v := range envs {
if strings.HasPrefix(k, "OS_") {
out[k] = v
}
}
return out
}
func (tf *TemplateFunctions) ProxyEnv() map[string]string {
cluster := tf.Cluster