Skip to content

Commit af79c5e

Browse files
committed
feat: gw ext peering with setup-peerings
Signed-off-by: Emanuele Di Pascale <[email protected]>
1 parent 3ea41f6 commit af79c5e

File tree

1 file changed

+92
-44
lines changed

1 file changed

+92
-44
lines changed

pkg/hhfab/testing.go

Lines changed: 92 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)