github.com/kyma-project/kyma-environment-broker@v0.0.1/common/hyperscaler/account_provider_test.go (about)

     1  package hyperscaler
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/kyma-project/kyma-environment-broker/common/gardener"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  	machineryv1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    13  )
    14  
    15  func TestGardenerSecretName(t *testing.T) {
    16  	t.Run("should return error if account pool is not configured", func(t *testing.T) {
    17  		//given
    18  		accountProvider := NewAccountProvider(nil, nil)
    19  
    20  		//when
    21  		_, err := accountProvider.GardenerSecretName(GCP, "tenantname", false)
    22  		require.Error(t, err)
    23  
    24  		//then
    25  		assert.Contains(t, err.Error(), "Gardener Account pool is not configured")
    26  	})
    27  
    28  	t.Run("should return correct secret name", func(t *testing.T) {
    29  		//given
    30  		gardenerFake := gardener.NewDynamicFakeClient(newSecretBinding("secretBinding1", "secret1", "azure", false, false))
    31  		accountPool := NewAccountPool(gardenerFake, testNamespace)
    32  
    33  		accountProvider := NewAccountProvider(accountPool, nil)
    34  
    35  		//when
    36  		secretName, err := accountProvider.GardenerSecretName(Azure, "tenantname", false)
    37  
    38  		//then
    39  		require.NoError(t, err)
    40  		assert.Equal(t, secretName, "secret1")
    41  	})
    42  
    43  	t.Run("should return correct shared secret name when secret is in another namespace", func(t *testing.T) {
    44  		//given
    45  		sb := &unstructured.Unstructured{
    46  			Object: map[string]interface{}{
    47  				"metadata": map[string]interface{}{
    48  					"name":      "secretBinding1",
    49  					"namespace": testNamespace,
    50  					"labels": map[string]interface{}{
    51  						"hyperscalerType": "azure",
    52  					},
    53  				},
    54  				"secretRef": map[string]interface{}{
    55  					"name":      "secret1",
    56  					"namespace": "anothernamespace",
    57  				},
    58  			},
    59  		}
    60  		sb.SetGroupVersionKind(secretBindingGVK)
    61  		gardenerFake := gardener.NewDynamicFakeClient(sb)
    62  		accountPool := NewAccountPool(gardenerFake, testNamespace)
    63  
    64  		accountProvider := NewAccountProvider(accountPool, nil)
    65  
    66  		//when
    67  		secretName, err := accountProvider.GardenerSecretName(Azure, "tenantname", false)
    68  
    69  		//then
    70  		require.NoError(t, err)
    71  		assert.Equal(t, secretName, "secret1")
    72  	})
    73  
    74  	t.Run("should return error when failed to find secret binding", func(t *testing.T) {
    75  		//given
    76  		gardenerFake := gardener.NewDynamicFakeClient()
    77  		accountPool := NewAccountPool(gardenerFake, testNamespace)
    78  
    79  		accountProvider := NewAccountProvider(accountPool, nil)
    80  
    81  		//when
    82  		_, err := accountProvider.GardenerSecretName(Azure, "tenantname", false)
    83  
    84  		//then
    85  		require.Error(t, err)
    86  	})
    87  }
    88  
    89  func TestGardenerSharedSecretName(t *testing.T) {
    90  	t.Run("should return error if shared account pool is not configured", func(t *testing.T) {
    91  		//given
    92  		accountProvider := NewAccountProvider(nil, nil)
    93  
    94  		//when
    95  		_, err := accountProvider.GardenerSharedSecretName(GCP, false)
    96  		require.Error(t, err)
    97  
    98  		//then
    99  		assert.Contains(t, err.Error(), "Gardener Shared Account pool is not configured")
   100  	})
   101  
   102  	t.Run("should return correct shared secret name", func(t *testing.T) {
   103  		//given
   104  		gardenerFake := gardener.NewDynamicFakeClient(newSecretBinding("secretBinding1", "secret1", "azure", true, false))
   105  		sharedAccountPool := NewSharedGardenerAccountPool(gardenerFake, testNamespace)
   106  
   107  		accountProvider := NewAccountProvider(nil, sharedAccountPool)
   108  
   109  		//when
   110  		secretName, err := accountProvider.GardenerSharedSecretName(Azure, false)
   111  
   112  		//then
   113  		require.NoError(t, err)
   114  		assert.Equal(t, secretName, "secret1")
   115  	})
   116  
   117  	t.Run("should return correct shared secret name when secret is in another namespace", func(t *testing.T) {
   118  		//given
   119  		sb := &unstructured.Unstructured{
   120  			Object: map[string]interface{}{
   121  				"metadata": map[string]interface{}{
   122  					"name":      "secretBinding1",
   123  					"namespace": testNamespace,
   124  					"labels": map[string]interface{}{
   125  						"hyperscalerType": "azure",
   126  						"shared":          "true",
   127  					},
   128  				},
   129  				"secretRef": map[string]interface{}{
   130  					"name":      "secret1",
   131  					"namespace": "anothernamespace",
   132  				},
   133  			},
   134  		}
   135  		sb.SetGroupVersionKind(secretBindingGVK)
   136  		gardenerFake := gardener.NewDynamicFakeClient(sb)
   137  		sharedAccountPool := NewSharedGardenerAccountPool(gardenerFake, testNamespace)
   138  
   139  		accountProvider := NewAccountProvider(nil, sharedAccountPool)
   140  
   141  		//when
   142  		secretName, err := accountProvider.GardenerSharedSecretName(Azure, false)
   143  
   144  		//then
   145  		require.NoError(t, err)
   146  		assert.Equal(t, secretName, "secret1")
   147  	})
   148  
   149  	t.Run("should return error when failed to find secret binding", func(t *testing.T) {
   150  		//given
   151  		gardenerFake := gardener.NewDynamicFakeClient()
   152  		sharedAccountPool := NewSharedGardenerAccountPool(gardenerFake, testNamespace)
   153  
   154  		accountProvider := NewAccountProvider(nil, sharedAccountPool)
   155  
   156  		//when
   157  		_, err := accountProvider.GardenerSharedSecretName(Azure, false)
   158  
   159  		//then
   160  		require.Error(t, err)
   161  	})
   162  }
   163  
   164  func TestMarkUnusedGardenerSecretBindingAsDirty(t *testing.T) {
   165  
   166  	for _, euAccess := range []bool{false, true} {
   167  		t.Run(fmt.Sprintf("EuAccess=%v", euAccess), func(t *testing.T) {
   168  			t.Run("should mark secret binding as dirty if unused", func(t *testing.T) {
   169  				//given
   170  				pool, secretBindingMock := newTestAccountPoolWithoutShoots(euAccess)
   171  
   172  				accountProvider := NewAccountProvider(pool, nil)
   173  
   174  				//when
   175  				err := accountProvider.MarkUnusedGardenerSecretBindingAsDirty(Type("azure"), "tenant1", euAccess)
   176  
   177  				//then
   178  				require.NoError(t, err)
   179  				secretBinding, err := secretBindingMock.Get(context.Background(), "secretBinding1", machineryv1.GetOptions{})
   180  				require.NoError(t, err)
   181  				assert.Equal(t, secretBinding.GetLabels()["dirty"], "true")
   182  			})
   183  
   184  			t.Run("should not mark secret binding as dirty if internal", func(t *testing.T) {
   185  				//given
   186  				pool, secretBindingMock := newTestAccountPoolWithSecretBindingInternal(euAccess)
   187  
   188  				accountProvider := NewAccountProvider(pool, nil)
   189  
   190  				//when
   191  				err := accountProvider.MarkUnusedGardenerSecretBindingAsDirty(Type("azure"), "tenant1", euAccess)
   192  
   193  				//then
   194  				require.NoError(t, err)
   195  				secretBinding, err := secretBindingMock.Get(context.Background(), "secretBinding1", machineryv1.GetOptions{})
   196  				require.NoError(t, err)
   197  				assert.Equal(t, secretBinding.GetLabels()["dirty"], "")
   198  			})
   199  
   200  			t.Run("should not mark secret binding as dirty if used by a cluster", func(t *testing.T) {
   201  				//given
   202  				pool, secretBindingMock := newTestAccountPoolWithSingleShoot(euAccess)
   203  
   204  				accountProvider := NewAccountProvider(pool, nil)
   205  
   206  				//when
   207  				err := accountProvider.MarkUnusedGardenerSecretBindingAsDirty(Type("azure"), "tenant1", euAccess)
   208  
   209  				//then
   210  				require.NoError(t, err)
   211  				secretBinding, err := secretBindingMock.Get(context.Background(), "secretBinding1", machineryv1.GetOptions{})
   212  				require.NoError(t, err)
   213  				assert.Equal(t, secretBinding.GetLabels()["dirty"], "")
   214  			})
   215  
   216  			t.Run("should not modify a secret binding if marked as dirty", func(t *testing.T) {
   217  				//given
   218  				pool, secretBindingMock := newTestAccountPoolWithSecretBindingDirty(euAccess)
   219  
   220  				accountProvider := NewAccountProvider(pool, nil)
   221  
   222  				//when
   223  				err := accountProvider.MarkUnusedGardenerSecretBindingAsDirty(Type("azure"), "tenant1", euAccess)
   224  
   225  				//then
   226  				require.NoError(t, err)
   227  				secretBinding, err := secretBindingMock.Get(context.Background(), "secretBinding1", machineryv1.GetOptions{})
   228  				require.NoError(t, err)
   229  				assert.Equal(t, secretBinding.GetLabels()["dirty"], "true")
   230  			})
   231  
   232  			t.Run("should not mark secret binding as dirty if used by multiple cluster", func(t *testing.T) {
   233  				//given
   234  				pool, secretBindingMock := newTestAccountPoolWithShootsUsingSecretBinding(euAccess)
   235  
   236  				accountProvider := NewAccountProvider(pool, nil)
   237  
   238  				//when
   239  				err := accountProvider.MarkUnusedGardenerSecretBindingAsDirty(Type("azure"), "tenant1", euAccess)
   240  
   241  				//then
   242  				require.NoError(t, err)
   243  				secretBinding, err := secretBindingMock.Get(context.Background(), "secretBinding1", machineryv1.GetOptions{})
   244  				require.NoError(t, err)
   245  				assert.Equal(t, secretBinding.GetLabels()["dirty"], "")
   246  			})
   247  
   248  			t.Run("should return error if failed to read secrets for particular hyperscaler type", func(t *testing.T) {
   249  				//given
   250  				accountProvider := NewAccountProvider(nil, nil)
   251  
   252  				//when
   253  				err := accountProvider.MarkUnusedGardenerSecretBindingAsDirty(Type("gcp"), "tenant1", euAccess)
   254  
   255  				//when
   256  				require.Error(t, err)
   257  				assert.Contains(t, err.Error(), "failed to release subscription for tenant tenant1. Gardener Account pool is not configured")
   258  			})
   259  		})
   260  	}
   261  }