sigs.k8s.io/cluster-api-provider-aws@v1.5.5/pkg/cloud/services/eks/cluster_test.go (about)

     1  /*
     2  Copyright 2020 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 eks
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/aws/aws-sdk-go/aws"
    23  	"github.com/aws/aws-sdk-go/service/eks"
    24  	"github.com/aws/aws-sdk-go/service/iam"
    25  	"github.com/golang/mock/gomock"
    26  	. "github.com/onsi/gomega"
    27  	"github.com/pkg/errors"
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"k8s.io/apimachinery/pkg/runtime"
    30  	"k8s.io/apimachinery/pkg/util/version"
    31  	"k8s.io/utils/pointer"
    32  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    33  
    34  	infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1"
    35  	ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/controlplane/eks/api/v1beta1"
    36  	"sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/scope"
    37  	"sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/eks/mock_eksiface"
    38  	"sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/iamauth/mock_iamauth"
    39  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    40  )
    41  
    42  func TestMakeEksEncryptionConfigs(t *testing.T) {
    43  	providerOne := "provider"
    44  	resourceOne := "resourceOne"
    45  	resourceTwo := "resourceTwo"
    46  	testCases := []struct {
    47  		name   string
    48  		input  *ekscontrolplanev1.EncryptionConfig
    49  		expect []*eks.EncryptionConfig
    50  	}{
    51  		{
    52  			name:   "nil input",
    53  			input:  nil,
    54  			expect: []*eks.EncryptionConfig{},
    55  		},
    56  		{
    57  			name: "nil input",
    58  			input: &ekscontrolplanev1.EncryptionConfig{
    59  				Provider:  &providerOne,
    60  				Resources: []*string{&resourceOne, &resourceTwo},
    61  			},
    62  			expect: []*eks.EncryptionConfig{{
    63  				Provider:  &eks.Provider{KeyArn: &providerOne},
    64  				Resources: []*string{&resourceOne, &resourceTwo},
    65  			}},
    66  		},
    67  	}
    68  	for _, tc := range testCases {
    69  		t.Run(tc.name, func(t *testing.T) {
    70  			g := NewWithT(t)
    71  			g.Expect(makeEksEncryptionConfigs(tc.input)).To(Equal(tc.expect))
    72  		})
    73  	}
    74  }
    75  
    76  func TestParseEKSVersion(t *testing.T) {
    77  	testCases := []struct {
    78  		name   string
    79  		input  string
    80  		expect version.Version
    81  	}{
    82  		{
    83  			name:   "with patch",
    84  			input:  "1.17.8",
    85  			expect: *version.MustParseGeneric("1.17"),
    86  		},
    87  		{
    88  			name:   "with v",
    89  			input:  "v1.17.8",
    90  			expect: *version.MustParseGeneric("1.17"),
    91  		},
    92  		{
    93  			name:   "no patch",
    94  			input:  "1.17",
    95  			expect: *version.MustParseGeneric("1.17"),
    96  		},
    97  	}
    98  	for _, tc := range testCases {
    99  		t.Run(tc.name, func(t *testing.T) {
   100  			g := NewWithT(t)
   101  			g.Expect(*parseEKSVersion(tc.input)).To(Equal(tc.expect))
   102  		})
   103  	}
   104  }
   105  func TestVersionToEKS(t *testing.T) {
   106  	testCases := []struct {
   107  		name   string
   108  		input  *version.Version
   109  		expect string
   110  	}{
   111  		{
   112  			name:   "with patch",
   113  			input:  version.MustParseGeneric("1.17.8"),
   114  			expect: "1.17",
   115  		},
   116  		{
   117  			name:   "no patch",
   118  			input:  version.MustParseGeneric("1.17"),
   119  			expect: "1.17",
   120  		},
   121  		{
   122  			name:   "with extra data",
   123  			input:  version.MustParseGeneric("1.17-alpha"),
   124  			expect: "1.17",
   125  		},
   126  	}
   127  	for _, tc := range testCases {
   128  		t.Run(tc.name, func(t *testing.T) {
   129  			g := NewWithT(t)
   130  			g.Expect(versionToEKS(tc.input)).To(Equal(tc.expect))
   131  		})
   132  	}
   133  }
   134  
   135  func TestMakeVPCConfig(t *testing.T) {
   136  	type input struct {
   137  		subnets        infrav1.Subnets
   138  		endpointAccess ekscontrolplanev1.EndpointAccess
   139  		securityGroups map[infrav1.SecurityGroupRole]infrav1.SecurityGroup
   140  	}
   141  
   142  	idOne := "one"
   143  	idTwo := "two"
   144  	testCases := []struct {
   145  		name   string
   146  		input  input
   147  		err    bool
   148  		expect *eks.VpcConfigRequest
   149  	}{
   150  		{
   151  			name: "no subnets",
   152  			input: input{
   153  				subnets:        nil,
   154  				endpointAccess: ekscontrolplanev1.EndpointAccess{},
   155  			},
   156  			err:    true,
   157  			expect: nil,
   158  		},
   159  		{
   160  			name: "enough subnets",
   161  			input: input{
   162  				subnets: []infrav1.SubnetSpec{
   163  					{
   164  						ID:               idOne,
   165  						CidrBlock:        "10.0.10.0/24",
   166  						AvailabilityZone: "us-west-2a",
   167  						IsPublic:         true,
   168  					},
   169  					{
   170  						ID:               idTwo,
   171  						CidrBlock:        "10.0.10.0/24",
   172  						AvailabilityZone: "us-west-2b",
   173  						IsPublic:         false,
   174  					},
   175  				},
   176  				endpointAccess: ekscontrolplanev1.EndpointAccess{},
   177  			},
   178  			expect: &eks.VpcConfigRequest{
   179  				SubnetIds: []*string{&idOne, &idTwo},
   180  			},
   181  		},
   182  		{
   183  			name: "security groups",
   184  			input: input{
   185  				subnets: []infrav1.SubnetSpec{
   186  					{
   187  						ID:               idOne,
   188  						CidrBlock:        "10.0.10.0/24",
   189  						AvailabilityZone: "us-west-2a",
   190  						IsPublic:         true,
   191  					},
   192  					{
   193  						ID:               idTwo,
   194  						CidrBlock:        "10.0.10.0/24",
   195  						AvailabilityZone: "us-west-2b",
   196  						IsPublic:         false,
   197  					},
   198  				},
   199  				endpointAccess: ekscontrolplanev1.EndpointAccess{},
   200  				securityGroups: map[infrav1.SecurityGroupRole]infrav1.SecurityGroup{
   201  					infrav1.SecurityGroupEKSNodeAdditional: {
   202  						ID: idOne,
   203  					},
   204  				},
   205  			},
   206  			expect: &eks.VpcConfigRequest{
   207  				SubnetIds:        []*string{&idOne, &idTwo},
   208  				SecurityGroupIds: []*string{&idOne},
   209  			},
   210  		},
   211  		{
   212  			name: "non canonical public access CIDR",
   213  			input: input{
   214  				subnets: []infrav1.SubnetSpec{
   215  					{
   216  						ID:               idOne,
   217  						CidrBlock:        "10.0.10.0/24",
   218  						AvailabilityZone: "us-west-2a",
   219  						IsPublic:         true,
   220  					},
   221  					{
   222  						ID:               idTwo,
   223  						CidrBlock:        "10.0.10.1/24",
   224  						AvailabilityZone: "us-west-2b",
   225  						IsPublic:         false,
   226  					},
   227  				},
   228  				endpointAccess: ekscontrolplanev1.EndpointAccess{
   229  					PublicCIDRs: []*string{aws.String("10.0.0.1/24")},
   230  				},
   231  			},
   232  			expect: &eks.VpcConfigRequest{
   233  				SubnetIds:         []*string{&idOne, &idTwo},
   234  				PublicAccessCidrs: []*string{aws.String("10.0.0.0/24")},
   235  			},
   236  		},
   237  	}
   238  	for _, tc := range testCases {
   239  		t.Run(tc.name, func(t *testing.T) {
   240  			g := NewWithT(t)
   241  			config, err := makeVpcConfig(tc.input.subnets, tc.input.endpointAccess, tc.input.securityGroups)
   242  			if tc.err {
   243  				g.Expect(err).To(HaveOccurred())
   244  			} else {
   245  				g.Expect(config).To(Equal(tc.expect))
   246  			}
   247  		})
   248  	}
   249  }
   250  
   251  func TestPublicAccessCIDRsEqual(t *testing.T) {
   252  	testCases := []struct {
   253  		name   string
   254  		a      []*string
   255  		b      []*string
   256  		expect bool
   257  	}{
   258  		{
   259  			name:   "no CIDRs",
   260  			a:      nil,
   261  			b:      nil,
   262  			expect: true,
   263  		},
   264  		{
   265  			name:   "every address",
   266  			a:      []*string{aws.String("0.0.0.0/0")},
   267  			b:      nil,
   268  			expect: true,
   269  		},
   270  		{
   271  			name:   "every address",
   272  			a:      []*string{aws.String("1.1.1.0/24")},
   273  			b:      []*string{aws.String("1.1.1.0/24")},
   274  			expect: true,
   275  		},
   276  	}
   277  	for _, tc := range testCases {
   278  		t.Run(tc.name, func(t *testing.T) {
   279  			g := NewWithT(t)
   280  			g.Expect(publicAccessCIDRsEqual(tc.a, tc.b)).To(Equal(tc.expect))
   281  		})
   282  	}
   283  }
   284  
   285  func TestMakeEKSLogging(t *testing.T) {
   286  	testCases := []struct {
   287  		name   string
   288  		input  *ekscontrolplanev1.ControlPlaneLoggingSpec
   289  		expect *eks.Logging
   290  	}{
   291  		{
   292  			name:   "no subnets",
   293  			input:  nil,
   294  			expect: nil,
   295  		},
   296  		{
   297  			name: "some enabled, some disabled",
   298  			input: &ekscontrolplanev1.ControlPlaneLoggingSpec{
   299  				APIServer: true,
   300  				Audit:     false,
   301  			},
   302  			expect: &eks.Logging{
   303  				ClusterLogging: []*eks.LogSetup{
   304  					{
   305  						Enabled: aws.Bool(true),
   306  						Types:   []*string{aws.String(eks.LogTypeApi)},
   307  					},
   308  					{
   309  						Enabled: aws.Bool(false),
   310  						Types: []*string{
   311  							aws.String(eks.LogTypeAudit),
   312  							aws.String(eks.LogTypeAuthenticator),
   313  							aws.String(eks.LogTypeControllerManager),
   314  							aws.String(eks.LogTypeScheduler),
   315  						},
   316  					},
   317  				},
   318  			},
   319  		},
   320  	}
   321  	for _, tc := range testCases {
   322  		t.Run(tc.name, func(t *testing.T) {
   323  			g := NewWithT(t)
   324  			logging := makeEksLogging(tc.input)
   325  			g.Expect(logging).To(Equal(tc.expect))
   326  		})
   327  	}
   328  }
   329  
   330  func TestReconcileClusterVersion(t *testing.T) {
   331  	clusterName := "default.cluster"
   332  	tests := []struct {
   333  		name        string
   334  		expect      func(m *mock_eksiface.MockEKSAPIMockRecorder)
   335  		expectError bool
   336  	}{
   337  		{
   338  			name: "no upgrade necessary",
   339  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
   340  				m.
   341  					DescribeCluster(gomock.AssignableToTypeOf(&eks.DescribeClusterInput{})).
   342  					Return(&eks.DescribeClusterOutput{
   343  						Cluster: &eks.Cluster{
   344  							Name:    aws.String("default.cluster"),
   345  							Version: aws.String("1.16"),
   346  						},
   347  					}, nil)
   348  			},
   349  			expectError: false,
   350  		},
   351  		{
   352  			name: "needs upgrade",
   353  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
   354  				m.
   355  					DescribeCluster(gomock.AssignableToTypeOf(&eks.DescribeClusterInput{})).
   356  					Return(&eks.DescribeClusterOutput{
   357  						Cluster: &eks.Cluster{
   358  							Name:    aws.String("default.cluster"),
   359  							Version: aws.String("1.14"),
   360  						},
   361  					}, nil)
   362  				m.WaitUntilClusterUpdating(
   363  					gomock.AssignableToTypeOf(&eks.DescribeClusterInput{}), gomock.Any(),
   364  				).Return(nil)
   365  				m.
   366  					UpdateClusterVersion(gomock.AssignableToTypeOf(&eks.UpdateClusterVersionInput{})).
   367  					Return(&eks.UpdateClusterVersionOutput{}, nil)
   368  			},
   369  			expectError: false,
   370  		},
   371  		{
   372  			name: "api error",
   373  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
   374  				m.
   375  					DescribeCluster(gomock.AssignableToTypeOf(&eks.DescribeClusterInput{})).
   376  					Return(&eks.DescribeClusterOutput{
   377  						Cluster: &eks.Cluster{
   378  							Name:    aws.String("default.cluster"),
   379  							Version: aws.String("1.14"),
   380  						},
   381  					}, nil)
   382  				m.
   383  					UpdateClusterVersion(gomock.AssignableToTypeOf(&eks.UpdateClusterVersionInput{})).
   384  					Return(&eks.UpdateClusterVersionOutput{}, errors.New(""))
   385  			},
   386  			expectError: true,
   387  		},
   388  	}
   389  
   390  	for _, tc := range tests {
   391  		t.Run(tc.name, func(t *testing.T) {
   392  			g := NewWithT(t)
   393  
   394  			mockControl := gomock.NewController(t)
   395  			defer mockControl.Finish()
   396  
   397  			eksMock := mock_eksiface.NewMockEKSAPI(mockControl)
   398  
   399  			scheme := runtime.NewScheme()
   400  			_ = infrav1.AddToScheme(scheme)
   401  			_ = ekscontrolplanev1.AddToScheme(scheme)
   402  			client := fake.NewClientBuilder().WithScheme(scheme).Build()
   403  			scope, err := scope.NewManagedControlPlaneScope(scope.ManagedControlPlaneScopeParams{
   404  				Client: client,
   405  				Cluster: &clusterv1.Cluster{
   406  					ObjectMeta: metav1.ObjectMeta{
   407  						Namespace: "ns",
   408  						Name:      clusterName,
   409  					},
   410  				},
   411  				ControlPlane: &ekscontrolplanev1.AWSManagedControlPlane{
   412  					Spec: ekscontrolplanev1.AWSManagedControlPlaneSpec{
   413  						Version: aws.String("1.16"),
   414  					},
   415  				},
   416  			})
   417  			g.Expect(err).To(BeNil())
   418  
   419  			tc.expect(eksMock.EXPECT())
   420  			s := NewService(scope)
   421  			s.EKSClient = eksMock
   422  
   423  			cluster, err := s.describeEKSCluster(clusterName)
   424  			g.Expect(err).To(BeNil())
   425  
   426  			err = s.reconcileClusterVersion(cluster)
   427  			if tc.expectError {
   428  				g.Expect(err).To(HaveOccurred())
   429  				return
   430  			}
   431  			g.Expect(err).To(BeNil())
   432  		})
   433  	}
   434  }
   435  
   436  func TestCreateCluster(t *testing.T) {
   437  	clusterName := "cluster.default"
   438  	version := aws.String("1.24")
   439  	tests := []struct {
   440  		name        string
   441  		expectEKS   func(m *mock_eksiface.MockEKSAPIMockRecorder)
   442  		expectError bool
   443  		role        *string
   444  		tags        map[string]*string
   445  		subnets     []infrav1.SubnetSpec
   446  	}{
   447  		{
   448  			name:        "cluster create with 2 subnets",
   449  			expectEKS:   func(m *mock_eksiface.MockEKSAPIMockRecorder) {},
   450  			expectError: false,
   451  			role:        aws.String("arn:role"),
   452  			tags: map[string]*string{
   453  				"kubernetes.io/cluster/" + clusterName: aws.String("owned"),
   454  			},
   455  			subnets: []infrav1.SubnetSpec{
   456  				{ID: "1", AvailabilityZone: "us-west-2a"}, {ID: "2", AvailabilityZone: "us-west-2b"},
   457  			},
   458  		},
   459  		{
   460  			name:        "cluster create without subnets",
   461  			expectEKS:   func(m *mock_eksiface.MockEKSAPIMockRecorder) {},
   462  			expectError: true,
   463  			role:        aws.String("arn:role"),
   464  			subnets:     []infrav1.SubnetSpec{},
   465  		},
   466  	}
   467  
   468  	for _, tc := range tests {
   469  		t.Run(tc.name, func(t *testing.T) {
   470  			g := NewWithT(t)
   471  
   472  			mockControl := gomock.NewController(t)
   473  			defer mockControl.Finish()
   474  
   475  			iamMock := mock_iamauth.NewMockIAMAPI(mockControl)
   476  			eksMock := mock_eksiface.NewMockEKSAPI(mockControl)
   477  
   478  			scheme := runtime.NewScheme()
   479  			_ = infrav1.AddToScheme(scheme)
   480  			_ = ekscontrolplanev1.AddToScheme(scheme)
   481  			client := fake.NewClientBuilder().WithScheme(scheme).Build()
   482  			scope, _ := scope.NewManagedControlPlaneScope(scope.ManagedControlPlaneScopeParams{
   483  				Client: client,
   484  				Cluster: &clusterv1.Cluster{
   485  					ObjectMeta: metav1.ObjectMeta{
   486  						Namespace: "ns",
   487  						Name:      "capi-name",
   488  					},
   489  				},
   490  				ControlPlane: &ekscontrolplanev1.AWSManagedControlPlane{
   491  					Spec: ekscontrolplanev1.AWSManagedControlPlaneSpec{
   492  						EKSClusterName: clusterName,
   493  						Version:        version,
   494  						RoleName:       tc.role,
   495  						NetworkSpec:    infrav1.NetworkSpec{Subnets: tc.subnets},
   496  					},
   497  				},
   498  			})
   499  			subnetIds := make([]*string, 0)
   500  			for i := range tc.subnets {
   501  				subnet := tc.subnets[i]
   502  				subnetIds = append(subnetIds, &subnet.ID)
   503  			}
   504  
   505  			if !tc.expectError {
   506  				roleOutput := iam.GetRoleOutput{Role: &iam.Role{Arn: tc.role}}
   507  				iamMock.EXPECT().GetRole(gomock.Any()).Return(&roleOutput, nil)
   508  				eksMock.EXPECT().CreateCluster(&eks.CreateClusterInput{
   509  					Name:             aws.String(clusterName),
   510  					EncryptionConfig: []*eks.EncryptionConfig{},
   511  					ResourcesVpcConfig: &eks.VpcConfigRequest{
   512  						SubnetIds: subnetIds,
   513  					},
   514  					RoleArn: tc.role,
   515  					Tags:    tc.tags,
   516  					Version: version,
   517  				}).Return(&eks.CreateClusterOutput{}, nil)
   518  			}
   519  			s := NewService(scope)
   520  			s.IAMClient = iamMock
   521  			s.EKSClient = eksMock
   522  
   523  			_, err := s.createCluster(clusterName)
   524  			if tc.expectError {
   525  				g.Expect(err).To(HaveOccurred())
   526  				return
   527  			}
   528  			g.Expect(err).To(BeNil())
   529  		})
   530  	}
   531  }
   532  
   533  func TestReconcileEKSEncryptionConfig(t *testing.T) {
   534  	clusterName := "default.cluster"
   535  	tests := []struct {
   536  		name                string
   537  		oldEncryptionConfig *ekscontrolplanev1.EncryptionConfig
   538  		newEncryptionConfig *ekscontrolplanev1.EncryptionConfig
   539  		expect              func(m *mock_eksiface.MockEKSAPIMockRecorder)
   540  		expectError         bool
   541  	}{
   542  		{
   543  			name:                "no upgrade necessary - encryption disabled",
   544  			oldEncryptionConfig: &ekscontrolplanev1.EncryptionConfig{},
   545  			newEncryptionConfig: &ekscontrolplanev1.EncryptionConfig{},
   546  			expect:              func(m *mock_eksiface.MockEKSAPIMockRecorder) {},
   547  			expectError:         false,
   548  		},
   549  		{
   550  			name: "no upgrade necessary - encryption config unchanged",
   551  			oldEncryptionConfig: &ekscontrolplanev1.EncryptionConfig{
   552  				Provider:  pointer.String("provider"),
   553  				Resources: []*string{pointer.String("foo"), pointer.String("bar")},
   554  			},
   555  			newEncryptionConfig: &ekscontrolplanev1.EncryptionConfig{
   556  				Provider:  pointer.String("provider"),
   557  				Resources: []*string{pointer.String("foo"), pointer.String("bar")},
   558  			},
   559  			expect:      func(m *mock_eksiface.MockEKSAPIMockRecorder) {},
   560  			expectError: false,
   561  		},
   562  		{
   563  			name:                "needs upgrade",
   564  			oldEncryptionConfig: nil,
   565  			newEncryptionConfig: &ekscontrolplanev1.EncryptionConfig{
   566  				Provider:  pointer.String("provider"),
   567  				Resources: []*string{pointer.String("foo"), pointer.String("bar")},
   568  			},
   569  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
   570  				m.WaitUntilClusterUpdating(
   571  					gomock.AssignableToTypeOf(&eks.DescribeClusterInput{}), gomock.Any(),
   572  				).Return(nil)
   573  				m.AssociateEncryptionConfig(gomock.AssignableToTypeOf(&eks.AssociateEncryptionConfigInput{})).Return(&eks.AssociateEncryptionConfigOutput{}, nil)
   574  			},
   575  			expectError: false,
   576  		},
   577  		{
   578  			name: "upgrade not allowed if encryption config updated as nil",
   579  			oldEncryptionConfig: &ekscontrolplanev1.EncryptionConfig{
   580  				Provider:  pointer.String("provider"),
   581  				Resources: []*string{pointer.String("foo"), pointer.String("bar")},
   582  			},
   583  			newEncryptionConfig: nil,
   584  			expect:              func(m *mock_eksiface.MockEKSAPIMockRecorder) {},
   585  			expectError:         true,
   586  		},
   587  		{
   588  			name: "upgrade not allowed if encryption config exists",
   589  			oldEncryptionConfig: &ekscontrolplanev1.EncryptionConfig{
   590  				Provider:  pointer.String("provider"),
   591  				Resources: []*string{pointer.String("foo"), pointer.String("bar")},
   592  			},
   593  			newEncryptionConfig: &ekscontrolplanev1.EncryptionConfig{
   594  				Provider:  pointer.String("new-provider"),
   595  				Resources: []*string{pointer.String("foo"), pointer.String("bar")},
   596  			},
   597  			expect:      func(m *mock_eksiface.MockEKSAPIMockRecorder) {},
   598  			expectError: true,
   599  		},
   600  	}
   601  
   602  	for _, tc := range tests {
   603  		t.Run(tc.name, func(t *testing.T) {
   604  			g := NewWithT(t)
   605  
   606  			mockControl := gomock.NewController(t)
   607  			defer mockControl.Finish()
   608  
   609  			eksMock := mock_eksiface.NewMockEKSAPI(mockControl)
   610  
   611  			scheme := runtime.NewScheme()
   612  			_ = infrav1.AddToScheme(scheme)
   613  			_ = ekscontrolplanev1.AddToScheme(scheme)
   614  			client := fake.NewClientBuilder().WithScheme(scheme).Build()
   615  			scope, err := scope.NewManagedControlPlaneScope(scope.ManagedControlPlaneScopeParams{
   616  				Client: client,
   617  				Cluster: &clusterv1.Cluster{
   618  					ObjectMeta: metav1.ObjectMeta{
   619  						Namespace: "ns",
   620  						Name:      clusterName,
   621  					},
   622  				},
   623  				ControlPlane: &ekscontrolplanev1.AWSManagedControlPlane{
   624  					Spec: ekscontrolplanev1.AWSManagedControlPlaneSpec{
   625  						Version:          aws.String("1.16"),
   626  						EncryptionConfig: tc.newEncryptionConfig,
   627  					},
   628  				},
   629  			})
   630  			g.Expect(err).To(BeNil())
   631  
   632  			tc.expect(eksMock.EXPECT())
   633  			s := NewService(scope)
   634  			s.EKSClient = eksMock
   635  
   636  			err = s.reconcileEKSEncryptionConfig(makeEksEncryptionConfigs(tc.oldEncryptionConfig))
   637  			if tc.expectError {
   638  				g.Expect(err).To(HaveOccurred())
   639  				return
   640  			}
   641  			g.Expect(err).To(BeNil())
   642  		})
   643  	}
   644  }