github.com/verrazzano/verrazzano@v1.7.0/platform-operator/internal/vzconfig/args_test.go (about)

     1  // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package vzconfig
     5  
     6  import (
     7  	"fmt"
     8  	"github.com/stretchr/testify/assert"
     9  	vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1"
    10  	installv1beta1 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1"
    11  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/validators"
    12  	corev1 "k8s.io/api/core/v1"
    13  	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    14  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    15  	"k8s.io/apimachinery/pkg/runtime"
    16  	"k8s.io/apimachinery/pkg/util/yaml"
    17  	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
    18  	"sigs.k8s.io/controller-runtime/pkg/client"
    19  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    20  	"testing"
    21  )
    22  
    23  const (
    24  	nodePort                 = installv1beta1.NodePort
    25  	compName                 = "istio"
    26  	ExternalIPArg            = "gateways.istio-ingressgateway.externalIPs"
    27  	specServiceJSONPath      = "spec.components.ingressGateways.0.k8s.service"
    28  	externalIPJsonPathSuffix = "externalIPs"
    29  	typeJSONPathSuffix       = "type"
    30  	externalIPJsonPath       = specServiceJSONPath + "." + externalIPJsonPathSuffix
    31  	validIP                  = "0.0.0.0"
    32  	invalidIP                = "0.0.0"
    33  	formatError              = "Must be a proper IP address format"
    34  	configMap                = "configMap"
    35  	secret                   = "secret"
    36  	values                   = "values"
    37  )
    38  
    39  // TestCheckExternalIPsArgs tests CheckExternalIPsArgs
    40  // GIVEN a v1alpha1 VZ CR with ExternalIP IstioOverrides
    41  // WHEN the override key is not found or the IP is invalid
    42  // THEN return an error, nil otherwise
    43  func TestCheckExternalIPsArgs(t *testing.T) {
    44  	asserts := assert.New(t)
    45  	createFakeTestClient()
    46  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
    47  
    48  	vz := getv1alpha1VZ()
    49  	createv1alpha1VZOverrides(vz, "", "", values, validIP)
    50  	err := CheckExternalIPsArgs(vz.Spec.Components.Istio.IstioInstallArgs, vz.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
    51  	asserts.NoError(err)
    52  	createv1alpha1VZOverrides(vz, "", "", values, invalidIP)
    53  	err = CheckExternalIPsArgs(vz.Spec.Components.Istio.IstioInstallArgs, vz.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
    54  	asserts.Error(err)
    55  	asserts.Contains(err.Error(), formatError)
    56  	createv1alpha1VZOverrides(vz, "", "", values, "")
    57  	err = CheckExternalIPsArgs(vz.Spec.Components.Istio.IstioInstallArgs, vz.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
    58  	asserts.Error(err)
    59  	asserts.Contains(err.Error(), "invalid data type")
    60  }
    61  
    62  // TestCheckExternalIPsOverridesArgs tests CheckExternalIPsOverridesArgs
    63  // GIVEN a v1beta1 VZ CR with ExternalIP IstioOverrides
    64  // WHEN the IP is not valid
    65  // THEN return an error, nil otherwise
    66  func TestCheckExternalIPsOverridesArgs(t *testing.T) {
    67  	asserts := assert.New(t)
    68  	createFakeTestClient()
    69  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
    70  
    71  	vz := getv1beta1VZ()
    72  	createv1beta1VZOverrides(vz, "", "", values, validIP)
    73  	err := CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
    74  	asserts.NoError(err)
    75  	createv1beta1VZOverrides(vz, "", "", values, invalidIP)
    76  	err = CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
    77  	asserts.Error(err)
    78  	asserts.Contains(err.Error(), formatError)
    79  	createv1beta1VZOverrides(vz, "", "", values, "")
    80  	err = CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
    81  	asserts.Error(err)
    82  	asserts.Contains(err.Error(), "invalid data type")
    83  }
    84  
    85  // TestCheckExternalIPsOverridesArgsWithPaths tests CheckExternalIPsOverridesArgsWithPaths
    86  // GIVEN a v1beta1 VZ CR with ExternalIP IstioOverrides
    87  // WHEN the IP is not valid
    88  // THEN return an error, nil otherwise
    89  func TestCheckExternalIPsOverridesArgsWithPaths(t *testing.T) {
    90  	asserts := assert.New(t)
    91  	createFakeTestClient()
    92  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
    93  
    94  	vz := getv1beta1VZ()
    95  	createv1beta1VZOverrides(vz, "", "", values, validIP)
    96  	err := CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
    97  	asserts.NoError(err)
    98  	createv1beta1VZOverrides(vz, "", "", values, invalidIP)
    99  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   100  	asserts.Error(err)
   101  	asserts.Contains(err.Error(), formatError)
   102  	createv1beta1VZOverrides(vz, "", "", values, "")
   103  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   104  	asserts.Error(err)
   105  	asserts.Contains(err.Error(), "invalid data type")
   106  }
   107  
   108  func TestValidIPWithConfigMapOverride(t *testing.T) {
   109  	asserts := assert.New(t)
   110  	createFakeTestClientWithConfigMap(createTestConfigMap(true, validIP, validIP))
   111  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
   112  
   113  	vz := getv1beta1VZ()
   114  	createv1beta1VZOverrides(vz, configMap, "", "", validIP)
   115  	err := CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
   116  	asserts.NoError(err)
   117  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   118  	asserts.NoError(err)
   119  
   120  	// Test CheckExternalIPsArgs uses a v1alpha1 vz resource
   121  	v1alpha1VZ := createv1alpha1VZOverrides(getv1alpha1VZ(), configMap, "", "", validIP)
   122  	err = CheckExternalIPsArgs(v1alpha1VZ.Spec.Components.Istio.IstioInstallArgs, v1alpha1VZ.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
   123  	asserts.NoError(err)
   124  }
   125  
   126  func TestInvalidIPWithConfigMapOverride(t *testing.T) {
   127  	asserts := assert.New(t)
   128  	createFakeTestClientWithConfigMap(createTestConfigMap(true, invalidIP, invalidIP))
   129  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
   130  
   131  	vz := getv1beta1VZ()
   132  	createv1beta1VZOverrides(vz, configMap, "", "", "")
   133  	err := CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
   134  	asserts.Error(err)
   135  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   136  	asserts.Error(err)
   137  
   138  	// Test CheckExternalIPsArgs uses a v1alpha1 vz resource
   139  	v1alpha1VZ := getv1alpha1VZ()
   140  	createv1alpha1VZOverrides(v1alpha1VZ, configMap, "", "", "")
   141  	err = CheckExternalIPsArgs(v1alpha1VZ.Spec.Components.Istio.IstioInstallArgs, v1alpha1VZ.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
   142  	asserts.Error(err)
   143  }
   144  
   145  func TestValidIPWithSecretOverride(t *testing.T) {
   146  	asserts := assert.New(t)
   147  	createFakeTestClientWithSecret(createTestSecret(true, validIP, validIP))
   148  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
   149  
   150  	vz := getv1beta1VZ()
   151  	createv1beta1VZOverrides(vz, "", secret, "", "")
   152  	err := CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
   153  	asserts.NoError(err)
   154  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   155  	asserts.NoError(err)
   156  
   157  	// Test CheckExternalIPsArgs uses a v1alpha1 vz resource
   158  	v1alpha1VZ := getv1alpha1VZ()
   159  	createv1alpha1VZOverrides(v1alpha1VZ, "", secret, "", "")
   160  	err = CheckExternalIPsArgs(v1alpha1VZ.Spec.Components.Istio.IstioInstallArgs, v1alpha1VZ.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
   161  	asserts.NoError(err)
   162  }
   163  
   164  func TestInvalidIPWithSecretOverride(t *testing.T) {
   165  	asserts := assert.New(t)
   166  	createFakeTestClientWithSecret(createTestSecret(true, "", ""))
   167  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
   168  
   169  	vz := getv1beta1VZ()
   170  	createv1beta1VZOverrides(vz, "", secret, invalidIP, invalidIP)
   171  	err := CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
   172  	asserts.Error(err)
   173  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   174  	asserts.Error(err)
   175  
   176  	// Test CheckExternalIPsArgs uses a v1alpha1 vz resource
   177  	v1alpha1VZ := getv1alpha1VZ()
   178  	createv1alpha1VZOverrides(v1alpha1VZ, "", secret, "", "")
   179  	err = CheckExternalIPsArgs(v1alpha1VZ.Spec.Components.Istio.IstioInstallArgs, v1alpha1VZ.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
   180  	asserts.Error(err)
   181  }
   182  
   183  func TestValidIPWithConfigMapSecretOverride(t *testing.T) {
   184  	asserts := assert.New(t)
   185  	createFakeTestClientWithConfigMapAndSecret(
   186  		createTestConfigMap(false, validIP, ""),
   187  		createTestSecret(false, validIP, ""))
   188  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
   189  
   190  	vz := getv1beta1VZ()
   191  	createv1beta1VZOverrides(vz, configMap, secret, "", "")
   192  	err := CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
   193  	asserts.NoError(err)
   194  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   195  	asserts.NoError(err)
   196  
   197  	// Test CheckExternalIPsArgs uses a v1alpha1 vz resource
   198  	v1alpha1VZ := getv1alpha1VZ()
   199  	createv1alpha1VZOverrides(v1alpha1VZ, configMap, secret, "", "")
   200  	err = CheckExternalIPsArgs(v1alpha1VZ.Spec.Components.Istio.IstioInstallArgs, v1alpha1VZ.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
   201  	asserts.NoError(err)
   202  }
   203  
   204  func TestInvalidIPWithConfigMapSecretOverride(t *testing.T) {
   205  	asserts := assert.New(t)
   206  	createFakeTestClientWithConfigMapAndSecret(
   207  		createTestConfigMap(false, invalidIP, ""),
   208  		createTestSecret(false, invalidIP, ""))
   209  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
   210  
   211  	vz := getv1beta1VZ()
   212  	createv1beta1VZOverrides(vz, configMap, secret, "", "")
   213  	err := CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
   214  	asserts.Error(err)
   215  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   216  	asserts.Error(err)
   217  
   218  	// Test CheckExternalIPsArgs uses a v1alpha1 vz resource
   219  	v1alpha1VZ := getv1alpha1VZ()
   220  	createv1alpha1VZOverrides(v1alpha1VZ, configMap, secret, "", "")
   221  	err = CheckExternalIPsArgs(v1alpha1VZ.Spec.Components.Istio.IstioInstallArgs, v1alpha1VZ.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
   222  	asserts.Error(err)
   223  }
   224  
   225  func TestValidIPWithConfigMapValue(t *testing.T) {
   226  	asserts := assert.New(t)
   227  	createFakeTestClientWithConfigMap(createTestConfigMap(false, validIP, ""))
   228  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
   229  
   230  	vz := getv1beta1VZ()
   231  	createv1beta1VZOverrides(vz, configMap, "", values, validIP)
   232  	err := CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
   233  	asserts.NoError(err)
   234  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   235  	asserts.NoError(err)
   236  
   237  	// Test CheckExternalIPsArgs uses a v1alpha1 vz resource
   238  	v1alpha1VZ := getv1alpha1VZ()
   239  	createv1alpha1VZOverrides(v1alpha1VZ, configMap, "", values, validIP)
   240  	err = CheckExternalIPsArgs(v1alpha1VZ.Spec.Components.Istio.IstioInstallArgs, v1alpha1VZ.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
   241  	asserts.NoError(err)
   242  
   243  }
   244  
   245  func TestInvalidIPWithConfigMapValue(t *testing.T) {
   246  	asserts := assert.New(t)
   247  	createFakeTestClientWithConfigMap(createTestConfigMap(false, invalidIP, ""))
   248  	defer func() { GetControllerRuntimeClient = validators.GetClient }()
   249  
   250  	vz := getv1beta1VZ()
   251  	createv1beta1VZOverrides(vz, configMap, "", values, invalidIP)
   252  	err := CheckExternalIPsOverridesArgs(vz.Spec.Components.Istio.ValueOverrides, externalIPJsonPath, compName, vz.Namespace)
   253  	asserts.Error(err)
   254  	err = CheckExternalIPsOverridesArgsWithPaths(vz.Spec.Components.Istio.ValueOverrides, specServiceJSONPath, typeJSONPathSuffix, string(nodePort), externalIPJsonPathSuffix, compName, vz.Namespace)
   255  	asserts.Error(err)
   256  
   257  	// Test CheckExternalIPsArgs uses a v1alpha1 vz resource
   258  	v1alpha1VZ := getv1alpha1VZ()
   259  	createv1alpha1VZOverrides(v1alpha1VZ, configMap, "", values, invalidIP)
   260  	err = CheckExternalIPsArgs(v1alpha1VZ.Spec.Components.Istio.IstioInstallArgs, v1alpha1VZ.Spec.Components.Istio.ValueOverrides, ExternalIPArg, externalIPJsonPath, compName, vz.Namespace)
   261  	asserts.Error(err)
   262  
   263  }
   264  
   265  // getv1alpha1VZ returns v1beta1 vz CR with Empty ValueOverirides
   266  func getv1alpha1VZ() vzapi.Verrazzano {
   267  	vz := vzapi.Verrazzano{
   268  		ObjectMeta: metav1.ObjectMeta{Namespace: "default"},
   269  		Spec: vzapi.VerrazzanoSpec{
   270  			Components: vzapi.ComponentSpec{
   271  				Istio: &vzapi.IstioComponent{
   272  					InstallOverrides: vzapi.InstallOverrides{
   273  						ValueOverrides: []vzapi.Overrides{
   274  							{}, {}, {},
   275  						},
   276  					},
   277  				},
   278  			},
   279  		},
   280  	}
   281  	return vz
   282  }
   283  
   284  // getv1beta1VZ returns v1beta1 vz CR with Empty ValueOverirides
   285  func getv1beta1VZ() installv1beta1.Verrazzano {
   286  	vz := installv1beta1.Verrazzano{
   287  		ObjectMeta: metav1.ObjectMeta{Namespace: "default"},
   288  		Spec: installv1beta1.VerrazzanoSpec{
   289  			Components: installv1beta1.ComponentSpec{
   290  				Istio: &installv1beta1.IstioComponent{
   291  					InstallOverrides: installv1beta1.InstallOverrides{
   292  						ValueOverrides: []installv1beta1.Overrides{
   293  							{}, {}, {},
   294  						},
   295  					},
   296  				},
   297  			},
   298  		},
   299  	}
   300  	return vz
   301  }
   302  
   303  func createv1beta1VZOverrides(vz installv1beta1.Verrazzano, configMap, secret, values, testIP string) installv1beta1.Verrazzano {
   304  	if configMap != "" {
   305  		vz.Spec.Components.Istio.InstallOverrides.ValueOverrides[0].ConfigMapRef = createTestConfigMapKeySelector()
   306  	}
   307  	if secret != "" {
   308  		vz.Spec.Components.Istio.InstallOverrides.ValueOverrides[1].SecretRef = createTestSecretKeySelector()
   309  	}
   310  	if values != "" {
   311  		vz.Spec.Components.Istio.InstallOverrides.ValueOverrides[2].Values = createTestValueJSON(testIP)
   312  	}
   313  	return vz
   314  }
   315  
   316  func createv1alpha1VZOverrides(vz vzapi.Verrazzano, configMap, secret, values, testIP string) vzapi.Verrazzano {
   317  	if configMap != "" {
   318  		vz.Spec.Components.Istio.InstallOverrides.ValueOverrides[0].ConfigMapRef = createTestConfigMapKeySelector()
   319  	}
   320  	if secret != "" {
   321  		vz.Spec.Components.Istio.InstallOverrides.ValueOverrides[1].SecretRef = createTestSecretKeySelector()
   322  	}
   323  	if values != "" {
   324  		vz.Spec.Components.Istio.InstallOverrides.ValueOverrides[2].Values = createTestValueJSON(testIP)
   325  	}
   326  	return vz
   327  }
   328  
   329  func createTestConfigMapKeySelector() *corev1.ConfigMapKeySelector {
   330  	return &corev1.ConfigMapKeySelector{
   331  		Key: "configMapKey",
   332  		LocalObjectReference: corev1.LocalObjectReference{
   333  			Name: "testCMName",
   334  		},
   335  	}
   336  }
   337  
   338  func createTestSecretKeySelector() *corev1.SecretKeySelector {
   339  	return &corev1.SecretKeySelector{
   340  		Key: "secretKey",
   341  		LocalObjectReference: corev1.LocalObjectReference{
   342  			Name: "testSecretName",
   343  		},
   344  	}
   345  }
   346  
   347  func createTestValueJSON(testIP string) *apiextensionsv1.JSON {
   348  	return &apiextensionsv1.JSON{
   349  		Raw: createValueOverrideData(testIP),
   350  	}
   351  }
   352  
   353  func createTestConfigMap(isArrayOfIPs bool, testIPA, testIPB string) *corev1.ConfigMap {
   354  	data := make(map[string]string)
   355  	data["configMapKey"] = createOverrideData(isArrayOfIPs, testIPA, testIPB)
   356  	return &corev1.ConfigMap{
   357  		ObjectMeta: metav1.ObjectMeta{
   358  			Namespace: "default",
   359  			Name:      "testCMName",
   360  		},
   361  		Data: data,
   362  	}
   363  }
   364  
   365  func createTestSecret(isArrayOfIPs bool, testIPA, testIPB string) *corev1.Secret {
   366  	data := make(map[string][]byte)
   367  	data["secretKey"] = []byte(createOverrideData(isArrayOfIPs, testIPA, testIPB))
   368  	return &corev1.Secret{
   369  		ObjectMeta: metav1.ObjectMeta{
   370  			Name:      "testSecretName",
   371  			Namespace: "default",
   372  		},
   373  		Data: data,
   374  	}
   375  }
   376  
   377  // createValueOverrideData returns an Istio override in json format
   378  func createValueOverrideData(externalIP string) []byte {
   379  	override := fmt.Sprintf(`spec:
   380    components:
   381      ingressGateways:
   382        - name: istio-ingressgateway
   383          k8s:
   384            service:
   385              type: NodePort
   386              externalIPs:    
   387              - %s`, externalIP)
   388  	json, _ := yaml.ToJSON([]byte(override))
   389  	return json
   390  }
   391  
   392  // createOverrideData returns an Istio override with either 1 or 2 externalIPs in string format
   393  func createOverrideData(isArrayOfIPs bool, testIPA, testIPB string) string {
   394  	var data string
   395  	if !isArrayOfIPs {
   396  		data = fmt.Sprintf(`spec:
   397    components:
   398      ingressGateways:
   399      - k8s:
   400          service:
   401            externalIPs:
   402            - ` + testIPA + `
   403            type: NodePort
   404        name: istio-ingressgateway`)
   405  	} else {
   406  		data = fmt.Sprintf(`spec:
   407    components:
   408      ingressGateways:
   409      - k8s:
   410          service:
   411            externalIPs:
   412            - ` + testIPA + `
   413            - ` + testIPB + `
   414            type: NodePort
   415        name: istio-ingressgateway`)
   416  	}
   417  	return data
   418  }
   419  
   420  func newScheme() *runtime.Scheme {
   421  	scheme := runtime.NewScheme()
   422  	clientgoscheme.AddToScheme(scheme)
   423  	return scheme
   424  }
   425  
   426  func createFakeTestClient() {
   427  	GetControllerRuntimeClient = func(scheme *runtime.Scheme) (client.Client, error) {
   428  		return fake.NewClientBuilder().WithScheme(newScheme()).WithObjects().Build(), nil
   429  	}
   430  }
   431  
   432  func createFakeTestClientWithConfigMap(testConfigMap *corev1.ConfigMap) {
   433  	GetControllerRuntimeClient = func(scheme *runtime.Scheme) (client.Client, error) {
   434  		return fake.NewClientBuilder().WithScheme(newScheme()).WithObjects(testConfigMap).Build(), nil
   435  	}
   436  }
   437  
   438  func createFakeTestClientWithSecret(testSecret *corev1.Secret) {
   439  	GetControllerRuntimeClient = func(scheme *runtime.Scheme) (client.Client, error) {
   440  		return fake.NewClientBuilder().WithScheme(newScheme()).WithObjects(testSecret).Build(), nil
   441  	}
   442  }
   443  
   444  func createFakeTestClientWithConfigMapAndSecret(testConfigMap *corev1.ConfigMap, testSecret *corev1.Secret) {
   445  	GetControllerRuntimeClient = func(scheme *runtime.Scheme) (client.Client, error) {
   446  		return fake.NewClientBuilder().WithScheme(newScheme()).WithObjects(testConfigMap, testSecret).Build(), nil
   447  	}
   448  }