github.com/solo-io/service-mesh-hub@v0.9.2/test/e2e/istio/federation_test.go (about)

     1  package istio_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	discoveryv1alpha2 "github.com/solo-io/service-mesh-hub/pkg/api/discovery.smh.solo.io/v1alpha2"
     9  	"github.com/solo-io/service-mesh-hub/pkg/api/networking.smh.solo.io/v1alpha2"
    10  	"github.com/solo-io/service-mesh-hub/pkg/mesh-networking/translation/utils/metautils"
    11  	"github.com/solo-io/service-mesh-hub/test/data"
    12  	"github.com/solo-io/service-mesh-hub/test/e2e"
    13  	"github.com/solo-io/service-mesh-hub/test/utils"
    14  	v1 "github.com/solo-io/skv2/pkg/api/core.skv2.solo.io/v1"
    15  	istionetworkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
    16  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    17  	"sigs.k8s.io/controller-runtime/pkg/client"
    18  
    19  	. "github.com/onsi/ginkgo"
    20  	. "github.com/onsi/gomega"
    21  )
    22  
    23  var _ = Describe("Federation", func() {
    24  	var (
    25  		err      error
    26  		manifest utils.Manifest
    27  		ctx      = context.Background()
    28  	)
    29  
    30  	AfterEach(func() {
    31  		manifest.Cleanup(BookinfoNamespace)
    32  	})
    33  
    34  	/*
    35  		These tests assume that federation has been established between mgmt and remote clusters.
    36  	*/
    37  
    38  	It("enables communication across clusters using global dns names", func() {
    39  		manifest, err = utils.NewManifest("federation-trafficpolicies.yaml")
    40  		Expect(err).NotTo(HaveOccurred())
    41  
    42  		By("with federation enabled, TrafficShifts can be used for subsets across meshes ", func() {
    43  			// create cross cluster traffic shift
    44  			trafficShiftReviewsV3 := data.RemoteTrafficShiftPolicy("bookinfo-policy", BookinfoNamespace, &v1.ClusterObjectRef{
    45  				Name:        "reviews",
    46  				Namespace:   BookinfoNamespace,
    47  				ClusterName: mgmtClusterName,
    48  			}, remoteClusterName, map[string]string{"version": "v3"}, 9080)
    49  
    50  			err = manifest.AppendResources(trafficShiftReviewsV3)
    51  			Expect(err).NotTo(HaveOccurred())
    52  			err = manifest.KubeApply(BookinfoNamespace)
    53  			Expect(err).NotTo(HaveOccurred())
    54  
    55  			// ensure status is updated
    56  			utils.AssertTrafficPolicyStatuses(dynamicClient, BookinfoNamespace)
    57  
    58  			// check we can eventually hit the v3 subset
    59  			Eventually(curlReviews, "30s", "1s").Should(ContainSubstring(`"color": "red"`))
    60  		})
    61  	})
    62  
    63  	It("should output a VirtualService for the federated ServiceEntry", func() {
    64  		By("fault injection should be applied when sending requests to a federated ServiceEntry", func() {
    65  			manifest, err = utils.NewManifest("federation-trafficpolicies.yaml")
    66  			Expect(err).NotTo(HaveOccurred())
    67  
    68  			// Create TrafficPolicy with fault injection applied to remote cluster
    69  			faultInjectionPolicy := &v1alpha2.TrafficPolicy{
    70  				ObjectMeta: metav1.ObjectMeta{
    71  					Name:      "remote-fault-injection",
    72  					Namespace: BookinfoNamespace,
    73  				},
    74  				TypeMeta: metav1.TypeMeta{
    75  					Kind:       "TrafficPolicy",
    76  					APIVersion: v1alpha2.SchemeGroupVersion.String(),
    77  				},
    78  				Spec: v1alpha2.TrafficPolicySpec{
    79  					SourceSelector: nil,
    80  					DestinationSelector: []*v1alpha2.TrafficTargetSelector{{
    81  						KubeServiceRefs: &v1alpha2.TrafficTargetSelector_KubeServiceRefs{
    82  							Services: []*v1.ClusterObjectRef{
    83  								{
    84  									Name:        "reviews",
    85  									Namespace:   BookinfoNamespace,
    86  									ClusterName: remoteClusterName,
    87  								},
    88  							},
    89  						},
    90  					}},
    91  					FaultInjection: &v1alpha2.TrafficPolicySpec_FaultInjection{
    92  						FaultInjectionType: &v1alpha2.TrafficPolicySpec_FaultInjection_Abort_{
    93  							&v1alpha2.TrafficPolicySpec_FaultInjection_Abort{
    94  								HttpStatus: http.StatusTeapot,
    95  							},
    96  						},
    97  						Percentage: 100,
    98  					},
    99  				},
   100  			}
   101  
   102  			err = manifest.AppendResources(faultInjectionPolicy)
   103  			Expect(err).NotTo(HaveOccurred())
   104  			err = manifest.KubeApply(BookinfoNamespace)
   105  			Expect(err).NotTo(HaveOccurred())
   106  
   107  			// ensure status is updated
   108  			utils.AssertTrafficPolicyStatuses(dynamicClient, BookinfoNamespace)
   109  
   110  			Eventually(curlRemoteReviews, "30s", "1s").Should(ContainSubstring("418"))
   111  
   112  			// Delete TrafficPolicy so it doesn't interfere with subsequent tests
   113  			manifest.KubeDelete(BookinfoNamespace)
   114  		})
   115  
   116  		// TODO(harveyxia) move this to a unit test if possible
   117  		By("traffic mirrors and shifts should use correct hostname for federated ServiceEntry", func() {
   118  			manifest, err = utils.NewManifest("federation-trafficpolicies.yaml")
   119  			Expect(err).NotTo(HaveOccurred())
   120  
   121  			// Create TrafficPolicy with fault injection applied to remote cluster
   122  			trafficPolicy := &v1alpha2.TrafficPolicy{
   123  				ObjectMeta: metav1.ObjectMeta{
   124  					Name:      "remote-mirror-and-shift",
   125  					Namespace: BookinfoNamespace,
   126  				},
   127  				TypeMeta: metav1.TypeMeta{
   128  					Kind:       "TrafficPolicy",
   129  					APIVersion: v1alpha2.SchemeGroupVersion.String(),
   130  				},
   131  				Spec: v1alpha2.TrafficPolicySpec{
   132  					SourceSelector: nil,
   133  					DestinationSelector: []*v1alpha2.TrafficTargetSelector{{
   134  						KubeServiceRefs: &v1alpha2.TrafficTargetSelector_KubeServiceRefs{
   135  							Services: []*v1.ClusterObjectRef{
   136  								{
   137  									Name:        "reviews",
   138  									Namespace:   BookinfoNamespace,
   139  									ClusterName: remoteClusterName,
   140  								},
   141  							},
   142  						},
   143  					}},
   144  					Mirror: &v1alpha2.TrafficPolicySpec_Mirror{
   145  						DestinationType: &v1alpha2.TrafficPolicySpec_Mirror_KubeService{
   146  							KubeService: &v1.ClusterObjectRef{
   147  								Name:        "reviews",
   148  								Namespace:   BookinfoNamespace,
   149  								ClusterName: mgmtClusterName,
   150  							},
   151  						},
   152  						Percentage: 50,
   153  						Port:       9080,
   154  					},
   155  					TrafficShift: &v1alpha2.TrafficPolicySpec_MultiDestination{
   156  						Destinations: []*v1alpha2.TrafficPolicySpec_MultiDestination_WeightedDestination{
   157  							{
   158  								DestinationType: &v1alpha2.TrafficPolicySpec_MultiDestination_WeightedDestination_KubeService{
   159  									KubeService: &v1alpha2.TrafficPolicySpec_MultiDestination_WeightedDestination_KubeDestination{
   160  										Name:        "reviews",
   161  										Namespace:   BookinfoNamespace,
   162  										ClusterName: mgmtClusterName,
   163  									},
   164  								},
   165  								Weight: 50,
   166  							},
   167  						},
   168  					},
   169  				},
   170  			}
   171  
   172  			err = manifest.AppendResources(trafficPolicy)
   173  			Expect(err).NotTo(HaveOccurred())
   174  			err = manifest.KubeApply(BookinfoNamespace)
   175  			Expect(err).NotTo(HaveOccurred())
   176  
   177  			// ensure status is updated
   178  			utils.AssertTrafficPolicyStatuses(dynamicClient, BookinfoNamespace)
   179  
   180  			var getFederatedVirtualService = func() (*istionetworkingv1alpha3.VirtualService, error) {
   181  				env := e2e.GetEnv()
   182  				vsClient := env.Management.VirtualServiceClient
   183  				meta := metautils.FederatedObjectMeta(
   184  					&metav1.ObjectMeta{
   185  						Name:        "reviews",
   186  						Namespace:   BookinfoNamespace,
   187  						ClusterName: remoteClusterName,
   188  					},
   189  					&discoveryv1alpha2.MeshSpec_MeshInstallation{
   190  						Namespace: "istio-system",
   191  						Cluster:   mgmtClusterName,
   192  					},
   193  					nil,
   194  				)
   195  				return vsClient.GetVirtualService(ctx, client.ObjectKey{Name: meta.Name, Namespace: meta.Namespace})
   196  			}
   197  
   198  			Eventually(func() bool {
   199  				virtualService, err := getFederatedVirtualService()
   200  				if err != nil {
   201  					return false
   202  				}
   203  				if len(virtualService.Spec.Http) > 0 {
   204  					httpRoute := virtualService.Spec.Http[0]
   205  					if httpRoute.GetMirror().GetHost() != fmt.Sprintf("reviews.%s.svc.cluster.local", BookinfoNamespace) {
   206  						return false
   207  					}
   208  					if len(httpRoute.GetRoute()) < 1 {
   209  						return false
   210  					}
   211  					if httpRoute.GetRoute()[0].GetDestination().GetHost() != fmt.Sprintf("reviews.%s.svc.cluster.local", BookinfoNamespace) {
   212  						return false
   213  					}
   214  					return true
   215  				}
   216  				return false
   217  			}, "30s", "1s").Should(BeTrue())
   218  		})
   219  	})
   220  })