istio.io/istio@v0.0.0-20240520182934-d79c90f27776/tests/integration/pilot/mcs/autoexport/autoexport_test.go (about)

     1  //go:build integ
     2  // +build integ
     3  
     4  // Copyright Istio Authors
     5  //
     6  // Licensed under the Apache License, Version 2.0 (the "License");
     7  // you may not use this file except in compliance with the License.
     8  // You may obtain a copy of the License at
     9  //
    10  //     http://www.apache.org/licenses/LICENSE-2.0
    11  //
    12  // Unless required by applicable law or agreed to in writing, software
    13  // distributed under the License is distributed on an "AS IS" BASIS,
    14  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  // See the License for the specific language governing permissions and
    16  // limitations under the License.
    17  
    18  package autoexport
    19  
    20  import (
    21  	"context"
    22  	"fmt"
    23  	"strconv"
    24  	"testing"
    25  	"time"
    26  
    27  	k8sErrors "k8s.io/apimachinery/pkg/api/errors"
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  
    30  	"istio.io/istio/pkg/test/framework"
    31  	"istio.io/istio/pkg/test/framework/components/echo"
    32  	"istio.io/istio/pkg/test/framework/components/echo/match"
    33  	"istio.io/istio/pkg/test/framework/components/istio"
    34  	"istio.io/istio/pkg/test/framework/label"
    35  	"istio.io/istio/pkg/test/framework/resource"
    36  	"istio.io/istio/pkg/test/util/retry"
    37  	"istio.io/istio/tests/integration/pilot/mcs/common"
    38  )
    39  
    40  var (
    41  	i     istio.Instance
    42  	echos common.EchoDeployment
    43  )
    44  
    45  func TestMain(m *testing.M) {
    46  	// nolint: staticcheck
    47  	framework.
    48  		NewSuite(m).
    49  		Label(label.CustomSetup).
    50  		RequireMultiPrimary().
    51  		RequireMinVersion(17).
    52  		Setup(common.InstallMCSCRDs).
    53  		Setup(istio.Setup(&i, enableMCSAutoExport)).
    54  		Setup(common.DeployEchosFunc("se", &echos)).
    55  		Run()
    56  }
    57  
    58  func TestAutoExport(t *testing.T) {
    59  	framework.NewTest(t).
    60  		Run(func(ctx framework.TestContext) {
    61  			serviceExportGVR := common.KubeSettings(ctx).ServiceExportGVR()
    62  			// Verify that ServiceExport is created automatically for services.
    63  			ctx.NewSubTest("exported").RunParallel(
    64  				func(ctx framework.TestContext) {
    65  					serviceB := match.ServiceName(echo.NamespacedName{Name: common.ServiceB, Namespace: echos.Namespace})
    66  					for _, cluster := range serviceB.GetMatches(echos.Instances).Clusters() {
    67  						cluster := cluster
    68  						ctx.NewSubTest(cluster.StableName()).RunParallel(func(ctx framework.TestContext) {
    69  							// Verify that the ServiceExport was created.
    70  							ctx.NewSubTest("create").Run(func(ctx framework.TestContext) {
    71  								retry.UntilSuccessOrFail(ctx, func() error {
    72  									serviceExport, err := cluster.Dynamic().Resource(serviceExportGVR).Namespace(echos.Namespace.Name()).Get(
    73  										context.TODO(), common.ServiceB, metav1.GetOptions{})
    74  									if err != nil {
    75  										return err
    76  									}
    77  
    78  									if serviceExport == nil {
    79  										return fmt.Errorf("serviceexport %s/%s not found in cluster %s",
    80  											echos.Namespace, common.ServiceB, cluster.Name())
    81  									}
    82  
    83  									return nil
    84  								}, retry.Timeout(30*time.Second))
    85  							})
    86  
    87  							// Delete the echo Service and verify that the ServiceExport is automatically removed.
    88  							ctx.NewSubTest("delete").Run(func(ctx framework.TestContext) {
    89  								err := cluster.Kube().CoreV1().Services(echos.Namespace.Name()).Delete(
    90  									context.TODO(), common.ServiceB, metav1.DeleteOptions{})
    91  								if err != nil {
    92  									ctx.Fatalf("failed deleting service %s/%s in cluster %s: %v",
    93  										echos.Namespace, common.ServiceB, cluster.Name(), err)
    94  								}
    95  								retry.UntilSuccessOrFail(t, func() error {
    96  									_, err := cluster.Dynamic().Resource(serviceExportGVR).Namespace(echos.Namespace.Name()).Get(
    97  										context.TODO(), common.ServiceB, metav1.GetOptions{})
    98  
    99  									if err != nil && k8sErrors.IsNotFound(err) {
   100  										// Success! We automatically removed the ServiceExport when the Service
   101  										// removed.
   102  										return nil
   103  									}
   104  
   105  									if err != nil {
   106  										return err
   107  									}
   108  
   109  									return fmt.Errorf("failed to remove serviceExport %s/%s in cluster %s",
   110  										echos.Namespace, common.ServiceB, cluster.Name())
   111  								}, retry.Timeout(30*time.Second))
   112  							})
   113  						})
   114  					}
   115  				})
   116  
   117  			// Verify that cluster-local services do not automatically generate ServiceExport.
   118  			ctx.NewSubTest("non-exported").RunParallel(func(ctx framework.TestContext) {
   119  				ns := "kube-system"
   120  				for i, cluster := range ctx.Clusters() {
   121  					cluster := cluster
   122  					ctx.NewSubTest(strconv.Itoa(i)).RunParallel(func(ctx framework.TestContext) {
   123  						services, err := cluster.Dynamic().Resource(serviceExportGVR).Namespace(ns).List(
   124  							context.TODO(), metav1.ListOptions{})
   125  						if err != nil {
   126  							ctx.Fatal(err)
   127  						}
   128  						if len(services.Items) > 0 {
   129  							ctx.Fatalf("serviceexports created for cluster-local services in cluster %s",
   130  								cluster.Name())
   131  						}
   132  					})
   133  				}
   134  			})
   135  		})
   136  }
   137  
   138  func enableMCSAutoExport(t resource.Context, cfg *istio.Config) {
   139  	cfg.ControlPlaneValues = fmt.Sprintf(`
   140  values:
   141    pilot:
   142      env:
   143        ENABLE_MCS_AUTO_EXPORT: "true"
   144        MCS_API_GROUP: %s
   145        MCS_API_VERSION: %s`,
   146  		common.KubeSettings(t).MCSAPIGroup,
   147  		common.KubeSettings(t).MCSAPIVersion)
   148  }