aboutsummaryrefslogtreecommitdiffstats
path: root/internal/pkg/ovn
diff options
context:
space:
mode:
authorRitu Sood <ritu.sood@intel.com>2019-08-06 19:35:42 -0700
committerRitu Sood <ritu.sood@intel.com>2019-08-15 10:03:47 -0700
commit8295a28f6d6e14f5adb62138271de393015061e9 (patch)
treed11b1e799de55e89d08bc810180d99ce65e6f21e /internal/pkg/ovn
parentaa41b49246d84b605a76d169f0c861ba0691a4fb (diff)
Use controller runtime and operator sdk
Changing the framework to use controller runtime and operator sdk. This allows to add CRD controllers for Network, Provider Network etc in the same operator. Binary renamed to nfn-operator (Network funtion networking). Change-Id: Ic25a3c3f5f1418fc0614f3aede48b41d9c1156cd Signed-off-by: Ritu Sood <ritu.sood@intel.com>
Diffstat (limited to 'internal/pkg/ovn')
-rw-r--r--internal/pkg/ovn/common.go65
-rw-r--r--internal/pkg/ovn/ovn.go368
-rw-r--r--internal/pkg/ovn/ovn_test.go44
-rw-r--r--internal/pkg/ovn/utils.go78
4 files changed, 246 insertions, 309 deletions
diff --git a/internal/pkg/ovn/common.go b/internal/pkg/ovn/common.go
index b504440..60cd202 100644
--- a/internal/pkg/ovn/common.go
+++ b/internal/pkg/ovn/common.go
@@ -3,69 +3,82 @@ package ovn
import (
"encoding/json"
"fmt"
- "github.com/sirupsen/logrus"
"math/big"
"math/rand"
"net"
+ logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
+ "strings"
"time"
)
-func SetupDistributedRouter(name string) error {
+var log = logf.Log.WithName("ovn")
- // Make sure br-int is created.
- stdout, stderr, err := RunOVSVsctlUnix("--", "--may-exist", "add-br", "br-int")
- if err != nil {
- logrus.Errorf("Failed to create br-int, stdout: %q, stderr: %q, error: %v", stdout, stderr, err)
- return err
+func parseOvnNetworkObject(ovnnetwork string) ([]map[string]interface{}, error) {
+ var ovnNet []map[string]interface{}
+
+ if ovnnetwork == "" {
+ return nil, fmt.Errorf("parseOvnNetworkObject:error")
}
+
+ if err := json.Unmarshal([]byte(ovnnetwork), &ovnNet); err != nil {
+ return nil, fmt.Errorf("parseOvnNetworkObject: failed to load ovn network err: %v | ovn network: %v", err, ovnnetwork)
+ }
+
+ return ovnNet, nil
+}
+
+func setupDistributedRouter(name string) error {
+
// Create a single common distributed router for the cluster.
- stdout, stderr, err = RunOVNNbctlUnix("--", "--may-exist", "lr-add", name, "--", "set", "logical_router", name, "external_ids:ovn4nfv-cluster-router=yes")
+ stdout, stderr, err := RunOVNNbctl("--", "--may-exist", "lr-add", name, "--", "set", "logical_router", name, "external_ids:ovn4nfv-cluster-router=yes")
if err != nil {
- logrus.Errorf("Failed to create a single common distributed router for the cluster, stdout: %q, stderr: %q, error: %v", stdout, stderr, err)
+ log.Error(err, "Failed to create a single common distributed router for the cluster", "stdout", stdout, "stderr", stderr)
return err
}
// Create a logical switch called "ovn4nfv-join" that will be used to connect gateway routers to the distributed router.
// The "ovn4nfv-join" will be allocated IP addresses in the range 100.64.1.0/24.
- stdout, stderr, err = RunOVNNbctlUnix("--may-exist", "ls-add", "ovn4nfv-join")
+ stdout, stderr, err = RunOVNNbctl("--may-exist", "ls-add", "ovn4nfv-join")
if err != nil {
- logrus.Errorf("Failed to create logical switch called \"ovn4nfv-join\", stdout: %q, stderr: %q, error: %v", stdout, stderr, err)
+ log.Error(err, "Failed to create logical switch called \"ovn4nfv-join\"", "stdout", stdout, "stderr", stderr)
return err
}
// Connect the distributed router to "ovn4nfv-join".
- routerMac, stderr, err := RunOVNNbctlUnix("--if-exist", "get", "logical_router_port", "rtoj-"+name, "mac")
+ routerMac, stderr, err := RunOVNNbctl("--if-exist", "get", "logical_router_port", "rtoj-"+name, "mac")
if err != nil {
- logrus.Errorf("Failed to get logical router port rtoj-%v, stderr: %q, error: %v", name, stderr, err)
+ log.Error(err, "Failed to get logical router port rtoj-", "name", name, "stdout", stdout, "stderr", stderr)
return err
}
if routerMac == "" {
routerMac = generateMac()
- stdout, stderr, err = RunOVNNbctlUnix("--", "--may-exist", "lrp-add", name, "rtoj-"+name, routerMac, "100.64.1.1/24", "--", "set", "logical_router_port", "rtoj-"+name, "external_ids:connect_to_ovn4nfvjoin=yes")
+ stdout, stderr, err = RunOVNNbctl("--", "--may-exist", "lrp-add", name, "rtoj-"+name, routerMac, "100.64.1.1/24", "--", "set", "logical_router_port", "rtoj-"+name, "external_ids:connect_to_ovn4nfvjoin=yes")
if err != nil {
- logrus.Errorf("Failed to add logical router port rtoj-%v, stdout: %q, stderr: %q, error: %v", name, stdout, stderr, err)
+ log.Error(err, "Failed to add logical router port rtoj", "name", name, "stdout", stdout, "stderr", stderr)
return err
}
}
// Connect the switch "ovn4nfv-join" to the router.
- stdout, stderr, err = RunOVNNbctlUnix("--", "--may-exist", "lsp-add", "ovn4nfv-join", "jtor-"+name, "--", "set", "logical_switch_port", "jtor-"+name, "type=router", "options:router-port=rtoj-"+name, "addresses="+"\""+routerMac+"\"")
+ stdout, stderr, err = RunOVNNbctl("--", "--may-exist", "lsp-add", "ovn4nfv-join", "jtor-"+name, "--", "set", "logical_switch_port", "jtor-"+name, "type=router", "options:router-port=rtoj-"+name, "addresses="+"\""+routerMac+"\"")
if err != nil {
- logrus.Errorf("Failed to add logical switch port to logical router, stdout: %q, stderr: %q, error: %v", stdout, stderr, err)
+ log.Error(err, "Failed to add logical switch port to logical router", "stdout", stdout, "stderr", stderr)
return err
}
return nil
}
-func parseOvnNetworkObject(ovnnetwork string) ([]map[string]interface{}, error) {
- var ovnNet []map[string]interface{}
-
- if ovnnetwork == "" {
- return nil, fmt.Errorf("parseOvnNetworkObject:error")
+// Find if switch exists
+func findLogicalSwitch(name string) bool {
+ // get logical switch from OVN
+ output, stderr, err := RunOVNNbctl("--data=bare", "--no-heading",
+ "--columns=name", "find", "logical_switch", "name="+name)
+ if err != nil {
+ log.Error(err, "Error in obtaining list of logical switch", "stderr", stderr)
+ return false
}
- if err := json.Unmarshal([]byte(ovnnetwork), &ovnNet); err != nil {
- return nil, fmt.Errorf("parseOvnNetworkObject: failed to load ovn network err: %v | ovn network: %v", err, ovnnetwork)
+ if strings.Compare(name, output) == 0 {
+ return true
}
-
- return ovnNet, nil
+ return false
}
// generateMac generates mac address.
diff --git a/internal/pkg/ovn/ovn.go b/internal/pkg/ovn/ovn.go
index 470416b..dad4641 100644
--- a/internal/pkg/ovn/ovn.go
+++ b/internal/pkg/ovn/ovn.go
@@ -2,93 +2,174 @@ package ovn
import (
"fmt"
+ "github.com/mitchellh/mapstructure"
+ kapi "k8s.io/api/core/v1"
+ kexec "k8s.io/utils/exec"
"strings"
"time"
-
- "github.com/sirupsen/logrus"
- kapi "k8s.io/api/core/v1"
- "k8s.io/client-go/kubernetes"
- "k8s.io/client-go/tools/cache"
- "ovn4nfv-k8s-plugin/internal/pkg/factory"
- "ovn4nfv-k8s-plugin/internal/pkg/kube"
)
-// Controller structure is the object which holds the controls for starting
-// and reacting upon the watched resources (e.g. pods, endpoints)
type Controller struct {
- kube kube.Interface
- watchFactory *factory.WatchFactory
-
gatewayCache map[string]string
- // A cache of all logical switches seen by the watcher
- logicalSwitchCache map[string]bool
- // A cache of all logical ports seen by the watcher and
- // its corresponding logical switch
- logicalPortCache map[string]string
}
-// NewOvnController creates a new OVN controller for creating logical network
-// infrastructure and policy
-func NewOvnController(kubeClient kubernetes.Interface, wf *factory.WatchFactory) *Controller {
- return &Controller{
- kube: &kube.Kube{KClient: kubeClient},
- watchFactory: wf,
- logicalSwitchCache: make(map[string]bool),
- logicalPortCache: make(map[string]string),
- gatewayCache: make(map[string]string),
+const (
+ ovn4nfvRouterName = "ovn4nfv-master"
+ Ovn4nfvAnnotationTag = "k8s.plugin.opnfv.org/ovnInterfaces"
+)
+
+type netInterface struct {
+ Name string
+ Interface string
+ NetType string
+ DefaultGateway string
+ IPAddress string
+ MacAddress string
+}
+
+var ovnCtl *Controller
+
+// NewOvnController creates a new OVN controller for creating logical networks
+func NewOvnController(exec kexec.Interface) (*Controller, error) {
+
+ if exec == nil {
+ exec = kexec.New()
+ }
+
+ if err := SetExec(exec); err != nil {
+ log.Error(err, "Failed to initialize exec helper")
+ return nil, err
+ }
+
+ if err := SetupOvnUtils(); err != nil {
+ log.Error(err, "Failed to initialize OVN State")
+ return nil, err
+ }
+ ovnCtl = &Controller{
+ gatewayCache: make(map[string]string),
}
+ return ovnCtl, nil
}
-// Run starts the actual watching. Also initializes any local structures needed.
-func (oc *Controller) Run() error {
- fmt.Println("ovn4nfvk8s watching Pods")
- for _, f := range []func() error{oc.WatchPods} {
- if err := f(); err != nil {
- return err
- }
+// GetOvnController returns OVN controller for creating logical networks
+func GetOvnController() (*Controller, error) {
+ if ovnCtl != nil {
+ return ovnCtl, nil
}
- return nil
+ return nil, fmt.Errorf("OVN Controller not initialized")
}
-// WatchPods starts the watching of Pod resource and calls back the appropriate handler logic
-func (oc *Controller) WatchPods() error {
- _, err := oc.watchFactory.AddPodHandler(cache.ResourceEventHandlerFuncs{
- AddFunc: func(obj interface{}) {
- pod := obj.(*kapi.Pod)
- if pod.Spec.NodeName != "" {
- oc.addLogicalPort(pod)
+// AddLogicalPorts adds ports to the Pod
+func (oc *Controller) AddLogicalPorts(pod *kapi.Pod, ovnNetObjs []map[string]interface{}) (key, value string) {
+
+ if ovnNetObjs == nil {
+ return
+ }
+
+ if pod.Spec.HostNetwork {
+ return
+ }
+
+ if _, ok := pod.Annotations[Ovn4nfvAnnotationTag]; ok {
+ log.Info("AddLogicalPorts : Pod annotation found")
+ return
+ }
+
+ var ovnString, outStr string
+ ovnString = "["
+ var ns netInterface
+ for _, net := range ovnNetObjs {
+
+ err := mapstructure.Decode(net, &ns)
+ if err != nil {
+ log.Error(err, "mapstruct error", "network", net)
+ return
+ }
+
+ if !findLogicalSwitch(ns.Name) {
+ log.Info("Logical Switch not found")
+ return
+ }
+ if ns.Interface == "" {
+ log.Info("Interface name must be provided")
+ return
+ }
+ if ns.DefaultGateway == "" {
+ ns.DefaultGateway = "false"
+ }
+ if ns.NetType == "" || ns.NetType != "provider" {
+ ns.NetType = "virtual"
+ }
+ if ns.NetType == "provider" {
+ if ns.IPAddress == "" {
+ log.Info("ipAddress must be provided for netType Provider")
+ return
}
- },
- UpdateFunc: func(old, newer interface{}) {
- podNew := newer.(*kapi.Pod)
- podOld := old.(*kapi.Pod)
- if podOld.Spec.NodeName == "" && podNew.Spec.NodeName != "" {
- oc.addLogicalPort(podNew)
+ if ns.DefaultGateway == "true" {
+ log.Info("defaultGateway not supported for provider network - Use ovnNetworkRoutes to add routes")
+ return
}
- },
- DeleteFunc: func(obj interface{}) {
- pod := obj.(*kapi.Pod)
- oc.deleteLogicalPort(pod)
- },
- }, oc.syncPods)
- return err
+
+ }
+
+ outStr = oc.addLogicalPortWithSwitch(pod, ns.Name, ns.IPAddress, ns.MacAddress, ns.Interface, ns.NetType)
+ if outStr == "" {
+ return
+ }
+ last := len(outStr) - 1
+ tmpString := outStr[:last]
+ tmpString += "," + "\\\"defaultGateway\\\":" + "\\\"" + ns.DefaultGateway + "\\\""
+ tmpString += "," + "\\\"interface\\\":" + "\\\"" + ns.Interface + "\\\"}"
+ ovnString += tmpString
+ ovnString += ","
+ }
+ last := len(ovnString) - 1
+ ovnString = ovnString[:last]
+ ovnString += "]"
+ key = Ovn4nfvAnnotationTag
+ value = ovnString
+ return key, value
}
-func (oc *Controller) syncPods(pods []interface{}) {
+func (oc *Controller) DeleteLogicalPorts(name, namespace string) {
+
+ log.Info("Deleting pod", "name", name)
+ logicalPort := fmt.Sprintf("%s_%s", namespace, name)
+
+ // get the list of logical ports from OVN
+ stdout, stderr, err := RunOVNNbctl("--data=bare", "--no-heading",
+ "--columns=name", "find", "logical_switch_port", "external_ids:pod=true")
+ if err != nil {
+ log.Error(err, "Error in obtaining list of logical ports ", "stdout", stdout, "stderr", stderr)
+ return
+ }
+ log.Info("Deleting", "Existing Ports", stdout)
+ existingLogicalPorts := strings.Fields(stdout)
+ for _, existingPort := range existingLogicalPorts {
+ if strings.Contains(existingPort, logicalPort) {
+ // found, delete this logical port
+ log.Info("Deleting", "existingPort", existingPort)
+ stdout, stderr, err := RunOVNNbctl("--if-exists", "lsp-del",
+ existingPort)
+ if err != nil {
+ log.Error(err, "Error in deleting pod's logical port ", "stdout", stdout, "stderr", stderr)
+ }
+ }
+ }
+ return
}
func (oc *Controller) getGatewayFromSwitch(logicalSwitch string) (string, string, error) {
var gatewayIPMaskStr, stderr string
var ok bool
var err error
- logrus.Infof("getGatewayFromSwitch: %s", logicalSwitch)
+ log.Info("getGatewayFromSwitch", "logicalSwitch", logicalSwitch)
if gatewayIPMaskStr, ok = oc.gatewayCache[logicalSwitch]; !ok {
- gatewayIPMaskStr, stderr, err = RunOVNNbctlUnix("--if-exists",
+ gatewayIPMaskStr, stderr, err = RunOVNNbctl("--if-exists",
"get", "logical_switch", logicalSwitch,
"external_ids:gateway_ip")
if err != nil {
- logrus.Errorf("Failed to get gateway IP: %s, stderr: %q, %v",
- gatewayIPMaskStr, stderr, err)
+ log.Error(err, "Failed to get gateway IP", "stderr", stderr, "gatewayIPMaskStr", gatewayIPMaskStr)
return "", "", err
}
if gatewayIPMaskStr == "" {
@@ -107,44 +188,6 @@ func (oc *Controller) getGatewayFromSwitch(logicalSwitch string) (string, string
return gatewayIP, mask, nil
}
-func (oc *Controller) deleteLogicalPort(pod *kapi.Pod) {
-
- if pod.Spec.HostNetwork {
- return
- }
-
- logrus.Infof("Deleting pod: %s", pod.Name)
- logicalPort := fmt.Sprintf("%s_%s", pod.Namespace, pod.Name)
-
- // get the list of logical ports from OVN
- output, stderr, err := RunOVNNbctlUnix("--data=bare", "--no-heading",
- "--columns=name", "find", "logical_switch_port", "external_ids:pod=true")
- if err != nil {
- logrus.Errorf("Error in obtaining list of logical ports, "+
- "stderr: %q, err: %v",
- stderr, err)
- return
- }
- logrus.Infof("Exising Ports : %s. ", output)
- existingLogicalPorts := strings.Fields(output)
- for _, existingPort := range existingLogicalPorts {
- if strings.Contains(existingPort, logicalPort) {
- // found, delete this logical port
- logrus.Infof("Deleting: %s. ", existingPort)
- out, stderr, err := RunOVNNbctlUnix("--if-exists", "lsp-del",
- existingPort)
- if err != nil {
- logrus.Errorf("Error in deleting pod's logical port "+
- "stdout: %q, stderr: %q err: %v",
- out, stderr, err)
- } else {
- delete(oc.logicalPortCache, existingPort)
- }
- }
- }
- return
-}
-
func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipAddress, macAddress, interfaceName, netType string) (annotation string) {
var out, stderr string
var err error
@@ -153,9 +196,6 @@ func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipA
return
}
- if !oc.logicalSwitchCache[logicalSwitch] {
- oc.logicalSwitchCache[logicalSwitch] = true
- }
var portName string
if interfaceName != "" {
portName = fmt.Sprintf("%s_%s_%s", pod.Namespace, pod.Name, interfaceName)
@@ -163,7 +203,7 @@ func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipA
return
}
- logrus.Infof("Creating logical port for %s on switch %s", portName, logicalSwitch)
+ log.Info("Creating logical port for on switch", "portName", portName, "logicalSwitch", logicalSwitch)
if ipAddress != "" && macAddress != "" {
isStaticIP = true
@@ -174,7 +214,7 @@ func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipA
}
if isStaticIP {
- out, stderr, err = RunOVNNbctlUnix("--may-exist", "lsp-add",
+ out, stderr, err = RunOVNNbctl("--may-exist", "lsp-add",
logicalSwitch, portName, "--", "lsp-set-addresses", portName,
fmt.Sprintf("%s %s", macAddress, ipAddress), "--", "--if-exists",
"clear", "logical_switch_port", portName, "dynamic_addresses", "--", "set",
@@ -183,13 +223,11 @@ func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipA
"external-ids:logical_switch="+logicalSwitch,
"external-ids:pod=true")
if err != nil {
- logrus.Errorf("Failed to add logical port to switch "+
- "stdout: %q, stderr: %q (%v)",
- out, stderr, err)
+ log.Error(err, "Failed to add logical port to switch", "out", out, "stderr", stderr)
return
}
} else {
- out, stderr, err = RunOVNNbctlUnix("--wait=sb", "--",
+ out, stderr, err = RunOVNNbctl("--wait=sb", "--",
"--may-exist", "lsp-add", logicalSwitch, portName,
"--", "lsp-set-addresses",
portName, "dynamic", "--", "set",
@@ -198,37 +236,32 @@ func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipA
"external-ids:logical_switch="+logicalSwitch,
"external-ids:pod=true")
if err != nil {
- logrus.Errorf("Error while creating logical port %s "+
- "stdout: %q, stderr: %q (%v)",
- portName, out, stderr, err)
+ log.Error(err, "Error while creating logical port %s ", "portName", portName, "stdout", out, "stderr", stderr)
return
}
}
- oc.logicalPortCache[portName] = logicalSwitch
count := 30
for count > 0 {
if isStaticIP {
- out, stderr, err = RunOVNNbctlUnix("get",
+ out, stderr, err = RunOVNNbctl("get",
"logical_switch_port", portName, "addresses")
} else {
- out, stderr, err = RunOVNNbctlUnix("get",
+ out, stderr, err = RunOVNNbctl("get",
"logical_switch_port", portName, "dynamic_addresses")
}
if err == nil && out != "[]" {
break
}
if err != nil {
- logrus.Errorf("Error while obtaining addresses for %s - %v", portName,
- err)
+ log.Error(err, "Error while obtaining addresses for", "portName", portName)
return
}
time.Sleep(time.Second)
count--
}
if count == 0 {
- logrus.Errorf("Error while obtaining addresses for %s "+
- "stdout: %q, stderr: %q, (%v)", portName, out, stderr, err)
+ log.Error(err, "Error while obtaining addresses for", "portName", portName, "stdout", out, "stderr", stderr)
return
}
@@ -239,14 +272,14 @@ func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipA
outStr = strings.Trim(outStr, `"`)
addresses := strings.Split(outStr, " ")
if len(addresses) != 2 {
- logrus.Errorf("Error while obtaining addresses for %s", portName)
+ log.Info("Error while obtaining addresses for", "portName", portName)
return
}
if netType == "virtual" {
gatewayIP, mask, err := oc.getGatewayFromSwitch(logicalSwitch)
if err != nil {
- logrus.Errorf("Error obtaining gateway address for switch %s: %s", logicalSwitch, err)
+ log.Error(err, "Error obtaining gateway address for switch", "logicalSwitch", logicalSwitch)
return
}
annotation = fmt.Sprintf(`{\"ip_address\":\"%s/%s\", \"mac_address\":\"%s\", \"gateway_ip\": \"%s\"}`, addresses[1], mask, addresses[0], gatewayIP)
@@ -256,102 +289,3 @@ func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipA
return annotation
}
-
-func (oc *Controller) findLogicalSwitch(name string) bool {
- // get logical switch from OVN
- output, stderr, err := RunOVNNbctlUnix("--data=bare", "--no-heading",
- "--columns=name", "find", "logical_switch", "name="+name)
- if err != nil {
- logrus.Errorf("Error in obtaining list of logical switch, "+
- "stderr: %q, err: %v",
- stderr, err)
- return false
- }
-
- if strings.Compare(name, output) == 0 {
- return true
- } else {
- logrus.Errorf("Error finding Switch %v", name)
- return false
- }
-}
-
-func (oc *Controller) addLogicalPort(pod *kapi.Pod) {
- var logicalSwitch string
- var ipAddress, macAddress, interfaceName, defaultGateway, netType string
-
- annotation := pod.Annotations["ovnNetwork"]
-
- if annotation != "" {
- ovnNetObjs, err := parseOvnNetworkObject(annotation)
- if err != nil {
- logrus.Errorf("addLogicalPort : Error Parsing OvnNetwork List")
- return
- }
- var ovnString, outStr string
- ovnString = "["
- for _, net := range ovnNetObjs {
- logicalSwitch = net["name"].(string)
- if !oc.findLogicalSwitch(logicalSwitch) {
- logrus.Errorf("Logical Switch not found")
- return
- }
- if _, ok := net["interface"]; ok {
- interfaceName = net["interface"].(string)
- } else {
- logrus.Errorf("Interface name must be provided")
- return
- }
- if _, ok := net["ipAddress"]; ok {
- ipAddress = net["ipAddress"].(string)
- } else {
- ipAddress = ""
- }
- if _, ok := net["macAddress"]; ok {
- macAddress = net["macAddress"].(string)
- } else {
- macAddress = ""
- }
- if _, ok := net["defaultGateway"]; ok {
- defaultGateway = net["defaultGateway"].(string)
- } else {
- defaultGateway = "false"
- }
- if _, ok := net["netType"]; ok {
- netType = net["netType"].(string)
- } else {
- netType = "virtual"
- }
- if netType != "provider" && netType != "virtual" {
- logrus.Errorf("netType is not supported")
- return
- }
- if netType == "provider" && ipAddress == "" {
- logrus.Errorf("ipAddress must be provided for netType Provider")
- return
- }
- if netType == "provider" && defaultGateway == "true" {
- logrus.Errorf("defaultGateway not supported for provider network - Use ovnNetworkRoutes to add routes")
- return
- }
- outStr = oc.addLogicalPortWithSwitch(pod, logicalSwitch, ipAddress, macAddress, interfaceName, netType)
- if outStr == "" {
- return
- }
- last := len(outStr) - 1
- tmpString := outStr[:last]
- tmpString += "," + "\\\"defaultGateway\\\":" + "\\\"" + defaultGateway + "\\\""
- tmpString += "," + "\\\"interface\\\":" + "\\\"" + interfaceName + "\\\"}"
- ovnString += tmpString
- ovnString += ","
- }
- last := len(ovnString) - 1
- ovnString = ovnString[:last]
- ovnString += "]"
- logrus.Debugf("ovnIfaceList - %v", ovnString)
- err = oc.kube.SetAnnotationOnPod(pod, "ovnIfaceList", ovnString)
- if err != nil {
- logrus.Errorf("Failed to set annotation on pod %s - %v", pod.Name, err)
- }
- }
-}
diff --git a/internal/pkg/ovn/ovn_test.go b/internal/pkg/ovn/ovn_test.go
index bc33d35..6e38759 100644
--- a/internal/pkg/ovn/ovn_test.go
+++ b/internal/pkg/ovn/ovn_test.go
@@ -9,9 +9,7 @@ import (
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/client-go/kubernetes/fake"
"ovn4nfv-k8s-plugin/internal/pkg/config"
- "ovn4nfv-k8s-plugin/internal/pkg/factory"
ovntest "ovn4nfv-k8s-plugin/internal/pkg/testing"
. "github.com/onsi/ginkgo"
@@ -30,10 +28,10 @@ var _ = Describe("Add logical Port", func() {
var app *cli.App
BeforeEach(func() {
-
app = cli.NewApp()
app.Name = "test"
app.Flags = config.Flags
+
})
It("tests Pod", func() {
@@ -68,15 +66,15 @@ var _ = Describe("Add logical Port", func() {
return fmt.Sprintf("/fake-bin/%s", file), nil
},
}
-
- err := SetExec(fexec)
+ oldSetupOvnUtils := SetupOvnUtils
+ // as we are exiting, revert ConfigureInterface back at end of function
+ defer func() { SetupOvnUtils = oldSetupOvnUtils }()
+ SetupOvnUtils = func() error {
+ return nil
+ }
+ ovnController, err := NewOvnController(fexec)
Expect(err).NotTo(HaveOccurred())
- fakeClient := &fake.Clientset{}
- var fakeWatchFactory factory.WatchFactory
-
- ovnController := NewOvnController(fakeClient, &fakeWatchFactory)
- Expect(err).NotTo(HaveOccurred())
var (
okPod = v1.Pod{
TypeMeta: metav1.TypeMeta{
@@ -84,8 +82,7 @@ var _ = Describe("Add logical Port", func() {
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
- Name: "ok",
- Annotations: map[string]string{"ovnNetwork": "[{ \"name\": \"ovn-prot-net\", \"interface\": \"net0\" , \"defaultGateway\": \"true\"}]"},
+ Name: "ok",
},
Spec: v1.PodSpec{
Containers: []v1.Container{
@@ -97,8 +94,8 @@ var _ = Describe("Add logical Port", func() {
},
}
)
-
- ovnController.addLogicalPort(&okPod)
+ a := []map[string]interface{}{{"name": "ovn-prot-net", "interface": "net0"}}
+ ovnController.AddLogicalPorts(&okPod, a)
Expect(fexec.CommandCalls).To(Equal(len(fakeCmds)))
return nil
@@ -137,13 +134,14 @@ var _ = Describe("Add logical Port", func() {
return fmt.Sprintf("/fake-bin/%s", file), nil
},
}
- err := SetExec(fexec)
+ oldSetupOvnUtils := SetupOvnUtils
+ // as we are exiting, revert ConfigureInterface back at end of function
+ defer func() { SetupOvnUtils = oldSetupOvnUtils }()
+ SetupOvnUtils = func() error {
+ return nil
+ }
+ ovnController, err := NewOvnController(fexec)
Expect(err).NotTo(HaveOccurred())
-
- fakeClient := &fake.Clientset{}
- var fakeWatchFactory factory.WatchFactory
-
- ovnController := NewOvnController(fakeClient, &fakeWatchFactory)
var (
okPod = v1.Pod{
TypeMeta: metav1.TypeMeta{
@@ -151,8 +149,7 @@ var _ = Describe("Add logical Port", func() {
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
- Name: "ok",
- Annotations: map[string]string{"ovnNetwork": "[{ \"name\": \"ovn-prot-net\", \"interface\": \"net0\", \"netType\": \"provider\", \"ipAddress\": \"192.168.1.3/24\", \"macAddress\": \"0a:00:00:00:00:01\" }]"},
+ Name: "ok",
},
Spec: v1.PodSpec{
Containers: []v1.Container{
@@ -164,7 +161,8 @@ var _ = Describe("Add logical Port", func() {
},
}
)
- ovnController.addLogicalPort(&okPod)
+ a := []map[string]interface{}{{"name": "ovn-prot-net", "interface": "net0", "netType": "provider", "ipAddress": "192.168.1.3/24", "macAddress": "0a:00:00:00:00:01"}}
+ ovnController.AddLogicalPorts(&okPod, a)
Expect(fexec.CommandCalls).To(Equal(len(fakeCmds)))
return nil
diff --git a/internal/pkg/ovn/utils.go b/internal/pkg/ovn/utils.go
index 1700bf8..2478ac2 100644
--- a/internal/pkg/ovn/utils.go
+++ b/internal/pkg/ovn/utils.go
@@ -3,55 +3,53 @@ package ovn
import (
"bytes"
"fmt"
+ kexec "k8s.io/utils/exec"
+ "os"
"strings"
"time"
- "unicode"
-
- "github.com/sirupsen/logrus"
- kexec "k8s.io/utils/exec"
)
const (
ovsCommandTimeout = 15
- ovsVsctlCommand = "ovs-vsctl"
- ovsOfctlCommand = "ovs-ofctl"
ovnNbctlCommand = "ovn-nbctl"
- ipCommand = "ip"
)
// Exec runs various OVN and OVS utilities
type execHelper struct {
exec kexec.Interface
- ofctlPath string
- vsctlPath string
nbctlPath string
- ipPath string
+ hostIP string
+ hostPort string
}
var runner *execHelper
+// SetupOvnUtils does internal OVN initialization
+var SetupOvnUtils = func() error {
+ runner.hostIP = os.Getenv("HOST_IP")
+ // OVN Host Port
+ runner.hostPort = "6641"
+ log.Info("Host Port", "IP", runner.hostIP, "Port", runner.hostPort)
+
+ // Setup Distributed Router
+ err := setupDistributedRouter(ovn4nfvRouterName)
+ if err != nil {
+ log.Error(err, "Failed to initialize OVN Distributed Router")
+ return err
+ }
+ return nil
+}
+
// SetExec validates executable paths and saves the given exec interface
// to be used for running various OVS and OVN utilites
func SetExec(exec kexec.Interface) error {
var err error
runner = &execHelper{exec: exec}
- runner.ofctlPath, err = exec.LookPath(ovsOfctlCommand)
- if err != nil {
- return err
- }
- runner.vsctlPath, err = exec.LookPath(ovsVsctlCommand)
- if err != nil {
- return err
- }
runner.nbctlPath, err = exec.LookPath(ovnNbctlCommand)
if err != nil {
return err
}
- runner.ipPath, err = exec.LookPath(ipCommand)
- if err != nil {
- return err
- }
return nil
}
@@ -65,7 +63,6 @@ func runOVNretry(cmdPath string, args ...string) (*bytes.Buffer, *bytes.Buffer,
if err == nil {
return stdout, stderr, err
}
-
// Connection refused
// Master may not be up so keep trying
if strings.Contains(stderr.String(), "Connection refused") {
@@ -87,34 +84,29 @@ func run(cmdPath string, args ...string) (*bytes.Buffer, *bytes.Buffer, error) {
cmd := runner.exec.Command(cmdPath, args...)
cmd.SetStdout(stdout)
cmd.SetStderr(stderr)
- logrus.Debugf("exec: %s %s", cmdPath, strings.Join(args, " "))
+ log.Info("exec:", "cmdPath", cmdPath, "args", strings.Join(args, " "))
err := cmd.Run()
if err != nil {
- logrus.Debugf("exec: %s %s => %v", cmdPath, strings.Join(args, " "), err)
+ log.Error(err, "exec:", "cmdPath", cmdPath, "args", strings.Join(args, " "))
}
return stdout, stderr, err
}
-// RunOVSVsctl runs a command via ovs-vsctl.
-func RunOVSVsctlUnix(args ...string) (string, string, error) {
- cmdArgs := []string{fmt.Sprintf("--timeout=%d", ovsCommandTimeout)}
- cmdArgs = append(cmdArgs, args...)
- stdout, stderr, err := run(runner.vsctlPath, cmdArgs...)
- return strings.Trim(strings.TrimSpace(stdout.String()), "\""), stderr.String(), err
-}
-
-// RunOVNNbctlUnix runs command via ovn-nbctl, with ovn-nbctl using the unix
-// domain sockets to connect to the ovsdb-server backing the OVN NB database.
-func RunOVNNbctlUnix(args ...string) (string, string, error) {
- cmdArgs := []string{fmt.Sprintf("--timeout=%d", ovsCommandTimeout)}
+// RunOVNSbctlWithTimeout runs command via ovn-nbctl with a specific timeout
+func RunOVNNbctlWithTimeout(timeout int, args ...string) (string, string, error) {
+ var cmdArgs []string
+ if len(runner.hostIP) > 0 {
+ cmdArgs = []string{
+ fmt.Sprintf("--db=tcp:%s:%s", runner.hostIP, runner.hostPort),
+ }
+ }
+ cmdArgs = append(cmdArgs, fmt.Sprintf("--timeout=%d", timeout))
cmdArgs = append(cmdArgs, args...)
stdout, stderr, err := runOVNretry(runner.nbctlPath, cmdArgs...)
- return strings.Trim(strings.TrimFunc(stdout.String(), unicode.IsSpace), "\""),
- stderr.String(), err
+ return strings.Trim(strings.TrimSpace(stdout.String()), "\""), stderr.String(), err
}
-// RunIP runs a command via the iproute2 "ip" utility
-func RunIP(args ...string) (string, string, error) {
- stdout, stderr, err := run(runner.ipPath, args...)
- return strings.TrimSpace(stdout.String()), stderr.String(), err
+// RunOVNNbctl runs a command via ovn-nbctl.
+func RunOVNNbctl(args ...string) (string, string, error) {
+ return RunOVNNbctlWithTimeout(ovsCommandTimeout, args...)
}