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

     1  /*
     2  Copyright 2022 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 network
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/aws/aws-sdk-go/aws"
    23  	"github.com/aws/aws-sdk-go/service/ec2"
    24  	"github.com/golang/mock/gomock"
    25  	. "github.com/onsi/gomega"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/utils/pointer"
    28  	"sigs.k8s.io/controller-runtime/pkg/client"
    29  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    30  
    31  	infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1"
    32  	ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/controlplane/eks/api/v1beta1"
    33  	"sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/awserrors"
    34  	"sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/scope"
    35  	"sigs.k8s.io/cluster-api-provider-aws/test/mocks"
    36  	"sigs.k8s.io/cluster-api/api/v1beta1"
    37  )
    38  
    39  func setupNewManagedControlPlaneScope(cl client.Client) (*scope.ManagedControlPlaneScope, error) {
    40  	return scope.NewManagedControlPlaneScope(scope.ManagedControlPlaneScopeParams{
    41  		Client:  cl,
    42  		Cluster: &v1beta1.Cluster{},
    43  		ControlPlane: &ekscontrolplanev1.AWSManagedControlPlane{
    44  			Spec: ekscontrolplanev1.AWSManagedControlPlaneSpec{
    45  				SecondaryCidrBlock: pointer.StringPtr("secondary-cidr"),
    46  				NetworkSpec: infrav1.NetworkSpec{
    47  					VPC: infrav1.VPCSpec{ID: "vpc-id"},
    48  				},
    49  			},
    50  		},
    51  	})
    52  }
    53  
    54  func setupScheme() (*runtime.Scheme, error) {
    55  	scheme := runtime.NewScheme()
    56  	if err := ekscontrolplanev1.AddToScheme(scheme); err != nil {
    57  		return nil, err
    58  	}
    59  	return scheme, nil
    60  }
    61  
    62  func TestService_associateSecondaryCidr(t *testing.T) {
    63  	mockCtrl := gomock.NewController(t)
    64  	defer mockCtrl.Finish()
    65  
    66  	tests := []struct {
    67  		name              string
    68  		haveSecondaryCIDR bool
    69  		expect            func(m *mocks.MockEC2APIMockRecorder)
    70  		wantErr           bool
    71  	}{
    72  		{
    73  			name: "Should not associate secondary CIDR if no secondary cidr block info present in control plane",
    74  		},
    75  		{
    76  			name:              "Should return error if unable to describe VPC",
    77  			haveSecondaryCIDR: true,
    78  			expect: func(m *mocks.MockEC2APIMockRecorder) {
    79  				m.DescribeVpcs(gomock.AssignableToTypeOf(&ec2.DescribeVpcsInput{})).Return(nil, awserrors.NewFailedDependency("dependency-failure"))
    80  			},
    81  			wantErr: true,
    82  		},
    83  		{
    84  			name:              "Should not associate secondary cidr block if already exist in VPC",
    85  			haveSecondaryCIDR: true,
    86  			expect: func(m *mocks.MockEC2APIMockRecorder) {
    87  				m.DescribeVpcs(gomock.AssignableToTypeOf(&ec2.DescribeVpcsInput{})).Return(&ec2.DescribeVpcsOutput{
    88  					Vpcs: []*ec2.Vpc{
    89  						{
    90  							CidrBlockAssociationSet: []*ec2.VpcCidrBlockAssociation{
    91  								{CidrBlock: aws.String("secondary-cidr")},
    92  							},
    93  						},
    94  					}}, nil)
    95  			},
    96  		},
    97  		{
    98  			name:              "Should return error if no VPC found",
    99  			haveSecondaryCIDR: true,
   100  			expect: func(m *mocks.MockEC2APIMockRecorder) {
   101  				m.DescribeVpcs(gomock.AssignableToTypeOf(&ec2.DescribeVpcsInput{})).Return(nil, nil)
   102  			},
   103  			wantErr: true,
   104  		},
   105  		{
   106  			name:              "Should return error if failed during associating secondary cidr block",
   107  			haveSecondaryCIDR: true,
   108  			expect: func(m *mocks.MockEC2APIMockRecorder) {
   109  				m.DescribeVpcs(gomock.AssignableToTypeOf(&ec2.DescribeVpcsInput{})).Return(&ec2.DescribeVpcsOutput{
   110  					Vpcs: []*ec2.Vpc{
   111  						{
   112  							CidrBlockAssociationSet: []*ec2.VpcCidrBlockAssociation{
   113  								{CidrBlock: aws.String("secondary-cidr-new")},
   114  							},
   115  						},
   116  					}}, nil)
   117  				m.AssociateVpcCidrBlock(gomock.AssignableToTypeOf(&ec2.AssociateVpcCidrBlockInput{})).Return(nil, awserrors.NewFailedDependency("dependency-failure"))
   118  			},
   119  			wantErr: true,
   120  		},
   121  	}
   122  	for _, tt := range tests {
   123  		t.Run(tt.name, func(t *testing.T) {
   124  			g := NewWithT(t)
   125  
   126  			scheme, err := setupScheme()
   127  			g.Expect(err).NotTo(HaveOccurred())
   128  			cl := fake.NewClientBuilder().WithScheme(scheme).Build()
   129  
   130  			ec2Mock := mocks.NewMockEC2API(mockCtrl)
   131  
   132  			mcpScope, err := setupNewManagedControlPlaneScope(cl)
   133  			g.Expect(err).NotTo(HaveOccurred())
   134  
   135  			if !tt.haveSecondaryCIDR {
   136  				mcpScope.ControlPlane.Spec.SecondaryCidrBlock = nil
   137  			}
   138  
   139  			s := NewService(mcpScope)
   140  			s.EC2Client = ec2Mock
   141  
   142  			if tt.expect != nil {
   143  				tt.expect(ec2Mock.EXPECT())
   144  			}
   145  
   146  			err = s.associateSecondaryCidr()
   147  			if tt.wantErr {
   148  				g.Expect(err).To(HaveOccurred())
   149  				return
   150  			}
   151  			g.Expect(err).NotTo(HaveOccurred())
   152  		})
   153  	}
   154  }
   155  
   156  func TestService_diassociateSecondaryCidr(t *testing.T) {
   157  	mockCtrl := gomock.NewController(t)
   158  	defer mockCtrl.Finish()
   159  
   160  	tests := []struct {
   161  		name              string
   162  		haveSecondaryCIDR bool
   163  		expect            func(m *mocks.MockEC2APIMockRecorder)
   164  		wantErr           bool
   165  	}{
   166  		{
   167  			name: "Should not disassociate secondary CIDR if no secondary cidr block info present in control plane",
   168  		},
   169  		{
   170  			name:              "Should return error if unable to describe VPC",
   171  			haveSecondaryCIDR: true,
   172  			expect: func(m *mocks.MockEC2APIMockRecorder) {
   173  				m.DescribeVpcs(gomock.AssignableToTypeOf(&ec2.DescribeVpcsInput{})).Return(nil, awserrors.NewFailedDependency("dependency-failure"))
   174  			},
   175  			wantErr: true,
   176  		},
   177  		{
   178  			name:              "Should return error if no VPC found",
   179  			haveSecondaryCIDR: true,
   180  			expect: func(m *mocks.MockEC2APIMockRecorder) {
   181  				m.DescribeVpcs(gomock.AssignableToTypeOf(&ec2.DescribeVpcsInput{})).Return(nil, nil)
   182  			},
   183  			wantErr: true,
   184  		},
   185  		{
   186  			name:              "Should diassociate secondary cidr block if already exist in VPC",
   187  			haveSecondaryCIDR: true,
   188  			expect: func(m *mocks.MockEC2APIMockRecorder) {
   189  				m.DescribeVpcs(gomock.AssignableToTypeOf(&ec2.DescribeVpcsInput{})).Return(&ec2.DescribeVpcsOutput{
   190  					Vpcs: []*ec2.Vpc{
   191  						{
   192  							CidrBlockAssociationSet: []*ec2.VpcCidrBlockAssociation{
   193  								{CidrBlock: aws.String("secondary-cidr")},
   194  							},
   195  						},
   196  					}}, nil)
   197  				m.DisassociateVpcCidrBlock(gomock.AssignableToTypeOf(&ec2.DisassociateVpcCidrBlockInput{})).Return(nil, nil)
   198  			},
   199  		},
   200  		{
   201  			name:              "Should return error if failed to diassociate secondary cidr block",
   202  			haveSecondaryCIDR: true,
   203  			expect: func(m *mocks.MockEC2APIMockRecorder) {
   204  				m.DescribeVpcs(gomock.AssignableToTypeOf(&ec2.DescribeVpcsInput{})).Return(&ec2.DescribeVpcsOutput{
   205  					Vpcs: []*ec2.Vpc{
   206  						{
   207  							CidrBlockAssociationSet: []*ec2.VpcCidrBlockAssociation{
   208  								{CidrBlock: aws.String("secondary-cidr")},
   209  							},
   210  						},
   211  					}}, nil)
   212  				m.DisassociateVpcCidrBlock(gomock.AssignableToTypeOf(&ec2.DisassociateVpcCidrBlockInput{})).Return(nil, awserrors.NewFailedDependency("dependency-failure"))
   213  			},
   214  			wantErr: true,
   215  		},
   216  	}
   217  	for _, tt := range tests {
   218  		t.Run(tt.name, func(t *testing.T) {
   219  			g := NewWithT(t)
   220  
   221  			scheme, err := setupScheme()
   222  			g.Expect(err).NotTo(HaveOccurred())
   223  			cl := fake.NewClientBuilder().WithScheme(scheme).Build()
   224  
   225  			ec2Mock := mocks.NewMockEC2API(mockCtrl)
   226  
   227  			mcpScope, err := setupNewManagedControlPlaneScope(cl)
   228  			g.Expect(err).NotTo(HaveOccurred())
   229  
   230  			if !tt.haveSecondaryCIDR {
   231  				mcpScope.ControlPlane.Spec.SecondaryCidrBlock = nil
   232  			}
   233  
   234  			s := NewService(mcpScope)
   235  			s.EC2Client = ec2Mock
   236  
   237  			if tt.expect != nil {
   238  				tt.expect(ec2Mock.EXPECT())
   239  			}
   240  
   241  			err = s.disassociateSecondaryCidr()
   242  			if tt.wantErr {
   243  				g.Expect(err).To(HaveOccurred())
   244  				return
   245  			}
   246  			g.Expect(err).NotTo(HaveOccurred())
   247  		})
   248  	}
   249  }