@@ -62,6 +62,11 @@ type expectedCalls struct {
6262 clientset * fake.Clientset
6363}
6464
65+ type vpcSubnets struct {
66+ publicIDs []string
67+ privateIDs []string
68+ }
69+
6570//counterfeiter:generate -o fakes/fake_nodegroup_task_creator.go . nodeGroupTaskCreator
6671type nodeGroupTaskCreator interface {
6772 NewUnmanagedNodeGroupTask (context.Context , []* api.NodeGroup , bool , bool , bool , vpc.Importer ) * tasks.TaskTree
@@ -253,6 +258,51 @@ var _ = DescribeTable("Create", func(t ngEntry) {
253258 },
254259 expectedErr : errors .Wrap (errors .New ("shared node security group missing, to fix this run 'eksctl update cluster --name=my-cluster --region='" ), "cluster compatibility check failed" )}),
255260
261+ Entry ("fails when nodegroup uses privateNetworking:true and there's no private subnet within vpc" , ngEntry {
262+ updateClusterConfig : func (c * api.ClusterConfig ) {
263+ c .NodeGroups [0 ].PrivateNetworking = true
264+ },
265+ mockCalls : func (m mockCalls ) {
266+ mockProviderWithVPCSubnets (m .mockProvider , & vpcSubnets {
267+ publicIDs : []string {"subnet-public-1" , "subnet-public-2" },
268+ })
269+ },
270+ expectedErr : fmt .Errorf ("all private subnets from vpc-1, that the cluster was originally created on, have been deleted; to create private nodegroups within vpc-1 please manually set valid private subnets via nodeGroup.SubnetIDs" ),
271+ }),
272+ Entry ("fails when nodegroup uses privateNetworking:false and there's no public subnet within vpc" , ngEntry {
273+ mockCalls : func (m mockCalls ) {
274+ mockProviderWithVPCSubnets (m .mockProvider , & vpcSubnets {
275+ publicIDs : []string {"subnet-private-1" , "subnet-private-2" },
276+ })
277+ },
278+ expectedErr : fmt .Errorf ("all public subnets from vpc-1, that the cluster was originally created on, have been deleted; to create public nodegroups within vpc-1 please manually set valid public subnets via nodeGroup.SubnetIDs" ),
279+ }),
280+ Entry ("fails when nodegroup uses privateNetworking:true and there's no private subnet within az" , ngEntry {
281+ updateClusterConfig : func (c * api.ClusterConfig ) {
282+ c .NodeGroups [0 ].PrivateNetworking = true
283+ c .NodeGroups [0 ].AvailabilityZones = []string {"us-west-2b" }
284+ },
285+ mockCalls : func (m mockCalls ) {
286+ mockProviderWithVPCSubnets (m .mockProvider , & vpcSubnets {
287+ publicIDs : []string {"subnet-public-1" , "subnet-public-2" },
288+ privateIDs : []string {"subnet-private-1" },
289+ })
290+ },
291+ expectedErr : fmt .Errorf ("all private subnets from us-west-2b, that the cluster was originally created on, have been deleted; to create private nodegroups within us-west-2b please manually set valid private subnets via nodeGroup.SubnetIDs" ),
292+ }),
293+ Entry ("fails when nodegroup uses privateNetworking:false and there's no private subnet within az" , ngEntry {
294+ updateClusterConfig : func (c * api.ClusterConfig ) {
295+ c .NodeGroups [0 ].AvailabilityZones = []string {"us-west-2a" , "us-west-2b" }
296+ },
297+ mockCalls : func (m mockCalls ) {
298+ mockProviderWithVPCSubnets (m .mockProvider , & vpcSubnets {
299+ publicIDs : []string {"subnet-public-2" },
300+ privateIDs : []string {"subnet-private-1" , "subnet-private-2" },
301+ })
302+ },
303+ expectedErr : fmt .Errorf ("all public subnets from us-west-2a, that the cluster was originally created on, have been deleted; to create public nodegroups within us-west-2a please manually set valid public subnets via nodeGroup.SubnetIDs" ),
304+ }),
305+
256306 Entry ("fails when existing local ng stacks in config file is not listed" , ngEntry {
257307 mockCalls : func (m mockCalls ) {
258308 m .nodeGroupFilter .SetOnlyLocalReturns (errors .New ("err" ))
@@ -435,7 +485,7 @@ var _ = DescribeTable("Create", func(t ngEntry) {
435485 m .kubeProvider .NewRawClientReturns (nil , & kubernetes.APIServerUnreachableError {
436486 Err : errors .New ("timeout" ),
437487 })
438- mockProviderWithConfig (m .mockProvider , defaultOutput , & ekstypes.VpcConfigResponse {
488+ mockProviderWithConfig (m .mockProvider , defaultOutput , nil , & ekstypes.VpcConfigResponse {
439489 ClusterSecurityGroupId : aws .String ("csg-1234" ),
440490 EndpointPublicAccess : false ,
441491 EndpointPrivateAccess : true ,
@@ -499,7 +549,7 @@ var _ = DescribeTable("Create", func(t ngEntry) {
499549 UpdateAuthConfigMap : api .Disabled (),
500550 },
501551 mockCalls : func (m mockCalls ) {
502- mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , & ekstypes.AccessConfigResponse {
552+ mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , nil , & ekstypes.AccessConfigResponse {
503553 AuthenticationMode : ekstypes .AuthenticationModeApi ,
504554 })
505555 defaultProviderMocks (m .mockProvider , defaultOutput )
@@ -519,7 +569,7 @@ var _ = DescribeTable("Create", func(t ngEntry) {
519569 UpdateAuthConfigMap : api .Enabled (),
520570 },
521571 mockCalls : func (m mockCalls ) {
522- mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , & ekstypes.AccessConfigResponse {
572+ mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , nil , & ekstypes.AccessConfigResponse {
523573 AuthenticationMode : ekstypes .AuthenticationModeApi ,
524574 })
525575 defaultProviderMocks (m .mockProvider , defaultOutput )
@@ -536,7 +586,7 @@ var _ = DescribeTable("Create", func(t ngEntry) {
536586
537587 Entry ("creates nodegroup using access entries when authenticationMode is API_AND_CONFIG_MAP and updateAuthConfigMap is not supplied" , ngEntry {
538588 mockCalls : func (m mockCalls ) {
539- mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , & ekstypes.AccessConfigResponse {
589+ mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , nil , & ekstypes.AccessConfigResponse {
540590 AuthenticationMode : ekstypes .AuthenticationModeApiAndConfigMap ,
541591 })
542592 defaultProviderMocks (m .mockProvider , defaultOutput )
@@ -553,7 +603,7 @@ var _ = DescribeTable("Create", func(t ngEntry) {
553603
554604 Entry ("creates nodegroup using aws-auth ConfigMap when authenticationMode is CONFIG_MAP and updateAuthConfigMap is true" , ngEntry {
555605 mockCalls : func (m mockCalls ) {
556- mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , & ekstypes.AccessConfigResponse {
606+ mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , nil , & ekstypes.AccessConfigResponse {
557607 AuthenticationMode : ekstypes .AuthenticationModeConfigMap ,
558608 })
559609 defaultProviderMocks (m .mockProvider , defaultOutput )
@@ -567,7 +617,7 @@ var _ = DescribeTable("Create", func(t ngEntry) {
567617
568618 Entry ("creates nodegroup using aws-auth ConfigMap when authenticationMode is CONFIG_MAP and updateAuthConfigMap is not supplied" , ngEntry {
569619 mockCalls : func (m mockCalls ) {
570- mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , & ekstypes.AccessConfigResponse {
620+ mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , nil , & ekstypes.AccessConfigResponse {
571621 AuthenticationMode : ekstypes .AuthenticationModeConfigMap ,
572622 })
573623 defaultProviderMocks (m .mockProvider , defaultOutput )
@@ -581,7 +631,7 @@ var _ = DescribeTable("Create", func(t ngEntry) {
581631
582632 Entry ("creates nodegroup but does not use either aws-auth ConfigMap or access entries when authenticationMode is API_AND_CONFIG_MAP and updateAuthConfigMap is false" , ngEntry {
583633 mockCalls : func (m mockCalls ) {
584- mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , & ekstypes.AccessConfigResponse {
634+ mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , nil , & ekstypes.AccessConfigResponse {
585635 AuthenticationMode : ekstypes .AuthenticationModeApiAndConfigMap ,
586636 })
587637 defaultProviderMocks (m .mockProvider , defaultOutput )
@@ -602,7 +652,7 @@ var _ = DescribeTable("Create", func(t ngEntry) {
602652
603653 Entry ("creates nodegroup but does not use either aws-auth ConfigMap or access entries when authenticationMode is CONFIG_MAP and updateAuthConfigMap is false" , ngEntry {
604654 mockCalls : func (m mockCalls ) {
605- mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , & ekstypes.AccessConfigResponse {
655+ mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , nil , & ekstypes.AccessConfigResponse {
606656 AuthenticationMode : ekstypes .AuthenticationModeConfigMap ,
607657 })
608658 defaultProviderMocks (m .mockProvider , defaultOutput )
@@ -623,7 +673,7 @@ var _ = DescribeTable("Create", func(t ngEntry) {
623673
624674 Entry ("authorizes nodegroups using aws-auth ConfigMap when authenticationMode is API_AND_CONFIG_MAP and updateAuthConfigMap is true" , ngEntry {
625675 mockCalls : func (m mockCalls ) {
626- mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , & ekstypes.AccessConfigResponse {
676+ mockProviderWithConfig (m .mockProvider , defaultOutput , nil , nil , nil , & ekstypes.AccessConfigResponse {
627677 AuthenticationMode : ekstypes .AuthenticationModeApiAndConfigMap ,
628678 })
629679 defaultProviderMocks (m .mockProvider , defaultOutput )
@@ -734,6 +784,14 @@ var defaultOutput = []cftypes.Output{
734784 OutputKey : aws .String ("SharedNodeSecurityGroup" ),
735785 OutputValue : aws .String ("sg-1" ),
736786 },
787+ {
788+ OutputKey : aws .String ("SubnetsPublic" ),
789+ OutputValue : aws .String ("subnet-public-1,subnet-public-2" ),
790+ },
791+ {
792+ OutputKey : aws .String ("SubnetsPrivate" ),
793+ OutputValue : aws .String ("subnet-private-1,subnet-private-2" ),
794+ },
737795}
738796
739797func getIAMIdentities (clientset kubernetes.Interface ) []iam.Identity {
@@ -766,14 +824,18 @@ func expectedCallsForAWSAuth(e expectedCalls) {
766824}
767825
768826func defaultProviderMocks (p * mockprovider.MockProvider , output []cftypes.Output ) {
769- mockProviderWithConfig (p , output , nil , nil , nil )
827+ mockProviderWithConfig (p , output , nil , nil , nil , nil )
770828}
771829
772830func mockProviderWithOutpostConfig (p * mockprovider.MockProvider , describeStacksOutput []cftypes.Output , outpostConfig * ekstypes.OutpostConfigResponse ) {
773- mockProviderWithConfig (p , describeStacksOutput , nil , outpostConfig , nil )
831+ mockProviderWithConfig (p , describeStacksOutput , nil , nil , outpostConfig , nil )
832+ }
833+
834+ func mockProviderWithVPCSubnets (p * mockprovider.MockProvider , subnets * vpcSubnets ) {
835+ mockProviderWithConfig (p , defaultOutput , subnets , nil , nil , nil )
774836}
775837
776- func mockProviderWithConfig (p * mockprovider.MockProvider , describeStacksOutput []cftypes.Output , vpcConfigRes * ekstypes.VpcConfigResponse , outpostConfig * ekstypes.OutpostConfigResponse , accessConfig * ekstypes.AccessConfigResponse ) {
838+ func mockProviderWithConfig (p * mockprovider.MockProvider , describeStacksOutput []cftypes.Output , subnets * vpcSubnets , vpcConfigRes * ekstypes.VpcConfigResponse , outpostConfig * ekstypes.OutpostConfigResponse , accessConfig * ekstypes.AccessConfigResponse ) {
777839 p .MockCloudFormation ().On ("ListStacks" , mock .Anything , mock .Anything ).Return (& cloudformation.ListStacksOutput {
778840 StackSummaries : []cftypes.StackSummary {
779841 {
@@ -854,6 +916,88 @@ func mockProviderWithConfig(p *mockprovider.MockProvider, describeStacksOutput [
854916 },
855917 },
856918 }, nil )
919+
920+ if subnets == nil {
921+ subnets = & vpcSubnets {
922+ publicIDs : []string {"subnet-public-1" , "subnet-public-2" },
923+ privateIDs : []string {"subnet-private-1" , "subnet-private-2" },
924+ }
925+ }
926+
927+ subnetPublic1 := ec2types.Subnet {
928+ SubnetId : aws .String ("subnet-public-1" ),
929+ CidrBlock : aws .String ("192.168.64.0/20" ),
930+ AvailabilityZone : aws .String ("us-west-2a" ),
931+ VpcId : aws .String ("vpc-1" ),
932+ MapPublicIpOnLaunch : aws .Bool (true ),
933+ }
934+ subnetPrivate1 := ec2types.Subnet {
935+ SubnetId : aws .String ("subnet-private-1" ),
936+ CidrBlock : aws .String ("192.168.128.0/20" ),
937+ AvailabilityZone : aws .String ("us-west-2a" ),
938+ VpcId : aws .String ("vpc-1" ),
939+ MapPublicIpOnLaunch : aws .Bool (false ),
940+ }
941+ subnetPublic2 := ec2types.Subnet {
942+ SubnetId : aws .String ("subnet-public-2" ),
943+ CidrBlock : aws .String ("192.168.80.0/20" ),
944+ AvailabilityZone : aws .String ("us-west-2b" ),
945+ VpcId : aws .String ("vpc-1" ),
946+ MapPublicIpOnLaunch : aws .Bool (true ),
947+ }
948+ subnetPrivate2 := ec2types.Subnet {
949+ SubnetId : aws .String ("subnet-private-2" ),
950+ CidrBlock : aws .String ("192.168.32.0/20" ),
951+ AvailabilityZone : aws .String ("us-west-2b" ),
952+ VpcId : aws .String ("vpc-1" ),
953+ MapPublicIpOnLaunch : aws .Bool (false ),
954+ }
955+
956+ subnetsForID := map [string ]ec2types.Subnet {
957+ "subnet-public-1" : subnetPublic1 ,
958+ "subnet-private-1" : subnetPrivate1 ,
959+ "subnet-public-2" : subnetPublic2 ,
960+ "subnet-private-2" : subnetPrivate2 ,
961+ }
962+
963+ mockDescribeSubnets := func (mp * mockprovider.MockProvider , vpcID string , subnetIDs []string ) {
964+ var subnets []ec2types.Subnet
965+ for _ , id := range subnetIDs {
966+ subnets = append (subnets , subnetsForID [id ])
967+ }
968+ if vpcID == "" {
969+ mp .MockEC2 ().On ("DescribeSubnets" , mock .Anything , & ec2.DescribeSubnetsInput {
970+ SubnetIds : subnetIDs ,
971+ }).Return (& ec2.DescribeSubnetsOutput {Subnets : subnets }, nil )
972+ return
973+ }
974+ mp .MockEC2 ().On ("DescribeSubnets" , mock .Anything , & ec2.DescribeSubnetsInput {
975+ Filters : []ec2types.Filter {
976+ {
977+ Name : aws .String ("vpc-id" ),
978+ Values : []string {vpcID },
979+ },
980+ },
981+ }).Return (& ec2.DescribeSubnetsOutput {Subnets : subnets }, nil )
982+ }
983+
984+ mockDescribeSubnets (p , "" , subnets .publicIDs )
985+ mockDescribeSubnets (p , "" , subnets .privateIDs )
986+ mockDescribeSubnets (p , "vpc-1" , append (subnets .publicIDs , subnets .privateIDs ... ))
987+
988+ p .MockEC2 ().On ("DescribeVpcs" , mock .Anything , mock .Anything ).Return (& ec2.DescribeVpcsOutput {
989+ Vpcs : []ec2types.Vpc {
990+ {
991+ CidrBlock : aws .String ("192.168.0.0/20" ),
992+ VpcId : aws .String ("vpc-1" ),
993+ CidrBlockAssociationSet : []ec2types.VpcCidrBlockAssociation {
994+ {
995+ CidrBlock : aws .String ("192.168.0.0/20" ),
996+ },
997+ },
998+ },
999+ },
1000+ }, nil )
8571001}
8581002
8591003func mockProviderForUnownedCluster (p * mockprovider.MockProvider , k * eksfakes.FakeKubeProvider , extraSGRules ... ec2types.SecurityGroupRule ) {
0 commit comments