mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 17:46:57 +02:00
Add Cloud Foundry routes as a source
This commit is contained in:
parent
3b44e39262
commit
b529a92d5b
3
main.go
3
main.go
@ -82,6 +82,9 @@ func main() {
|
|||||||
KubeMaster: cfg.Master,
|
KubeMaster: cfg.Master,
|
||||||
ServiceTypeFilter: cfg.ServiceTypeFilter,
|
ServiceTypeFilter: cfg.ServiceTypeFilter,
|
||||||
IstioIngressGatewayServices: cfg.IstioIngressGatewayServices,
|
IstioIngressGatewayServices: cfg.IstioIngressGatewayServices,
|
||||||
|
CFAPIEndpoint: cfg.CFAPIEndpoint,
|
||||||
|
CFUsername: cfg.CFUsername,
|
||||||
|
CFPassword: cfg.CFPassword,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup all the selected sources by names and pass them the desired configuration.
|
// Lookup all the selected sources by names and pass them the desired configuration.
|
||||||
|
@ -105,6 +105,9 @@ type Config struct {
|
|||||||
CRDSourceAPIVersion string
|
CRDSourceAPIVersion string
|
||||||
CRDSourceKind string
|
CRDSourceKind string
|
||||||
ServiceTypeFilter []string
|
ServiceTypeFilter []string
|
||||||
|
CFAPIEndpoint string
|
||||||
|
CFUsername string
|
||||||
|
CFPassword string
|
||||||
RFC2136Host string
|
RFC2136Host string
|
||||||
RFC2136Port int
|
RFC2136Port int
|
||||||
RFC2136Zone string
|
RFC2136Zone string
|
||||||
@ -182,6 +185,9 @@ var defaultConfig = &Config{
|
|||||||
CRDSourceAPIVersion: "externaldns.k8s.io/v1alpha1",
|
CRDSourceAPIVersion: "externaldns.k8s.io/v1alpha1",
|
||||||
CRDSourceKind: "DNSEndpoint",
|
CRDSourceKind: "DNSEndpoint",
|
||||||
ServiceTypeFilter: []string{},
|
ServiceTypeFilter: []string{},
|
||||||
|
CFAPIEndpoint: "",
|
||||||
|
CFUsername: "",
|
||||||
|
CFPassword: ""
|
||||||
RFC2136Host: "",
|
RFC2136Host: "",
|
||||||
RFC2136Port: 0,
|
RFC2136Port: 0,
|
||||||
RFC2136Zone: "",
|
RFC2136Zone: "",
|
||||||
@ -245,8 +251,13 @@ func (cfg *Config) ParseFlags(args []string) error {
|
|||||||
// Flags related to Istio
|
// Flags related to Istio
|
||||||
app.Flag("istio-ingress-gateway", "The fully-qualified name of the Istio ingress gateway service. Flag can be specified multiple times (default: istio-system/istio-ingressgateway)").Default("istio-system/istio-ingressgateway").StringsVar(&cfg.IstioIngressGatewayServices)
|
app.Flag("istio-ingress-gateway", "The fully-qualified name of the Istio ingress gateway service. Flag can be specified multiple times (default: istio-system/istio-ingressgateway)").Default("istio-system/istio-ingressgateway").StringsVar(&cfg.IstioIngressGatewayServices)
|
||||||
|
|
||||||
|
// Flags related to cloud foundry
|
||||||
|
app.Flag("cf-api-endpoint", "The fully-qualified domain name of the cloud foundry instance you are targeting").Default(defaultConfig.CFAPIEndpoint).StringVar(&cfg.CFAPIEndpoint)
|
||||||
|
app.Flag("cf-username", "The username to log into the cloud foundry API").Default(defaultConfig.CFUsername).StringVar(&cfg.CFUsername)
|
||||||
|
app.Flag("cf-password", "The password to log into the cloud foundry API").Default(defaultConfig.CFPassword).StringVar(&cfg.CFPassword)
|
||||||
|
|
||||||
// Flags related to processing sources
|
// Flags related to processing sources
|
||||||
app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, fake, connector, istio-gateway, crd").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "istio-gateway", "fake", "connector", "crd")
|
app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, fake, connector, istio-gateway, crd").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "istio-gateway", "route", "fake", "connector", "crd")
|
||||||
app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
|
app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
|
||||||
app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
|
app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
|
||||||
app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate)
|
app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate)
|
||||||
|
58
source/route.go
Normal file
58
source/route.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 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 source
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
cfclient "github.com/cloudfoundry-community/go-cfclient"
|
||||||
|
"github.com/kubernetes-incubator/external-dns/endpoint"
|
||||||
|
)
|
||||||
|
|
||||||
|
type routeSource struct {
|
||||||
|
client *cfclient.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRouteSource creates a new routeSource with the given config
|
||||||
|
func NewRouteSource(cfClient *cfclient.Client) (Source, error) {
|
||||||
|
return &routeSource{
|
||||||
|
client: cfClient,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Endpoints returns endpoint objects
|
||||||
|
func (rs *routeSource) Endpoints() ([]*endpoint.Endpoint, error) {
|
||||||
|
endpoints := []*endpoint.Endpoint{}
|
||||||
|
|
||||||
|
u, err := url.Parse(rs.client.Config.ApiAddress)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
domains, _ := rs.client.ListDomains()
|
||||||
|
for _, domain := range domains {
|
||||||
|
q := url.Values{}
|
||||||
|
q.Set("q", "domain_guid:"+domain.Guid)
|
||||||
|
routes, _ := rs.client.ListRoutesByQuery(q)
|
||||||
|
for _, element := range routes {
|
||||||
|
endpoints = append(endpoints,
|
||||||
|
endpoint.NewEndpointWithTTL(element.Host+"."+domain.Name, endpoint.RecordTypeCNAME, 300, u.Host))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoints, nil
|
||||||
|
}
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
cfclient "github.com/cloudfoundry-community/go-cfclient"
|
||||||
"github.com/linki/instrumented_http"
|
"github.com/linki/instrumented_http"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
istiocrd "istio.io/istio/pilot/pkg/config/kube/crd"
|
istiocrd "istio.io/istio/pilot/pkg/config/kube/crd"
|
||||||
@ -53,12 +54,16 @@ type Config struct {
|
|||||||
KubeMaster string
|
KubeMaster string
|
||||||
ServiceTypeFilter []string
|
ServiceTypeFilter []string
|
||||||
IstioIngressGatewayServices []string
|
IstioIngressGatewayServices []string
|
||||||
|
CFAPIEndpoint string
|
||||||
|
CFUsername string
|
||||||
|
CFPassword string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientGenerator provides clients
|
// ClientGenerator provides clients
|
||||||
type ClientGenerator interface {
|
type ClientGenerator interface {
|
||||||
KubeClient() (kubernetes.Interface, error)
|
KubeClient() (kubernetes.Interface, error)
|
||||||
IstioClient() (istiomodel.ConfigStore, error)
|
IstioClient() (istiomodel.ConfigStore, error)
|
||||||
|
CloudFoundryClient(cfAPPEndpoint string, cfUsername string, cfPassword string) (*cfclient.Client, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SingletonClientGenerator stores provider clients and guarantees that only one instance of client
|
// SingletonClientGenerator stores provider clients and guarantees that only one instance of client
|
||||||
@ -69,8 +74,10 @@ type SingletonClientGenerator struct {
|
|||||||
RequestTimeout time.Duration
|
RequestTimeout time.Duration
|
||||||
kubeClient kubernetes.Interface
|
kubeClient kubernetes.Interface
|
||||||
istioClient istiomodel.ConfigStore
|
istioClient istiomodel.ConfigStore
|
||||||
|
cfClient *cfclient.Client
|
||||||
kubeOnce sync.Once
|
kubeOnce sync.Once
|
||||||
istioOnce sync.Once
|
istioOnce sync.Once
|
||||||
|
cfOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeClient generates a kube client if it was not created before
|
// KubeClient generates a kube client if it was not created before
|
||||||
@ -91,6 +98,27 @@ func (p *SingletonClientGenerator) IstioClient() (istiomodel.ConfigStore, error)
|
|||||||
return p.istioClient, err
|
return p.istioClient, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloudFoundryClient generates a cf client if it was not created before
|
||||||
|
func (p *SingletonClientGenerator) CloudFoundryClient(cfAPIEndpoint string, cfUsername string, cfPassword string) (*cfclient.Client, error) {
|
||||||
|
var err error
|
||||||
|
p.cfOnce.Do(func() {
|
||||||
|
p.cfClient, err = NewCFClient(cfAPIEndpoint, cfUsername, cfPassword)
|
||||||
|
})
|
||||||
|
return p.cfClient, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCFClient return a new CF client object.
|
||||||
|
func NewCFClient(cfAPIEndpoint string, cfUsername string, cfPassword string) (*cfclient.Client, error) {
|
||||||
|
c := &cfclient.Config{
|
||||||
|
ApiAddress: "https://" + cfAPIEndpoint,
|
||||||
|
Username: cfUsername,
|
||||||
|
Password: cfPassword,
|
||||||
|
}
|
||||||
|
client, _ := cfclient.NewClient(c)
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ByNames returns multiple Sources given multiple names.
|
// ByNames returns multiple Sources given multiple names.
|
||||||
func ByNames(p ClientGenerator, names []string, cfg *Config) ([]Source, error) {
|
func ByNames(p ClientGenerator, names []string, cfg *Config) ([]Source, error) {
|
||||||
sources := []Source{}
|
sources := []Source{}
|
||||||
@ -130,6 +158,12 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewIstioGatewaySource(kubernetesClient, istioClient, cfg.IstioIngressGatewayServices, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation)
|
return NewIstioGatewaySource(kubernetesClient, istioClient, cfg.IstioIngressGatewayServices, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation)
|
||||||
|
case "route":
|
||||||
|
cfClient, err := p.CloudFoundryClient(cfg.CFAPIEndpoint, cfg.CFUsername, cfg.CFPassword)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewRouteSource(cfClient)
|
||||||
case "fake":
|
case "fake":
|
||||||
return NewFakeSource(cfg.FQDNTemplate)
|
return NewFakeSource(cfg.FQDNTemplate)
|
||||||
case "connector":
|
case "connector":
|
||||||
|
Loading…
Reference in New Issue
Block a user