aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRitu Sood <ritu.sood@intel.com>2019-02-17 05:58:57 -0800
committerRitu Sood <ritu.sood@intel.com>2019-02-17 06:01:05 -0800
commit8dffa72e276cd58669f589f7d2693a046f644695 (patch)
treec59b5685f1cabf99a584ed642224924086936905
parent95d21eeecec4ea01078c62527faa0fe8c3f9c539 (diff)
Add Routes to Pod
Based on Pod annotations list ovnNetworkRoutes routes are added to the Pod namespace Change-Id: If6b8b6375d798dcbd45e51ccd5adae4b24369c5c Signed-off-by: Ritu Sood <ritu.sood@intel.com>
-rw-r--r--cmd/ovn4nfvk8s-cni/app/helper_linux.go26
-rw-r--r--cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go54
-rw-r--r--cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni_test.go72
3 files changed, 151 insertions, 1 deletions
diff --git a/cmd/ovn4nfvk8s-cni/app/helper_linux.go b/cmd/ovn4nfvk8s-cni/app/helper_linux.go
index 1a98a61..fc4fd94 100644
--- a/cmd/ovn4nfvk8s-cni/app/helper_linux.go
+++ b/cmd/ovn4nfvk8s-cni/app/helper_linux.go
@@ -143,6 +143,32 @@ var ConfigureInterface = func(args *skel.CmdArgs, namespace, podName, macAddress
return []*current.Interface{hostIface, contIface}, nil
}
+func setupRoute(netns ns.NetNS, dst, gw, dev string) error {
+ // Add Route to the namespace
+ err := netns.Do(func(_ ns.NetNS) error {
+ dstAddr, dstAddrNet, _ := net.ParseCIDR(dst)
+ ipNet := net.IPNet{IP: dstAddr, Mask: dstAddrNet.Mask}
+ link, err := netlink.LinkByName(dev)
+ err = ip.AddRoute(&ipNet, net.ParseIP(gw), link)
+ if err != nil {
+ logrus.Errorf("ip.AddRoute failed %v dst %v gw %v", err, dst, gw)
+ }
+ return err
+ })
+ return err
+}
+
+// ConfigureRoute sets up the container routes
+var ConfigureRoute = func(args *skel.CmdArgs, dst, gw, dev string) error {
+ netns, err := ns.GetNS(args.Netns)
+ if err != nil {
+ return fmt.Errorf("failed to open netns %q: %v", args.Netns, err)
+ }
+ defer netns.Close()
+ err = setupRoute(netns, dst, gw, dev)
+ return err
+}
+
// PlatformSpecificCleanup deletes the OVS port
func PlatformSpecificCleanup(ifaceName string) (bool, error) {
done := false
diff --git a/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go b/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go
index 923363b..2722eaa 100644
--- a/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go
+++ b/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go
@@ -196,6 +196,53 @@ func addMultipleInterfaces(args *skel.CmdArgs, ovnAnnotation, namespace, podName
return dstResult
}
+func addRoutes(args *skel.CmdArgs, ovnAnnotation string, dstResult types.Result) types.Result {
+ logrus.Infof("ovn4nfvk8s-cni: addRoutes ")
+
+ var ovnAnnotatedMap []map[string]string
+ ovnAnnotatedMap, err := parseOvnNetworkObject(ovnAnnotation)
+ if err != nil {
+ logrus.Errorf("addLogicalPort : Error Parsing Ovn Route List %v", err)
+ return nil
+ }
+
+ var result types.Result
+ var routes []*types.Route
+ for _, ovnNet := range ovnAnnotatedMap {
+ dst := ovnNet["dst"]
+ gw := ovnNet["gw"]
+ dev := ovnNet["dev"]
+ if dst == "" || gw == "" || dev == "" {
+ logrus.Errorf("failed in pod annotation key extract")
+ return nil
+ }
+ err = app.ConfigureRoute(args, dst, gw, dev)
+ if err != nil {
+ logrus.Errorf("Failed to configure interface in pod: %v", err)
+ return nil
+ }
+ dstAddr, dstAddrNet, _ := net.ParseCIDR(dst)
+ routes = append(routes, &types.Route{
+ Dst: net.IPNet{IP: dstAddr, Mask: dstAddrNet.Mask},
+ GW: net.ParseIP(gw),
+ })
+ }
+
+ result = &current.Result{
+ Routes: routes,
+ }
+ // Build the result structure to pass back to the runtime
+ dstResult, err = mergeWithResult(result, dstResult)
+ if err != nil {
+ logrus.Errorf("Failed to merge results: %v", err)
+ return nil
+ }
+ logrus.Infof("addRoutes: %s", prettyPrint(dstResult))
+ return dstResult
+
+}
+
+
func cmdAdd(args *skel.CmdArgs) error {
logrus.Infof("ovn4nfvk8s-cni: cmdAdd ")
conf := &types.NetConf{}
@@ -243,6 +290,13 @@ func cmdAdd(args *skel.CmdArgs) error {
return fmt.Errorf("Error while obtaining pod annotations")
}
result := addMultipleInterfaces(args, ovnAnnotation, namespace, podName)
+ // Add Routes to the pod if annotation found for routes
+ ovnRouteAnnotation, ok := annotation["ovnNetworkRoutes"]
+ if ok {
+ logrus.Infof("ovn4nfvk8s-cni: ovnNetworkRoutes Annotation Found %+v", ovnRouteAnnotation)
+ result = addRoutes(args, ovnRouteAnnotation, result)
+ }
+
return result.Print()
}
diff --git a/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni_test.go b/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni_test.go
index d5b7b6b..e1190ca 100644
--- a/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni_test.go
+++ b/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni_test.go
@@ -3,9 +3,14 @@
package main
import (
+ "encoding/json"
+
"github.com/containernetworking/cni/pkg/skel"
+ "github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
+ "net"
"ovn4nfv-k8s-plugin/cmd/ovn4nfvk8s-cni/app"
+ "reflect"
"testing"
)
@@ -21,13 +26,19 @@ func TestAddMultipleInterfaces(t *testing.T) {
Sandbox: "102103104",
}}, nil
}
- args := &skel.CmdArgs{"102103104", "default", "eth0", "", "", nil}
+ oldConfigureRoute := app.ConfigureRoute
+ defer func() { app.ConfigureRoute = oldConfigureRoute }()
+ app.ConfigureRoute = func(args *skel.CmdArgs, dst, gw, dev string) error {
+ return nil
+ }
+ args := &skel.CmdArgs{"102103104", "default", "eth0", "", "", nil}
ovnAnnotation := "[{\"ip_address\":\"172.16.24.2/24\", \"mac_address\":\"0a:00:00:00:00:0c\", \"gateway_ip\": \"172.16.24.1\",\"interface\":\"net0\"}] "
result := addMultipleInterfaces(args, ovnAnnotation, "default", "pod")
if result == nil {
t.Errorf("Failed addMultipleInterfaces %+v", ovnAnnotation)
}
+ resultSave := result
ovnAnnotation = "[{\"ip_address\":\"172.16.24.2/24\", \"mac_address\":\"0a:00:00:00:00:0c\", \"gateway_ip\": \"172.16.24.1\",\"defaultGateway\":\"true\",\"interface\":\"net0\"}] "
result = addMultipleInterfaces(args, ovnAnnotation, "default", "pod")
if result == nil {
@@ -53,4 +64,63 @@ func TestAddMultipleInterfaces(t *testing.T) {
if result == nil {
t.Errorf("Failed addMultipleInterfaces %+v", ovnAnnotation)
}
+ // Test add route feature
+ ovnRoutesAnnotation := "[{ \"dst\": \"172.16.29.0/24\", \"gw\": \"172.16.24.1\", \"dev\": \"eth0\" }]"
+ result = addRoutes(args, ovnRoutesAnnotation, resultSave)
+ if result == nil {
+ t.Errorf("Failed addRoutes %+v", ovnRoutesAnnotation)
+ }
+
+ ovnRoutesAnnotation = "[{ \"dst\": \"172.16.30.0/24\", \"gw\": \"172.16.25.1\", \"dev\": \"eth0\"}, { \"dst\": \"172.16.31.0/24\", \"gw\": \"172.16.26.1\", \"dev\": \"eth1\" }]"
+ result = addRoutes(args, ovnRoutesAnnotation, resultSave)
+ if result == nil {
+ t.Errorf("Failed addRoutes %+v", ovnRoutesAnnotation)
+ }
+ newResult, err := current.NewResultFromResult(result)
+ if err != nil {
+ t.Errorf("Failed addMultipleInterfaces %+v", newResult)
+ }
+ addr1, addrNet1, _ := net.ParseCIDR("172.16.24.2/24")
+ addr2, addrNet2, _ := net.ParseCIDR("172.16.29.0/24")
+ addr3, addrNet3, _ := net.ParseCIDR("172.16.30.0/24")
+ addr4, addrNet4, _ := net.ParseCIDR("172.16.31.0/24")
+ expectedResult := &current.Result{
+ CNIVersion: "0.3.1",
+ Interfaces: []*current.Interface{
+ {
+ Name: "pod",
+ Mac: "0a:00:00:00:00:0c",
+ Sandbox: "102103104",
+ },
+ },
+ IPs: []*current.IPConfig{
+ {
+ Version: "4",
+ Interface: current.Int(1),
+ Address: net.IPNet{IP: addr1, Mask: addrNet1.Mask},
+ Gateway: net.ParseIP("172.16.24.1"),
+ },
+ },
+ Routes: []*types.Route{
+ {
+ Dst: net.IPNet{IP: addr2, Mask: addrNet2.Mask},
+ GW: net.ParseIP("172.16.24.1"),
+ },
+ {
+ Dst: net.IPNet{IP: addr3, Mask: addrNet3.Mask},
+ GW: net.ParseIP("172.16.25.1"),
+ },
+ {
+ Dst: net.IPNet{IP: addr4, Mask: addrNet4.Mask},
+ GW: net.ParseIP("172.16.26.1"),
+ },
+ },
+ DNS: types.DNS{},
+ }
+ jsonBytes1, err := json.Marshal(newResult.Routes)
+ jsonBytes2, err := json.Marshal(expectedResult.Routes)
+ if !reflect.DeepEqual(jsonBytes1, jsonBytes2) {
+ t.Errorf("Routes are not correct")
+ }
+
}