mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2026-05-04 14:21:33 +02:00
feat: Add F5 TransportServer source
This commit is contained in:
parent
560c5aebbf
commit
2ea4a15075
@ -422,7 +422,7 @@ func (cfg *Config) ParseFlags(args []string) error {
|
||||
app.Flag("skipper-routegroup-groupversion", "The resource version for skipper routegroup").Default(source.DefaultRoutegroupVersion).StringVar(&cfg.SkipperRouteGroupVersion)
|
||||
|
||||
// Flags related to processing source
|
||||
app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, pod, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver, traefik-proxy)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-grpcroute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress", "f5-virtualserver", "traefik-proxy")
|
||||
app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, pod, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver, f5-transportserver, traefik-proxy)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-grpcroute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress", "f5-virtualserver", "f5-transportserver", "traefik-proxy")
|
||||
app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName)
|
||||
app.Flag("namespace", "Limit resources queried for endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
|
||||
app.Flag("annotation-filter", "Filter resources queried for endpoints by annotation, using label selector semantics").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
|
||||
|
||||
213
source/f5_transportserver.go
Normal file
213
source/f5_transportserver.go
Normal file
@ -0,0 +1,213 @@
|
||||
/*
|
||||
Copyright 2022 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"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/dynamic/dynamicinformer"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
f5 "github.com/F5Networks/k8s-bigip-ctlr/v2/config/apis/cis/v1"
|
||||
|
||||
"sigs.k8s.io/external-dns/endpoint"
|
||||
)
|
||||
|
||||
var f5TransportServerGVR = schema.GroupVersionResource{
|
||||
Group: "cis.f5.com",
|
||||
Version: "v1",
|
||||
Resource: "transportservers",
|
||||
}
|
||||
|
||||
// transportServerSource is an implementation of Source for F5 TransportServer objects.
|
||||
type f5TransportServerSource struct {
|
||||
dynamicKubeClient dynamic.Interface
|
||||
transportServerInformer informers.GenericInformer
|
||||
kubeClient kubernetes.Interface
|
||||
annotationFilter string
|
||||
namespace string
|
||||
unstructuredConverter *unstructuredConverter
|
||||
}
|
||||
|
||||
func NewF5TransportServerSource(
|
||||
ctx context.Context,
|
||||
dynamicKubeClient dynamic.Interface,
|
||||
kubeClient kubernetes.Interface,
|
||||
namespace string,
|
||||
annotationFilter string,
|
||||
) (Source, error) {
|
||||
informerFactory := dynamicinformer.NewFilteredDynamicSharedInformerFactory(dynamicKubeClient, 0, namespace, nil)
|
||||
transportServerInformer := informerFactory.ForResource(f5TransportServerGVR)
|
||||
|
||||
transportServerInformer.Informer().AddEventHandler(
|
||||
cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
informerFactory.Start(ctx.Done())
|
||||
|
||||
// wait for the local cache to be populated.
|
||||
if err := waitForDynamicCacheSync(context.Background(), informerFactory); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
uc, err := newTSUnstructuredConverter()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to setup unstructured converter")
|
||||
}
|
||||
|
||||
return &f5TransportServerSource{
|
||||
dynamicKubeClient: dynamicKubeClient,
|
||||
transportServerInformer: transportServerInformer,
|
||||
kubeClient: kubeClient,
|
||||
namespace: namespace,
|
||||
annotationFilter: annotationFilter,
|
||||
unstructuredConverter: uc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Endpoints returns endpoint objects for each host-target combination that should be processed.
|
||||
// Retrieves all TransportServers in the source's namespace(s).
|
||||
func (ts *f5TransportServerSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
|
||||
transportServerObjects, err := ts.transportServerInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var transportServers []*f5.TransportServer
|
||||
for _, tsObj := range transportServerObjects {
|
||||
unstructuredHost, ok := tsObj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return nil, errors.New("could not convert")
|
||||
}
|
||||
|
||||
transportServer := &f5.TransportServer{}
|
||||
err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, transportServer, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transportServers = append(transportServers, transportServer)
|
||||
}
|
||||
|
||||
transportServers, err = ts.filterByAnnotations(transportServers)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to filter TransportServers")
|
||||
}
|
||||
|
||||
endpoints, err := ts.endpointsFromTransportServers(transportServers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Sort endpoints
|
||||
for _, ep := range endpoints {
|
||||
sort.Sort(ep.Targets)
|
||||
}
|
||||
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
func (ts *f5TransportServerSource) AddEventHandler(ctx context.Context, handler func()) {
|
||||
log.Debug("Adding event handler for TransportServer")
|
||||
|
||||
ts.transportServerInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
|
||||
}
|
||||
|
||||
// endpointsFromTransportServers extracts the endpoints from a slice of TransportServers
|
||||
func (ts *f5TransportServerSource) endpointsFromTransportServers(transportServers []*f5.TransportServer) ([]*endpoint.Endpoint, error) {
|
||||
var endpoints []*endpoint.Endpoint
|
||||
|
||||
for _, transportServer := range transportServers {
|
||||
resource := fmt.Sprintf("f5-transportserver/%s/%s", transportServer.Namespace, transportServer.Name)
|
||||
|
||||
ttl := getTTLFromAnnotations(transportServer.Annotations, resource)
|
||||
|
||||
targets := getTargetsFromTargetAnnotation(transportServer.Annotations)
|
||||
if len(targets) == 0 && transportServer.Spec.VirtualServerAddress != "" {
|
||||
targets = append(targets, transportServer.Spec.VirtualServerAddress)
|
||||
}
|
||||
if len(targets) == 0 && transportServer.Status.VSAddress != "" {
|
||||
targets = append(targets, transportServer.Status.VSAddress)
|
||||
}
|
||||
|
||||
endpoints = append(endpoints, endpointsForHostname(transportServer.Spec.Host, targets, ttl, nil, "", resource)...)
|
||||
}
|
||||
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
// newUnstructuredConverter returns a new unstructuredConverter initialized
|
||||
func newTSUnstructuredConverter() (*unstructuredConverter, error) {
|
||||
uc := &unstructuredConverter{
|
||||
scheme: runtime.NewScheme(),
|
||||
}
|
||||
|
||||
// Add the core types we need
|
||||
uc.scheme.AddKnownTypes(f5TransportServerGVR.GroupVersion(), &f5.TransportServer{}, &f5.TransportServerList{})
|
||||
if err := scheme.AddToScheme(uc.scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return uc, nil
|
||||
}
|
||||
|
||||
// filterByAnnotations filters a list of TransportServers by a given annotation selector.
|
||||
func (ts *f5TransportServerSource) filterByAnnotations(transportServers []*f5.TransportServer) ([]*f5.TransportServer, error) {
|
||||
labelSelector, err := metav1.ParseToLabelSelector(ts.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 transportServers, nil
|
||||
}
|
||||
|
||||
filteredList := []*f5.TransportServer{}
|
||||
|
||||
for _, ts := range transportServers {
|
||||
// convert the TransportServer's annotations to an equivalent label selector
|
||||
annotations := labels.Set(ts.Annotations)
|
||||
|
||||
// include TransportServer if its annotations match the selector
|
||||
if selector.Matches(annotations) {
|
||||
filteredList = append(filteredList, ts)
|
||||
}
|
||||
}
|
||||
|
||||
return filteredList, nil
|
||||
}
|
||||
285
source/f5_transportserver_test.go
Normal file
285
source/f5_transportserver_test.go
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
Copyright 2022 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"
|
||||
"github.com/stretchr/testify/require"
|
||||
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"
|
||||
|
||||
f5 "github.com/F5Networks/k8s-bigip-ctlr/v2/config/apis/cis/v1"
|
||||
)
|
||||
|
||||
const defaultF5TransportServerNamespace = "transportserver"
|
||||
|
||||
func TestF5TransportServerEndpoints(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
annotationFilter string
|
||||
transportServer f5.TransportServer
|
||||
expected []*endpoint.Endpoint
|
||||
}{
|
||||
{
|
||||
name: "F5 TransportServer with target annotation",
|
||||
annotationFilter: "",
|
||||
transportServer: f5.TransportServer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: f5TransportServerGVR.GroupVersion().String(),
|
||||
Kind: "TransportServer",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-vs",
|
||||
Namespace: defaultF5TransportServerNamespace,
|
||||
Annotations: map[string]string{
|
||||
targetAnnotationKey: "192.168.1.150",
|
||||
},
|
||||
},
|
||||
Spec: f5.TransportServerSpec{
|
||||
Host: "www.example.com",
|
||||
VirtualServerAddress: "192.168.1.100",
|
||||
},
|
||||
Status: f5.TransportServerStatus{
|
||||
VSAddress: "192.168.1.200",
|
||||
},
|
||||
},
|
||||
expected: []*endpoint.Endpoint{
|
||||
{
|
||||
DNSName: "www.example.com",
|
||||
Targets: []string{"192.168.1.150"},
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
RecordTTL: 0,
|
||||
Labels: endpoint.Labels{
|
||||
"resource": "f5-transportserver/transportserver/test-vs",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "F5 TransportServer with host and VirtualServerAddress set",
|
||||
annotationFilter: "",
|
||||
transportServer: f5.TransportServer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: f5TransportServerGVR.GroupVersion().String(),
|
||||
Kind: "TransportServer",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-vs",
|
||||
Namespace: defaultF5TransportServerNamespace,
|
||||
},
|
||||
Spec: f5.TransportServerSpec{
|
||||
Host: "www.example.com",
|
||||
VirtualServerAddress: "192.168.1.100",
|
||||
},
|
||||
Status: f5.TransportServerStatus{
|
||||
VSAddress: "192.168.1.200",
|
||||
},
|
||||
},
|
||||
expected: []*endpoint.Endpoint{
|
||||
{
|
||||
DNSName: "www.example.com",
|
||||
Targets: []string{"192.168.1.100"},
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
RecordTTL: 0,
|
||||
Labels: endpoint.Labels{
|
||||
"resource": "f5-transportserver/transportserver/test-vs",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "F5 TransportServer with host set and IP address from the status field",
|
||||
annotationFilter: "",
|
||||
transportServer: f5.TransportServer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: f5TransportServerGVR.GroupVersion().String(),
|
||||
Kind: "TransportServer",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-vs",
|
||||
Namespace: defaultF5TransportServerNamespace,
|
||||
},
|
||||
Spec: f5.TransportServerSpec{
|
||||
Host: "www.example.com",
|
||||
},
|
||||
Status: f5.TransportServerStatus{
|
||||
VSAddress: "192.168.1.100",
|
||||
},
|
||||
},
|
||||
expected: []*endpoint.Endpoint{
|
||||
{
|
||||
DNSName: "www.example.com",
|
||||
Targets: []string{"192.168.1.100"},
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
RecordTTL: 0,
|
||||
Labels: endpoint.Labels{
|
||||
"resource": "f5-transportserver/transportserver/test-vs",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "F5 TransportServer with no IP address set",
|
||||
annotationFilter: "",
|
||||
transportServer: f5.TransportServer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: f5TransportServerGVR.GroupVersion().String(),
|
||||
Kind: "TransportServer",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-vs",
|
||||
Namespace: defaultF5TransportServerNamespace,
|
||||
},
|
||||
Spec: f5.TransportServerSpec{
|
||||
Host: "www.example.com",
|
||||
},
|
||||
Status: f5.TransportServerStatus{
|
||||
VSAddress: "",
|
||||
},
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "F5 TransportServer with matching annotation filter",
|
||||
annotationFilter: "foo=bar",
|
||||
transportServer: f5.TransportServer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: f5TransportServerGVR.GroupVersion().String(),
|
||||
Kind: "TransportServer",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-vs",
|
||||
Namespace: defaultF5TransportServerNamespace,
|
||||
Annotations: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Spec: f5.TransportServerSpec{
|
||||
Host: "www.example.com",
|
||||
VirtualServerAddress: "192.168.1.100",
|
||||
},
|
||||
},
|
||||
expected: []*endpoint.Endpoint{
|
||||
{
|
||||
DNSName: "www.example.com",
|
||||
Targets: []string{"192.168.1.100"},
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
RecordTTL: 0,
|
||||
Labels: endpoint.Labels{
|
||||
"resource": "f5-transportserver/transportserver/test-vs",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "F5 TransportServer with non-matching annotation filter",
|
||||
annotationFilter: "foo=bar",
|
||||
transportServer: f5.TransportServer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: f5TransportServerGVR.GroupVersion().String(),
|
||||
Kind: "TransportServer",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-vs",
|
||||
Namespace: defaultF5TransportServerNamespace,
|
||||
Annotations: map[string]string{
|
||||
"bar": "foo",
|
||||
},
|
||||
},
|
||||
Spec: f5.TransportServerSpec{
|
||||
Host: "www.example.com",
|
||||
VirtualServerAddress: "192.168.1.100",
|
||||
},
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "F5 TransportServer TTL annotation",
|
||||
transportServer: f5.TransportServer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: f5TransportServerGVR.GroupVersion().String(),
|
||||
Kind: "TransportServer",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-vs",
|
||||
Namespace: defaultF5TransportServerNamespace,
|
||||
Annotations: map[string]string{
|
||||
"external-dns.alpha.kubernetes.io/ttl": "600",
|
||||
},
|
||||
},
|
||||
Spec: f5.TransportServerSpec{
|
||||
Host: "www.example.com",
|
||||
VirtualServerAddress: "192.168.1.100",
|
||||
},
|
||||
},
|
||||
expected: []*endpoint.Endpoint{
|
||||
{
|
||||
DNSName: "www.example.com",
|
||||
Targets: []string{"192.168.1.100"},
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
RecordTTL: 600,
|
||||
Labels: endpoint.Labels{
|
||||
"resource": "f5-transportserver/transportserver/test-vs",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeKubernetesClient := fakeKube.NewSimpleClientset()
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypes(f5TransportServerGVR.GroupVersion(), &f5.TransportServer{}, &f5.TransportServerList{})
|
||||
fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme)
|
||||
|
||||
transportServer := unstructured.Unstructured{}
|
||||
|
||||
transportServerJSON, err := json.Marshal(tc.transportServer)
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, transportServer.UnmarshalJSON(transportServerJSON))
|
||||
|
||||
// Create TransportServer resources
|
||||
_, err = fakeDynamicClient.Resource(f5TransportServerGVR).Namespace(defaultF5TransportServerNamespace).Create(context.Background(), &transportServer, metav1.CreateOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
source, err := NewF5TransportServerSource(context.TODO(), fakeDynamicClient, fakeKubernetesClient, defaultF5TransportServerNamespace, tc.annotationFilter)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, source)
|
||||
|
||||
count := &unstructured.UnstructuredList{}
|
||||
for len(count.Items) < 1 {
|
||||
count, _ = fakeDynamicClient.Resource(f5TransportServerGVR).Namespace(defaultF5TransportServerNamespace).List(context.Background(), metav1.ListOptions{})
|
||||
}
|
||||
|
||||
endpoints, err := source.Endpoints(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, endpoints, len(tc.expected))
|
||||
assert.Equal(t, endpoints, tc.expected)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -354,6 +354,16 @@ func BuildWithConfig(ctx context.Context, source string, p ClientGenerator, cfg
|
||||
return nil, err
|
||||
}
|
||||
return NewF5VirtualServerSource(ctx, dynamicClient, kubernetesClient, cfg.Namespace, cfg.AnnotationFilter)
|
||||
case "f5-transportserver":
|
||||
kubernetesClient, err := p.KubeClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dynamicClient, err := p.DynamicKubernetesClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewF5TransportServerSource(ctx, dynamicClient, kubernetesClient, cfg.Namespace, cfg.AnnotationFilter)
|
||||
}
|
||||
|
||||
return nil, ErrSourceNotFound
|
||||
|
||||
@ -130,6 +130,11 @@ func (suite *ByNamesTestSuite) TestAllInitialized() {
|
||||
Version: "v1",
|
||||
Resource: "virtualservers",
|
||||
}: "VirtualServersList",
|
||||
{
|
||||
Group: "cis.f5.com",
|
||||
Version: "v1",
|
||||
Resource: "transportservers",
|
||||
}: "TransportServersList",
|
||||
{
|
||||
Group: "traefik.containo.us",
|
||||
Version: "v1alpha1",
|
||||
@ -162,9 +167,9 @@ func (suite *ByNamesTestSuite) TestAllInitialized() {
|
||||
}: "IngressRouteUDPList",
|
||||
}), nil)
|
||||
|
||||
sources, err := ByNames(context.TODO(), mockClientGenerator, []string{"service", "ingress", "istio-gateway", "contour-httpproxy", "kong-tcpingress", "f5-virtualserver", "traefik-proxy", "fake"}, &Config{})
|
||||
sources, err := ByNames(context.TODO(), mockClientGenerator, []string{"service", "ingress", "istio-gateway", "contour-httpproxy", "kong-tcpingress", "f5-virtualserver", "f5-transportserver", "traefik-proxy", "fake"}, &Config{})
|
||||
suite.NoError(err, "should not generate errors")
|
||||
suite.Len(sources, 8, "should generate all eight sources")
|
||||
suite.Len(sources, 9, "should generate all nine sources")
|
||||
}
|
||||
|
||||
func (suite *ByNamesTestSuite) TestOnlyFake() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user