@@ -859,6 +859,10 @@ func (c *Config) SetupPeerings(ctx context.Context, vlab *VLAB, opts SetupPeerin
859859 if err := kube .List (ctx , externalList ); err != nil {
860860 return fmt .Errorf ("listing externals: %w" , err )
861861 }
862+ externals := map [string ]* vpcapi.External {}
863+ for _ , ext := range externalList .Items {
864+ externals [ext .Name ] = & ext
865+ }
862866
863867 switchGroupList := & wiringapi.SwitchGroupList {}
864868 if err := kube .List (ctx , switchGroupList ); err != nil {
@@ -1021,6 +1025,9 @@ func (c *Config) SetupPeerings(ctx context.Context, vlab *VLAB, opts SetupPeerin
10211025 if ext == "" {
10221026 return fmt .Errorf ("invalid external peering request %s, external should be non-empty" , reqName )
10231027 }
1028+ if _ , ok := externals [ext ]; ! ok {
1029+ return fmt .Errorf ("external %s not found for external peering" , ext )
1030+ }
10241031
10251032 if ! strings .HasPrefix (vpc , "vpc-" ) {
10261033 if vpcID , err := strconv .ParseUint (vpc , 10 , 64 ); err == nil {
@@ -1030,19 +1037,9 @@ func (c *Config) SetupPeerings(ctx context.Context, vlab *VLAB, opts SetupPeerin
10301037 vpc = "vpc-" + vpc
10311038 }
10321039
1033- extPeering := & vpcapi.ExternalPeeringSpec {
1034- Permit : vpcapi.ExternalPeeringSpecPermit {
1035- VPC : vpcapi.ExternalPeeringSpecVPC {
1036- Name : vpc ,
1037- Subnets : []string {},
1038- },
1039- External : vpcapi.ExternalPeeringSpecExternal {
1040- Name : ext ,
1041- Prefixes : []vpcapi.ExternalPeeringSpecPrefix {},
1042- },
1043- },
1044- }
1045-
1040+ gw := false
1041+ vpcSubnets := []string {}
1042+ extPrefixes := []string {}
10461043 for idx , option := range parts [1 :] {
10471044 parts := strings .Split (option , "=" )
10481045 if len (parts ) > 2 {
@@ -1055,54 +1052,105 @@ func (c *Config) SetupPeerings(ctx context.Context, vlab *VLAB, opts SetupPeerin
10551052 optValue = parts [1 ]
10561053 }
10571054
1058- if optName == "vpc_subnets" || optName == "subnets" || optName == "s" {
1055+ switch optName {
1056+ case "gw" , "gateway" :
1057+ gw = true
1058+ case "vpc-subnets" , "subnets" , "s" :
10591059 if optValue == "" {
10601060 return fmt .Errorf ("invalid external peering option #%d %s, VPC subnet names should be non-empty" , idx , option )
10611061 }
1062-
1063- extPeering .Permit .VPC .Subnets = append (extPeering .Permit .VPC .Subnets , strings .Split (optValue , "," )... )
1064- } else if optName == "ext_prefixes" || optName == "prefixes" || optName == "p" {
1062+ vpcSubnets = strings .Split (optValue , "," )
1063+ case "ext-prefixes" , "prefixes" , "p" :
10651064 if optValue == "" {
10661065 return fmt .Errorf ("invalid external peering option #%d %s, external prefixes should be non-empty" , idx , option )
10671066 }
1067+ extPrefixes = strings .Split (optValue , "," )
1068+ default :
1069+ return fmt .Errorf ("invalid peering option #%d %s" , idx , option )
1070+ }
1071+ }
10681072
1069- for _ , rawPrefix := range strings .Split (optValue , "," ) {
1070- prefix := vpcapi.ExternalPeeringSpecPrefix {
1071- Prefix : rawPrefix ,
1073+ if ! gw {
1074+ extPeering := & vpcapi.ExternalPeeringSpec {
1075+ Permit : vpcapi.ExternalPeeringSpecPermit {
1076+ VPC : vpcapi.ExternalPeeringSpecVPC {
1077+ Name : vpc ,
1078+ Subnets : vpcSubnets ,
1079+ },
1080+ External : vpcapi.ExternalPeeringSpecExternal {
1081+ Name : ext ,
1082+ Prefixes : []vpcapi.ExternalPeeringSpecPrefix {},
1083+ },
1084+ },
1085+ }
1086+ for idx , rawPrefix := range extPrefixes {
1087+ prefix := vpcapi.ExternalPeeringSpecPrefix {
1088+ Prefix : rawPrefix ,
1089+ }
1090+ if strings .Contains (rawPrefix , "_" ) {
1091+ prefixParts := strings .Split (rawPrefix , "_" )
1092+ if len (prefixParts ) > 1 {
1093+ return fmt .Errorf ("invalid external peering option #%d, external prefix should be in format 1.2.3.4/24 (found %s)" , idx , rawPrefix )
10721094 }
1073- if strings .Contains (rawPrefix , "_" ) {
1074- prefixParts := strings .Split (rawPrefix , "_" )
1075- if len (prefixParts ) > 1 {
1076- return fmt .Errorf ("invalid external peering option #%d %s, external prefix should be in format 1.2.3.4/24" , idx , option )
1077- }
10781095
1079- prefix .Prefix = prefixParts [0 ]
1080- }
1096+ prefix .Prefix = prefixParts [0 ]
1097+ }
10811098
1082- extPeering .Permit .External .Prefixes = append (extPeering .Permit .External .Prefixes , prefix )
1099+ extPeering .Permit .External .Prefixes = append (extPeering .Permit .External .Prefixes , prefix )
1100+ }
1101+ if len (extPeering .Permit .VPC .Subnets ) == 0 {
1102+ extPeering .Permit .VPC .Subnets = []string {"default" }
1103+ }
1104+ slices .Sort (extPeering .Permit .VPC .Subnets )
1105+
1106+ if len (extPeering .Permit .External .Prefixes ) == 0 {
1107+ extPeering .Permit .External .Prefixes = []vpcapi.ExternalPeeringSpecPrefix {
1108+ {
1109+ Prefix : "0.0.0.0/0" ,
1110+ },
10831111 }
1084- } else {
1085- return fmt .Errorf ("invalid external peering option #%d %s" , idx , option )
10861112 }
1087- }
1113+ slices .SortFunc (extPeering .Permit .External .Prefixes , func (a , b vpcapi.ExternalPeeringSpecPrefix ) int {
1114+ return strings .Compare (a .Prefix , b .Prefix )
1115+ })
10881116
1089- if len (extPeering .Permit .VPC .Subnets ) == 0 {
1090- extPeering .Permit .VPC .Subnets = []string {"default" }
1091- }
1092- slices .Sort (extPeering .Permit .VPC .Subnets )
1117+ externalPeerings [fmt .Sprintf ("%s--%s" , vpc , ext )] = extPeering
1118+ } else {
1119+ vpcExpose := gwapi.PeeringEntryExpose {}
1120+ if vpc1 , ok := vpcs [vpc ]; ok {
1121+ for subnetName , subnet := range vpc1 .Spec .Subnets {
1122+ if len (vpcSubnets ) > 0 && ! slices .Contains (vpcSubnets , subnetName ) {
1123+ continue
1124+ }
1125+ vpcExpose .IPs = append (vpcExpose .IPs , gwapi.PeeringEntryIP {CIDR : subnet .Subnet })
1126+ }
1127+ }
1128+
1129+ ips := []gwapi.PeeringEntryIP {}
1130+ for idx , p := range extPrefixes {
1131+ if _ , err := netip .ParsePrefix (p ); err != nil {
1132+ return fmt .Errorf ("invalid external peering option #%d, external prefix %q is not valid: %w" , idx , p , err )
1133+ }
1134+ ips = append (ips , gwapi.PeeringEntryIP {CIDR : p })
1135+ }
1136+ if len (ips ) == 0 {
1137+ ips = append (ips , gwapi.PeeringEntryIP {CIDR : "0.0.0.0/0" })
1138+ }
1139+ extExpose := gwapi.PeeringEntryExpose {
1140+ IPs : ips ,
1141+ }
10931142
1094- if len (extPeering .Permit .External .Prefixes ) == 0 {
1095- extPeering .Permit .External .Prefixes = []vpcapi.ExternalPeeringSpecPrefix {
1096- {
1097- Prefix : "0.0.0.0/0" ,
1143+ gwPeerings [fmt .Sprintf ("%s--%s" , vpc , ext )] = & gwapi.PeeringSpec {
1144+ Peering : map [string ]* gwapi.PeeringEntry {
1145+ vpc : {
1146+ Expose : []gwapi.PeeringEntryExpose {vpcExpose },
1147+ },
1148+ ext : {
1149+ Expose : []gwapi.PeeringEntryExpose {extExpose },
1150+ },
10981151 },
10991152 }
11001153 }
1101- slices .SortFunc (extPeering .Permit .External .Prefixes , func (a , b vpcapi.ExternalPeeringSpecPrefix ) int {
1102- return strings .Compare (a .Prefix , b .Prefix )
1103- })
1104-
1105- externalPeerings [fmt .Sprintf ("%s--%s" , vpc , ext )] = extPeering
11061154 } else {
11071155 return fmt .Errorf ("invalid request name %s" , reqName )
11081156 }
0 commit comments