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 }