github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/btpmanager/credentials/manager_test.go (about)

     1  package btpmgrcreds
     2  
     3  import (
     4  	"context"
     5  	"math"
     6  	"math/rand"
     7  	"os"
     8  	"os/exec"
     9  	"strings"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	"k8s.io/apimachinery/pkg/api/errors"
    15  
    16  	uuid2 "github.com/google/uuid"
    17  	"github.com/kyma-project/kyma-environment-broker/internal"
    18  	"github.com/kyma-project/kyma-environment-broker/internal/provisioner"
    19  	"github.com/kyma-project/kyma-environment-broker/internal/storage"
    20  	"github.com/kyma-project/kyma-environment-broker/internal/storage/dbmodel"
    21  	kymaevent "github.com/kyma-project/runtime-watcher/listener/pkg/event"
    22  	"github.com/kyma-project/runtime-watcher/listener/pkg/types"
    23  	"github.com/sirupsen/logrus"
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  	apicorev1 "k8s.io/api/core/v1"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    29  	"k8s.io/client-go/rest"
    30  	"k8s.io/client-go/tools/clientcmd"
    31  	"k8s.io/client-go/tools/clientcmd/api"
    32  	"sigs.k8s.io/controller-runtime/pkg/client"
    33  	"sigs.k8s.io/controller-runtime/pkg/envtest"
    34  	"sigs.k8s.io/controller-runtime/pkg/event"
    35  )
    36  
    37  const (
    38  	expectedTakenInstancesCount    = 3
    39  	expectedRejectedInstancesCount = 1
    40  	expectedAllInstancesCount      = expectedTakenInstancesCount + expectedRejectedInstancesCount
    41  	credentialsLen                 = 16
    42  	jobReconciliationDelay         = time.Second * 0
    43  )
    44  
    45  var (
    46  	changedInstancesCount = int(math.Ceil(expectedTakenInstancesCount / 2))
    47  	testDataIndexes       = []int{0, 2}
    48  	random                = rand.New(rand.NewSource(1))
    49  )
    50  
    51  const (
    52  	envTestAssets = "KUBEBUILDER_ASSETS"
    53  )
    54  
    55  type Environment struct {
    56  	ctx          context.Context
    57  	skrs         []*envtest.Environment
    58  	skrRuntimeId map[string]string
    59  	kcp          client.Client
    60  	kebDb        storage.BrokerStorage
    61  	logs         *logrus.Logger
    62  	manager      *Manager
    63  	watcher      *Watcher
    64  	job          *Job
    65  	t            *testing.T
    66  }
    67  
    68  func InitEnvironment(ctx context.Context, t *testing.T) *Environment {
    69  	logs := logrus.New()
    70  	logs.SetFormatter(&logrus.JSONFormatter{})
    71  	newEnvironment := &Environment{
    72  		skrs:  make([]*envtest.Environment, 0),
    73  		kebDb: storage.NewMemoryStorage(),
    74  		logs:  logs,
    75  		ctx:   ctx,
    76  		t:     t,
    77  	}
    78  
    79  	newEnvironment.createTestData()
    80  	newEnvironment.manager = NewManager(ctx, newEnvironment.kcp, newEnvironment.kebDb.Instances(), logs, false, provisioner.NewFakeClient())
    81  	newEnvironment.watcher = NewWatcher(ctx, "3333", "btp-manager-secret-watcher", newEnvironment.manager, logs)
    82  	newEnvironment.job = NewJob(newEnvironment.manager, logs)
    83  	newEnvironment.assertThatCorrectNumberOfInstancesExists()
    84  	return newEnvironment
    85  }
    86  
    87  func TestBtpManagerReconciler(t *testing.T) {
    88  	if os.Getenv(envTestAssets) == "" {
    89  		out, err := exec.Command("/bin/sh", "../../../setup-envtest.sh").Output()
    90  		require.NoError(t, err)
    91  		path := strings.Replace(string(out), "\n", "", -1)
    92  		os.Setenv(envTestAssets, path)
    93  	}
    94  
    95  	t.Run("btp manager credentials tests", func(t *testing.T) {
    96  		ctx, cancel := context.WithCancel(context.Background())
    97  		environment := InitEnvironment(ctx, t)
    98  
    99  		t.Run("reconcile, when all secrets are not set", func(t *testing.T) {
   100  			environment.assertAllSecretsNotExists()
   101  			takenInstancesCount, updateDone, updateNotDoneDueError, updateNotDoneDueOkState, err := environment.manager.ReconcileAll(jobReconciliationDelay)
   102  			assert.NoError(t, err)
   103  			assert.Equal(t, expectedTakenInstancesCount, takenInstancesCount)
   104  			assert.Equal(t, expectedTakenInstancesCount, updateDone)
   105  			assert.Equal(t, 0, updateNotDoneDueError+updateNotDoneDueOkState)
   106  			environment.assertAllSecretDataAreSet()
   107  			environment.assureConsistency()
   108  		})
   109  
   110  		t.Run("reconcile, when all secrets are correct", func(t *testing.T) {
   111  			environment.assertAllSecretDataAreSet()
   112  			takenInstancesCount, updateDone, updateNotDoneDueError, updateNotDoneDueOkState, err := environment.manager.ReconcileAll(jobReconciliationDelay)
   113  			assert.NoError(t, err)
   114  			environment.assertThatCorrectNumberOfInstancesExists()
   115  			assert.Equal(t, expectedTakenInstancesCount, takenInstancesCount)
   116  			assert.Equal(t, updateDone, 0)
   117  			assert.Equal(t, updateNotDoneDueError+updateNotDoneDueOkState, expectedTakenInstancesCount)
   118  			environment.assertAllSecretDataAreSet()
   119  			environment.assureConsistency()
   120  		})
   121  
   122  		t.Run("reconcile, when some secrets are incorrect (dynamic selected)", func(t *testing.T) {
   123  			skrs := environment.getSkrsForSimulateChange([]int{})
   124  			environment.simulateSecretChangeOnSkr(skrs)
   125  			environment.assertAllSecretDataAreSet()
   126  			takenInstancesCount, updateDone, updateNotDoneDueError, updateNotDoneDueOkState, err := environment.manager.ReconcileAll(jobReconciliationDelay)
   127  			assert.NoError(t, err)
   128  			environment.assertThatCorrectNumberOfInstancesExists()
   129  			assert.Equal(t, expectedTakenInstancesCount, takenInstancesCount)
   130  			assert.Equal(t, updateDone, len(skrs))
   131  			assert.Equal(t, updateNotDoneDueError+updateNotDoneDueOkState, expectedTakenInstancesCount-len(skrs))
   132  			environment.assertAllSecretDataAreSet()
   133  			environment.assureConsistency()
   134  		})
   135  
   136  		t.Run("reconcile, when some secrets are incorrect (static selected)", func(t *testing.T) {
   137  			max := max(testDataIndexes)
   138  			assert.GreaterOrEqual(t, expectedTakenInstancesCount-1, max)
   139  			skrs := environment.getSkrsForSimulateChange(testDataIndexes)
   140  			environment.simulateSecretChangeOnSkr(skrs)
   141  			environment.assertAllSecretDataAreSet()
   142  			takenInstancesCount, updateDone, updateNotDoneDueError, updateNotDoneDueOkState, err := environment.manager.ReconcileAll(jobReconciliationDelay)
   143  			assert.NoError(t, err)
   144  			environment.assertThatCorrectNumberOfInstancesExists()
   145  			assert.Equal(t, expectedTakenInstancesCount, takenInstancesCount)
   146  			assert.Equal(t, updateDone, len(testDataIndexes))
   147  			assert.Equal(t, updateNotDoneDueError+updateNotDoneDueOkState, expectedTakenInstancesCount-len(testDataIndexes))
   148  			environment.assertAllSecretDataAreSet()
   149  			environment.assureConsistency()
   150  		})
   151  
   152  		t.Run("change one instance", func(t *testing.T) {
   153  			skrs := environment.getSkrsForSimulateChange([]int{0})
   154  			environment.simulateSecretChangeOnSkr(skrs)
   155  			kymaName := environment.findRuntimeIdForSkr(skrs[0].Config.Host)
   156  			inconsistentClusters := environment.assureThatClusterIsInIncorrectState()
   157  			assert.Equal(t, 1, inconsistentClusters)
   158  			go environment.watcher.ReactOnSkrEvent()
   159  			time.Sleep(time.Millisecond * 100)
   160  			environment.watcher.listener.ReceivedEvents <- event.GenericEvent{Object: kymaevent.GenericEvent(&types.WatchEvent{
   161  				Owner: client.ObjectKey{
   162  					Name: kymaName,
   163  				},
   164  			})}
   165  			time.Sleep(time.Millisecond * 100)
   166  			environment.assureConsistency()
   167  		})
   168  
   169  		t.Run("change many instances", func(t *testing.T) {
   170  			assert.GreaterOrEqual(t, expectedTakenInstancesCount, 1)
   171  			skrs := environment.getSkrsForSimulateChange([]int{1, expectedTakenInstancesCount - 1})
   172  			environment.simulateSecretChangeOnSkr(skrs)
   173  			assert.GreaterOrEqual(t, len(skrs), 2)
   174  			kymaName := environment.findRuntimeIdForSkr(skrs[0].Config.Host)
   175  			kymaName2 := environment.findRuntimeIdForSkr(skrs[1].Config.Host)
   176  			inconsistentClusters := environment.assureThatClusterIsInIncorrectState()
   177  			assert.Equal(t, 2, inconsistentClusters)
   178  			go environment.watcher.ReactOnSkrEvent()
   179  			time.Sleep(time.Millisecond * 100)
   180  			wg := &sync.WaitGroup{}
   181  			wg.Add(1)
   182  			go func() {
   183  				defer wg.Done()
   184  				environment.watcher.listener.ReceivedEvents <- event.GenericEvent{Object: kymaevent.GenericEvent(&types.WatchEvent{
   185  					Owner: client.ObjectKey{
   186  						Name: kymaName,
   187  					},
   188  				})}
   189  			}()
   190  
   191  			wg.Add(1)
   192  			go func() {
   193  				defer wg.Done()
   194  				environment.watcher.listener.ReceivedEvents <- event.GenericEvent{Object: kymaevent.GenericEvent(&types.WatchEvent{
   195  					Owner: client.ObjectKey{
   196  						Name: kymaName2,
   197  					},
   198  				})}
   199  			}()
   200  			defer wg.Wait()
   201  			time.Sleep(time.Millisecond * 100)
   202  			environment.assureConsistency()
   203  		})
   204  
   205  		t.Cleanup(func() {
   206  			cancel()
   207  		})
   208  	})
   209  }
   210  
   211  func TestManager(t *testing.T) {
   212  	manager := Manager{
   213  		logger: logrus.New(),
   214  	}
   215  	t.Run("compare secrets with all different data", func(t *testing.T) {
   216  		current, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   217  			ClientID:          "a",
   218  			ClientSecret:      "a",
   219  			ServiceManagerURL: "a",
   220  			URL:               "a",
   221  			XSAppName:         "a",
   222  		}, "a")
   223  		assert.NoError(t, err)
   224  
   225  		expected, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   226  			ClientID:          "b",
   227  			ClientSecret:      "b",
   228  			ServiceManagerURL: "b",
   229  			URL:               "b",
   230  			XSAppName:         "b",
   231  		}, "b")
   232  		assert.NoError(t, err)
   233  
   234  		notMatchingKeys, err := manager.compareSecrets(current, expected)
   235  		assert.NoError(t, err)
   236  		assert.NotNil(t, notMatchingKeys)
   237  		assert.Greater(t, len(notMatchingKeys), 0)
   238  		assert.Equal(t, notMatchingKeys, []string{secretClientSecret, secretClientId, secretSmUrl, secretTokenUrl, secretClusterId})
   239  	})
   240  
   241  	t.Run("compare secrets with partially different data", func(t *testing.T) {
   242  		current, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   243  			ClientID:          "a",
   244  			ClientSecret:      "a",
   245  			ServiceManagerURL: "a",
   246  			URL:               "a",
   247  			XSAppName:         "a",
   248  		}, "a")
   249  		assert.NoError(t, err)
   250  
   251  		expected, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   252  			ClientID:          "b",
   253  			ClientSecret:      "b",
   254  			ServiceManagerURL: "a",
   255  			URL:               "a",
   256  			XSAppName:         "a",
   257  		}, "a")
   258  		assert.NoError(t, err)
   259  
   260  		notMatchingKeys, err := manager.compareSecrets(current, expected)
   261  		assert.NoError(t, err)
   262  		assert.NotNil(t, notMatchingKeys)
   263  		assert.Greater(t, len(notMatchingKeys), 0)
   264  		assert.Equal(t, notMatchingKeys, []string{secretClientSecret, secretClientId})
   265  	})
   266  
   267  	t.Run("compare secrets with the same data", func(t *testing.T) {
   268  		current, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   269  			ClientID:          "a1",
   270  			ClientSecret:      "a2",
   271  			ServiceManagerURL: "a3",
   272  			URL:               "a4",
   273  			XSAppName:         "a5",
   274  		}, "a6")
   275  		assert.NoError(t, err)
   276  
   277  		expected, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   278  			ClientID:          "a1",
   279  			ClientSecret:      "a2",
   280  			ServiceManagerURL: "a3",
   281  			URL:               "a4",
   282  			XSAppName:         "a5",
   283  		}, "a6")
   284  		assert.NoError(t, err)
   285  
   286  		notMatchingKeys, err := manager.compareSecrets(current, expected)
   287  		assert.NoError(t, err)
   288  		assert.NotNil(t, notMatchingKeys)
   289  		assert.Equal(t, len(notMatchingKeys), 0)
   290  	})
   291  
   292  	t.Run("compare secrets where some of data is missing and data is same", func(t *testing.T) {
   293  		current, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   294  			ClientID:          "a",
   295  			ClientSecret:      "a",
   296  			ServiceManagerURL: "a",
   297  			URL:               "a",
   298  			XSAppName:         "a",
   299  		}, "a")
   300  		assert.NoError(t, err)
   301  		delete(current.Data, secretClientSecret)
   302  
   303  		expected, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   304  			ClientID:          "a",
   305  			ClientSecret:      "a",
   306  			ServiceManagerURL: "a",
   307  			URL:               "a",
   308  			XSAppName:         "a",
   309  		}, "a")
   310  
   311  		notMatchingKeys, err := manager.compareSecrets(current, expected)
   312  		assert.Nil(t, notMatchingKeys)
   313  		assert.Error(t, err)
   314  	})
   315  
   316  	t.Run("compare secrets where some of data is missing and data are different", func(t *testing.T) {
   317  		current, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   318  			ClientID:          "a",
   319  			ClientSecret:      "a",
   320  			ServiceManagerURL: "a",
   321  			URL:               "a",
   322  			XSAppName:         "a",
   323  		}, "a")
   324  		assert.NoError(t, err)
   325  		delete(current.Data, secretClientSecret)
   326  
   327  		expected, err := PrepareSecret(&internal.ServiceManagerOperatorCredentials{
   328  			ClientID:          "b",
   329  			ClientSecret:      "b",
   330  			ServiceManagerURL: "b",
   331  			URL:               "b",
   332  			XSAppName:         "b",
   333  		}, "b")
   334  		assert.NoError(t, err)
   335  
   336  		notMatchingKeys, err := manager.compareSecrets(current, expected)
   337  		assert.Nil(t, notMatchingKeys)
   338  		assert.Error(t, err)
   339  	})
   340  }
   341  
   342  func (e *Environment) createTestData() {
   343  	e.createClusters(expectedTakenInstancesCount)
   344  	e.skrRuntimeId = make(map[string]string, 0)
   345  	for i := 0; i < expectedTakenInstancesCount; i++ {
   346  		cfg := *e.skrs[i].Config
   347  		clusterId := cfg.Host
   348  		kubeConfig := restConfigToString(cfg)
   349  		require.NotEmpty(e.t, kubeConfig)
   350  		instanceId, runtimeId := e.createInstance(kubeConfig, generateServiceManagerCredentials(), clusterId)
   351  		e.createKyma(runtimeId, instanceId)
   352  		e.skrRuntimeId[clusterId] = runtimeId
   353  	}
   354  
   355  	for i := 0; i < expectedRejectedInstancesCount; i++ {
   356  		e.createInstance("", generateServiceManagerCredentials(), "")
   357  	}
   358  }
   359  
   360  func (e *Environment) createClusters(count int) {
   361  	tempSkrs := make([]*envtest.Environment, 0)
   362  	wg := &sync.WaitGroup{}
   363  	for i := 0; i <= count; i++ {
   364  		wg.Add(1)
   365  		func(i int) {
   366  			defer wg.Done()
   367  			if i == count {
   368  				//KCP
   369  				testEnv := &envtest.Environment{
   370  					CRDDirectoryPaths: []string{"testdata/crds/kyma.yaml"},
   371  				}
   372  				cfg, err := testEnv.Start()
   373  				if err != nil {
   374  					e.logs.Errorf("%e", err)
   375  					return
   376  				}
   377  				k8sClient, err := client.New(cfg, client.Options{})
   378  				if err != nil {
   379  					e.logs.Errorf("%e", err)
   380  					return
   381  				}
   382  				e.kcp = k8sClient
   383  
   384  				namespace := &apicorev1.Namespace{}
   385  				namespace.ObjectMeta = metav1.ObjectMeta{Name: kcpNamespace}
   386  				err = e.kcp.Create(context.Background(), namespace)
   387  				if err != nil {
   388  					e.logs.Errorf("%e", err)
   389  					return
   390  				}
   391  			} else {
   392  				//SKR
   393  				testEnv := &envtest.Environment{}
   394  				_, err := testEnv.Start()
   395  				if err != nil {
   396  					e.logs.Errorf("%e", err)
   397  					return
   398  				}
   399  				tempSkrs = append(tempSkrs, testEnv)
   400  			}
   401  		}(i)
   402  	}
   403  	wg.Wait()
   404  	e.skrs = append(e.skrs, tempSkrs...)
   405  	require.Equal(e.t, len(e.skrs), count)
   406  	require.NotNil(e.t, e.kcp)
   407  }
   408  
   409  func (e *Environment) createInstance(kubeConfig string, credentials *internal.ServiceManagerOperatorCredentials, clusterId string) (string, string) {
   410  	instanceId, err := uuid2.NewUUID()
   411  	require.NoError(e.t, err)
   412  
   413  	runtimeId := ""
   414  	reconcilable := false
   415  	if kubeConfig != "" && clusterId != "" {
   416  		runtimeUUID, err := uuid2.NewUUID()
   417  		require.NoError(e.t, err)
   418  		runtimeId = runtimeUUID.String()
   419  		e.createKubeConfigSecret(kubeConfig, runtimeId)
   420  		reconcilable = true
   421  	}
   422  
   423  	instance := &internal.Instance{
   424  		InstanceID: instanceId.String(),
   425  		RuntimeID:  runtimeId,
   426  		InstanceDetails: internal.InstanceDetails{
   427  			ServiceManagerClusterID: clusterId,
   428  		},
   429  		Parameters: internal.ProvisioningParameters{
   430  			ErsContext: internal.ERSContext{
   431  				SMOperatorCredentials: credentials,
   432  			},
   433  			Parameters: internal.ProvisioningParametersDTO{
   434  				Kubeconfig: kubeConfig,
   435  			},
   436  		},
   437  	}
   438  	instance.Reconcilable = reconcilable
   439  
   440  	err = e.kebDb.Instances().Insert(*instance)
   441  	require.NoError(e.t, err)
   442  	return instanceId.String(), runtimeId
   443  }
   444  
   445  func (e *Environment) createKyma(runtimeId, instanceId string) {
   446  	u := &unstructured.Unstructured{}
   447  	u.SetGroupVersionKind(KymaGvk)
   448  	u.SetNamespace(kcpNamespace)
   449  	u.SetName(runtimeId)
   450  	labels := make(map[string]string, 1)
   451  	labels[instanceIdLabel] = instanceId
   452  	u.SetLabels(labels)
   453  	err := e.kcp.Create(e.ctx, u)
   454  	require.NoError(e.t, err)
   455  }
   456  
   457  func (e *Environment) createKubeConfigSecret(cfg, runtimeId string) {
   458  	secret := &apicorev1.Secret{
   459  		TypeMeta: metav1.TypeMeta{Kind: "Secret"},
   460  		ObjectMeta: metav1.ObjectMeta{
   461  			Name:      getKubeConfigSecretName(runtimeId),
   462  			Namespace: kcpNamespace,
   463  		},
   464  		Data: map[string][]byte{
   465  			"config": []byte(cfg),
   466  		},
   467  		Type: apicorev1.SecretTypeOpaque,
   468  	}
   469  	err := e.kcp.Create(e.ctx, secret)
   470  	require.NoError(e.t, err)
   471  }
   472  
   473  func (e *Environment) changeSecret(restCfg *rest.Config) {
   474  	skrSecret := e.getSecretFromSkr(restCfg)
   475  	newCredentials := generateServiceManagerCredentials()
   476  	skrSecret.Data[secretClientSecret] = []byte(newCredentials.ClientSecret)
   477  	skrSecret.Data[secretSmUrl] = []byte(newCredentials.ServiceManagerURL)
   478  	skrSecret.Data[secretTokenUrl] = []byte(newCredentials.URL)
   479  	skrSecret.Data[secretClusterId] = []byte(generateRandomText(credentialsLen))
   480  	skrSecret.Data[secretClientId] = []byte(newCredentials.ClientID)
   481  	e.updateSecretToSkr(restCfg, skrSecret)
   482  }
   483  
   484  func (e *Environment) getSecretFromSkr(restCfg *rest.Config) *apicorev1.Secret {
   485  	skrClient, err := client.New(restCfg, client.Options{})
   486  	require.NoError(e.t, err)
   487  	skrSecret := &apicorev1.Secret{}
   488  	err = skrClient.Get(context.Background(), client.ObjectKey{Name: BtpManagerSecretName, Namespace: BtpManagerSecretNamespace}, skrSecret)
   489  	if err != nil && errors.IsNotFound(err) {
   490  		return nil
   491  	}
   492  	require.NoError(e.t, err)
   493  	return skrSecret
   494  }
   495  
   496  func (e *Environment) updateSecretToSkr(restCfg *rest.Config, secret *apicorev1.Secret) {
   497  	skrClient, err := client.New(restCfg, client.Options{})
   498  	require.NoError(e.t, err)
   499  	err = skrClient.Update(context.Background(), secret)
   500  	require.NoError(e.t, err)
   501  }
   502  
   503  func (e *Environment) getSkrsForSimulateChange(skrIndexes []int) []*envtest.Environment {
   504  	var result []*envtest.Environment
   505  	if skrIndexes == nil || len(skrIndexes) == 0 {
   506  		indexSet := map[int]struct{}{}
   507  		for {
   508  			if len(indexSet) == changedInstancesCount {
   509  				break
   510  			}
   511  			random := rand.Intn(expectedTakenInstancesCount)
   512  			_, ok := indexSet[random]
   513  			if !ok {
   514  				indexSet[random] = struct{}{}
   515  			}
   516  		}
   517  
   518  		for index, _ := range indexSet {
   519  			testEnv := e.skrs[index]
   520  			result = append(result, testEnv)
   521  		}
   522  	} else {
   523  		for _, index := range skrIndexes {
   524  			testEnv := e.skrs[index]
   525  			result = append(result, testEnv)
   526  		}
   527  	}
   528  	return result
   529  }
   530  
   531  func (e *Environment) simulateSecretChangeOnSkr(skrs []*envtest.Environment) {
   532  	for _, skr := range skrs {
   533  		e.changeSecret(skr.Config)
   534  	}
   535  }
   536  
   537  func (e *Environment) findRuntimeIdForSkr(host string) string {
   538  	value, ok := e.skrRuntimeId[host]
   539  	require.True(e.t, ok)
   540  	return value
   541  }
   542  
   543  func (e *Environment) assertAllSecretsNotExists() {
   544  	for _, skr := range e.skrs {
   545  		skrSecret := e.getSecretFromSkr(skr.Config)
   546  		require.Nil(e.t, skrSecret)
   547  	}
   548  }
   549  
   550  func (e *Environment) assertAllSecretsExists() {
   551  	for _, skr := range e.skrs {
   552  		skrSecret := e.getSecretFromSkr(skr.Config)
   553  		require.NotNil(e.t, skrSecret)
   554  	}
   555  }
   556  
   557  func (e *Environment) assertAllSecretDataAreSet() {
   558  	for _, skr := range e.skrs {
   559  		skrSecret := e.getSecretFromSkr(skr.Config)
   560  		require.NotNil(e.t, skrSecret)
   561  
   562  		require.NotEmpty(e.t, getString(skrSecret.Data, secretClientId))
   563  		require.NotEmpty(e.t, getString(skrSecret.Data, secretClientSecret))
   564  		require.NotEmpty(e.t, getString(skrSecret.Data, secretSmUrl))
   565  		require.NotEmpty(e.t, getString(skrSecret.Data, secretTokenUrl))
   566  		require.NotEmpty(e.t, getString(skrSecret.Data, secretClusterId))
   567  
   568  	}
   569  }
   570  
   571  func (e *Environment) assureConsistency() {
   572  	takenInstances, err := e.manager.GetReconcileCandidates()
   573  	require.NoError(e.t, err)
   574  	require.Equal(e.t, expectedTakenInstancesCount, len(takenInstances))
   575  
   576  	for _, instance := range takenInstances {
   577  		skrK8sCfg, credentials := []byte(instance.Parameters.Parameters.Kubeconfig), instance.Parameters.ErsContext.SMOperatorCredentials
   578  		restCfg, err := clientcmd.RESTConfigFromKubeConfig(skrK8sCfg)
   579  		require.NoError(e.t, err)
   580  		skrSecret := e.getSecretFromSkr(restCfg)
   581  		require.NotNil(e.t, skrSecret)
   582  
   583  		require.Equal(e.t, getString(skrSecret.Data, secretClientId), credentials.ClientID)
   584  		require.Equal(e.t, getString(skrSecret.Data, secretClientSecret), credentials.ClientSecret)
   585  		require.Equal(e.t, getString(skrSecret.Data, secretSmUrl), credentials.ServiceManagerURL)
   586  		require.Equal(e.t, getString(skrSecret.Data, secretTokenUrl), credentials.URL)
   587  		require.Equal(e.t, getString(skrSecret.Data, secretClusterId), instance.InstanceDetails.ServiceManagerClusterID)
   588  	}
   589  }
   590  
   591  func (e *Environment) assureThatClusterIsInIncorrectState() int {
   592  	takenInstances, err := e.manager.GetReconcileCandidates()
   593  	require.NoError(e.t, err)
   594  	require.Equal(e.t, expectedTakenInstancesCount, len(takenInstances))
   595  
   596  	incorrectClusters := 0
   597  	for _, instance := range takenInstances {
   598  		require.NoError(e.t, err)
   599  		skrK8sCfg, credentials := []byte(instance.Parameters.Parameters.Kubeconfig), instance.Parameters.ErsContext.SMOperatorCredentials
   600  		restCfg, err := clientcmd.RESTConfigFromKubeConfig(skrK8sCfg)
   601  		require.NoError(e.t, err)
   602  		skrSecret := e.getSecretFromSkr(restCfg)
   603  		require.NotNil(e.t, skrSecret)
   604  
   605  		if getString(skrSecret.Data, secretClientSecret) != credentials.ClientSecret {
   606  			incorrectClusters++
   607  			continue
   608  		}
   609  		if getString(skrSecret.Data, secretClientId) != credentials.ClientID {
   610  			incorrectClusters++
   611  			continue
   612  		}
   613  		if getString(skrSecret.Data, secretTokenUrl) != credentials.URL {
   614  			incorrectClusters++
   615  			continue
   616  		}
   617  		if getString(skrSecret.Data, secretClusterId) != instance.InstanceDetails.ServiceManagerClusterID {
   618  			incorrectClusters++
   619  			continue
   620  		}
   621  	}
   622  
   623  	return incorrectClusters
   624  }
   625  
   626  func (e *Environment) assertThatCorrectNumberOfInstancesExists() {
   627  	instances, _, _, err := e.kebDb.Instances().List(dbmodel.InstanceFilter{})
   628  	require.NoError(e.t, err)
   629  	require.Equal(e.t, expectedAllInstancesCount, len(instances))
   630  }
   631  
   632  func restConfigToString(restConfig rest.Config) string {
   633  	bytes, err := clientcmd.Write(api.Config{
   634  		Clusters: map[string]*api.Cluster{
   635  			"default": {
   636  				Server:                   restConfig.Host,
   637  				InsecureSkipTLSVerify:    restConfig.Insecure,
   638  				CertificateAuthorityData: restConfig.CAData,
   639  			},
   640  		},
   641  		Contexts: map[string]*api.Context{
   642  			"default": {
   643  				Cluster:  "default",
   644  				AuthInfo: "default",
   645  			},
   646  		},
   647  		AuthInfos: map[string]*api.AuthInfo{
   648  			"default": {
   649  				ClientCertificateData: restConfig.CertData,
   650  				ClientKeyData:         restConfig.KeyData,
   651  				Token:                 restConfig.BearerToken,
   652  				Username:              restConfig.Username,
   653  				Password:              restConfig.Password,
   654  			},
   655  		},
   656  		CurrentContext: "default",
   657  	})
   658  	if err != nil {
   659  		return ""
   660  	} else {
   661  		return string(bytes)
   662  	}
   663  }
   664  
   665  func generateServiceManagerCredentials() *internal.ServiceManagerOperatorCredentials {
   666  	return &internal.ServiceManagerOperatorCredentials{
   667  		ClientID:          generateRandomText(credentialsLen),
   668  		ClientSecret:      generateRandomText(credentialsLen),
   669  		ServiceManagerURL: generateRandomText(credentialsLen),
   670  		URL:               generateRandomText(credentialsLen),
   671  		XSAppName:         generateRandomText(credentialsLen),
   672  	}
   673  }
   674  
   675  func generateRandomText(count int) string {
   676  	letterRunes := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
   677  	runes := make([]rune, count)
   678  	for i := range runes {
   679  		runes[i] = letterRunes[random.Intn(len(letterRunes))]
   680  	}
   681  	return string(runes)
   682  }
   683  
   684  func max(slice []int) int {
   685  	max := 0
   686  	for _, v := range slice {
   687  		if v > max {
   688  			max = v
   689  		}
   690  	}
   691  	return max
   692  }
   693  
   694  func getString(m map[string][]byte, key string) string {
   695  	value, ok := m[key]
   696  	if !ok {
   697  		return ""
   698  	}
   699  	return string(value)
   700  }