Skip to content

Commit 58cc17c

Browse files
committed
Create provider network based on NAD Config
Configuration is based on the NAD passed in the Octavia.Spec.OctaviaNetworkAttachment string (default 'octavia') JIRA: OSPRH-7553
1 parent 3a1a634 commit 58cc17c

File tree

7 files changed

+137
-29
lines changed

7 files changed

+137
-29
lines changed

api/bases/octavia.openstack.org_octavias.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,11 @@ spec:
892892
- secret
893893
- serviceAccount
894894
type: object
895+
octaviaNetworkAttachment:
896+
default: octavia
897+
description: OctaviaNetworkAttachment is a NetworkAttachment resource
898+
name for the Octavia Management Network
899+
type: string
895900
octaviaWorker:
896901
description: OctaviaHousekeeping - Spec definition for the Octavia
897902
Housekeeping agent for the Octavia deployment
@@ -1197,6 +1202,7 @@ spec:
11971202
- apacheContainerImage
11981203
- databaseInstance
11991204
- octaviaAPI
1205+
- octaviaNetworkAttachment
12001206
- rabbitMqClusterName
12011207
- secret
12021208
type: object

api/v1beta1/octavia_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ type OctaviaSpecBase struct {
192192
// +kubebuilder:validation:Required
193193
// Apache Container Image URL
194194
ApacheContainerImage string `json:"apacheContainerImage"`
195+
196+
// +kubebuilder:validation:Required
197+
// +kubebuilder:default=octavia
198+
// OctaviaNetworkAttachment is a NetworkAttachment resource name for the Octavia Management Network
199+
OctaviaNetworkAttachment string `json:"octaviaNetworkAttachment"`
195200
}
196201

197202
// PasswordSelector to identify the DB and AdminUser password from the Secret

config/crd/bases/octavia.openstack.org_octavias.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,11 @@ spec:
892892
- secret
893893
- serviceAccount
894894
type: object
895+
octaviaNetworkAttachment:
896+
default: octavia
897+
description: OctaviaNetworkAttachment is a NetworkAttachment resource
898+
name for the Octavia Management Network
899+
type: string
895900
octaviaWorker:
896901
description: OctaviaHousekeeping - Spec definition for the Octavia
897902
Housekeeping agent for the Octavia deployment
@@ -1197,6 +1202,7 @@ spec:
11971202
- apacheContainerImage
11981203
- databaseInstance
11991204
- octaviaAPI
1205+
- octaviaNetworkAttachment
12001206
- rabbitMqClusterName
12011207
- secret
12021208
type: object

controllers/octavia_controller.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,13 +642,24 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav
642642
// Amphora reconciliation
643643
// ------------------------------------------------------------------------------------------------------------
644644

645+
nad, err := nad.GetNADWithName(ctx, helper, instance.Spec.OctaviaNetworkAttachment, instance.Namespace)
646+
if err != nil {
647+
return ctrl.Result{}, err
648+
}
649+
650+
networkParameters, err := octavia.GetNetworkParametersFromNAD(nad)
651+
if err != nil {
652+
return ctrl.Result{}, err
653+
}
654+
645655
// Create load balancer management network and get its Id (networkInfo is actually a struct and contains
646656
// multiple details.
647657
networkInfo, err := octavia.EnsureAmphoraManagementNetwork(
648658
ctx,
649659
instance.Namespace,
650660
instance.Spec.TenantName,
651661
&instance.Spec.LbMgmtNetworks,
662+
networkParameters,
652663
&Log,
653664
helper,
654665
)

pkg/octavia/lb_mgmt_network.go

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -291,20 +291,29 @@ func ensureNetworkExt(client *gophercloud.ServiceClient, createOpts networks.Cre
291291
return foundNetwork, nil
292292
}
293293

294-
func ensureProvSubnet(client *gophercloud.ServiceClient, providerNetwork *networks.Network, log *logr.Logger) (
295-
*subnets.Subnet, error) {
296-
gatewayIP := LbProvSubnetGatewayIP
294+
func ensureProvSubnet(
295+
client *gophercloud.ServiceClient,
296+
providerNetwork *networks.Network,
297+
networkParameters *NetworkParameters,
298+
log *logr.Logger,
299+
) (*subnets.Subnet, error) {
300+
var gatewayIP string
301+
if networkParameters.Gateway.IsValid() {
302+
gatewayIP = networkParameters.Gateway.String()
303+
} else {
304+
gatewayIP = ""
305+
}
297306
createOpts := subnets.CreateOpts{
298307
Name: LbProvSubnetName,
299308
Description: LbProvSubnetDescription,
300309
NetworkID: providerNetwork.ID,
301310
TenantID: providerNetwork.TenantID,
302-
CIDR: LbProvSubnetCIDR,
311+
CIDR: networkParameters.CIDR.String(),
303312
IPVersion: gophercloud.IPVersion(4),
304313
AllocationPools: []subnets.AllocationPool{
305314
{
306-
Start: LbProvSubnetAllocationPoolStart,
307-
End: LbProvSubnetAllocationPoolEnd,
315+
Start: networkParameters.AllocationStart.String(),
316+
End: networkParameters.AllocationEnd.String(),
308317
},
309318
},
310319
GatewayIP: &gatewayIP,
@@ -339,6 +348,7 @@ func ensureLbMgmtSubnet(
339348
client *gophercloud.ServiceClient,
340349
networkDetails *octaviav1.OctaviaLbMgmtNetworks,
341350
tenantNetwork *networks.Network,
351+
networkParameters *NetworkParameters,
342352
log *logr.Logger,
343353
) (*subnets.Subnet, error) {
344354
ipVersion := networkDetails.SubnetIPVersion
@@ -381,7 +391,7 @@ func ensureLbMgmtSubnet(
381391
},
382392
HostRoutes: []subnets.HostRoute{
383393
{
384-
DestinationCIDR: LbProvSubnetCIDR,
394+
DestinationCIDR: networkParameters.CIDR.String(),
385395
NextHop: LbMgmtRouterPortIPv4,
386396
},
387397
},
@@ -422,10 +432,10 @@ func ensureLbMgmtNetwork(client *gophercloud.ServiceClient, networkDetails *octa
422432
return mgmtNetwork, nil
423433
}
424434

425-
func externalFixedIPs(subnetID string) []routers.ExternalFixedIP {
435+
func externalFixedIPs(subnetID string, networkParameters *NetworkParameters) []routers.ExternalFixedIP {
426436
ips := []routers.ExternalFixedIP{
427437
{
428-
IPAddress: LbRouterFixedIPAddress,
438+
IPAddress: networkParameters.RouterIPAddress.String(),
429439
SubnetID: subnetID,
430440
},
431441
}
@@ -452,6 +462,7 @@ func compareExternalFixedIPs(a []routers.ExternalFixedIP, b []routers.ExternalFi
452462
func reconcileRouter(client *gophercloud.ServiceClient, router *routers.Router,
453463
gatewayNetwork *networks.Network,
454464
gatewaySubnet *subnets.Subnet,
465+
networkParameters *NetworkParameters,
455466
log *logr.Logger) (*routers.Router, error) {
456467

457468
if !router.AdminStateUp {
@@ -464,7 +475,7 @@ func reconcileRouter(client *gophercloud.ServiceClient, router *routers.Router,
464475
needsUpdate := false
465476
updateInfo := routers.UpdateOpts{}
466477
enableSNAT := false
467-
fixedIPs := externalFixedIPs(gatewaySubnet.ID)
478+
fixedIPs := externalFixedIPs(gatewaySubnet.ID, networkParameters)
468479

469480
//
470481
// TODO(beagles) we don't care about the other fields right now because we
@@ -752,6 +763,7 @@ func EnsureAmphoraManagementNetwork(
752763
ns string,
753764
tenantName string,
754765
netDetails *octaviav1.OctaviaLbMgmtNetworks,
766+
networkParameters *NetworkParameters,
755767
log *logr.Logger,
756768
helper *helper.Helper,
757769
) (NetworkProvisioningSummary, error) {
@@ -772,7 +784,7 @@ func EnsureAmphoraManagementNetwork(
772784
if err != nil {
773785
return NetworkProvisioningSummary{}, err
774786
}
775-
tenantSubnet, err := ensureLbMgmtSubnet(client, netDetails, tenantNetwork, log)
787+
tenantSubnet, err := ensureLbMgmtSubnet(client, netDetails, tenantNetwork, networkParameters, log)
776788
if err != nil {
777789
return NetworkProvisioningSummary{}, err
778790
}
@@ -811,7 +823,7 @@ func EnsureAmphoraManagementNetwork(
811823
return NetworkProvisioningSummary{}, err
812824
}
813825

814-
providerSubnet, err := ensureProvSubnet(client, providerNetwork, log)
826+
providerSubnet, err := ensureProvSubnet(client, providerNetwork, networkParameters, log)
815827
if err != nil {
816828
return NetworkProvisioningSummary{}, err
817829
}
@@ -822,7 +834,7 @@ func EnsureAmphoraManagementNetwork(
822834
}
823835
if router != nil {
824836
log.Info("Router object found, reconciling")
825-
router, err = reconcileRouter(client, router, providerNetwork, providerSubnet, log)
837+
router, err = reconcileRouter(client, router, providerNetwork, providerSubnet, networkParameters, log)
826838
if err != nil {
827839
return NetworkProvisioningSummary{}, err
828840
}
@@ -833,7 +845,7 @@ func EnsureAmphoraManagementNetwork(
833845
gatewayInfo := routers.GatewayInfo{
834846
NetworkID: providerNetwork.ID,
835847
EnableSNAT: &enableSNAT,
836-
ExternalFixedIPs: externalFixedIPs(providerSubnet.ID),
848+
ExternalFixedIPs: externalFixedIPs(providerSubnet.ID, networkParameters),
837849
}
838850
adminStateUp := true
839851
createOpts := routers.CreateOpts{

pkg/octavia/network_consts.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,10 @@ const (
8383
// LbProvSubnetDescription -
8484
LbProvSubnetDescription = "LBaaS Management Provider Subnet"
8585

86-
// IPv4 consts
87-
88-
// LbProvSubnetCIDR -
89-
LbProvSubnetCIDR = "172.23.0.0/24"
90-
91-
// LbProvSubnetAllocationPoolStart -
92-
LbProvSubnetAllocationPoolStart = "172.23.0.100"
86+
// LbProvSubnetPoolSize -
87+
LbProvSubnetPoolSize = 25
9388

94-
// LbProvSubnetAllocationPoolEnd -
95-
LbProvSubnetAllocationPoolEnd = "172.23.0.125"
96-
97-
// LbProvSubnetGatewayIP -
98-
LbProvSubnetGatewayIP = ""
89+
// IPv4 consts
9990

10091
// TODO(beagles): support IPv6 for the provider network.
10192
// LbRouterName -
@@ -104,9 +95,6 @@ const (
10495
// LbProvPhysicalNet -
10596
LbProvPhysicalNet = "octavia"
10697

107-
// LbRouterFixedIPAddress
108-
LbRouterFixedIPAddress = "172.23.0.150"
109-
11098
// LbMgmtRouterPortName
11199
LbMgmtRouterPortName = "lb-mgmt-router-port"
112100

pkg/octavia/network_parameters.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package octavia
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/netip"
7+
8+
networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
9+
)
10+
11+
// NetworkParameters - Parameters for the Octavia networks, based on the config of the NAD
12+
type NetworkParameters struct {
13+
CIDR netip.Prefix
14+
AllocationStart netip.Addr
15+
AllocationEnd netip.Addr
16+
Gateway netip.Addr
17+
RouterIPAddress netip.Addr
18+
}
19+
20+
// NADConfig - IPAM parameters of the NAD
21+
type NADConfig struct {
22+
IPAM NADIpam `json:"ipam"`
23+
}
24+
25+
type NADIpam struct {
26+
CIDR netip.Prefix `json:"range"`
27+
RangeStart netip.Addr `json:"range_start"`
28+
RangeEnd netip.Addr `json:"range_end"`
29+
30+
Routes []NADRoute `json:"routes"`
31+
}
32+
33+
type NADRoute struct {
34+
Gateway netip.Addr `json:"gw"`
35+
}
36+
37+
func getConfigFromNAD(
38+
nad *networkv1.NetworkAttachmentDefinition,
39+
) (*NADConfig, error) {
40+
nadConfig := &NADConfig{}
41+
jsonDoc := []byte(nad.Spec.Config)
42+
err := json.Unmarshal(jsonDoc, nadConfig)
43+
if err != nil {
44+
return nil, err
45+
}
46+
47+
return nadConfig, nil
48+
}
49+
50+
func GetNetworkParametersFromNAD(
51+
nad *networkv1.NetworkAttachmentDefinition,
52+
) (*NetworkParameters, error) {
53+
networkParameters := &NetworkParameters{}
54+
55+
nadConfig, err := getConfigFromNAD(nad)
56+
if err != nil {
57+
return nil, fmt.Errorf("cannot read network parameters: %w", err)
58+
}
59+
60+
networkParameters.CIDR = nadConfig.IPAM.CIDR
61+
62+
networkParameters.AllocationStart = nadConfig.IPAM.RangeEnd.Next()
63+
end := networkParameters.AllocationStart
64+
for i := 0; i < LbProvSubnetPoolSize; i++ {
65+
if !networkParameters.CIDR.Contains(end) {
66+
return nil, fmt.Errorf("cannot allocate %d IP addresses in %s", LbProvSubnetPoolSize, networkParameters.CIDR)
67+
}
68+
end = end.Next()
69+
}
70+
networkParameters.AllocationEnd = end
71+
// TODO(gthiemonge) Remove routes from NAD, manage them in the operator
72+
if len(nadConfig.IPAM.Routes) > 0 {
73+
networkParameters.RouterIPAddress = nadConfig.IPAM.Routes[0].Gateway
74+
} else {
75+
return nil, fmt.Errorf("cannot find gateway information in network attachment")
76+
}
77+
// Gateway is currently unset
78+
79+
return networkParameters, err
80+
}

0 commit comments

Comments
 (0)