Skip to content

Commit

Permalink
Add ServiceNetwork attribute to networks in netconfig
Browse files Browse the repository at this point in the history
This would allow us to identify the ctlplane network when
using custom network and also generate inventory using
the ServiceNetwork.

Signed-off-by: rabi <[email protected]>
  • Loading branch information
rabi committed Sep 11, 2024
1 parent 31f905c commit feac125
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 15 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 @@ -180,6 +180,9 @@ spec:
- nexthop
type: object
type: array
serviceNetwork:
description: ServiceNetwork mapping
type: string
subnet:
description: Subnet name
pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$
Expand All @@ -191,6 +194,7 @@ spec:
- address
- dnsDomain
- network
- serviceNetwork
- subnet
type: object
type: array
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 @@ -55,6 +55,9 @@ spec:
...
pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$
type: string
serviceNetwork:
description: Service network mapping
type: string
subnets:
description: Subnets of the network
items:
Expand Down Expand Up @@ -129,6 +132,7 @@ spec:
required:
- dnsDomain
- name
- serviceNetwork
- subnets
type: object
type: array
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"`

// ServiceNetwork mapping
ServiceNetwork string `json:"serviceNetwork"`
}

// 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
// Service network mapping
ServiceNetwork string `json:"serviceNetwork"`
}

// Subnet definition
Expand Down
9 changes: 5 additions & 4 deletions apis/network/v1beta1/netconfig_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,12 @@ var _ webhook.Defaulter = &NetConfig{}

// Default implements webhook.Defaulter so a webhook will be registered for the type
func (r *NetConfig) Default() {
netconfiglog.Info("default", "name", r.Name)
for _, net := range r.Spec.Networks {
if net.ServiceNetwork == "" {
net.ServiceNetwork = string(net.Name)
}
}

// TODO(user): fill in your defaulting logic.
}

//+kubebuilder:webhook:path=/validate-network-openstack-org-v1beta1-netconfig,mutating=false,failurePolicy=fail,sideEffects=None,groups=network.openstack.org,resources=netconfigs,verbs=create;update;delete,versions=v1beta1,name=vnetconfig.kb.io,admissionReviewVersions=v1
Expand Down Expand Up @@ -146,7 +149,6 @@ func valiateNetworks(
allErrs := field.ErrorList{}
netNames := map[string]field.Path{}
netCIDR := map[string]field.Path{}

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

Expand All @@ -172,7 +174,6 @@ func valiateNetworks(
}
}
}

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 @@ -180,6 +180,9 @@ spec:
- nexthop
type: object
type: array
serviceNetwork:
description: ServiceNetwork mapping
type: string
subnet:
description: Subnet name
pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$
Expand All @@ -191,6 +194,7 @@ spec:
- address
- dnsDomain
- network
- serviceNetwork
- subnet
type: object
type: array
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 @@ -55,6 +55,9 @@ spec:
...
pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$
type: string
serviceNetwork:
description: Service network mapping
type: string
subnets:
description: Subnets of the network
items:
Expand Down Expand Up @@ -129,6 +132,7 @@ spec:
required:
- dnsDomain
- name
- serviceNetwork
- subnets
type: object
type: array
Expand Down
30 changes: 21 additions & 9 deletions controllers/network/ipset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"context"
"fmt"
"net"
"sort"
"strings"

corev1 "k8s.io/api/core/v1"
k8s_errors "k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -43,6 +45,8 @@ import (
util "github.com/openstack-k8s-operators/lib-common/modules/common/util"
)

const CtlPlaneNetwork = "ctlplane"

// IPSetReconciler reconciles a IPSet object
type IPSetReconciler struct {
client.Client
Expand Down Expand Up @@ -274,6 +278,13 @@ 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 (strings.EqualFold(instance.Status.Reservation[i].ServiceNetwork,
CtlPlaneNetwork) && !strings.EqualFold(instance.Status.Reservation[j].ServiceNetwork,
CtlPlaneNetwork))
})

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 +437,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,
ServiceNetwork: netDef.ServiceNetwork,
}
if ipsetNet.DefaultRoute != nil && *ipsetNet.DefaultRoute && subnetDef.Gateway != nil {
ipsetRes.Gateway = subnetDef.Gateway
Expand Down
14 changes: 14 additions & 0 deletions tests/functional/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,20 @@ func GetNetSpec(name string, subnets ...networkv1.Subnet) networkv1.Network {
return net
}

func GetNetCtlplaneSpec(name string, 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{},
ServiceNetwork: "ctlplane",
}

net.Subnets = append(net.Subnets, subnets...)

return net
}

func GetDefaultNetConfigSpec() map[string]interface{} {
net := GetNetSpec(net1, GetSubnet1(subnet1))
return GetNetConfigSpec(net)
Expand Down
15 changes: 13 additions & 2 deletions tests/functional/ipset_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ var _ = Describe("IPSet controller", func() {
BeforeEach(func() {
netSpecs = []networkv1.Network{}
netSpecs = append(netSpecs, GetNetSpec(net1, GetSubnet1(subnet1)))
netSpecs = append(netSpecs, GetNetSpec(net2, GetSubnet2(subnet1)))
netSpecs = append(netSpecs, GetNetCtlplaneSpec(net2, GetSubnet2(subnet1)))
netSpecs = append(netSpecs, GetNetSpec(net3, GetSubnet3(subnet1)))

ipSetNetworks = []networkv1.IPSetNetwork{}
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 Down

0 comments on commit feac125

Please sign in to comment.