mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-09-20 23:50:59 +02:00
Add OpenShift route as possible source
This commit is contained in:
parent
2767488552
commit
d476efb02c
2
go.mod
2
go.mod
@ -37,6 +37,8 @@ require (
|
|||||||
github.com/miekg/dns v1.0.14
|
github.com/miekg/dns v1.0.14
|
||||||
github.com/nesv/go-dynect v0.6.0
|
github.com/nesv/go-dynect v0.6.0
|
||||||
github.com/nic-at/rc0go v1.1.0
|
github.com/nic-at/rc0go v1.1.0
|
||||||
|
github.com/openshift/api v0.0.0-20190322043348-8741ff068a47
|
||||||
|
github.com/openshift/client-go v3.9.0+incompatible
|
||||||
github.com/oracle/oci-go-sdk v1.8.0
|
github.com/oracle/oci-go-sdk v1.8.0
|
||||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
|
3
go.sum
3
go.sum
@ -438,7 +438,10 @@ github.com/open-policy-agent/opa v0.8.2/go.mod h1:rlfeSeHuZmMEpmrcGla42AjkOUjP4r
|
|||||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
|
github.com/openshift/api v0.0.0-20190322043348-8741ff068a47 h1:PAlaAXvwmPxgh8gm0/eVmNMGLeJ1bURwyKvJVLnsr6s=
|
||||||
github.com/openshift/api v0.0.0-20190322043348-8741ff068a47/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
|
github.com/openshift/api v0.0.0-20190322043348-8741ff068a47/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
|
||||||
|
github.com/openshift/client-go v3.9.0+incompatible h1:13k3Ok0B7TA2hA3bQW2aFqn6y04JaJWdk7ITTyg+Ek0=
|
||||||
|
github.com/openshift/client-go v3.9.0+incompatible/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk=
|
||||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||||
github.com/operator-framework/operator-sdk v0.7.0/go.mod h1:iVyukRkam5JZa8AnjYf+/G3rk7JI1+M6GsU0sq0B9NA=
|
github.com/operator-framework/operator-sdk v0.7.0/go.mod h1:iVyukRkam5JZa8AnjYf+/G3rk7JI1+M6GsU0sq0B9NA=
|
||||||
|
278
source/ocproute.go
Normal file
278
source/ocproute.go
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 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 (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
routeapi "github.com/openshift/api/route/v1"
|
||||||
|
versioned "github.com/openshift/client-go/route/clientset/versioned"
|
||||||
|
extInformers "github.com/openshift/client-go/route/informers/externalversions"
|
||||||
|
routeInformer "github.com/openshift/client-go/route/informers/externalversions/route/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
|
||||||
|
"sigs.k8s.io/external-dns/endpoint"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ocpRouteSource is an implementation of Source for OpenShift Route objects.
|
||||||
|
// Route implementation will use the spec.host value for the hostname
|
||||||
|
// Use targetAnnotationKey to explicitly set Endpoint. (useful if the router
|
||||||
|
// does not update, or to override with alternative endpoint)
|
||||||
|
type ocpRouteSource struct {
|
||||||
|
client versioned.Interface
|
||||||
|
namespace string
|
||||||
|
annotationFilter string
|
||||||
|
fqdnTemplate *template.Template
|
||||||
|
combineFQDNAnnotation bool
|
||||||
|
ignoreHostnameAnnotation bool
|
||||||
|
routeInformer routeInformer.RouteInformer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOcpRouteSource creates a new ocpRouteSource with the given config.
|
||||||
|
func NewOcpRouteSource(
|
||||||
|
ocpClient versioned.Interface,
|
||||||
|
namespace string,
|
||||||
|
annotationFilter string,
|
||||||
|
fqdnTemplate string,
|
||||||
|
combineFQDNAnnotation bool,
|
||||||
|
ignoreHostnameAnnotation bool,
|
||||||
|
) (Source, error) {
|
||||||
|
var (
|
||||||
|
tmpl *template.Template
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if fqdnTemplate != "" {
|
||||||
|
tmpl, err = template.New("endpoint").Funcs(template.FuncMap{
|
||||||
|
"trimPrefix": strings.TrimPrefix,
|
||||||
|
}).Parse(fqdnTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use shared informer to listen for add/update/delete of Routes in the specified namespace.
|
||||||
|
// Set resync period to 0, to prevent processing when nothing has changed.
|
||||||
|
informerFactory := extInformers.NewFilteredSharedInformerFactory(ocpClient, 0, namespace, nil)
|
||||||
|
routeInformer := informerFactory.Route().V1().Routes()
|
||||||
|
|
||||||
|
// Add default resource event handlers to properly initialize informer.
|
||||||
|
routeInformer.Informer().AddEventHandler(
|
||||||
|
cache.ResourceEventHandlerFuncs{
|
||||||
|
AddFunc: func(obj interface{}) {
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO informer is not explicitly stopped since controller is not passing in its channel.
|
||||||
|
informerFactory.Start(wait.NeverStop)
|
||||||
|
|
||||||
|
// wait for the local cache to be populated.
|
||||||
|
err = wait.Poll(time.Second, 60*time.Second, func() (bool, error) {
|
||||||
|
return routeInformer.Informer().HasSynced() == true, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to sync cache: ${err}")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ocpRouteSource{
|
||||||
|
client: ocpClient,
|
||||||
|
namespace: namespace,
|
||||||
|
annotationFilter: annotationFilter,
|
||||||
|
fqdnTemplate: tmpl,
|
||||||
|
combineFQDNAnnotation: combineFQDNAnnotation,
|
||||||
|
ignoreHostnameAnnotation: ignoreHostnameAnnotation,
|
||||||
|
routeInformer: routeInformer,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Endpoints returns endpoint objects for each host-target combination that should be processed.
|
||||||
|
// Retrieves all OpenShift Route resources on all namespaces
|
||||||
|
func (ors *ocpRouteSource) Endpoints() ([]*endpoint.Endpoint, error) {
|
||||||
|
ocpRoutes, err := ors.routeInformer.Lister().Routes(ors.namespace).List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ocpRoutes, err = ors.filterByAnnotations(ocpRoutes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoints := []*endpoint.Endpoint{}
|
||||||
|
|
||||||
|
for _, ocpRoute := range ocpRoutes {
|
||||||
|
// Check controller annotation to see if we are responsible.
|
||||||
|
controller, ok := ocpRoute.Annotations[controllerAnnotationKey]
|
||||||
|
if ok && controller != controllerAnnotationValue {
|
||||||
|
log.Debugf("Skipping OpenShift Route %s/%s because controller value does not match, found: %s, required: %s",
|
||||||
|
ocpRoute.Namespace, ocpRoute.Name, controller, controllerAnnotationValue)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
orEndpoints := endpointsFromOcpRoute(ocpRoute, ors.ignoreHostnameAnnotation)
|
||||||
|
|
||||||
|
// apply template if host is missing on OpenShift Route
|
||||||
|
if (ors.combineFQDNAnnotation || len(orEndpoints) ==0) && ors.fqdnTemplate != nil {
|
||||||
|
oEndpoints, err := ors.endpointsFromTemplate(ocpRoute)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if ors.combineFQDNAnnotation {
|
||||||
|
orEndpoints = append(orEndpoints, oEndpoints...)
|
||||||
|
} else {
|
||||||
|
orEndpoints = oEndpoints
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(orEndpoints) == 0 {
|
||||||
|
log.Debugf("No endpoints could be generated from OpenShift Route %s/%s", ocpRoute.Namespace, ocpRoute.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Endpoints generated from OpenShift Route: %s/%s: %v", ocpRoute.Namespace, ocpRoute.Name, orEndpoints)
|
||||||
|
ors.setResourceLabel(ocpRoute, orEndpoints)
|
||||||
|
endpoints = append(endpoints, orEndpoints...)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ep := range endpoints {
|
||||||
|
sort.Sort(ep.Targets)
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoints, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ors *ocpRouteSource) endpointsFromTemplate(ocpRoute *routeapi.Route) ([]*endpoint.Endpoint, error) {
|
||||||
|
// Process the whole template string
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := ors.fqdnTemplate.Execute(&buf, ocpRoute)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to apply template on OpenShift Route #{route.String()}: #{err}")
|
||||||
|
}
|
||||||
|
|
||||||
|
hostnames := buf.String()
|
||||||
|
|
||||||
|
ttl, err := getTTLFromAnnotations(ocpRoute.Annotations)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
targets := getTargetsFromTargetAnnotation(ocpRoute.Annotations)
|
||||||
|
|
||||||
|
if len(targets) == 0 {
|
||||||
|
targets = targetsFromOcpRouteStatus(ocpRoute.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
providerSpecific, setIdentifier := getProviderSpecificAnnotations(ocpRoute.Annotations)
|
||||||
|
|
||||||
|
var endpoints []*endpoint.Endpoint
|
||||||
|
// splits the FQDN template and removes the trailing periods
|
||||||
|
hostnameList := strings.Split(strings.Replace(hostnames, " ", "", -1), ",")
|
||||||
|
for _, hostname := range hostnameList {
|
||||||
|
hostname = strings.TrimSuffix(hostname, ".")
|
||||||
|
endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...)
|
||||||
|
}
|
||||||
|
return endpoints, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ors *ocpRouteSource) filterByAnnotations(ocpRoutes []*routeapi.Route) ([]*routeapi.Route, error) {
|
||||||
|
labelSelector, err := metav1.ParseToLabelSelector(ors.annotationFilter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
selector, err := metav1.LabelSelectorAsSelector(labelSelector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty filter returns original list
|
||||||
|
if selector.Empty() {
|
||||||
|
return ocpRoutes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
filteredList := []*routeapi.Route{}
|
||||||
|
|
||||||
|
for _, ocpRoute := range ocpRoutes {
|
||||||
|
// convert the Route's annotations to an equivalent label selector
|
||||||
|
annotations := labels.Set(ocpRoute.Annotations)
|
||||||
|
|
||||||
|
// include ocpRoute if its annotations match the selector
|
||||||
|
if selector.Matches(annotations) {
|
||||||
|
filteredList = append(filteredList, ocpRoute)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ors *ocpRouteSource) setResourceLabel(ocpRoute *routeapi.Route, endpoints []*endpoint.Endpoint) {
|
||||||
|
for _, ep := range endpoints {
|
||||||
|
ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("route/${ocpRoute.Namespace}/${ocpRoute.Name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endpointsFromOcpRoute extracts the endpoints from a OpenShift Route object
|
||||||
|
func endpointsFromOcpRoute(ocpRoute *routeapi.Route, ignoreHostnameAnnotation bool) []*endpoint.Endpoint {
|
||||||
|
var endpoints []*endpoint.Endpoint
|
||||||
|
|
||||||
|
ttl, err := getTTLFromAnnotations(ocpRoute.Annotations)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
targets := getTargetsFromTargetAnnotation(ocpRoute.Annotations)
|
||||||
|
|
||||||
|
if len(targets) == 0 {
|
||||||
|
targets = targetsFromOcpRouteStatus(ocpRoute.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
providerSpecific, setIdentifier := getProviderSpecificAnnotations(ocpRoute.Annotations)
|
||||||
|
|
||||||
|
if host := ocpRoute.Spec.Host; host != "" {
|
||||||
|
endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip endpoints if we do not want entries from annotations
|
||||||
|
if !ignoreHostnameAnnotation {
|
||||||
|
hostnameList := getHostnamesFromAnnotations(ocpRoute.Annotations)
|
||||||
|
for _, hostname := range hostnameList {
|
||||||
|
endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return endpoints
|
||||||
|
}
|
||||||
|
|
||||||
|
func targetsFromOcpRouteStatus(status routeapi.RouteStatus) endpoint.Targets {
|
||||||
|
var targets endpoint.Targets
|
||||||
|
|
||||||
|
for _, ing := range status.Ingress {
|
||||||
|
if ing.Host != "" {
|
||||||
|
targets = append(targets, ing.Host)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return targets
|
||||||
|
}
|
@ -26,6 +26,7 @@ import (
|
|||||||
|
|
||||||
"github.com/cloudfoundry-community/go-cfclient"
|
"github.com/cloudfoundry-community/go-cfclient"
|
||||||
contour "github.com/heptio/contour/apis/generated/clientset/versioned"
|
contour "github.com/heptio/contour/apis/generated/clientset/versioned"
|
||||||
|
openshift "github.com/openshift/client-go/route/clientset/versioned"
|
||||||
"github.com/linki/instrumented_http"
|
"github.com/linki/instrumented_http"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
istiocontroller "istio.io/istio/pilot/pkg/config/kube/crd/controller"
|
istiocontroller "istio.io/istio/pilot/pkg/config/kube/crd/controller"
|
||||||
@ -70,22 +71,25 @@ type ClientGenerator interface {
|
|||||||
IstioClient() (istiomodel.ConfigStore, error)
|
IstioClient() (istiomodel.ConfigStore, error)
|
||||||
CloudFoundryClient(cfAPPEndpoint string, cfUsername string, cfPassword string) (*cfclient.Client, error)
|
CloudFoundryClient(cfAPPEndpoint string, cfUsername string, cfPassword string) (*cfclient.Client, error)
|
||||||
ContourClient() (contour.Interface, error)
|
ContourClient() (contour.Interface, error)
|
||||||
|
OpenShiftClient() (openshift.Interface, 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
|
||||||
// will be generated
|
// will be generated
|
||||||
type SingletonClientGenerator struct {
|
type SingletonClientGenerator struct {
|
||||||
KubeConfig string
|
KubeConfig string
|
||||||
KubeMaster string
|
KubeMaster string
|
||||||
RequestTimeout time.Duration
|
RequestTimeout time.Duration
|
||||||
kubeClient kubernetes.Interface
|
kubeClient kubernetes.Interface
|
||||||
istioClient istiomodel.ConfigStore
|
istioClient istiomodel.ConfigStore
|
||||||
cfClient *cfclient.Client
|
cfClient *cfclient.Client
|
||||||
contourClient contour.Interface
|
contourClient contour.Interface
|
||||||
kubeOnce sync.Once
|
openshiftClient openshift.Interface
|
||||||
istioOnce sync.Once
|
kubeOnce sync.Once
|
||||||
cfOnce sync.Once
|
istioOnce sync.Once
|
||||||
contourOnce sync.Once
|
cfOnce sync.Once
|
||||||
|
contourOnce sync.Once
|
||||||
|
openshiftOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeClient generates a kube client if it was not created before
|
// KubeClient generates a kube client if it was not created before
|
||||||
@ -139,6 +143,14 @@ func (p *SingletonClientGenerator) ContourClient() (contour.Interface, error) {
|
|||||||
return p.contourClient, err
|
return p.contourClient, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *SingletonClientGenerator) OpenShiftClient() (openshift.Interface, error) {
|
||||||
|
var err error
|
||||||
|
p.openshiftOnce.Do(func() {
|
||||||
|
p.openshiftClient, err = NewOpenShiftClient(p.KubeConfig, p.KubeMaster, p.RequestTimeout)
|
||||||
|
})
|
||||||
|
return p.openshiftClient, err
|
||||||
|
}
|
||||||
|
|
||||||
// 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{}
|
||||||
@ -200,6 +212,12 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewContourIngressRouteSource(kubernetesClient, contourClient, cfg.ContourLoadBalancerService, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation)
|
return NewContourIngressRouteSource(kubernetesClient, contourClient, cfg.ContourLoadBalancerService, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation)
|
||||||
|
case "openshift-route":
|
||||||
|
ocpClient, err := p.OpenShiftClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewOcpRouteSource(ocpClient, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation)
|
||||||
case "fake":
|
case "fake":
|
||||||
return NewFakeSource(cfg.FQDNTemplate)
|
return NewFakeSource(cfg.FQDNTemplate)
|
||||||
case "connector":
|
case "connector":
|
||||||
@ -354,3 +372,36 @@ func NewContourClient(kubeConfig, kubeMaster string, requestTimeout time.Duratio
|
|||||||
|
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewOpenShiftClient(kubeConfig, kubeMaster string, requestTimeout time.Duration) (*openshift.Clientset, error) {
|
||||||
|
if kubeConfig == "" {
|
||||||
|
if _, err := os.Stat(clientcmd.RecommendedHomeFile); err == nil {
|
||||||
|
kubeConfig = clientcmd.RecommendedHomeFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := clientcmd.BuildConfigFromFlags(kubeMaster, kubeConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
|
||||||
|
return instrumented_http.NewTransport(rt, &instrumented_http.Callbacks{
|
||||||
|
PathProcessor: func(path string) string {
|
||||||
|
parts := strings.Split(path, "/")
|
||||||
|
return parts[len(parts)-1]
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Timeout = requestTimeout
|
||||||
|
|
||||||
|
client, err := openshift.NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Created OpenShift client %s", config.Host)
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user