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

     1  /*
     2  Copyright 2018 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  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/runtime"
    28  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    29  
    30  	infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1"
    31  	"sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/scope"
    32  	"sigs.k8s.io/cluster-api-provider-aws/test/mocks"
    33  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    34  )
    35  
    36  func TestReconcileInternetGateways(t *testing.T) {
    37  	mockCtrl := gomock.NewController(t)
    38  	defer mockCtrl.Finish()
    39  
    40  	testCases := []struct {
    41  		name   string
    42  		input  *infrav1.NetworkSpec
    43  		expect func(m *mocks.MockEC2APIMockRecorder)
    44  	}{
    45  		{
    46  			name: "has igw",
    47  			input: &infrav1.NetworkSpec{
    48  				VPC: infrav1.VPCSpec{
    49  					ID: "vpc-gateways",
    50  					Tags: infrav1.Tags{
    51  						infrav1.ClusterTagKey("test-cluster"): "owned",
    52  					},
    53  				},
    54  			},
    55  			expect: func(m *mocks.MockEC2APIMockRecorder) {
    56  				m.DescribeInternetGateways(gomock.AssignableToTypeOf(&ec2.DescribeInternetGatewaysInput{})).
    57  					Return(&ec2.DescribeInternetGatewaysOutput{
    58  						InternetGateways: []*ec2.InternetGateway{
    59  							{
    60  								InternetGatewayId: aws.String("igw-0"),
    61  								Attachments: []*ec2.InternetGatewayAttachment{
    62  									{
    63  										State: aws.String(ec2.AttachmentStatusAttached),
    64  										VpcId: aws.String("vpc-gateways"),
    65  									},
    66  								},
    67  							},
    68  						},
    69  					}, nil)
    70  
    71  				m.CreateTags(gomock.AssignableToTypeOf(&ec2.CreateTagsInput{})).
    72  					Return(nil, nil)
    73  			},
    74  		},
    75  		{
    76  			name: "no igw attached, creates one",
    77  			input: &infrav1.NetworkSpec{
    78  				VPC: infrav1.VPCSpec{
    79  					ID: "vpc-gateways",
    80  					Tags: infrav1.Tags{
    81  						infrav1.ClusterTagKey("test-cluster"): "owned",
    82  					},
    83  				},
    84  			},
    85  			expect: func(m *mocks.MockEC2APIMockRecorder) {
    86  				m.DescribeInternetGateways(gomock.AssignableToTypeOf(&ec2.DescribeInternetGatewaysInput{})).
    87  					Return(&ec2.DescribeInternetGatewaysOutput{}, nil)
    88  
    89  				m.CreateInternetGateway(gomock.AssignableToTypeOf(&ec2.CreateInternetGatewayInput{})).
    90  					Return(&ec2.CreateInternetGatewayOutput{
    91  						InternetGateway: &ec2.InternetGateway{
    92  							InternetGatewayId: aws.String("igw-1"),
    93  							Tags: []*ec2.Tag{
    94  								{
    95  									Key:   aws.String(infrav1.ClusterTagKey("test-cluster")),
    96  									Value: aws.String("owned"),
    97  								},
    98  								{
    99  									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
   100  									Value: aws.String("common"),
   101  								},
   102  								{
   103  									Key:   aws.String("Name"),
   104  									Value: aws.String("test-cluster-igw"),
   105  								},
   106  							},
   107  						},
   108  					}, nil)
   109  
   110  				m.AttachInternetGateway(gomock.Eq(&ec2.AttachInternetGatewayInput{
   111  					InternetGatewayId: aws.String("igw-1"),
   112  					VpcId:             aws.String("vpc-gateways"),
   113  				})).
   114  					Return(&ec2.AttachInternetGatewayOutput{}, nil)
   115  			},
   116  		},
   117  	}
   118  
   119  	for _, tc := range testCases {
   120  		t.Run(tc.name, func(t *testing.T) {
   121  			ec2Mock := mocks.NewMockEC2API(mockCtrl)
   122  
   123  			scheme := runtime.NewScheme()
   124  			_ = infrav1.AddToScheme(scheme)
   125  			client := fake.NewClientBuilder().WithScheme(scheme).Build()
   126  			scope, err := scope.NewClusterScope(scope.ClusterScopeParams{
   127  				Client: client,
   128  				Cluster: &clusterv1.Cluster{
   129  					ObjectMeta: metav1.ObjectMeta{Name: "test-cluster"},
   130  				},
   131  				AWSCluster: &infrav1.AWSCluster{
   132  					ObjectMeta: metav1.ObjectMeta{Name: "test"},
   133  					Spec: infrav1.AWSClusterSpec{
   134  						NetworkSpec: *tc.input,
   135  					},
   136  				},
   137  			})
   138  			if err != nil {
   139  				t.Fatalf("Failed to create test context: %v", err)
   140  			}
   141  
   142  			tc.expect(ec2Mock.EXPECT())
   143  
   144  			s := NewService(scope)
   145  			s.EC2Client = ec2Mock
   146  
   147  			if err := s.reconcileInternetGateways(); err != nil {
   148  				t.Fatalf("got an unexpected error: %v", err)
   149  			}
   150  		})
   151  	}
   152  }
   153  
   154  func TestDeleteInternetGateways(t *testing.T) {
   155  	mockCtrl := gomock.NewController(t)
   156  	defer mockCtrl.Finish()
   157  
   158  	testCases := []struct {
   159  		name    string
   160  		input   *infrav1.NetworkSpec
   161  		expect  func(m *mocks.MockEC2APIMockRecorder)
   162  		wantErr bool
   163  	}{
   164  		{
   165  			name: "Should ignore deletion if vpc is unmanaged",
   166  			input: &infrav1.NetworkSpec{
   167  				VPC: infrav1.VPCSpec{
   168  					ID: "vpc-gateways",
   169  				},
   170  			},
   171  			expect: func(m *mocks.MockEC2APIMockRecorder) {},
   172  		},
   173  		{
   174  			name: "Should ignore deletion if internet gateway is not found",
   175  			input: &infrav1.NetworkSpec{
   176  				VPC: infrav1.VPCSpec{
   177  					ID: "vpc-gateways",
   178  					Tags: infrav1.Tags{
   179  						infrav1.ClusterTagKey("test-cluster"): "owned",
   180  					},
   181  				},
   182  			},
   183  			expect: func(m *mocks.MockEC2APIMockRecorder) {
   184  				m.DescribeInternetGateways(gomock.Eq(&ec2.DescribeInternetGatewaysInput{
   185  					Filters: []*ec2.Filter{
   186  						{
   187  							Name:   aws.String("attachment.vpc-id"),
   188  							Values: aws.StringSlice([]string{"vpc-gateways"}),
   189  						},
   190  					},
   191  				})).Return(&ec2.DescribeInternetGatewaysOutput{}, nil)
   192  			},
   193  		},
   194  		{
   195  			name: "Should successfully delete the internet gateway",
   196  			input: &infrav1.NetworkSpec{
   197  				VPC: infrav1.VPCSpec{
   198  					ID: "vpc-gateways",
   199  					Tags: infrav1.Tags{
   200  						infrav1.ClusterTagKey("test-cluster"): "owned",
   201  					},
   202  				},
   203  			},
   204  			expect: func(m *mocks.MockEC2APIMockRecorder) {
   205  				m.DescribeInternetGateways(gomock.AssignableToTypeOf(&ec2.DescribeInternetGatewaysInput{})).
   206  					Return(&ec2.DescribeInternetGatewaysOutput{
   207  						InternetGateways: []*ec2.InternetGateway{
   208  							{
   209  								InternetGatewayId: aws.String("igw-0"),
   210  								Attachments: []*ec2.InternetGatewayAttachment{
   211  									{
   212  										State: aws.String(ec2.AttachmentStatusAttached),
   213  										VpcId: aws.String("vpc-gateways"),
   214  									},
   215  								},
   216  							},
   217  						},
   218  					}, nil)
   219  				m.DetachInternetGateway(&ec2.DetachInternetGatewayInput{
   220  					InternetGatewayId: aws.String("igw-0"),
   221  					VpcId:             aws.String("vpc-gateways"),
   222  				}).Return(&ec2.DetachInternetGatewayOutput{}, nil)
   223  				m.DeleteInternetGateway(&ec2.DeleteInternetGatewayInput{
   224  					InternetGatewayId: aws.String("igw-0"),
   225  				}).Return(&ec2.DeleteInternetGatewayOutput{}, nil)
   226  			},
   227  		},
   228  	}
   229  	for _, tc := range testCases {
   230  		t.Run(tc.name, func(t *testing.T) {
   231  			g := NewWithT(t)
   232  			ec2Mock := mocks.NewMockEC2API(mockCtrl)
   233  
   234  			scheme := runtime.NewScheme()
   235  			err := infrav1.AddToScheme(scheme)
   236  			g.Expect(err).NotTo(HaveOccurred())
   237  			client := fake.NewClientBuilder().WithScheme(scheme).Build()
   238  
   239  			scope, err := scope.NewClusterScope(scope.ClusterScopeParams{
   240  				Client: client,
   241  				Cluster: &clusterv1.Cluster{
   242  					ObjectMeta: metav1.ObjectMeta{Name: "test-cluster"},
   243  				},
   244  				AWSCluster: &infrav1.AWSCluster{
   245  					ObjectMeta: metav1.ObjectMeta{Name: "test"},
   246  					Spec: infrav1.AWSClusterSpec{
   247  						NetworkSpec: *tc.input,
   248  					},
   249  				},
   250  			})
   251  			g.Expect(err).NotTo(HaveOccurred())
   252  
   253  			tc.expect(ec2Mock.EXPECT())
   254  
   255  			s := NewService(scope)
   256  			s.EC2Client = ec2Mock
   257  
   258  			err = s.deleteInternetGateways()
   259  			if tc.wantErr {
   260  				g.Expect(err).To(HaveOccurred())
   261  				return
   262  			}
   263  			g.Expect(err).NotTo(HaveOccurred())
   264  		})
   265  	}
   266  }