Merge pull request #1693 from LuxChanLu/gloo-proxy

feat: add gloo proxy source
This commit is contained in:
Kubernetes Prow Robot 2021-03-18 07:51:19 -07:00 committed by GitHub
commit 030d86c201
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 643 additions and 2 deletions

View File

@ -0,0 +1,101 @@
# Configuring ExternalDNS to use the Gloo Proxy Source
This tutorial describes how to configure ExternalDNS to use the Gloo Proxy source.
It is meant to supplement the other provider-specific setup tutorials.
### Manifest (for clusters without RBAC enabled)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
# update this to the desired external-dns version
image: k8s.gcr.io/external-dns/external-dns:v0.7.6
args:
- --source=gloo-proxy
- --gloo-namespace=custom-gloo-system # gloo system namespace. Omit to use the default (gloo-system)
- --provider=aws
- --registry=txt
- --txt-owner-id=my-identifier
```
### Manifest (for clusters with RBAC enabled)
Could be change if you have mulitple sources
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list","watch"]
- apiGroups: ["gloo.solo.io"]
resources: ["proxies"]
verbs: ["get","watch","list"]
- apiGroups: ["gateway.solo.io"]
resources: ["virtualservices"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
# update this to the desired external-dns version
image: k8s.gcr.io/external-dns/external-dns:v0.7.6
args:
- --source=gloo-proxy
- --gloo-namespace=custom-gloo-system # gloo system namespace. Omit to use the default (gloo-system)
- --provider=aws
- --registry=txt
- --txt-owner-id=my-identifier
```

View File

@ -121,6 +121,7 @@ func main() {
CFUsername: cfg.CFUsername,
CFPassword: cfg.CFPassword,
ContourLoadBalancerService: cfg.ContourLoadBalancerService,
GlooNamespace: cfg.GlooNamespace,
SkipperRouteGroupVersion: cfg.SkipperRouteGroupVersion,
RequestTimeout: cfg.RequestTimeout,
}

View File

@ -45,6 +45,7 @@ type Config struct {
KubeConfig string
RequestTimeout time.Duration
ContourLoadBalancerService string
GlooNamespace string
SkipperRouteGroupVersion string
Sources []string
Namespace string
@ -169,6 +170,7 @@ var defaultConfig = &Config{
KubeConfig: "",
RequestTimeout: time.Second * 30,
ContourLoadBalancerService: "heptio-contour/contour",
GlooNamespace: "gloo-system",
SkipperRouteGroupVersion: "zalando.org/v1",
Sources: nil,
Namespace: "",
@ -332,12 +334,14 @@ func (cfg *Config) ParseFlags(args []string) error {
// Flags related to Contour
app.Flag("contour-load-balancer", "The fully-qualified name of the Contour load balancer service. (default: heptio-contour/contour)").Default("heptio-contour/contour").StringVar(&cfg.ContourLoadBalancerService)
// Flags related to Gloo
app.Flag("gloo-namespace", "Gloo namespace. (default: gloo-system)").Default("gloo-system").StringVar(&cfg.GlooNamespace)
// Flags related to Skipper RouteGroup
app.Flag("skipper-routegroup-groupversion", "The resource version for skipper routegroup").Default(source.DefaultRoutegroupVersion).StringVar(&cfg.SkipperRouteGroupVersion)
// 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, node, fake, connector, istio-gateway, istio-virtualservice, cloudfoundry, contour-ingressroute, contour-httpproxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-ingressroute", "contour-httpproxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host")
app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, istio-gateway, istio-virtualservice, cloudfoundry, contour-ingressroute, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-ingressroute", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host")
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("label-filter", "Filter sources managed by external-dns via label selector when listing all resources; currently only supported by source CRD").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter)

View File

@ -35,6 +35,7 @@ var (
KubeConfig: "",
RequestTimeout: time.Second * 30,
ContourLoadBalancerService: "heptio-contour/contour",
GlooNamespace: "gloo-system",
SkipperRouteGroupVersion: "zalando.org/v1",
Sources: []string{"service"},
Namespace: "",
@ -115,6 +116,7 @@ var (
KubeConfig: "/some/path",
RequestTimeout: time.Second * 77,
ContourLoadBalancerService: "heptio-contour-other/contour-other",
GlooNamespace: "gloo-not-system",
SkipperRouteGroupVersion: "zalando.org/v2",
Sources: []string{"service", "ingress", "connector"},
Namespace: "namespace",
@ -222,6 +224,7 @@ func TestParseFlags(t *testing.T) {
"--kubeconfig=/some/path",
"--request-timeout=77s",
"--contour-load-balancer=heptio-contour-other/contour-other",
"--gloo-namespace=gloo-not-system",
"--skipper-routegroup-groupversion=zalando.org/v2",
"--source=service",
"--source=ingress",
@ -320,6 +323,7 @@ func TestParseFlags(t *testing.T) {
"EXTERNAL_DNS_KUBECONFIG": "/some/path",
"EXTERNAL_DNS_REQUEST_TIMEOUT": "77s",
"EXTERNAL_DNS_CONTOUR_LOAD_BALANCER": "heptio-contour-other/contour-other",
"EXTERNAL_DNS_GLOO_NAMESPACE": "gloo-not-system",
"EXTERNAL_DNS_SKIPPER_ROUTEGROUP_GROUPVERSION": "zalando.org/v2",
"EXTERNAL_DNS_SOURCE": "service\ningress\nconnector",
"EXTERNAL_DNS_NAMESPACE": "namespace",

200
source/gloo.go Normal file
View File

@ -0,0 +1,200 @@
/*
Copyright 2020n 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 (
"context"
"encoding/json"
"strings"
log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/external-dns/endpoint"
)
var (
proxyGVR = schema.GroupVersionResource{
Group: "gloo.solo.io",
Version: "v1",
Resource: "proxies",
}
virtualServiceGVR = schema.GroupVersionResource{
Group: "gateway.solo.io",
Version: "v1",
Resource: "virtualservices",
}
)
// Basic redefinition of "Proxy" CRD : https://github.com/solo-io/gloo/blob/v1.4.6/projects/gloo/pkg/api/v1/proxy.pb.go
type proxy struct {
metav1.TypeMeta `json:",inline"`
Metadata metav1.ObjectMeta `json:"metadata,omitempty"`
Spec proxySpec `json:"spec,omitempty"`
}
type proxySpec struct {
Listeners []proxySpecListener `json:"listeners,omitempty"`
}
type proxySpecListener struct {
HTTPListener proxySpecHTTPListener `json:"httpListener,omitempty"`
}
type proxySpecHTTPListener struct {
VirtualHosts []proxyVirtualHost `json:"virtualHosts,omitempty"`
}
type proxyVirtualHost struct {
Domains []string `json:"domains,omitempty"`
Metadata proxyVirtualHostMetadata `json:"metadata,omitempty"`
}
type proxyVirtualHostMetadata struct {
Source []proxyVirtualHostMetadataSource `json:"sources,omitempty"`
}
type proxyVirtualHostMetadataSource struct {
Kind string `json:"kind,omitempty"`
Name string `json:"name,omitempty"`
Namespace string `json:"namespace,omitempty"`
}
type glooSource struct {
dynamicKubeClient dynamic.Interface
kubeClient kubernetes.Interface
glooNamespace string
}
// NewGlooSource creates a new glooSource with the given config
func NewGlooSource(dynamicKubeClient dynamic.Interface, kubeClient kubernetes.Interface, glooNamespace string) (Source, error) {
return &glooSource{
dynamicKubeClient,
kubeClient,
glooNamespace,
}, nil
}
func (gs *glooSource) AddEventHandler(ctx context.Context, handler func()) {
}
// Endpoints returns endpoint objects
func (gs *glooSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
endpoints := []*endpoint.Endpoint{}
proxies, err := gs.dynamicKubeClient.Resource(proxyGVR).Namespace(gs.glooNamespace).List(ctx, metav1.ListOptions{})
if err != nil {
return nil, err
}
for _, obj := range proxies.Items {
proxy := proxy{}
jsonString, err := obj.MarshalJSON()
if err != nil {
return nil, err
}
err = json.Unmarshal(jsonString, &proxy)
if err != nil {
return nil, err
}
log.Debugf("Gloo: Find %s proxy", proxy.Metadata.Name)
proxyTargets, err := gs.proxyTargets(ctx, proxy.Metadata.Name)
if err != nil {
return nil, err
}
log.Debugf("Gloo[%s]: Find %d target(s) (%+v)", proxy.Metadata.Name, len(proxyTargets), proxyTargets)
proxyEndpoints, err := gs.generateEndpointsFromProxy(ctx, &proxy, proxyTargets)
if err != nil {
return nil, err
}
log.Debugf("Gloo[%s]: Generate %d endpoint(s)", proxy.Metadata.Name, len(proxyEndpoints))
endpoints = append(endpoints, proxyEndpoints...)
}
return endpoints, nil
}
func (gs *glooSource) generateEndpointsFromProxy(ctx context.Context, proxy *proxy, targets endpoint.Targets) ([]*endpoint.Endpoint, error) {
endpoints := []*endpoint.Endpoint{}
for _, listener := range proxy.Spec.Listeners {
for _, virtualHost := range listener.HTTPListener.VirtualHosts {
annotations, err := gs.annotationsFromProxySource(ctx, virtualHost)
if err != nil {
return nil, err
}
ttl, err := getTTLFromAnnotations(annotations)
if err != nil {
return nil, err
}
providerSpecific, setIdentifier := getProviderSpecificAnnotations(annotations)
for _, domain := range virtualHost.Domains {
endpoints = append(endpoints, endpointsForHostname(strings.TrimSuffix(domain, "."), targets, ttl, providerSpecific, setIdentifier)...)
}
}
}
return endpoints, nil
}
func (gs *glooSource) annotationsFromProxySource(ctx context.Context, virtualHost proxyVirtualHost) (map[string]string, error) {
annotations := map[string]string{}
for _, src := range virtualHost.Metadata.Source {
kind := sourceKind(src.Kind)
if kind != nil {
source, err := gs.dynamicKubeClient.Resource(*kind).Namespace(src.Namespace).Get(ctx, src.Name, metav1.GetOptions{})
if err != nil {
return nil, err
}
for key, value := range source.GetAnnotations() {
annotations[key] = value
}
}
}
return annotations, nil
}
func (gs *glooSource) proxyTargets(ctx context.Context, name string) (endpoint.Targets, error) {
svc, err := gs.kubeClient.CoreV1().Services(gs.glooNamespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
return nil, err
}
var targets endpoint.Targets
switch svc.Spec.Type {
case corev1.ServiceTypeLoadBalancer:
for _, lb := range svc.Status.LoadBalancer.Ingress {
if lb.IP != "" {
targets = append(targets, lb.IP)
}
if lb.Hostname != "" {
targets = append(targets, lb.Hostname)
}
}
default:
log.WithField("gateway", name).WithField("service", svc).Warn("Gloo: Proxy service type not supported")
}
return targets, nil
}
func sourceKind(kind string) *schema.GroupVersionResource {
switch kind {
case "*v1.VirtualService":
return &virtualServiceGVR
}
return nil
}

320
source/gloo_test.go Normal file
View File

@ -0,0 +1,320 @@
/*
Copyright 2020n 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 (
"context"
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
fakeDynamic "k8s.io/client-go/dynamic/fake"
fakeKube "k8s.io/client-go/kubernetes/fake"
"sigs.k8s.io/external-dns/endpoint"
)
// This is a compile-time validation that glooSource is a Source.
var _ Source = &glooSource{}
const defaultGlooNamespace = "gloo-system"
// Internal proxy test
var internalProxy = proxy{
TypeMeta: metav1.TypeMeta{
APIVersion: proxyGVR.GroupVersion().String(),
Kind: "Proxy",
},
Metadata: metav1.ObjectMeta{
Name: "internal",
Namespace: defaultGlooNamespace,
},
Spec: proxySpec{
Listeners: []proxySpecListener{
{
HTTPListener: proxySpecHTTPListener{
VirtualHosts: []proxyVirtualHost{
{
Domains: []string{"a.test", "b.test"},
Metadata: proxyVirtualHostMetadata{
Source: []proxyVirtualHostMetadataSource{
{
Kind: "*v1.Unknown",
Name: "my-unknown-svc",
Namespace: "unknown",
},
},
},
},
{
Domains: []string{"c.test"},
Metadata: proxyVirtualHostMetadata{
Source: []proxyVirtualHostMetadataSource{
{
Kind: "*v1.VirtualService",
Name: "my-internal-svc",
Namespace: "internal",
},
},
},
},
},
},
},
},
},
}
var internalProxySvc = corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: internalProxy.Metadata.Name,
Namespace: internalProxy.Metadata.Namespace,
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeLoadBalancer,
},
Status: corev1.ServiceStatus{
LoadBalancer: corev1.LoadBalancerStatus{
Ingress: []corev1.LoadBalancerIngress{
corev1.LoadBalancerIngress{
IP: "203.0.113.1",
},
corev1.LoadBalancerIngress{
IP: "203.0.113.2",
},
corev1.LoadBalancerIngress{
IP: "203.0.113.3",
},
},
},
},
}
var internalProxySource = metav1.PartialObjectMetadata{
TypeMeta: metav1.TypeMeta{
APIVersion: virtualServiceGVR.GroupVersion().String(),
Kind: "VirtualService",
},
ObjectMeta: metav1.ObjectMeta{
Name: internalProxy.Spec.Listeners[0].HTTPListener.VirtualHosts[1].Metadata.Source[0].Name,
Namespace: internalProxy.Spec.Listeners[0].HTTPListener.VirtualHosts[1].Metadata.Source[0].Namespace,
Annotations: map[string]string{
"external-dns.alpha.kubernetes.io/ttl": "42",
"external-dns.alpha.kubernetes.io/aws-geolocation-country-code": "LU",
"external-dns.alpha.kubernetes.io/set-identifier": "identifier",
},
},
}
// External proxy test
var externalProxy = proxy{
TypeMeta: metav1.TypeMeta{
APIVersion: proxyGVR.GroupVersion().String(),
Kind: "Proxy",
},
Metadata: metav1.ObjectMeta{
Name: "external",
Namespace: defaultGlooNamespace,
},
Spec: proxySpec{
Listeners: []proxySpecListener{
{
HTTPListener: proxySpecHTTPListener{
VirtualHosts: []proxyVirtualHost{
{
Domains: []string{"d.test"},
Metadata: proxyVirtualHostMetadata{
Source: []proxyVirtualHostMetadataSource{
{
Kind: "*v1.Unknown",
Name: "my-unknown-svc",
Namespace: "unknown",
},
},
},
},
{
Domains: []string{"e.test"},
Metadata: proxyVirtualHostMetadata{
Source: []proxyVirtualHostMetadataSource{
{
Kind: "*v1.VirtualService",
Name: "my-external-svc",
Namespace: "external",
},
},
},
},
},
},
},
},
},
}
var externalProxySvc = corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: externalProxy.Metadata.Name,
Namespace: externalProxy.Metadata.Namespace,
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeLoadBalancer,
},
Status: corev1.ServiceStatus{
LoadBalancer: corev1.LoadBalancerStatus{
Ingress: []corev1.LoadBalancerIngress{
corev1.LoadBalancerIngress{
Hostname: "a.example.org",
},
corev1.LoadBalancerIngress{
Hostname: "b.example.org",
},
corev1.LoadBalancerIngress{
Hostname: "c.example.org",
},
},
},
},
}
var externalProxySource = metav1.PartialObjectMetadata{
TypeMeta: metav1.TypeMeta{
APIVersion: virtualServiceGVR.GroupVersion().String(),
Kind: "VirtualService",
},
ObjectMeta: metav1.ObjectMeta{
Name: externalProxy.Spec.Listeners[0].HTTPListener.VirtualHosts[1].Metadata.Source[0].Name,
Namespace: externalProxy.Spec.Listeners[0].HTTPListener.VirtualHosts[1].Metadata.Source[0].Namespace,
Annotations: map[string]string{
"external-dns.alpha.kubernetes.io/ttl": "24",
"external-dns.alpha.kubernetes.io/aws-geolocation-country-code": "JP",
"external-dns.alpha.kubernetes.io/set-identifier": "identifier-external",
},
},
}
func TestGlooSource(t *testing.T) {
fakeKubernetesClient := fakeKube.NewSimpleClientset()
fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(runtime.NewScheme())
source, err := NewGlooSource(fakeDynamicClient, fakeKubernetesClient, defaultGlooNamespace)
assert.NoError(t, err)
assert.NotNil(t, source)
internalProxyUnstructured := unstructured.Unstructured{}
externalProxyUnstructured := unstructured.Unstructured{}
internalProxySourceUnstructured := unstructured.Unstructured{}
externalProxySourceUnstructured := unstructured.Unstructured{}
internalProxyAsJSON, err := json.Marshal(internalProxy)
assert.NoError(t, err)
externalProxyAsJSON, err := json.Marshal(externalProxy)
assert.NoError(t, err)
internalProxySvcAsJSON, err := json.Marshal(internalProxySource)
assert.NoError(t, err)
externalProxySvcAsJSON, err := json.Marshal(externalProxySource)
assert.NoError(t, err)
assert.NoError(t, internalProxyUnstructured.UnmarshalJSON(internalProxyAsJSON))
assert.NoError(t, externalProxyUnstructured.UnmarshalJSON(externalProxyAsJSON))
assert.NoError(t, internalProxySourceUnstructured.UnmarshalJSON(internalProxySvcAsJSON))
assert.NoError(t, externalProxySourceUnstructured.UnmarshalJSON(externalProxySvcAsJSON))
// Create proxy resources
_, err = fakeDynamicClient.Resource(proxyGVR).Namespace(defaultGlooNamespace).Create(context.Background(), &internalProxyUnstructured, metav1.CreateOptions{})
assert.NoError(t, err)
_, err = fakeDynamicClient.Resource(proxyGVR).Namespace(defaultGlooNamespace).Create(context.Background(), &externalProxyUnstructured, metav1.CreateOptions{})
assert.NoError(t, err)
// Create proxy source
_, err = fakeDynamicClient.Resource(virtualServiceGVR).Namespace(internalProxySource.Namespace).Create(context.Background(), &internalProxySourceUnstructured, metav1.CreateOptions{})
assert.NoError(t, err)
_, err = fakeDynamicClient.Resource(virtualServiceGVR).Namespace(externalProxySource.Namespace).Create(context.Background(), &externalProxySourceUnstructured, metav1.CreateOptions{})
assert.NoError(t, err)
// Create proxy service resources
_, err = fakeKubernetesClient.CoreV1().Services(internalProxySvc.GetNamespace()).Create(context.Background(), &internalProxySvc, metav1.CreateOptions{})
assert.NoError(t, err)
_, err = fakeKubernetesClient.CoreV1().Services(externalProxySvc.GetNamespace()).Create(context.Background(), &externalProxySvc, metav1.CreateOptions{})
assert.NoError(t, err)
endpoints, err := source.Endpoints(context.Background())
assert.NoError(t, err)
assert.Len(t, endpoints, 5)
assert.Equal(t, endpoints, []*endpoint.Endpoint{
&endpoint.Endpoint{
DNSName: "a.test",
Targets: []string{internalProxySvc.Status.LoadBalancer.Ingress[0].IP, internalProxySvc.Status.LoadBalancer.Ingress[1].IP, internalProxySvc.Status.LoadBalancer.Ingress[2].IP},
RecordType: endpoint.RecordTypeA,
RecordTTL: 0,
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{},
},
&endpoint.Endpoint{
DNSName: "b.test",
Targets: []string{internalProxySvc.Status.LoadBalancer.Ingress[0].IP, internalProxySvc.Status.LoadBalancer.Ingress[1].IP, internalProxySvc.Status.LoadBalancer.Ingress[2].IP},
RecordType: endpoint.RecordTypeA,
RecordTTL: 0,
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{},
},
&endpoint.Endpoint{
DNSName: "c.test",
Targets: []string{internalProxySvc.Status.LoadBalancer.Ingress[0].IP, internalProxySvc.Status.LoadBalancer.Ingress[1].IP, internalProxySvc.Status.LoadBalancer.Ingress[2].IP},
RecordType: endpoint.RecordTypeA,
SetIdentifier: "identifier",
RecordTTL: 42,
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
endpoint.ProviderSpecificProperty{
Name: "aws/geolocation-country-code",
Value: "LU",
},
},
},
&endpoint.Endpoint{
DNSName: "d.test",
Targets: []string{externalProxySvc.Status.LoadBalancer.Ingress[0].Hostname, externalProxySvc.Status.LoadBalancer.Ingress[1].Hostname, externalProxySvc.Status.LoadBalancer.Ingress[2].Hostname},
RecordType: endpoint.RecordTypeCNAME,
RecordTTL: 0,
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{},
},
&endpoint.Endpoint{
DNSName: "e.test",
Targets: []string{externalProxySvc.Status.LoadBalancer.Ingress[0].Hostname, externalProxySvc.Status.LoadBalancer.Ingress[1].Hostname, externalProxySvc.Status.LoadBalancer.Ingress[2].Hostname},
RecordType: endpoint.RecordTypeCNAME,
SetIdentifier: "identifier-external",
RecordTTL: 24,
Labels: endpoint.Labels{},
ProviderSpecific: endpoint.ProviderSpecific{
endpoint.ProviderSpecificProperty{
Name: "aws/geolocation-country-code",
Value: "JP",
},
},
},
})
}

View File

@ -61,6 +61,7 @@ type Config struct {
CFUsername string
CFPassword string
ContourLoadBalancerService string
GlooNamespace string
SkipperRouteGroupVersion string
RequestTimeout time.Duration
}
@ -239,6 +240,16 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err
return nil, err
}
return NewContourHTTPProxySource(dynamicClient, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation)
case "gloo-proxy":
kubernetesClient, err := p.KubeClient()
if err != nil {
return nil, err
}
dynamicClient, err := p.DynamicKubernetesClient()
if err != nil {
return nil, err
}
return NewGlooSource(dynamicClient, kubernetesClient, cfg.GlooNamespace)
case "openshift-route":
ocpClient, err := p.OpenShiftClient()
if err != nil {