feat(source/istio): support version 1.25+ (#5611)

* feat(source/istio): support version 1.22

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>

* feat(source/istio): support version 1.22

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>

* feat(source/istio): support version 1.22

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>

* feat(source/istio): support version 1.22

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>

* feat(source/istio): support version 1.22

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>

* feat(source/istio): support version 1.22

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>

* feat(source/istio): support version 1.22

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>

* feat(source/istio): support version 1.25+

Co-authored-by: mthemis-provenir <168411899+mthemis-provenir@users.noreply.github.com>

---------

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
Co-authored-by: mthemis-provenir <168411899+mthemis-provenir@users.noreply.github.com>
This commit is contained in:
Ivan Ka 2025-07-07 18:19:28 +01:00 committed by GitHub
parent 5c42ed00c7
commit 252a5e016c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 126 additions and 135 deletions

View File

@ -5,9 +5,13 @@ It is meant to supplement the other provider-specific setup tutorials.
**Note:** Using the Istio Gateway source requires Istio >=1.0.0. **Note:** Using the Istio Gateway source requires Istio >=1.0.0.
* Manifest (for clusters without RBAC enabled) **Note:** Currently supported versions are `1.25` and `1.26` with `v1beta1` stored version.
* Manifest (for clusters with RBAC enabled)
* Update existing ExternalDNS Deployment - [Support status of Istio releases](https://istio.io/latest/docs/releases/supported-releases/)
- Manifest (for clusters without RBAC enabled)
- Manifest (for clusters with RBAC enabled)
- Update existing ExternalDNS Deployment
## Manifest (for clusters without RBAC enabled) ## Manifest (for clusters without RBAC enabled)
@ -119,9 +123,9 @@ spec:
## Update existing ExternalDNS Deployment ## Update existing ExternalDNS Deployment
* For clusters with running `external-dns`, you can just update the deployment. - For clusters with running `external-dns`, you can just update the deployment.
* With access to the `kube-system` namespace, update the existing `external-dns` deployment. - With access to the `kube-system` namespace, update the existing `external-dns` deployment.
* Add a parameter to the arguments of the container to create dns entries with `--source=istio-gateway`. - Add a parameter to the arguments of the container to create dns entries with `--source=istio-gateway`.
Execute the following command or update the argument. Execute the following command or update the argument.
@ -148,13 +152,13 @@ The following are relevant snippets from that tutorial.
With automatic sidecar injection: With automatic sidecar injection:
```bash ```bash
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.6/samples/httpbin/httpbin.yaml kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.25/samples/httpbin/httpbin.yaml
``` ```
Otherwise: Otherwise:
```bash ```bash
kubectl apply -f <(istioctl kube-inject -f https://raw.githubusercontent.com/istio/istio/release-1.6/samples/httpbin/httpbin.yaml) kubectl apply -f <(istioctl kube-inject -f https://raw.githubusercontent.com/istio/istio/release-1.25/samples/httpbin/httpbin.yaml)
``` ```
### Using a Gateway as a source ### Using a Gateway as a source
@ -320,13 +324,13 @@ EOF
## Debug ExternalDNS ## Debug ExternalDNS
* Look for the deployment pod to see the status - Look for the deployment pod to see the status
```console$ kubectl get pods | grep external-dns ```console$ kubectl get pods | grep external-dns
external-dns-6b84999479-4knv9 1/1 Running 0 3h29m external-dns-6b84999479-4knv9 1/1 Running 0 3h29m
``` ```
* Watch for the logs as follows - Watch for the logs as follows
```console ```console
kubectl logs -f external-dns-6b84999479-4knv9 kubectl logs -f external-dns-6b84999479-4knv9
@ -336,7 +340,7 @@ At this point, you can `create` or `update` any `Istio Gateway` object with `hos
> **ATTENTION**: Make sure to specify those whose account is related to the DNS record. > **ATTENTION**: Make sure to specify those whose account is related to the DNS record.
* Successful executions will print the following - Successful executions will print the following
```console ```console
time="2020-01-17T06:08:08Z" level=info msg="Desired change: CREATE httpbin.example.com A" time="2020-01-17T06:08:08Z" level=info msg="Desired change: CREATE httpbin.example.com A"
@ -345,7 +349,7 @@ time="2020-01-17T06:08:08Z" level=info msg="2 record(s) in zone example.com. wer
time="2020-01-17T06:09:08Z" level=info msg="All records are already up to date, there are no changes for the matching hosted zones" time="2020-01-17T06:09:08Z" level=info msg="All records are already up to date, there are no changes for the matching hosted zones"
``` ```
* If there's any problem around `clusterrole`, you would see the errors showing wrong permissions: - If there's any problem around `clusterrole`, you would see the errors showing wrong permissions:
```console ```console
source \"gateways\" in API group \"networking.istio.io\" at the cluster scope" source \"gateways\" in API group \"networking.istio.io\" at the cluster scope"

View File

@ -18,7 +18,6 @@ package registry
import ( import (
"context" "context"
"fmt"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
@ -1511,7 +1510,6 @@ func TestNewTXTScheme(t *testing.T) {
assert.Nil(t, ctx.Value(provider.RecordsContextKey)) assert.Nil(t, ctx.Value(provider.RecordsContextKey))
} }
err := r.ApplyChanges(ctx, changes) err := r.ApplyChanges(ctx, changes)
fmt.Println(err)
require.NoError(t, err) require.NoError(t, err)
} }

View File

@ -24,10 +24,10 @@ import (
"text/template" "text/template"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" networkingv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
istioclient "istio.io/client-go/pkg/clientset/versioned" istioclient "istio.io/client-go/pkg/clientset/versioned"
istioinformers "istio.io/client-go/pkg/informers/externalversions" istioinformers "istio.io/client-go/pkg/informers/externalversions"
networkingv1alpha3informer "istio.io/client-go/pkg/informers/externalversions/networking/v1alpha3" networkingv1beta1informer "istio.io/client-go/pkg/informers/externalversions/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
kubeinformers "k8s.io/client-go/informers" kubeinformers "k8s.io/client-go/informers"
@ -57,7 +57,7 @@ type gatewaySource struct {
combineFQDNAnnotation bool combineFQDNAnnotation bool
ignoreHostnameAnnotation bool ignoreHostnameAnnotation bool
serviceInformer coreinformers.ServiceInformer serviceInformer coreinformers.ServiceInformer
gatewayInformer networkingv1alpha3informer.GatewayInformer gatewayInformer networkingv1beta1informer.GatewayInformer
} }
// NewIstioGatewaySource creates a new gatewaySource with the given config. // NewIstioGatewaySource creates a new gatewaySource with the given config.
@ -81,10 +81,10 @@ func NewIstioGatewaySource(
informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0, kubeinformers.WithNamespace(namespace)) informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0, kubeinformers.WithNamespace(namespace))
serviceInformer := informerFactory.Core().V1().Services() serviceInformer := informerFactory.Core().V1().Services()
istioInformerFactory := istioinformers.NewSharedInformerFactory(istioClient, 0) istioInformerFactory := istioinformers.NewSharedInformerFactory(istioClient, 0)
gatewayInformer := istioInformerFactory.Networking().V1alpha3().Gateways() gatewayInformer := istioInformerFactory.Networking().V1beta1().Gateways()
// Add default resource event handlers to properly initialize informer. // Add default resource event handlers to properly initialize informer.
serviceInformer.Informer().AddEventHandler( _, _ = serviceInformer.Informer().AddEventHandler(
cache.ResourceEventHandlerFuncs{ cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) { AddFunc: func(obj interface{}) {
log.Debug("service added") log.Debug("service added")
@ -92,7 +92,7 @@ func NewIstioGatewaySource(
}, },
) )
gatewayInformer.Informer().AddEventHandler( _, _ = gatewayInformer.Informer().AddEventHandler(
cache.ResourceEventHandlerFuncs{ cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) { AddFunc: func(obj interface{}) {
log.Debug("gateway added") log.Debug("gateway added")
@ -127,7 +127,7 @@ func NewIstioGatewaySource(
// Endpoints returns endpoint objects for each host-target combination that should be processed. // Endpoints returns endpoint objects for each host-target combination that should be processed.
// Retrieves all gateway resources in the source's namespace(s). // Retrieves all gateway resources in the source's namespace(s).
func (sc *gatewaySource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) { func (sc *gatewaySource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
gwList, err := sc.istioClient.NetworkingV1alpha3().Gateways(sc.namespace).List(ctx, metav1.ListOptions{}) gwList, err := sc.istioClient.NetworkingV1beta1().Gateways(sc.namespace).List(ctx, metav1.ListOptions{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -140,12 +140,14 @@ func (sc *gatewaySource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e
var endpoints []*endpoint.Endpoint var endpoints []*endpoint.Endpoint
log.Debugf("Found %d gateways in namespace %s", len(gateways), sc.namespace)
for _, gateway := range gateways { for _, gateway := range gateways {
// Check controller annotation to see if we are responsible. // Check controller annotation to see if we are responsible.
controller, ok := gateway.Annotations[controllerAnnotationKey] controller, ok := gateway.Annotations[controllerAnnotationKey]
if ok && controller != controllerAnnotationValue { if ok && controller != controllerAnnotationValue {
log.Debugf("Skipping gateway %s/%s because controller value does not match, found: %s, required: %s", log.Debugf("Skipping gateway %s/%s,%s because controller value does not match, found: %s, required: %s",
gateway.Namespace, gateway.Name, controller, controllerAnnotationValue) gateway.Namespace, gateway.APIVersion, gateway.Name, controller, controllerAnnotationValue)
continue continue
} }
@ -168,6 +170,8 @@ func (sc *gatewaySource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e
} }
} }
log.Debugf("Processing gateway '%s/%s.%s' and hosts %q", gateway.Namespace, gateway.APIVersion, gateway.Name, strings.Join(gwHostnames, ","))
if len(gwHostnames) == 0 { if len(gwHostnames) == 0 {
log.Debugf("No hostnames could be generated from gateway %s/%s", gateway.Namespace, gateway.Name) log.Debugf("No hostnames could be generated from gateway %s/%s", gateway.Namespace, gateway.Name)
continue continue
@ -183,10 +187,11 @@ func (sc *gatewaySource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e
continue continue
} }
log.Debugf("Endpoints generated from gateway: %s/%s: %v", gateway.Namespace, gateway.Name, gwEndpoints) log.Debugf("Endpoints generated from %q '%s/%s.%s': %q", gateway.Kind, gateway.Namespace, gateway.APIVersion, gateway.Name, gwEndpoints)
endpoints = append(endpoints, gwEndpoints...) endpoints = append(endpoints, gwEndpoints...)
} }
// TODO: sort on endpoint creation
for _, ep := range endpoints { for _, ep := range endpoints {
sort.Sort(ep.Targets) sort.Sort(ep.Targets)
} }
@ -198,11 +203,11 @@ func (sc *gatewaySource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e
func (sc *gatewaySource) AddEventHandler(ctx context.Context, handler func()) { func (sc *gatewaySource) AddEventHandler(ctx context.Context, handler func()) {
log.Debug("Adding event handler for Istio Gateway") log.Debug("Adding event handler for Istio Gateway")
sc.gatewayInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) _, _ = sc.gatewayInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
} }
// filterByAnnotations filters a list of configs by a given annotation selector. // filterByAnnotations filters a list of configs by a given annotation selector.
func (sc *gatewaySource) filterByAnnotations(gateways []*networkingv1alpha3.Gateway) ([]*networkingv1alpha3.Gateway, error) { func (sc *gatewaySource) filterByAnnotations(gateways []*networkingv1beta1.Gateway) ([]*networkingv1beta1.Gateway, error) {
selector, err := annotations.ParseFilter(sc.annotationFilter) selector, err := annotations.ParseFilter(sc.annotationFilter)
if err != nil { if err != nil {
return nil, err return nil, err
@ -213,7 +218,7 @@ func (sc *gatewaySource) filterByAnnotations(gateways []*networkingv1alpha3.Gate
return gateways, nil return gateways, nil
} }
var filteredList []*networkingv1alpha3.Gateway var filteredList []*networkingv1beta1.Gateway
for _, gw := range gateways { for _, gw := range gateways {
// include if the annotations match the selector // include if the annotations match the selector
@ -225,7 +230,7 @@ func (sc *gatewaySource) filterByAnnotations(gateways []*networkingv1alpha3.Gate
return filteredList, nil return filteredList, nil
} }
func (sc *gatewaySource) targetsFromIngress(ctx context.Context, ingressStr string, gateway *networkingv1alpha3.Gateway) (endpoint.Targets, error) { func (sc *gatewaySource) targetsFromIngress(ctx context.Context, ingressStr string, gateway *networkingv1beta1.Gateway) (endpoint.Targets, error) {
namespace, name, err := ParseIngress(ingressStr) namespace, name, err := ParseIngress(ingressStr)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse Ingress annotation on Gateway (%s/%s): %w", gateway.Namespace, gateway.Name, err) return nil, fmt.Errorf("failed to parse Ingress annotation on Gateway (%s/%s): %w", gateway.Namespace, gateway.Name, err)
@ -251,7 +256,7 @@ func (sc *gatewaySource) targetsFromIngress(ctx context.Context, ingressStr stri
return targets, nil return targets, nil
} }
func (sc *gatewaySource) targetsFromGateway(ctx context.Context, gateway *networkingv1alpha3.Gateway) (endpoint.Targets, error) { func (sc *gatewaySource) targetsFromGateway(ctx context.Context, gateway *networkingv1beta1.Gateway) (endpoint.Targets, error) {
targets := annotations.TargetsFromTargetAnnotation(gateway.Annotations) targets := annotations.TargetsFromTargetAnnotation(gateway.Annotations)
if len(targets) > 0 { if len(targets) > 0 {
return targets, nil return targets, nil
@ -266,22 +271,21 @@ func (sc *gatewaySource) targetsFromGateway(ctx context.Context, gateway *networ
} }
// endpointsFromGatewayConfig extracts the endpoints from an Istio Gateway Config object // endpointsFromGatewayConfig extracts the endpoints from an Istio Gateway Config object
func (sc *gatewaySource) endpointsFromGateway(ctx context.Context, hostnames []string, gateway *networkingv1alpha3.Gateway) ([]*endpoint.Endpoint, error) { func (sc *gatewaySource) endpointsFromGateway(ctx context.Context, hostnames []string, gateway *networkingv1beta1.Gateway) ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint var endpoints []*endpoint.Endpoint
var err error var err error
resource := fmt.Sprintf("gateway/%s/%s", gateway.Namespace, gateway.Name) targets, err := sc.targetsFromGateway(ctx, gateway)
if err != nil {
ttl := annotations.TTLFromAnnotations(gateway.Annotations, resource) return nil, err
targets := annotations.TargetsFromTargetAnnotation(gateway.Annotations)
if len(targets) == 0 {
targets, err = sc.targetsFromGateway(ctx, gateway)
if err != nil {
return nil, err
}
} }
if len(targets) == 0 {
return endpoints, nil
}
resource := fmt.Sprintf("gateway/%s/%s", gateway.Namespace, gateway.Name)
ttl := annotations.TTLFromAnnotations(gateway.Annotations, resource)
providerSpecific, setIdentifier := annotations.ProviderSpecificAnnotations(gateway.Annotations) providerSpecific, setIdentifier := annotations.ProviderSpecificAnnotations(gateway.Annotations)
for _, host := range hostnames { for _, host := range hostnames {
@ -291,7 +295,7 @@ func (sc *gatewaySource) endpointsFromGateway(ctx context.Context, hostnames []s
return endpoints, nil return endpoints, nil
} }
func (sc *gatewaySource) hostNamesFromGateway(gateway *networkingv1alpha3.Gateway) ([]string, error) { func (sc *gatewaySource) hostNamesFromGateway(gateway *networkingv1beta1.Gateway) ([]string, error) {
var hostnames []string var hostnames []string
for _, server := range gateway.Spec.Servers { for _, server := range gateway.Spec.Servers {
for _, host := range server.Hosts { for _, host := range server.Hosts {

View File

@ -24,8 +24,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
networkingv1alpha3api "istio.io/api/networking/v1alpha3" networkingv1alpha3api "istio.io/api/networking/v1beta1"
networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1beta1"
istiofake "istio.io/client-go/pkg/clientset/versioned/fake" istiofake "istio.io/client-go/pkg/clientset/versioned/fake"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
networkv1 "k8s.io/api/networking/v1" networkv1 "k8s.io/api/networking/v1"
@ -1494,7 +1494,7 @@ func testGatewayEndpoints(t *testing.T) {
fakeIstioClient := istiofake.NewSimpleClientset() fakeIstioClient := istiofake.NewSimpleClientset()
for _, config := range ti.configItems { for _, config := range ti.configItems {
gatewayCfg := config.Config() gatewayCfg := config.Config()
_, err := fakeIstioClient.NetworkingV1alpha3().Gateways(ti.targetNamespace).Create(context.Background(), gatewayCfg, metav1.CreateOptions{}) _, err := fakeIstioClient.NetworkingV1beta1().Gateways(ti.targetNamespace).Create(context.Background(), gatewayCfg, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
} }

View File

@ -20,15 +20,16 @@ import (
"cmp" "cmp"
"context" "context"
"fmt" "fmt"
"slices"
"sort" "sort"
"strings" "strings"
"text/template" "text/template"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
istioclient "istio.io/client-go/pkg/clientset/versioned" istioclient "istio.io/client-go/pkg/clientset/versioned"
istioinformers "istio.io/client-go/pkg/informers/externalversions" istioinformers "istio.io/client-go/pkg/informers/externalversions"
networkingv1alpha3informer "istio.io/client-go/pkg/informers/externalversions/networking/v1alpha3" networkingv1beta1informer "istio.io/client-go/pkg/informers/externalversions/networking/v1beta1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
@ -58,8 +59,8 @@ type virtualServiceSource struct {
combineFQDNAnnotation bool combineFQDNAnnotation bool
ignoreHostnameAnnotation bool ignoreHostnameAnnotation bool
serviceInformer coreinformers.ServiceInformer serviceInformer coreinformers.ServiceInformer
virtualserviceInformer networkingv1alpha3informer.VirtualServiceInformer vServiceInformer networkingv1beta1informer.VirtualServiceInformer
gatewayInformer networkingv1alpha3informer.GatewayInformer gatewayInformer networkingv1beta1informer.GatewayInformer
} }
// NewIstioVirtualServiceSource creates a new virtualServiceSource with the given config. // NewIstioVirtualServiceSource creates a new virtualServiceSource with the given config.
@ -83,11 +84,11 @@ func NewIstioVirtualServiceSource(
informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0, kubeinformers.WithNamespace(namespace)) informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0, kubeinformers.WithNamespace(namespace))
serviceInformer := informerFactory.Core().V1().Services() serviceInformer := informerFactory.Core().V1().Services()
istioInformerFactory := istioinformers.NewSharedInformerFactoryWithOptions(istioClient, 0, istioinformers.WithNamespace(namespace)) istioInformerFactory := istioinformers.NewSharedInformerFactoryWithOptions(istioClient, 0, istioinformers.WithNamespace(namespace))
virtualServiceInformer := istioInformerFactory.Networking().V1alpha3().VirtualServices() virtualServiceInformer := istioInformerFactory.Networking().V1beta1().VirtualServices()
gatewayInformer := istioInformerFactory.Networking().V1alpha3().Gateways() gatewayInformer := istioInformerFactory.Networking().V1beta1().Gateways()
// Add default resource event handlers to properly initialize informer. // Add default resource event handlers to properly initialize informer.
serviceInformer.Informer().AddEventHandler( _, _ = serviceInformer.Informer().AddEventHandler(
cache.ResourceEventHandlerFuncs{ cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) { AddFunc: func(obj interface{}) {
log.Debug("service added") log.Debug("service added")
@ -95,7 +96,7 @@ func NewIstioVirtualServiceSource(
}, },
) )
virtualServiceInformer.Informer().AddEventHandler( _, _ = virtualServiceInformer.Informer().AddEventHandler(
cache.ResourceEventHandlerFuncs{ cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) { AddFunc: func(obj interface{}) {
log.Debug("virtual service added") log.Debug("virtual service added")
@ -103,7 +104,7 @@ func NewIstioVirtualServiceSource(
}, },
) )
gatewayInformer.Informer().AddEventHandler( _, _ = gatewayInformer.Informer().AddEventHandler(
cache.ResourceEventHandlerFuncs{ cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) { AddFunc: func(obj interface{}) {
log.Debug("gateway added") log.Debug("gateway added")
@ -131,7 +132,7 @@ func NewIstioVirtualServiceSource(
combineFQDNAnnotation: combineFQDNAnnotation, combineFQDNAnnotation: combineFQDNAnnotation,
ignoreHostnameAnnotation: ignoreHostnameAnnotation, ignoreHostnameAnnotation: ignoreHostnameAnnotation,
serviceInformer: serviceInformer, serviceInformer: serviceInformer,
virtualserviceInformer: virtualServiceInformer, vServiceInformer: virtualServiceInformer,
gatewayInformer: gatewayInformer, gatewayInformer: gatewayInformer,
}, nil }, nil
} }
@ -139,7 +140,7 @@ func NewIstioVirtualServiceSource(
// Endpoints returns endpoint objects for each host-target combination that should be processed. // Endpoints returns endpoint objects for each host-target combination that should be processed.
// Retrieves all VirtualService resources in the source's namespace(s). // Retrieves all VirtualService resources in the source's namespace(s).
func (sc *virtualServiceSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) { func (sc *virtualServiceSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
virtualServices, err := sc.virtualserviceInformer.Lister().VirtualServices(sc.namespace).List(labels.Everything()) virtualServices, err := sc.vServiceInformer.Lister().VirtualServices(sc.namespace).List(labels.Everything())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -150,23 +151,25 @@ func (sc *virtualServiceSource) Endpoints(ctx context.Context) ([]*endpoint.Endp
var endpoints []*endpoint.Endpoint var endpoints []*endpoint.Endpoint
for _, virtualService := range virtualServices { log.Debugf("Found %d virtualservice in namespace %s", len(virtualServices), sc.namespace)
for _, vService := range virtualServices {
// Check controller annotation to see if we are responsible. // Check controller annotation to see if we are responsible.
controller, ok := virtualService.Annotations[controllerAnnotationKey] controller, ok := vService.Annotations[controllerAnnotationKey]
if ok && controller != controllerAnnotationValue { if ok && controller != controllerAnnotationValue {
log.Debugf("Skipping VirtualService %s/%s because controller value does not match, found: %s, required: %s", log.Debugf("Skipping VirtualService %s/%s.%s because controller value does not match, found: %s, required: %s",
virtualService.Namespace, virtualService.Name, controller, controllerAnnotationValue) vService.Namespace, vService.APIVersion, vService.Name, controller, controllerAnnotationValue)
continue continue
} }
gwEndpoints, err := sc.endpointsFromVirtualService(ctx, virtualService) gwEndpoints, err := sc.endpointsFromVirtualService(ctx, vService)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// apply template if host is missing on VirtualService // apply template if host is missing on VirtualService
if (sc.combineFQDNAnnotation || len(gwEndpoints) == 0) && sc.fqdnTemplate != nil { if (sc.combineFQDNAnnotation || len(gwEndpoints) == 0) && sc.fqdnTemplate != nil {
iEndpoints, err := sc.endpointsFromTemplate(ctx, virtualService) iEndpoints, err := sc.endpointsFromTemplate(ctx, vService)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -179,14 +182,15 @@ func (sc *virtualServiceSource) Endpoints(ctx context.Context) ([]*endpoint.Endp
} }
if len(gwEndpoints) == 0 { if len(gwEndpoints) == 0 {
log.Debugf("No endpoints could be generated from VirtualService %s/%s", virtualService.Namespace, virtualService.Name) log.Debugf("No endpoints could be generated from VirtualService %s/%s", vService.Namespace, vService.Name)
continue continue
} }
log.Debugf("Endpoints generated from VirtualService: %s/%s: %v", virtualService.Namespace, virtualService.Name, gwEndpoints) log.Debugf("Endpoints generated from %q '%s/%s.%s': %q", vService.Kind, vService.Namespace, vService.APIVersion, vService.Name, gwEndpoints)
endpoints = append(endpoints, gwEndpoints...) endpoints = append(endpoints, gwEndpoints...)
} }
// TODO: sort on endpoint creation
for _, ep := range endpoints { for _, ep := range endpoints {
sort.Sort(ep.Targets) sort.Sort(ep.Targets)
} }
@ -198,16 +202,16 @@ func (sc *virtualServiceSource) Endpoints(ctx context.Context) ([]*endpoint.Endp
func (sc *virtualServiceSource) AddEventHandler(_ context.Context, handler func()) { func (sc *virtualServiceSource) AddEventHandler(_ context.Context, handler func()) {
log.Debug("Adding event handler for Istio VirtualService") log.Debug("Adding event handler for Istio VirtualService")
sc.virtualserviceInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) _, _ = sc.vServiceInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
} }
func (sc *virtualServiceSource) getGateway(_ context.Context, gatewayStr string, virtualService *networkingv1alpha3.VirtualService) (*networkingv1alpha3.Gateway, error) { func (sc *virtualServiceSource) getGateway(_ context.Context, gatewayStr string, virtualService *v1beta1.VirtualService) (*v1beta1.Gateway, error) {
if gatewayStr == "" || gatewayStr == IstioMeshGateway { if gatewayStr == "" || gatewayStr == IstioMeshGateway {
// This refers to "all sidecars in the mesh"; ignore. // This refers to "all sidecars in the mesh"; ignore.
return nil, nil return nil, nil
} }
namespace, name, err := parseGateway(gatewayStr) namespace, name, err := ParseIngress(gatewayStr)
if err != nil { if err != nil {
log.Debugf("Failed parsing gatewayStr %s of VirtualService %s/%s", gatewayStr, virtualService.Namespace, virtualService.Name) log.Debugf("Failed parsing gatewayStr %s of VirtualService %s/%s", gatewayStr, virtualService.Namespace, virtualService.Name)
return nil, err return nil, err
@ -229,7 +233,7 @@ func (sc *virtualServiceSource) getGateway(_ context.Context, gatewayStr string,
return gateway, nil return gateway, nil
} }
func (sc *virtualServiceSource) endpointsFromTemplate(ctx context.Context, virtualService *networkingv1alpha3.VirtualService) ([]*endpoint.Endpoint, error) { func (sc *virtualServiceSource) endpointsFromTemplate(ctx context.Context, virtualService *v1beta1.VirtualService) ([]*endpoint.Endpoint, error) {
hostnames, err := fqdn.ExecTemplate(sc.fqdnTemplate, virtualService) hostnames, err := fqdn.ExecTemplate(sc.fqdnTemplate, virtualService)
if err != nil { if err != nil {
return nil, err return nil, err
@ -253,7 +257,7 @@ func (sc *virtualServiceSource) endpointsFromTemplate(ctx context.Context, virtu
} }
// filterByAnnotations filters a list of configs by a given annotation selector. // filterByAnnotations filters a list of configs by a given annotation selector.
func (sc *virtualServiceSource) filterByAnnotations(virtualservices []*networkingv1alpha3.VirtualService) ([]*networkingv1alpha3.VirtualService, error) { func (sc *virtualServiceSource) filterByAnnotations(vServices []*v1beta1.VirtualService) ([]*v1beta1.VirtualService, error) {
selector, err := annotations.ParseFilter(sc.annotationFilter) selector, err := annotations.ParseFilter(sc.annotationFilter)
if err != nil { if err != nil {
return nil, err return nil, err
@ -261,12 +265,12 @@ func (sc *virtualServiceSource) filterByAnnotations(virtualservices []*networkin
// empty filter returns original list // empty filter returns original list
if selector.Empty() { if selector.Empty() {
return virtualservices, nil return vServices, nil
} }
var filteredList []*networkingv1alpha3.VirtualService var filteredList []*v1beta1.VirtualService
for _, vs := range virtualservices { for _, vs := range vServices {
// include if the annotations match the selector // include if the annotations match the selector
if selector.Matches(labels.Set(vs.Annotations)) { if selector.Matches(labels.Set(vs.Annotations)) {
filteredList = append(filteredList, vs) filteredList = append(filteredList, vs)
@ -278,26 +282,24 @@ func (sc *virtualServiceSource) filterByAnnotations(virtualservices []*networkin
// append a target to the list of targets unless it's already in the list // append a target to the list of targets unless it's already in the list
func appendUnique(targets []string, target string) []string { func appendUnique(targets []string, target string) []string {
for _, element := range targets { if slices.Contains(targets, target) {
if element == target { return targets
return targets
}
} }
return append(targets, target) return append(targets, target)
} }
func (sc *virtualServiceSource) targetsFromVirtualService(ctx context.Context, virtualService *networkingv1alpha3.VirtualService, vsHost string) ([]string, error) { func (sc *virtualServiceSource) targetsFromVirtualService(ctx context.Context, vService *v1beta1.VirtualService, vsHost string) ([]string, error) {
var targets []string var targets []string
// for each host we need to iterate through the gateways because each host might match for only one of the gateways // for each host we need to iterate through the gateways because each host might match for only one of the gateways
for _, gateway := range virtualService.Spec.Gateways { for _, gateway := range vService.Spec.Gateways {
gw, err := sc.getGateway(ctx, gateway, virtualService) gw, err := sc.getGateway(ctx, gateway, vService)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if gw == nil { if gw == nil {
continue continue
} }
if !virtualServiceBindsToGateway(virtualService, gw, vsHost) { if !virtualServiceBindsToGateway(vService, gw, vsHost) {
continue continue
} }
tgs, err := sc.targetsFromGateway(ctx, gw) tgs, err := sc.targetsFromGateway(ctx, gw)
@ -308,24 +310,23 @@ func (sc *virtualServiceSource) targetsFromVirtualService(ctx context.Context, v
targets = appendUnique(targets, target) targets = appendUnique(targets, target)
} }
} }
return targets, nil return targets, nil
} }
// endpointsFromVirtualService extracts the endpoints from an Istio VirtualService Config object // endpointsFromVirtualService extracts the endpoints from an Istio VirtualService Config object
func (sc *virtualServiceSource) endpointsFromVirtualService(ctx context.Context, virtualservice *networkingv1alpha3.VirtualService) ([]*endpoint.Endpoint, error) { func (sc *virtualServiceSource) endpointsFromVirtualService(ctx context.Context, vService *v1beta1.VirtualService) ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint var endpoints []*endpoint.Endpoint
var err error var err error
resource := fmt.Sprintf("virtualservice/%s/%s", virtualservice.Namespace, virtualservice.Name) resource := fmt.Sprintf("virtualservice/%s/%s", vService.Namespace, vService.Name)
ttl := annotations.TTLFromAnnotations(virtualservice.Annotations, resource) ttl := annotations.TTLFromAnnotations(vService.Annotations, resource)
targetsFromAnnotation := annotations.TargetsFromTargetAnnotation(virtualservice.Annotations) targetsFromAnnotation := annotations.TargetsFromTargetAnnotation(vService.Annotations)
providerSpecific, setIdentifier := annotations.ProviderSpecificAnnotations(virtualservice.Annotations) providerSpecific, setIdentifier := annotations.ProviderSpecificAnnotations(vService.Annotations)
for _, host := range virtualservice.Spec.Hosts { for _, host := range vService.Spec.Hosts {
if host == "" || host == "*" { if host == "" || host == "*" {
continue continue
} }
@ -340,7 +341,7 @@ func (sc *virtualServiceSource) endpointsFromVirtualService(ctx context.Context,
targets := targetsFromAnnotation targets := targetsFromAnnotation
if len(targets) == 0 { if len(targets) == 0 {
targets, err = sc.targetsFromVirtualService(ctx, virtualservice, host) targets, err = sc.targetsFromVirtualService(ctx, vService, host)
if err != nil { if err != nil {
return endpoints, err return endpoints, err
} }
@ -351,11 +352,11 @@ func (sc *virtualServiceSource) endpointsFromVirtualService(ctx context.Context,
// Skip endpoints if we do not want entries from annotations // Skip endpoints if we do not want entries from annotations
if !sc.ignoreHostnameAnnotation { if !sc.ignoreHostnameAnnotation {
hostnameList := annotations.HostnamesFromAnnotations(virtualservice.Annotations) hostnameList := annotations.HostnamesFromAnnotations(vService.Annotations)
for _, hostname := range hostnameList { for _, hostname := range hostnameList {
targets := targetsFromAnnotation targets := targetsFromAnnotation
if len(targets) == 0 { if len(targets) == 0 {
targets, err = sc.targetsFromVirtualService(ctx, virtualservice, hostname) targets, err = sc.targetsFromVirtualService(ctx, vService, hostname)
if err != nil { if err != nil {
return endpoints, err return endpoints, err
} }
@ -369,13 +370,13 @@ func (sc *virtualServiceSource) endpointsFromVirtualService(ctx context.Context,
// checks if the given VirtualService should actually bind to the given gateway // checks if the given VirtualService should actually bind to the given gateway
// see requirements here: https://istio.io/docs/reference/config/networking/gateway/#Server // see requirements here: https://istio.io/docs/reference/config/networking/gateway/#Server
func virtualServiceBindsToGateway(virtualService *networkingv1alpha3.VirtualService, gateway *networkingv1alpha3.Gateway, vsHost string) bool { func virtualServiceBindsToGateway(vService *v1beta1.VirtualService, gateway *v1beta1.Gateway, vsHost string) bool {
isValid := false isValid := false
if len(virtualService.Spec.ExportTo) == 0 { if len(vService.Spec.ExportTo) == 0 {
isValid = true isValid = true
} else { } else {
for _, ns := range virtualService.Spec.ExportTo { for _, ns := range vService.Spec.ExportTo {
if ns == "*" || ns == gateway.Namespace || (ns == "." && gateway.Namespace == virtualService.Namespace) { if ns == "*" || ns == gateway.Namespace || (ns == "." && gateway.Namespace == vService.Namespace) {
isValid = true isValid = true
} }
} }
@ -396,7 +397,7 @@ func virtualServiceBindsToGateway(virtualService *networkingv1alpha3.VirtualServ
continue continue
} }
if namespace == "*" || namespace == virtualService.Namespace || (namespace == "." && virtualService.Namespace == gateway.Namespace) { if namespace == "*" || namespace == vService.Namespace || (namespace == "." && vService.Namespace == gateway.Namespace) {
if host == "*" { if host == "*" {
return true return true
} }
@ -416,23 +417,7 @@ func virtualServiceBindsToGateway(virtualService *networkingv1alpha3.VirtualServ
return false return false
} }
// TODO: similar to ParseIngress func (sc *virtualServiceSource) targetsFromIngress(ctx context.Context, ingressStr string, gateway *v1beta1.Gateway) (endpoint.Targets, error) {
func parseGateway(gateway string) (string, string, error) {
var namespace, name string
var err error
parts := strings.Split(gateway, "/")
if len(parts) == 2 {
namespace, name = parts[0], parts[1]
} else if len(parts) == 1 {
name = parts[0]
} else {
err = fmt.Errorf("invalid gateway name (name or namespace/name) found '%v'", gateway)
}
return namespace, name, err
}
func (sc *virtualServiceSource) targetsFromIngress(ctx context.Context, ingressStr string, gateway *networkingv1alpha3.Gateway) (endpoint.Targets, error) {
namespace, name, err := ParseIngress(ingressStr) namespace, name, err := ParseIngress(ingressStr)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse Ingress annotation on Gateway (%s/%s): %w", gateway.Namespace, gateway.Name, err) return nil, fmt.Errorf("failed to parse Ingress annotation on Gateway (%s/%s): %w", gateway.Namespace, gateway.Name, err)
@ -459,7 +444,7 @@ func (sc *virtualServiceSource) targetsFromIngress(ctx context.Context, ingressS
return targets, nil return targets, nil
} }
func (sc *virtualServiceSource) targetsFromGateway(ctx context.Context, gateway *networkingv1alpha3.Gateway) (endpoint.Targets, error) { func (sc *virtualServiceSource) targetsFromGateway(ctx context.Context, gateway *v1beta1.Gateway) (endpoint.Targets, error) {
targets := annotations.TargetsFromTargetAnnotation(gateway.Annotations) targets := annotations.TargetsFromTargetAnnotation(gateway.Annotations)
if len(targets) > 0 { if len(targets) > 0 {
return targets, nil return targets, nil

View File

@ -25,8 +25,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"istio.io/api/meta/v1alpha1" "istio.io/api/meta/v1alpha1"
istionetworking "istio.io/api/networking/v1alpha3" istionetworking "istio.io/api/networking/v1beta1"
networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" networkingv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
istiofake "istio.io/client-go/pkg/clientset/versioned/fake" istiofake "istio.io/client-go/pkg/clientset/versioned/fake"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
networkv1 "k8s.io/api/networking/v1" networkv1 "k8s.io/api/networking/v1"
@ -44,8 +44,8 @@ type VirtualServiceSuite struct {
source Source source Source
lbServices []*v1.Service lbServices []*v1.Service
ingresses []*networkv1.Ingress ingresses []*networkv1.Ingress
gwconfig *networkingv1alpha3.Gateway gwconfig *networkingv1beta1.Gateway
vsconfig *networkingv1alpha3.VirtualService vsconfig *networkingv1beta1.VirtualService
} }
func (suite *VirtualServiceSuite) SetupTest() { func (suite *VirtualServiceSuite) SetupTest() {
@ -98,7 +98,7 @@ func (suite *VirtualServiceSuite) SetupTest() {
namespace: "istio-system", namespace: "istio-system",
dnsnames: [][]string{{"*"}}, dnsnames: [][]string{{"*"}},
}).Config() }).Config()
_, err = fakeIstioClient.NetworkingV1alpha3().Gateways(suite.gwconfig.Namespace).Create(context.Background(), suite.gwconfig, metav1.CreateOptions{}) _, err = fakeIstioClient.NetworkingV1beta1().Gateways(suite.gwconfig.Namespace).Create(context.Background(), suite.gwconfig, metav1.CreateOptions{})
suite.NoError(err, "should succeed") suite.NoError(err, "should succeed")
suite.vsconfig = (fakeVirtualServiceConfig{ suite.vsconfig = (fakeVirtualServiceConfig{
@ -107,7 +107,7 @@ func (suite *VirtualServiceSuite) SetupTest() {
gateways: []string{"istio-system/foo-gateway-with-targets"}, gateways: []string{"istio-system/foo-gateway-with-targets"},
dnsnames: []string{"foo"}, dnsnames: []string{"foo"},
}).Config() }).Config()
_, err = fakeIstioClient.NetworkingV1alpha3().VirtualServices(suite.vsconfig.Namespace).Create(context.Background(), suite.vsconfig, metav1.CreateOptions{}) _, err = fakeIstioClient.NetworkingV1beta1().VirtualServices(suite.vsconfig.Namespace).Create(context.Background(), suite.vsconfig, metav1.CreateOptions{})
suite.NoError(err, "should succeed") suite.NoError(err, "should succeed")
suite.source, err = NewIstioVirtualServiceSource( suite.source, err = NewIstioVirtualServiceSource(
@ -1948,8 +1948,8 @@ func testVirtualServiceEndpoints(t *testing.T) {
t.Run(ti.title, func(t *testing.T) { t.Run(ti.title, func(t *testing.T) {
t.Parallel() t.Parallel()
var gateways []*networkingv1alpha3.Gateway var gateways []*networkingv1beta1.Gateway
var virtualservices []*networkingv1alpha3.VirtualService var virtualservices []*networkingv1beta1.VirtualService
for _, gwItem := range ti.gwConfigs { for _, gwItem := range ti.gwConfigs {
gateways = append(gateways, gwItem.Config()) gateways = append(gateways, gwItem.Config())
@ -1958,7 +1958,7 @@ func testVirtualServiceEndpoints(t *testing.T) {
virtualservices = append(virtualservices, vsItem.Config()) virtualservices = append(virtualservices, vsItem.Config())
} }
fakeKubernetesClient := fake.NewSimpleClientset() fakeKubernetesClient := fake.NewClientset()
for _, lb := range ti.lbServices { for _, lb := range ti.lbServices {
service := lb.Service() service := lb.Service()
@ -1975,12 +1975,12 @@ func testVirtualServiceEndpoints(t *testing.T) {
fakeIstioClient := istiofake.NewSimpleClientset() fakeIstioClient := istiofake.NewSimpleClientset()
for _, gateway := range gateways { for _, gateway := range gateways {
_, err := fakeIstioClient.NetworkingV1alpha3().Gateways(gateway.Namespace).Create(context.Background(), gateway, metav1.CreateOptions{}) _, err := fakeIstioClient.NetworkingV1beta1().Gateways(gateway.Namespace).Create(context.Background(), gateway, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
} }
for _, virtualservice := range virtualservices { for _, vService := range virtualservices {
_, err := fakeIstioClient.NetworkingV1alpha3().VirtualServices(virtualservice.Namespace).Create(context.Background(), virtualservice, metav1.CreateOptions{}) _, err := fakeIstioClient.NetworkingV1beta1().VirtualServices(vService.Namespace).Create(context.Background(), vService, metav1.CreateOptions{})
require.NoError(t, err) require.NoError(t, err)
} }
@ -2041,7 +2041,7 @@ func testGatewaySelectorMatchesService(t *testing.T) {
} }
func newTestVirtualServiceSource(loadBalancerList []fakeIngressGatewayService, ingressList []fakeIngress, gwList []fakeGatewayConfig) (*virtualServiceSource, error) { func newTestVirtualServiceSource(loadBalancerList []fakeIngressGatewayService, ingressList []fakeIngress, gwList []fakeGatewayConfig) (*virtualServiceSource, error) {
fakeKubernetesClient := fake.NewSimpleClientset() fakeKubernetesClient := fake.NewClientset()
fakeIstioClient := istiofake.NewSimpleClientset() fakeIstioClient := istiofake.NewSimpleClientset()
for _, lb := range loadBalancerList { for _, lb := range loadBalancerList {
@ -2064,7 +2064,7 @@ func newTestVirtualServiceSource(loadBalancerList []fakeIngressGatewayService, i
gwObj := gw.Config() gwObj := gw.Config()
// use create instead of add // use create instead of add
// https://github.com/kubernetes/client-go/blob/92512ee2b8cf6696e9909245624175b7f0c971d9/testing/fixture.go#LL336C3-L336C52 // https://github.com/kubernetes/client-go/blob/92512ee2b8cf6696e9909245624175b7f0c971d9/testing/fixture.go#LL336C3-L336C52
_, err := fakeIstioClient.NetworkingV1alpha3().Gateways(gw.namespace).Create(context.Background(), gwObj, metav1.CreateOptions{}) _, err := fakeIstioClient.NetworkingV1beta1().Gateways(gw.namespace).Create(context.Background(), gwObj, metav1.CreateOptions{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -2101,7 +2101,7 @@ type fakeVirtualServiceConfig struct {
exportTo string exportTo string
} }
func (c fakeVirtualServiceConfig) Config() *networkingv1alpha3.VirtualService { func (c fakeVirtualServiceConfig) Config() *networkingv1beta1.VirtualService {
vs := istionetworking.VirtualService{ vs := istionetworking.VirtualService{
Gateways: c.gateways, Gateways: c.gateways,
Hosts: c.dnsnames, Hosts: c.dnsnames,
@ -2110,7 +2110,7 @@ func (c fakeVirtualServiceConfig) Config() *networkingv1alpha3.VirtualService {
vs.ExportTo = []string{c.exportTo} vs.ExportTo = []string{c.exportTo}
} }
return &networkingv1alpha3.VirtualService{ return &networkingv1beta1.VirtualService{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: c.name, Name: c.name,
Namespace: c.namespace, Namespace: c.namespace,
@ -2127,13 +2127,13 @@ func TestVirtualServiceSourceGetGateway(t *testing.T) {
type args struct { type args struct {
ctx context.Context ctx context.Context
gatewayStr string gatewayStr string
virtualService *networkingv1alpha3.VirtualService virtualService *networkingv1beta1.VirtualService
} }
tests := []struct { tests := []struct {
name string name string
fields fields fields fields
args args args args
want *networkingv1alpha3.Gateway want *networkingv1beta1.Gateway
expectedErrStr string expectedErrStr string
}{ }{
{name: "EmptyGateway", fields: fields{ {name: "EmptyGateway", fields: fields{
@ -2155,7 +2155,7 @@ func TestVirtualServiceSourceGetGateway(t *testing.T) {
}, args: args{ }, args: args{
ctx: context.TODO(), ctx: context.TODO(),
gatewayStr: "doesnt/exist", gatewayStr: "doesnt/exist",
virtualService: &networkingv1alpha3.VirtualService{ virtualService: &networkingv1beta1.VirtualService{
TypeMeta: metav1.TypeMeta{}, TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{Name: "exist", Namespace: "doesnt"}, ObjectMeta: metav1.ObjectMeta{Name: "exist", Namespace: "doesnt"},
Spec: istionetworking.VirtualService{}, Spec: istionetworking.VirtualService{},
@ -2167,8 +2167,8 @@ func TestVirtualServiceSourceGetGateway(t *testing.T) {
}, args: args{ }, args: args{
ctx: context.TODO(), ctx: context.TODO(),
gatewayStr: "1/2/3/", gatewayStr: "1/2/3/",
virtualService: &networkingv1alpha3.VirtualService{}, virtualService: &networkingv1beta1.VirtualService{},
}, want: nil, expectedErrStr: "invalid gateway name (name or namespace/name) found '1/2/3/'"}, }, want: nil, expectedErrStr: "invalid ingress name (name or namespace/name) found \"1/2/3/\""},
{name: "ExistingGateway", fields: fields{ {name: "ExistingGateway", fields: fields{
virtualServiceSource: func() *virtualServiceSource { virtualServiceSource: func() *virtualServiceSource {
vs, _ := newTestVirtualServiceSource(nil, nil, []fakeGatewayConfig{{ vs, _ := newTestVirtualServiceSource(nil, nil, []fakeGatewayConfig{{
@ -2180,13 +2180,13 @@ func TestVirtualServiceSourceGetGateway(t *testing.T) {
}, args: args{ }, args: args{
ctx: context.TODO(), ctx: context.TODO(),
gatewayStr: "bar/foo", gatewayStr: "bar/foo",
virtualService: &networkingv1alpha3.VirtualService{ virtualService: &networkingv1beta1.VirtualService{
TypeMeta: metav1.TypeMeta{}, TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
Spec: istionetworking.VirtualService{}, Spec: istionetworking.VirtualService{},
Status: v1alpha1.IstioStatus{}, Status: v1alpha1.IstioStatus{},
}, },
}, want: &networkingv1alpha3.Gateway{ }, want: &networkingv1beta1.Gateway{
TypeMeta: metav1.TypeMeta{}, TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
Spec: istionetworking.Gateway{}, Spec: istionetworking.Gateway{},