Skip to content

Commit

Permalink
WIP Add IsCtlPlane attribute to network
Browse files Browse the repository at this point in the history
We don't have to hardcode the ctlplane network in dataplane
operator.

Signed-off-by: rabi <[email protected]>
  • Loading branch information
rabi committed Sep 11, 2024
1 parent 31f905c commit 5456391
Show file tree
Hide file tree
Showing 12 changed files with 74 additions and 24 deletions.
4 changes: 4 additions & 0 deletions apis/bases/network.openstack.org_ipsets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ spec:
gateway:
description: Gateway optional gateway for the network
type: string
isCtlPlane:
description: Whether it is ctlplane network
type: boolean
mtu:
description: MTU of the network
type: integer
Expand Down Expand Up @@ -190,6 +193,7 @@ spec:
required:
- address
- dnsDomain
- isCtlPlane
- network
- subnet
type: object
Expand Down
4 changes: 4 additions & 0 deletions apis/bases/network.openstack.org_netconfigs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ spec:
dnsDomain:
description: DNSDomain name of the Network
type: string
isCtlPlane:
description: Whether this network is control plane network
type: boolean
mtu:
default: 1500
description: MTU of the network
Expand Down Expand Up @@ -128,6 +131,7 @@ spec:
type: array
required:
- dnsDomain
- isCtlPlane
- name
- subnets
type: object
Expand Down
1 change: 1 addition & 0 deletions apis/network/v1beta1/common_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const (
errDefaultRouteChanged = "defaultRoute must not change"
errMultiDefaultRoute = "%s defaultRoute can only be requested on a singe network"
errNoDefaultRoute = "defaultRoute requested, but not configured for subnet %s"
errMultiControlPlane = "ctlPlaneNetwork can only be on a singe network"
)

func getNetConfig(
Expand Down
3 changes: 3 additions & 0 deletions apis/network/v1beta1/ipset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ type IPSetReservation struct {

// DNSDomain of the subnet
DNSDomain string `json:"dnsDomain"`

// Whether it is ctlplane network
IsCtlPlane bool `json:"isCtlPlane"`
}

// IPSetStatus defines the observed state of IPSet
Expand Down
4 changes: 4 additions & 0 deletions apis/network/v1beta1/netconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ type Network struct {
// +kubebuilder:validation:Required
// Subnets of the network
Subnets []Subnet `json:"subnets"`

// +kubebuilder:validation:optional
// Whether this network is control plane network
IsCtlPlane bool `json:"isCtlPlane"`
}

// Subnet definition
Expand Down
10 changes: 8 additions & 2 deletions apis/network/v1beta1/netconfig_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func valiateNetworks(
allErrs := field.ErrorList{}
netNames := map[string]field.Path{}
netCIDR := map[string]field.Path{}

ctlPlaneCount := 0
for netIdx, _net := range networks {
path := path.Child("networks").Index(netIdx)

Expand All @@ -171,8 +171,14 @@ func valiateNetworks(
allErrs = append(allErrs, err...)
}
}
}
if _net.IsCtlPlane {
ctlPlaneCount++
}
if ctlPlaneCount > 1 {
allErrs = append(allErrs, field.Invalid(path.Child("IsCtlPlane"), _net.IsCtlPlane, errMultiControlPlane))
}

}
return allErrs
}

Expand Down
4 changes: 4 additions & 0 deletions config/crd/bases/network.openstack.org_ipsets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ spec:
gateway:
description: Gateway optional gateway for the network
type: string
isCtlPlane:
description: Whether it is ctlplane network
type: boolean
mtu:
description: MTU of the network
type: integer
Expand Down Expand Up @@ -190,6 +193,7 @@ spec:
required:
- address
- dnsDomain
- isCtlPlane
- network
- subnet
type: object
Expand Down
4 changes: 4 additions & 0 deletions config/crd/bases/network.openstack.org_netconfigs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ spec:
dnsDomain:
description: DNSDomain name of the Network
type: string
isCtlPlane:
description: Whether this network is control plane network
type: boolean
mtu:
default: 1500
description: MTU of the network
Expand Down Expand Up @@ -128,6 +131,7 @@ spec:
type: array
required:
- dnsDomain
- isCtlPlane
- name
- subnets
type: object
Expand Down
1 change: 1 addition & 0 deletions config/samples/network_v1beta1_netconfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ spec:
start: 192.168.122.150
cidr: 192.168.122.0/24
gateway: 192.168.122.1
isCtlPlane: true
- name: internalapi
dnsDomain: internalapi.example.com
subnets:
Expand Down
25 changes: 16 additions & 9 deletions controllers/network/ipset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"net"
"sort"

corev1 "k8s.io/api/core/v1"
k8s_errors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -274,6 +275,11 @@ func (r *IPSetReconciler) reconcileNormal(ctx context.Context, instance *network
return ctrl.Result{}, err
}

// sort instance.Status.Reservations by Network
sort.Slice(instance.Status.Reservation, func(i, j int) bool {
return instance.Status.Reservation[i].IsCtlPlane && !instance.Status.Reservation[j].IsCtlPlane
})

instance.Status.Conditions.MarkTrue(networkv1.ReservationReadyCondition, networkv1.ReservationReadyMessage)

Log.Info("IPSet is ready:", "instance", instance.Name, "ipSetRes", ipSetRes.Spec.Reservation)
Expand Down Expand Up @@ -426,15 +432,16 @@ func (r *IPSetReconciler) ensureReservation(
// add IP to the reservation and IPSet status reservations
reservationSpec.Reservation[string(netDef.Name)] = *ip
ipsetRes := networkv1.IPSetReservation{
Network: netDef.Name,
Subnet: subnetDef.Name,
Address: ip.Address,
MTU: netDef.MTU,
Cidr: subnetDef.Cidr,
Vlan: subnetDef.Vlan,
Gateway: subnetDef.Gateway,
Routes: subnetDef.Routes,
DNSDomain: netDef.DNSDomain,
Network: netDef.Name,
Subnet: subnetDef.Name,
Address: ip.Address,
MTU: netDef.MTU,
Cidr: subnetDef.Cidr,
Vlan: subnetDef.Vlan,
Gateway: subnetDef.Gateway,
Routes: subnetDef.Routes,
DNSDomain: netDef.DNSDomain,
IsCtlPlane: netDef.IsCtlPlane,
}
if ipsetNet.DefaultRoute != nil && *ipsetNet.DefaultRoute && subnetDef.Gateway != nil {
ipsetRes.Gateway = subnetDef.Gateway
Expand Down
13 changes: 7 additions & 6 deletions tests/functional/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,12 +469,13 @@ func GetNetConfigSpec(nets ...networkv1.Network) map[string]interface{} {
return spec
}

func GetNetSpec(name string, subnets ...networkv1.Subnet) networkv1.Network {
func GetNetSpec(name string, isCtlPlane bool, subnets ...networkv1.Subnet) networkv1.Network {
net := networkv1.Network{
Name: networkv1.NetNameStr(name),
DNSDomain: fmt.Sprintf("%s.example.com", strings.ToLower(name)),
MTU: 1400,
Subnets: []networkv1.Subnet{},
Name: networkv1.NetNameStr(name),
DNSDomain: fmt.Sprintf("%s.example.com", strings.ToLower(name)),
MTU: 1400,
Subnets: []networkv1.Subnet{},
IsCtlPlane: isCtlPlane,
}

net.Subnets = append(net.Subnets, subnets...)
Expand All @@ -483,7 +484,7 @@ func GetNetSpec(name string, subnets ...networkv1.Subnet) networkv1.Network {
}

func GetDefaultNetConfigSpec() map[string]interface{} {
net := GetNetSpec(net1, GetSubnet1(subnet1))
net := GetNetSpec(net1, false, GetSubnet1(subnet1))
return GetNetConfigSpec(net)
}

Expand Down
25 changes: 18 additions & 7 deletions tests/functional/ipset_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ var _ = Describe("IPSet controller", func() {

When("a GetDefaultIPSetSpec IPSet gets created using a custom NetConfig", func() {
BeforeEach(func() {
netSpec := GetNetSpec(net1, GetSubnet1(subnet1))
netSpec := GetNetSpec(net1, false, GetSubnet1(subnet1))
netSpec.Subnets[0].DNSDomain = ptr.To("subnet1.net-1.example.com")
netCfg := CreateNetConfig(namespace, GetNetConfigSpec(netSpec))
ipset := CreateIPSet(namespace, GetDefaultIPSetSpec())
Expand Down Expand Up @@ -319,9 +319,9 @@ var _ = Describe("IPSet controller", func() {
var ipSetNetworks []networkv1.IPSetNetwork
BeforeEach(func() {
netSpecs = []networkv1.Network{}
netSpecs = append(netSpecs, GetNetSpec(net1, GetSubnet1(subnet1)))
netSpecs = append(netSpecs, GetNetSpec(net2, GetSubnet2(subnet1)))
netSpecs = append(netSpecs, GetNetSpec(net3, GetSubnet3(subnet1)))
netSpecs = append(netSpecs, GetNetSpec(net1, false, GetSubnet1(subnet1)))
netSpecs = append(netSpecs, GetNetSpec(net2, true, GetSubnet2(subnet1)))
netSpecs = append(netSpecs, GetNetSpec(net3, false, GetSubnet3(subnet1)))

ipSetNetworks = []networkv1.IPSetNetwork{}
ipSetNetworks = append(ipSetNetworks, GetIPSetNet1Lower())
Expand Down Expand Up @@ -369,11 +369,22 @@ var _ = Describe("IPSet controller", func() {

Eventually(func(g Gomega) {
g.Expect(k8sClient.Get(ctx, ipSetName, instance)).Should(Succeed())
ctlplaneNetwork := instance.Status.Reservation[0].Network
ctlplaneFound := false
for i := 0; i < len(ipSetNetworks); i++ {
// first assert that the instance networks are in the same order as we specified
g.Expect(instance.Spec.Networks[i].Name).To(Equal(ipSetNetworks[i].Name))
// then assert that the reservation networks are in the same order
g.Expect(instance.Spec.Networks[i].Name).To(Equal(instance.Status.Reservation[i].Network))
// other than ctlplane network being the first one.
if ipSetNetworks[i].Name == ctlplaneNetwork {
ctlplaneFound = true
continue
}
if ctlplaneFound {
g.Expect(instance.Spec.Networks[i].Name).To(Equal(instance.Status.Reservation[i].Network))
} else {
g.Expect(instance.Spec.Networks[i].Name).To(Equal(instance.Status.Reservation[i+1].Network))
}
}
g.Expect(k8sClient.Update(ctx, instance)).Should(Succeed())
}, timeout, interval).Should(Succeed())
Expand All @@ -382,8 +393,8 @@ var _ = Describe("IPSet controller", func() {

When("an IPSet with Immutable flag gets created", func() {
BeforeEach(func() {
net1Spec := GetNetSpec(net1, GetSubnet1(subnet1))
net2Spec := GetNetSpec(net2, GetSubnet2(subnet1))
net1Spec := GetNetSpec(net1, false, GetSubnet1(subnet1))
net2Spec := GetNetSpec(net2, false, GetSubnet2(subnet1))
netCfg := CreateNetConfig(namespace, GetNetConfigSpec(net1Spec, net2Spec))
netCfgName.Name = netCfg.GetName()
netCfgName.Namespace = netCfg.GetNamespace()
Expand Down

0 comments on commit 5456391

Please sign in to comment.