Skip to content

Commit

Permalink
libovsdb: cleanup ModelClient usage for routers & ports
Browse files Browse the repository at this point in the history
Signed-off-by: Jaime Caamaño Ruiz <jcaamano@redhat.com>
  • Loading branch information
jcaamano committed Apr 19, 2022
1 parent 4e3c26a commit 8b14898
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 365 deletions.
149 changes: 147 additions & 2 deletions go-controller/pkg/libovsdbops/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

type logicalRouterPredicate func(*nbdb.LogicalRouter) bool

// GetLogicalRouter looks up a logical router from the cache
func GetLogicalRouter(nbClient libovsdbclient.Client, router *nbdb.LogicalRouter) (*nbdb.LogicalRouter, error) {
found := []*nbdb.LogicalRouter{}
opModel := OperationModel{
Expand All @@ -36,6 +37,8 @@ func GetLogicalRouter(nbClient libovsdbclient.Client, router *nbdb.LogicalRouter
return found[0], nil
}

// FindLogicalRoutersWithPredicate looks up logical routers from the cache based on a
// given predicate
func FindLogicalRoutersWithPredicate(nbClient libovsdbclient.Client, p logicalRouterPredicate) ([]*nbdb.LogicalRouter, error) {
ctx, cancel := context.WithTimeout(context.Background(), types.OVSDBTimeout)
defer cancel()
Expand All @@ -44,6 +47,150 @@ func FindLogicalRoutersWithPredicate(nbClient libovsdbclient.Client, p logicalRo
return found, err
}

// CreateOrUpdateLogicalRouter creates or updates the provided logical router
func CreateOrUpdateLogicalRouter(nbClient libovsdbclient.Client, router *nbdb.LogicalRouter) error {
opModel := OperationModel{
Name: &router.Name,
Model: router,
ModelPredicate: func(item *nbdb.LogicalRouter) bool { return item.Name == router.Name },
OnModelUpdates: onModelUpdatesAll(),
ErrNotFound: false,
BulkOp: false,
}

m := NewModelClient(nbClient)
_, err := m.CreateOrUpdate(opModel)
return err
}

// UpdateLogicalRouterSetExternalIDs sets external IDs on the provided logical
// router adding any missing, removing the ones set to an empty value and
// updating existing
func UpdateLogicalRouterSetExternalIDs(nbClient libovsdbclient.Client, router *nbdb.LogicalRouter) error {
externalIds := router.ExternalIDs
router, err := GetLogicalRouter(nbClient, router)
if err != nil {
return err
}

if router.ExternalIDs == nil {
router.ExternalIDs = map[string]string{}
}

for k, v := range externalIds {
if v == "" {
delete(router.ExternalIDs, k)
} else {
router.ExternalIDs[k] = v
}
}

opModel := OperationModel{
Model: router,
OnModelUpdates: []interface{}{&router.ExternalIDs},
ErrNotFound: true,
BulkOp: false,
}

m := NewModelClient(nbClient)
_, err = m.CreateOrUpdate(opModel)
return err
}

// DeleteLogicalRouter deletes the provided logical router
func DeleteLogicalRouter(nbClient libovsdbclient.Client, router *nbdb.LogicalRouter) error {
opModel := OperationModel{
Model: router,
ModelPredicate: func(item *nbdb.LogicalRouter) bool { return item.Name == router.Name },
ErrNotFound: false,
BulkOp: false,
}

m := NewModelClient(nbClient)
return m.Delete(opModel)
}

// LOGICAL ROUTER PORT OPs

// GetLogicalRouterPort looks up a logical router port from the cache
func GetLogicalRouterPort(nbClient libovsdbclient.Client, lrp *nbdb.LogicalRouterPort) (*nbdb.LogicalRouterPort, error) {
found := &nbdb.LogicalRouterPort{
UUID: lrp.UUID,
Name: lrp.Name,
}
ctx, cancel := context.WithTimeout(context.Background(), types.OVSDBTimeout)
defer cancel()
err := nbClient.Get(ctx, found)
return found, err
}

// CreateOrUpdateLogicalRouterPorts creates or updates the provided logical
// router ports and adds them to the provided logical router
func CreateOrUpdateLogicalRouterPorts(nbClient libovsdbclient.Client, router *nbdb.LogicalRouter, lrps ...*nbdb.LogicalRouterPort) error {
originalPorts := router.Ports
router.Ports = make([]string, 0, len(lrps))
opModels := make([]OperationModel, 0, len(lrps)+1)
for i := range lrps {
lrp := lrps[i]
opModel := OperationModel{
Model: lrp,
OnModelUpdates: onModelUpdatesAll(),
DoAfter: func() { router.Ports = append(router.Ports, lrp.UUID) },
ErrNotFound: false,
BulkOp: false,
}
opModels = append(opModels, opModel)
}
opModel := OperationModel{
Model: router,
ModelPredicate: func(item *nbdb.LogicalRouter) bool { return item.Name == router.Name },
OnModelMutations: []interface{}{&router.Ports},
ErrNotFound: true,
BulkOp: false,
}
opModels = append(opModels, opModel)

m := NewModelClient(nbClient)
_, err := m.CreateOrUpdate(opModels...)
router.Ports = originalPorts
return err
}

// DeleteLogicalRouterPorts deletes the provided logical router ports and
// removes them from the provided logical router
func DeleteLogicalRouterPorts(nbClient libovsdbclient.Client, router *nbdb.LogicalRouter, lrps ...*nbdb.LogicalRouterPort) error {
originalPorts := router.Ports
router.Ports = make([]string, 0, len(lrps))
opModels := make([]OperationModel, 0, len(lrps)+1)
for i := range lrps {
lrp := lrps[i]
opModel := OperationModel{
Model: lrp,
DoAfter: func() {
if lrp.UUID != "" {
router.Ports = append(router.Ports, lrp.UUID)
}
},
ErrNotFound: false,
BulkOp: false,
}
opModels = append(opModels, opModel)
}
opModel := OperationModel{
Model: router,
ModelPredicate: func(item *nbdb.LogicalRouter) bool { return item.Name == router.Name },
OnModelMutations: []interface{}{&router.Ports},
ErrNotFound: true,
BulkOp: false,
}
opModels = append(opModels, opModel)

m := NewModelClient(nbClient)
err := m.Delete(opModels...)
router.Ports = originalPorts
return err
}

// LOGICAL ROUTER POLICY OPs

type logicalRouterPolicyPredicate func(*nbdb.LogicalRouterPolicy) bool
Expand Down Expand Up @@ -477,7 +624,6 @@ func AddLoadBalancersToLogicalRouterOps(nbClient libovsdbclient.Client, ops []li
router.LoadBalancer = append(router.LoadBalancer, lb.UUID)
}
opModel := OperationModel{
Name: router.Name,
Model: router,
ModelPredicate: func(item *nbdb.LogicalRouter) bool { return item.Name == router.Name },
OnModelMutations: []interface{}{&router.LoadBalancer},
Expand All @@ -500,7 +646,6 @@ func RemoveLoadBalancersFromLogicalRouterOps(nbClient libovsdbclient.Client, ops
router.LoadBalancer = append(router.LoadBalancer, lb.UUID)
}
opModel := OperationModel{
Name: router.Name,
Model: router,
ModelPredicate: func(item *nbdb.LogicalRouter) bool { return item.Name == router.Name },
OnModelMutations: []interface{}{&router.LoadBalancer},
Expand Down
15 changes: 7 additions & 8 deletions go-controller/pkg/ovn/egressgw.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ovn

import (
"context"
"encoding/json"
"fmt"
"net"
Expand Down Expand Up @@ -1096,21 +1095,21 @@ func (oc *Controller) buildOVNECMPCache() map[string][]*ovnRoute {
return nil
}

ctx, cancel := context.WithTimeout(context.Background(), types.OVSDBTimeout)
defer cancel()
ovnRouteCache := make(map[string][]*ovnRoute)
for _, logicalRouterStaticRoute := range logicalRouterStaticRoutes {
logicalRouterRes := []nbdb.LogicalRouter{}
if err := oc.nbClient.WhereCache(func(lr *nbdb.LogicalRouter) bool {
return util.SliceHasStringItem(lr.StaticRoutes, logicalRouterStaticRoute.UUID)
}).List(ctx, &logicalRouterRes); err != nil {
p := func(item *nbdb.LogicalRouter) bool {
return util.SliceHasStringItem(item.StaticRoutes, logicalRouterStaticRoute.UUID)
}
logicalRouters, err := libovsdbops.FindLogicalRoutersWithPredicate(oc.nbClient, p)
if err != nil {
klog.Errorf("CleanECMPRoutes: failed to find logical router for %s, err: %v", logicalRouterStaticRoute.UUID, err)
continue
}

route := &ovnRoute{
nextHop: logicalRouterStaticRoute.Nexthop,
uuid: logicalRouterStaticRoute.UUID,
router: logicalRouterRes[0].Name,
router: logicalRouters[0].Name,
outport: *logicalRouterStaticRoute.OutputPort,
}
podIP, _, _ := net.ParseCIDR(logicalRouterStaticRoute.IPPrefix)
Expand Down
61 changes: 21 additions & 40 deletions go-controller/pkg/ovn/gateway/gateway.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package gateway

import (
"context"
"fmt"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types"
"strings"

"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/libovsdbops"

"github.com/ovn-org/libovsdb/client"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/nbdb"
"github.com/pkg/errors"
Expand All @@ -24,55 +24,36 @@ var (

// GetOvnGateways return all created gateways.
func GetOvnGateways(nbClient client.Client) ([]string, error) {
logicalRouterRes := []nbdb.LogicalRouter{}
ctx, cancel := context.WithTimeout(context.Background(), types.OVSDBTimeout)
defer cancel()
if err := nbClient.WhereCache(func(lr *nbdb.LogicalRouter) bool {
return lr.Options["chassis"] != "null"
}).List(ctx, &logicalRouterRes); err != nil {
p := func(item *nbdb.LogicalRouter) bool {
return item.Options["chassis"] != "null"
}
logicalRouters, err := libovsdbops.FindLogicalRoutersWithPredicate(nbClient, p)
if err != nil {
return nil, err
}

result := []string{}
for _, logicalRouter := range logicalRouterRes {
for _, logicalRouter := range logicalRouters {
result = append(result, logicalRouter.Name)
}
return result, nil
}

// GetGatewayPhysicalIP return gateway physical IP
func GetGatewayPhysicalIP(nbClient client.Client, gatewayRouter string) (string, error) {
logicalRouterRes := []nbdb.LogicalRouter{}
ctx, cancel := context.WithTimeout(context.Background(), types.OVSDBTimeout)
defer cancel()
if err := nbClient.WhereCache(func(lr *nbdb.LogicalRouter) bool {
physicalIP, exists := lr.ExternalIDs["physical_ip"]
return lr.Name == gatewayRouter && exists && physicalIP != ""
}).List(ctx, &logicalRouterRes); err != nil {
return "", errors.Wrapf(err, "error to obtain physical IP on router %s, err: %v", gatewayRouter, err)
}
if len(logicalRouterRes) == 0 {
return "", fmt.Errorf("no physical IP found for gateway %s", gatewayRouter)
}
return logicalRouterRes[0].ExternalIDs["physical_ip"], nil
}

// GetGatewayPhysicalIPs return gateway physical IPs
func GetGatewayPhysicalIPs(nbClient client.Client, gatewayRouter string) ([]string, error) {
logicalRouterRes := []nbdb.LogicalRouter{}
ctx, cancel := context.WithTimeout(context.Background(), types.OVSDBTimeout)
defer cancel()
if err := nbClient.WhereCache(func(lr *nbdb.LogicalRouter) bool {
physicalIPs, exists := lr.ExternalIDs["physical_ips"]
return lr.Name == gatewayRouter && exists && physicalIPs != ""
}).List(ctx, &logicalRouterRes); err != nil {
return nil, errors.Wrapf(err, "error to obtain physical IP on router %s, err: %v", gatewayRouter, err)
logicalRouter := &nbdb.LogicalRouter{Name: gatewayRouter}
logicalRouter, err := libovsdbops.GetLogicalRouter(nbClient, logicalRouter)
if err != nil {
return nil, fmt.Errorf("error getting router %s: %v", gatewayRouter, err)
}
if len(logicalRouterRes) == 1 {
return strings.Split(logicalRouterRes[0].ExternalIDs["physical_ips"], ","), nil

if ips := logicalRouter.ExternalIDs["physical_ips"]; ips != "" {
return strings.Split(ips, ","), nil
}
physicalIP, err := GetGatewayPhysicalIP(nbClient, gatewayRouter)
if err != nil {
return nil, err

if ip := logicalRouter.ExternalIDs["physical_ip"]; ip != "" {
return []string{ip}, nil
}
return []string{physicalIP}, nil

return nil, fmt.Errorf("no physical IPs found for gateway %s", gatewayRouter)
}

0 comments on commit 8b14898

Please sign in to comment.