Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions api/wiring/v1beta1/connection_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"maps"
"net"
"net/netip"
"strings"

"github.com/fatih/color"
Expand Down Expand Up @@ -988,6 +989,11 @@ func (conn *Connection) Validate(ctx context.Context, kube kclient.Reader, fabri
return nil, errors.Wrapf(err, "failed to list connections")
}

fabricSubnet, err := netip.ParsePrefix(fabricCfg.FabricSubnet)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse fabric subnet %s", fabricCfg.FabricSubnet)
}
fabricIPs := map[netip.Addr]bool{}
for _, other := range conns.Items {
if other.Name == conn.Name {
continue
Expand All @@ -1003,6 +1009,184 @@ func (conn *Connection) Validate(ctx context.Context, kube kclient.Reader, fabri
return nil, errors.Errorf("port %s is already used by other connection", port)
}
}
switch {
case other.Spec.Fabric != nil:
for _, link := range other.Spec.Fabric.Links {
if link.Spine.IP != "" {
if ip, err := netip.ParsePrefix(link.Spine.IP); err == nil {
fabricIPs[ip.Addr()] = true
}
}
if link.Leaf.IP != "" {
if ip, err := netip.ParsePrefix(link.Leaf.IP); err == nil {
fabricIPs[ip.Addr()] = true
}
}
}
case other.Spec.Mesh != nil:
for _, link := range other.Spec.Mesh.Links {
if link.Leaf1.IP != "" {
if ip, err := netip.ParsePrefix(link.Leaf1.IP); err == nil {
fabricIPs[ip.Addr()] = true
}
}
if link.Leaf2.IP != "" {
if ip, err := netip.ParsePrefix(link.Leaf2.IP); err == nil {
fabricIPs[ip.Addr()] = true
}
}
}
case other.Spec.Gateway != nil:
for _, link := range other.Spec.Gateway.Links {
if link.Gateway.IP != "" {
if ip, err := netip.ParsePrefix(link.Gateway.IP); err == nil {
fabricIPs[ip.Addr()] = true
}
}
if link.Switch.IP != "" {
if ip, err := netip.ParsePrefix(link.Switch.IP); err == nil {
fabricIPs[ip.Addr()] = true
}
}
}
}
}

if conn.Spec.Fabric != nil { //nolint:gocritic
cf := conn.Spec.Fabric
for idx, link := range cf.Links {
if link.Spine.IP == "" || link.Leaf.IP == "" {
continue
}

spinePrefix, err := netip.ParsePrefix(link.Spine.IP)
if err != nil {
return nil, errors.Wrapf(err, "parsing fabric connection %s link %d spine IP %s", conn.Name, idx, link.Spine.IP)
}
if spinePrefix.Bits() != 31 {
return nil, errors.Errorf("fabric connection %s link %d spine IP %s is not a /31", conn.Name, idx, spinePrefix) //nolint:goerr113
}

spineIP := spinePrefix.Addr()
if !fabricSubnet.Contains(spineIP) {
return nil, errors.Errorf("fabric connection %s link %d spine IP %s is not in the fabric subnet %s", conn.Name, idx, spineIP, fabricSubnet) //nolint:goerr113
}
if _, exist := fabricIPs[spineIP]; exist {
return nil, errors.Errorf("fabric connection %s link %d spine IP %s is already in use", conn.Name, idx, spineIP) //nolint:goerr113
}
fabricIPs[spineIP] = true

leafPrefix, err := netip.ParsePrefix(link.Leaf.IP)
if err != nil {
return nil, errors.Wrapf(err, "parsing fabric connection %s link %d leaf IP %s", conn.Name, idx, link.Leaf.IP)
}
if leafPrefix.Bits() != 31 {
return nil, errors.Errorf("fabric connection %s link %d leaf IP %s is not a /31", conn.Name, idx, leafPrefix) //nolint:goerr113
}

leafIP := leafPrefix.Addr()
if !fabricSubnet.Contains(leafIP) {
return nil, errors.Errorf("fabric connection %s link %d leaf IP %s is not in the fabric subnet %s", conn.Name, idx, leafIP, fabricSubnet) //nolint:goerr113
}
if _, exist := fabricIPs[leafIP]; exist {
return nil, errors.Errorf("fabric connection %s link %d leaf IP %s is already in use", conn.Name, idx, leafIP) //nolint:goerr113
}
fabricIPs[leafIP] = true

if spinePrefix.Masked() != leafPrefix.Masked() {
return nil, errors.Errorf("fabric connection %s link %d spine IP %s and leaf IP %s are not in the same subnet", conn.Name, idx, spineIP, leafIP) //nolint:goerr113
}
}
} else if conn.Spec.Mesh != nil {
cm := conn.Spec.Mesh
for idx, link := range cm.Links {
if link.Leaf1.IP == "" || link.Leaf2.IP == "" {
continue
}

leaf1Prefix, err := netip.ParsePrefix(link.Leaf1.IP)
if err != nil {
return nil, errors.Wrapf(err, "parsing mesh connection %s link %d leaf1 IP %s", conn.Name, idx, link.Leaf1.IP)
}
if leaf1Prefix.Bits() != 31 {
return nil, errors.Errorf("mesh connection %s link %d leaf1 IP %s is not a /31", conn.Name, idx, leaf1Prefix) //nolint:goerr113
}

leaf1IP := leaf1Prefix.Addr()
if !fabricSubnet.Contains(leaf1IP) {
return nil, errors.Errorf("mesh connection %s link %d leaf1 IP %s is not in the fabric subnet %s", conn.Name, idx, leaf1IP, fabricSubnet) //nolint:goerr113
}
if _, exist := fabricIPs[leaf1IP]; exist {
return nil, errors.Errorf("mesh connection %s link %d leaf1 IP %s is already in use", conn.Name, idx, leaf1IP) //nolint:goerr113
}
fabricIPs[leaf1IP] = true

leaf2Prefix, err := netip.ParsePrefix(link.Leaf2.IP)
if err != nil {
return nil, errors.Wrapf(err, "parsing mesh connection %s link %d leaf2 IP %s", conn.Name, idx, link.Leaf2.IP)
}
if leaf2Prefix.Bits() != 31 {
return nil, errors.Errorf("mesh connection %s link %d leaf2 IP %s is not a /31", conn.Name, idx, leaf2Prefix) //nolint:goerr113
}

leaf2IP := leaf2Prefix.Addr()
if !fabricSubnet.Contains(leaf2IP) {
return nil, errors.Errorf("mesh connection %s link %d leaf2 IP %s is not in the fabric subnet %s", conn.Name, idx, leaf2IP, fabricSubnet) //nolint:goerr113
}
if _, exist := fabricIPs[leaf2IP]; exist {
return nil, errors.Errorf("mesh connection %s link %d leaf2 IP %s is already in use", conn.Name, idx, leaf2IP) //nolint:goerr113
}
fabricIPs[leaf2IP] = true

if leaf1Prefix.Masked() != leaf2Prefix.Masked() {
return nil, errors.Errorf("mesh connection %s link %d leaf1 IP %s and leaf2 IP %s are not in the same subnet", conn.Name, idx, leaf1IP, leaf2IP) //nolint:goerr113
}
}
} else if conn.Spec.Gateway != nil {
cg := conn.Spec.Gateway
for idx, link := range cg.Links {
if link.Switch.IP == "" || link.Gateway.IP == "" {
continue
}

switchPrefix, err := netip.ParsePrefix(link.Switch.IP)
if err != nil {
return nil, errors.Wrapf(err, "parsing gateway connection %s link %d switch IP %s", conn.Name, idx, link.Switch.IP)
}
if switchPrefix.Bits() != 31 {
return nil, errors.Errorf("gateway connection %s link %d switch IP %s is not a /31", conn.Name, idx, switchPrefix) //nolint:goerr113
}

switchIP := switchPrefix.Addr()
if !fabricSubnet.Contains(switchIP) {
return nil, errors.Errorf("gateway connection %s link %d switch IP %s is not in the fabric subnet %s", conn.Name, idx, switchIP, fabricSubnet) //nolint:goerr113
}
if _, exist := fabricIPs[switchIP]; exist {
return nil, errors.Errorf("gateway connection %s link %d switch IP %s is already in use", conn.Name, idx, switchIP) //nolint:goerr113
}
fabricIPs[switchIP] = true

gwPrefix, err := netip.ParsePrefix(link.Gateway.IP)
if err != nil {
return nil, errors.Wrapf(err, "parsing gateway connection %s link %d gateway IP %s", conn.Name, idx, link.Gateway.IP)
}
if gwPrefix.Bits() != 31 {
return nil, errors.Errorf("gateway connection %s link %d gateway IP %s is not a /31", conn.Name, idx, gwPrefix) //nolint:goerr113
}

gwIP := gwPrefix.Addr()
if !fabricSubnet.Contains(gwIP) {
return nil, errors.Errorf("gateway connection %s link %d gateway IP %s is not in the fabric subnet %s", conn.Name, idx, gwIP, fabricSubnet) //nolint:goerr113
}
if _, exist := fabricIPs[gwIP]; exist {
return nil, errors.Errorf("gateway connection %s link %d gateway IP %s is already in use", conn.Name, idx, gwIP) //nolint:goerr113
}
fabricIPs[gwIP] = true

if switchPrefix.Masked() != gwPrefix.Masked() {
return nil, errors.Errorf("gateway connection %s link %d switch IP %s and gateway IP %s are not in the same subnet", conn.Name, idx, switchIP, gwIP) //nolint:goerr113
}
}
}
}

Expand Down
Loading
Loading