aboutsummaryrefslogtreecommitdiffstats
path: root/internal/pkg/util
diff options
context:
space:
mode:
authorRitu Sood <ritu.sood@intel.com>2018-11-10 09:56:52 -0800
committerVictor Morales <victor.morales@intel.com>2018-11-20 01:50:58 -0800
commit5026d1d89b05eac5e004279b742df6745a73d93a (patch)
tree8f9aed1e476706e008b746debda6d616bd0ac7a5 /internal/pkg/util
parent9506ae48eb545d502cc3685a99862740d28e7afb (diff)
Seed code for the Plugin
The code includes ovn4nfvk8s Plugin & CNI. It implements multiple OVN interfaces for Pods and assumes Multus (or similar CNI) calls its CNI not as first CNI. Change-Id: I524c1d18752eb6dbc8d34addd3b60d5bbaa06ff4 Signed-off-by: Ritu Sood <ritu.sood@intel.com> Signed-off-by: Victor Morales <victor.morales@intel.com>
Diffstat (limited to 'internal/pkg/util')
-rw-r--r--internal/pkg/util/.gitkeep0
-rw-r--r--internal/pkg/util/net.go34
-rw-r--r--internal/pkg/util/ovs.go126
3 files changed, 160 insertions, 0 deletions
diff --git a/internal/pkg/util/.gitkeep b/internal/pkg/util/.gitkeep
deleted file mode 100644
index e69de29..0000000
--- a/internal/pkg/util/.gitkeep
+++ /dev/null
diff --git a/internal/pkg/util/net.go b/internal/pkg/util/net.go
new file mode 100644
index 0000000..1ff7fbb
--- /dev/null
+++ b/internal/pkg/util/net.go
@@ -0,0 +1,34 @@
+package util
+
+import (
+ "fmt"
+ "math/big"
+ "math/rand"
+ "net"
+ "time"
+)
+
+// GenerateMac generates mac address.
+func GenerateMac() string {
+ prefix := "00:00:00"
+ newRand := rand.New(rand.NewSource(time.Now().UnixNano()))
+ mac := fmt.Sprintf("%s:%02x:%02x:%02x", prefix, newRand.Intn(255), newRand.Intn(255), newRand.Intn(255))
+ return mac
+}
+
+// NextIP returns IP incremented by 1
+func NextIP(ip net.IP) net.IP {
+ i := ipToInt(ip)
+ return intToIP(i.Add(i, big.NewInt(1)))
+}
+
+func ipToInt(ip net.IP) *big.Int {
+ if v := ip.To4(); v != nil {
+ return big.NewInt(0).SetBytes(v)
+ }
+ return big.NewInt(0).SetBytes(ip.To16())
+}
+
+func intToIP(i *big.Int) net.IP {
+ return net.IP(i.Bytes())
+}
diff --git a/internal/pkg/util/ovs.go b/internal/pkg/util/ovs.go
new file mode 100644
index 0000000..22b42b9
--- /dev/null
+++ b/internal/pkg/util/ovs.go
@@ -0,0 +1,126 @@
+package util
+
+import (
+ "bytes"
+ "fmt"
+ "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
+}
+
+var runner *execHelper
+
+// 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
+}
+
+// Run the ovn-ctl command and retry if "Connection refused"
+// poll waitng for service to become available
+func runOVNretry(cmdPath string, args ...string) (*bytes.Buffer, *bytes.Buffer, error) {
+
+ retriesLeft := 200
+ for {
+ stdout, stderr, err := run(cmdPath, args...)
+ if err == nil {
+ return stdout, stderr, err
+ }
+
+ // Connection refused
+ // Master may not be up so keep trying
+ if strings.Contains(stderr.String(), "Connection refused") {
+ if retriesLeft == 0 {
+ return stdout, stderr, err
+ }
+ retriesLeft--
+ time.Sleep(2 * time.Second)
+ } else {
+ // Some other problem for caller to handle
+ return stdout, stderr, err
+ }
+ }
+}
+
+func run(cmdPath string, args ...string) (*bytes.Buffer, *bytes.Buffer, error) {
+ stdout := &bytes.Buffer{}
+ stderr := &bytes.Buffer{}
+ cmd := runner.exec.Command(cmdPath, args...)
+ cmd.SetStdout(stdout)
+ cmd.SetStderr(stderr)
+ logrus.Debugf("exec: %s %s", cmdPath, strings.Join(args, " "))
+ err := cmd.Run()
+ if err != nil {
+ logrus.Debugf("exec: %s %s => %v", cmdPath, strings.Join(args, " "), err)
+ }
+ return stdout, stderr, err
+}
+
+// RunOVSOfctl runs a command via ovs-ofctl.
+func RunOVSOfctl(args ...string) (string, string, error) {
+ stdout, stderr, err := run(runner.ofctlPath, args...)
+ return strings.Trim(stdout.String(), "\" \n"), stderr.String(), err
+}
+
+// RunOVSVsctl runs a command via ovs-vsctl.
+func RunOVSVsctl(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)}
+ cmdArgs = append(cmdArgs, args...)
+ stdout, stderr, err := runOVNretry(runner.nbctlPath, cmdArgs...)
+ return strings.Trim(strings.TrimFunc(stdout.String(), unicode.IsSpace), "\""),
+ 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
+}