sigs.k8s.io/cluster-api-provider-aws@v1.5.5/api/v1beta1/awsclustercontrolleridentity_webhook_test.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package v1beta1
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	. "github.com/onsi/gomega"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  
    26  	clusterv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
    27  )
    28  
    29  func TestAWSClusterControllerIdentityCreationValidation(t *testing.T) {
    30  	tests := []struct {
    31  		name      string
    32  		identity  *AWSClusterControllerIdentity
    33  		wantError bool
    34  	}{
    35  		{
    36  			name: "only allow AWSClusterControllerIdentity creation with name default",
    37  			identity: &AWSClusterControllerIdentity{
    38  				ObjectMeta: metav1.ObjectMeta{
    39  					Name: "default",
    40  				},
    41  			},
    42  			wantError: false,
    43  		},
    44  		{
    45  			name: "do not allow AWSClusterControllerIdentity creation with name other than default",
    46  			identity: &AWSClusterControllerIdentity{
    47  				ObjectMeta: metav1.ObjectMeta{
    48  					Name: "test",
    49  				},
    50  			},
    51  			wantError: true,
    52  		},
    53  	}
    54  	for _, tt := range tests {
    55  		t.Run(tt.name, func(t *testing.T) {
    56  			identity := tt.identity.DeepCopy()
    57  			identity.TypeMeta = metav1.TypeMeta{
    58  				APIVersion: GroupVersion.String(),
    59  				Kind:       "AWSClusterControllerIdentity",
    60  			}
    61  			ctx := context.TODO()
    62  			if err := testEnv.Create(ctx, identity); (err != nil) != tt.wantError {
    63  				t.Errorf("ValidateCreate() error = %v, wantErr %v", err, tt.wantError)
    64  			}
    65  			testEnv.Delete(ctx, identity)
    66  		})
    67  	}
    68  }
    69  
    70  func TestAWSClusterControllerIdentityLabelSelectorAsSelectorValidation(t *testing.T) {
    71  	tests := []struct {
    72  		name      string
    73  		selectors map[string]string
    74  		wantError bool
    75  	}{
    76  		{
    77  			name:      "should not return error for valid selector",
    78  			selectors: map[string]string{"foo": "bar"},
    79  			wantError: false,
    80  		},
    81  		{
    82  			name:      "should return error for invalid selector",
    83  			selectors: map[string]string{"-123-foo": "bar"},
    84  			wantError: true,
    85  		},
    86  	}
    87  	for _, tt := range tests {
    88  		t.Run(tt.name, func(t *testing.T) {
    89  			identity := &AWSClusterControllerIdentity{
    90  				TypeMeta: metav1.TypeMeta{
    91  					APIVersion: GroupVersion.String(),
    92  					Kind:       "AWSClusterControllerIdentity",
    93  				},
    94  				ObjectMeta: metav1.ObjectMeta{
    95  					Name: AWSClusterControllerIdentityName,
    96  				},
    97  				Spec: AWSClusterControllerIdentitySpec{
    98  					AWSClusterIdentitySpec: AWSClusterIdentitySpec{
    99  						AllowedNamespaces: &AllowedNamespaces{
   100  							Selector: metav1.LabelSelector{
   101  								MatchLabels: tt.selectors,
   102  							},
   103  						},
   104  					},
   105  				},
   106  			}
   107  
   108  			ctx := context.TODO()
   109  			if err := testEnv.Create(ctx, identity); (err != nil) != tt.wantError {
   110  				t.Errorf("ValidateCreate() error = %v, wantErr %v", err, tt.wantError)
   111  			}
   112  			testEnv.Delete(ctx, identity)
   113  		})
   114  	}
   115  }
   116  
   117  func TestAWSClusterControllerValidateUpdate(t *testing.T) {
   118  	controllerIdentity := &AWSClusterControllerIdentity{
   119  		TypeMeta: metav1.TypeMeta{
   120  			APIVersion: GroupVersion.String(),
   121  			Kind:       "AWSClusterControllerIdentity",
   122  		},
   123  		ObjectMeta: metav1.ObjectMeta{
   124  			Name: AWSClusterControllerIdentityName,
   125  		},
   126  		Spec: AWSClusterControllerIdentitySpec{
   127  			AWSClusterIdentitySpec: AWSClusterIdentitySpec{
   128  				AllowedNamespaces: &AllowedNamespaces{},
   129  			},
   130  		},
   131  	}
   132  
   133  	ctx := context.TODO()
   134  	defer testEnv.Delete(ctx, controllerIdentity)
   135  
   136  	if err := testEnv.Create(ctx, controllerIdentity); err != nil {
   137  		t.Errorf("controllerIdentity creation failed %v", err)
   138  	}
   139  
   140  	tests := []struct {
   141  		name      string
   142  		identity  *AWSClusterControllerIdentity
   143  		wantError bool
   144  	}{
   145  		{
   146  			name: "do not allow any spec changes",
   147  			identity: &AWSClusterControllerIdentity{
   148  				ObjectMeta: metav1.ObjectMeta{
   149  					Name: "default",
   150  				},
   151  			},
   152  			wantError: true,
   153  		},
   154  		{
   155  			name: "do not allow name change",
   156  			identity: &AWSClusterControllerIdentity{
   157  				ObjectMeta: metav1.ObjectMeta{
   158  					Name: "test",
   159  				},
   160  			},
   161  			wantError: true,
   162  		},
   163  		{
   164  			name:      "no error when updating with same object",
   165  			identity:  controllerIdentity,
   166  			wantError: false,
   167  		},
   168  	}
   169  	for _, tt := range tests {
   170  		t.Run(tt.name, func(t *testing.T) {
   171  			identity := tt.identity.DeepCopy()
   172  			identity.TypeMeta = metav1.TypeMeta{
   173  				APIVersion: GroupVersion.String(),
   174  				Kind:       "AWSClusterControllerIdentity",
   175  			}
   176  			ctx := context.TODO()
   177  			if err := testEnv.Update(ctx, identity); (err != nil) != tt.wantError {
   178  				t.Errorf("ValidateUpdate() error = %v, wantErr %v", err, tt.wantError)
   179  			}
   180  		})
   181  	}
   182  }
   183  
   184  func TestAWSClusterControllerIdentityUpdateValidation(t *testing.T) {
   185  	controllerIdentity := &AWSClusterControllerIdentity{
   186  		TypeMeta: metav1.TypeMeta{
   187  			APIVersion: GroupVersion.String(),
   188  			Kind:       "AWSClusterControllerIdentityName",
   189  		},
   190  		ObjectMeta: metav1.ObjectMeta{
   191  			Name: AWSClusterControllerIdentityName,
   192  		},
   193  		Spec: AWSClusterControllerIdentitySpec{
   194  			AWSClusterIdentitySpec: AWSClusterIdentitySpec{
   195  				AllowedNamespaces: &AllowedNamespaces{
   196  					Selector: metav1.LabelSelector{
   197  						MatchLabels: map[string]string{"foo": "bar"},
   198  					},
   199  				},
   200  			},
   201  		},
   202  	}
   203  
   204  	ctx := context.TODO()
   205  	defer testEnv.Delete(ctx, controllerIdentity)
   206  
   207  	if err := testEnv.Create(ctx, controllerIdentity); err != nil {
   208  		t.Errorf("controllerIdentity creation failed %v", err)
   209  	}
   210  
   211  	tests := []struct {
   212  		name      string
   213  		identity  *AWSClusterControllerIdentity
   214  		wantError bool
   215  	}{
   216  		{
   217  			name:      "should not return error for valid selector",
   218  			identity:  controllerIdentity,
   219  			wantError: false,
   220  		},
   221  		{
   222  			name: "should return error for invalid selector",
   223  			identity: &AWSClusterControllerIdentity{
   224  				ObjectMeta: metav1.ObjectMeta{
   225  					Name: AWSClusterControllerIdentityName,
   226  				},
   227  				Spec: AWSClusterControllerIdentitySpec{
   228  					AWSClusterIdentitySpec: AWSClusterIdentitySpec{
   229  						AllowedNamespaces: &AllowedNamespaces{
   230  							Selector: metav1.LabelSelector{
   231  								MatchLabels: map[string]string{"-foo-123": "bar"},
   232  							},
   233  						},
   234  					},
   235  				},
   236  			},
   237  			wantError: true,
   238  		},
   239  	}
   240  	for _, tt := range tests {
   241  		t.Run(tt.name, func(t *testing.T) {
   242  			identity := tt.identity.DeepCopy()
   243  			ctx := context.TODO()
   244  			if err := testEnv.Update(ctx, identity); (err != nil) != tt.wantError {
   245  				t.Errorf("ValidateUpdate() error = %v, wantErr %v", err, tt.wantError)
   246  			}
   247  		})
   248  	}
   249  }
   250  
   251  func TestAWSClusterControllerIdentity_Default(t *testing.T) {
   252  	g := NewWithT(t)
   253  	tests := []struct {
   254  		name                               string
   255  		beforeAWSClusterControllerIdentity *AWSClusterControllerIdentity
   256  		afterAWSClusterControllerIdentity  *AWSClusterControllerIdentity
   257  	}{
   258  		{
   259  			name: "Set label while creating AWSClusterControllerIdentity if labels are undefined",
   260  			beforeAWSClusterControllerIdentity: &AWSClusterControllerIdentity{
   261  				ObjectMeta: metav1.ObjectMeta{
   262  					Name: "default",
   263  				},
   264  			},
   265  			afterAWSClusterControllerIdentity: &AWSClusterControllerIdentity{
   266  				ObjectMeta: metav1.ObjectMeta{
   267  					Name: "default",
   268  					Labels: map[string]string{
   269  						clusterv1.ClusterctlMoveHierarchyLabelName: "",
   270  					},
   271  				},
   272  			},
   273  		},
   274  		{
   275  			name: "Not update any label while creating AWSClusterControllerIdentity if labels are already defined",
   276  			beforeAWSClusterControllerIdentity: &AWSClusterControllerIdentity{
   277  				ObjectMeta: metav1.ObjectMeta{
   278  					Name: "default",
   279  					Labels: map[string]string{
   280  						clusterv1.ClusterctlMoveHierarchyLabelName: "abc",
   281  					},
   282  				},
   283  			},
   284  			afterAWSClusterControllerIdentity: &AWSClusterControllerIdentity{
   285  				ObjectMeta: metav1.ObjectMeta{
   286  					Name: "default",
   287  					Labels: map[string]string{
   288  						clusterv1.ClusterctlMoveHierarchyLabelName: "abc",
   289  					},
   290  				},
   291  			},
   292  		},
   293  	}
   294  
   295  	for _, tt := range tests {
   296  		t.Run(tt.name, func(t *testing.T) {
   297  			ctx := context.TODO()
   298  			awsClusterControllerIdentity := tt.beforeAWSClusterControllerIdentity.DeepCopy()
   299  			g.Expect(testEnv.Create(ctx, awsClusterControllerIdentity)).To(Succeed())
   300  			g.Expect(len(awsClusterControllerIdentity.ObjectMeta.Labels)).To(Not(Equal(0)))
   301  			g.Expect(awsClusterControllerIdentity.ObjectMeta.Labels[clusterv1.ClusterctlMoveHierarchyLabelName]).To(Equal(tt.afterAWSClusterControllerIdentity.ObjectMeta.Labels[clusterv1.ClusterctlMoveHierarchyLabelName]))
   302  			g.Expect(testEnv.Delete(ctx, awsClusterControllerIdentity)).To(Succeed())
   303  		})
   304  	}
   305  }