Skip to content

Commit

Permalink
fix: Do not Recreate Logical_Router_Port when Vpc recreated (#1570)
Browse files Browse the repository at this point in the history
* fix issue 1569

* rename some local variable
  • Loading branch information
lrh3321 committed Jun 1, 2022
1 parent c651a2f commit ea2686b
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 0 deletions.
42 changes: 42 additions & 0 deletions pkg/controller/vpc.go
Expand Up @@ -162,6 +162,43 @@ func (c *Controller) handleUpdateVpcStatus(key string) error {
return nil
}

func (c *Controller) reconcileRouterPorts(vpc *kubeovnv1.Vpc) error {
subnets, _, err := c.getVpcSubnets(vpc)
if err != nil {
klog.ErrorS(err, "unable to get related subnets", "vpc", vpc.Name)
return err
}

router := vpc.Name
for _, subnetName := range subnets {
routerPortName := ovs.LogicalRouterPortName(router, subnetName)
exists, err := c.ovnClient.LogicalRouterPortExists(routerPortName)
if err != nil {
return err
}

if !exists {
subnet, err := c.subnetsLister.Get(subnetName)
if err != nil {
if k8serrors.IsNotFound(err) {
continue
}
klog.ErrorS(err, "unable to get subnet", "subnet", subnetName)
return err
}

klog.V(1).InfoS("router port not exists, trying to create", "vpc", vpc.Name, "subnet", subnetName)

networks := util.GetIpAddrWithMask(subnet.Spec.Gateway, subnet.Spec.CIDRBlock)
if err := c.ovnClient.AddLogicalRouterPort(router, routerPortName, "", networks); err != nil {
klog.ErrorS(err, "unable to create router port", "vpc", vpc.Name, "subnet", subnetName)
return err
}
}
}
return nil
}

type VpcLoadBalancer struct {
TcpLoadBalancer string
TcpSessLoadBalancer string
Expand Down Expand Up @@ -271,6 +308,11 @@ func (c *Controller) handleAddOrUpdateVpc(key string) error {
return err
}

if err := c.reconcileRouterPorts(vpc); err != nil {
klog.ErrorS(err, "unable to reconcileRouterPorts")
return err
}

var newPeers []string
for _, peering := range vpc.Spec.VpcPeerings {
if err = util.CheckCidrs(peering.LocalConnectIP); err != nil {
Expand Down
31 changes: 31 additions & 0 deletions pkg/ovs/ovn-nb-logical_router.go
@@ -0,0 +1,31 @@
package ovs

import (
"context"
"fmt"

"github.com/ovn-org/libovsdb/client"

"github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb"
)

func (c OvnClient) GetLogicalRouter(name string, ignoreNotFound bool) (*ovnnb.LogicalRouter, error) {
predicate := func(model *ovnnb.LogicalRouter) bool {
return model.Name == name
}
// Logical_Router has no indexes defined in the schema
var result []*ovnnb.LogicalRouter
if err := c.ovnNbClient.WhereCache(predicate).List(context.TODO(), &result); err != nil || len(result) == 0 {
if ignoreNotFound && (err == client.ErrNotFound || len(result) == 0) {
return nil, nil
}
return nil, fmt.Errorf("failed to get logical router %s: %v", name, err)
}

return result[0], nil
}

func (c OvnClient) LogicalRouterExists(name string) (bool, error) {
lr, err := c.GetLogicalRouter(name, true)
return lr != nil, err
}
82 changes: 82 additions & 0 deletions pkg/ovs/ovn-nb-logical_router_port.go
@@ -0,0 +1,82 @@
package ovs

import (
"context"
"fmt"
"strings"

"github.com/ovn-org/libovsdb/client"
"github.com/ovn-org/libovsdb/model"
"github.com/ovn-org/libovsdb/ovsdb"

ovsclient "github.com/kubeovn/kube-ovn/pkg/ovsdb/client"
"github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb"
"github.com/kubeovn/kube-ovn/pkg/util"
)

func (c OvnClient) GetLogicalRouterPort(name string, ignoreNotFound bool) (*ovnnb.LogicalRouterPort, error) {
lrp := &ovnnb.LogicalRouterPort{Name: name}
if err := c.ovnNbClient.Get(context.TODO(), lrp); err != nil {
if ignoreNotFound && err == client.ErrNotFound {
return nil, nil
}
return nil, fmt.Errorf("failed to get logical router port %s: %v", name, err)
}

return lrp, nil
}

func (c OvnClient) AddLogicalRouterPort(lr, name, mac, networks string) error {
router, err := c.GetLogicalRouter(lr, false)
if err != nil {
return err
}

if mac == "" {
mac = util.GenerateMac()
}

var ops []ovsdb.Operation

lrp := &ovnnb.LogicalRouterPort{
UUID: ovsclient.NamedUUID(),
Name: name,
MAC: mac,
Networks: strings.Split(networks, ","),
ExternalIDs: map[string]string{"vendor": util.CniTypeName},
}

// ensure there is no port in the same name, before we create it in the transaction
waitOp := ConstructWaitForNameNotExistsOperation(name, "Logical_Router_Port")
ops = append(ops, waitOp)

createOps, err := c.ovnNbClient.Create(lrp)
if err != nil {
return err
}
ops = append(ops, createOps...)

mutationOps, err := c.ovnNbClient.
Where(router).
Mutate(router,
model.Mutation{
Field: &router.Ports,
Mutator: ovsdb.MutateOperationInsert,
Value: []string{lrp.UUID},
},
)
if err != nil {
return err
}
ops = append(ops, mutationOps...)

if err := Transact(c.ovnNbClient, "lrp-add", ops, c.ovnNbClient.Timeout); err != nil {
return fmt.Errorf("failed to create logical router port %s: %v", name, err)
}
return nil
}

func (c OvnClient) LogicalRouterPortExists(name string) (bool, error) {
lrp, err := c.GetLogicalRouterPort(name, true)
return lrp != nil, err
}
19 changes: 19 additions & 0 deletions pkg/ovs/ovn.go
Expand Up @@ -53,6 +53,8 @@ const (
Policy = "--policy"
PolicyDstIP = "dst-ip"
PolicySrcIP = "src-ip"

OVSDBWaitTimeout = 0
)

// NewLegacyClient init a legacy ovn client
Expand Down Expand Up @@ -119,3 +121,20 @@ func Transact(c client.Client, method string, operations []ovsdb.Operation, time

return nil
}

func ConstructWaitForNameNotExistsOperation(name string, table string) ovsdb.Operation {
return ConstructWaitForUniqueOperation(table, "name", name)
}

func ConstructWaitForUniqueOperation(table string, column string, value interface{}) ovsdb.Operation {
timeout := OVSDBWaitTimeout
return ovsdb.Operation{
Op: ovsdb.OperationWait,
Table: table,
Timeout: &timeout,
Where: []ovsdb.Condition{{Column: column, Function: ovsdb.ConditionEqual, Value: value}},
Columns: []string{column},
Until: "!=",
Rows: []ovsdb.Row{{column: value}},
}
}
8 changes: 8 additions & 0 deletions pkg/ovs/util.go
Expand Up @@ -23,3 +23,11 @@ func trimCommandOutput(raw []byte) string {
output := strings.TrimSpace(string(raw))
return strings.Trim(output, "\"")
}

func LogicalRouterPortName(lr, ls string) string {
return fmt.Sprintf("%s-%s", lr, ls)
}

func LogicalSwitchPortName(lr, ls string) string {
return fmt.Sprintf("%s-%s", ls, lr)
}
1 change: 1 addition & 0 deletions pkg/ovsdb/client/client.go
Expand Up @@ -84,6 +84,7 @@ func NewNbClient(addr string, timeout int) (client.Client, error) {

monitorOpts := []client.MonitorOption{
client.WithTable(&ovnnb.LogicalRouter{}),
client.WithTable(&ovnnb.LogicalRouterPort{}),
client.WithTable(&ovnnb.LogicalRouterPolicy{}),
client.WithTable(&ovnnb.LogicalSwitchPort{}),
client.WithTable(&ovnnb.PortGroup{}),
Expand Down

0 comments on commit ea2686b

Please sign in to comment.