Skip to content

Commit

Permalink
Merge pull request #30 from linkernetworks/alex/network-controller
Browse files Browse the repository at this point in the history
Add network controller

Former-commit-id: c0298a16614b2adc44cafd777b4270d2c2bcec08 [formerly dd01cbf]
Former-commit-id: b983b59baae23791621a1de3f22c9176c76f9632
  • Loading branch information
John-Lin authored Jun 26, 2018
2 parents 89ecca1 + 5761b55 commit 7069fbe
Show file tree
Hide file tree
Showing 10 changed files with 747 additions and 193 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ notifications:

before_install:
- go get -u github.com/kardianos/govendor
- sudo apt-get install -y git build-essential openvswitch-switch
- docker run -d -v /run/openvswitch/db.sock:/var/run/openvswitch/db.sock -p 50051:50051 sdnvortex/network-controller:v0.1.1 /go/bin/server -tcp=0.0.0.0:50051

install:
- make pre-build

script:
- make build
- make test
- make src.test-coverage
- sudo -E PATH=$PATH TEST_GRPC=1 make src.test-coverage
- docker build --tag sdnvortex/vortex --file ./dockerfiles/Dockerfile .

before_deploy:
Expand Down
4 changes: 1 addition & 3 deletions src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/linkernetworks/logger"
"github.com/linkernetworks/mongo"
"github.com/linkernetworks/redis"
"k8s.io/client-go/rest"
)

type Config struct {
Expand All @@ -18,8 +17,6 @@ type Config struct {

// the version settings of the current application
Version string `json:"version"`

Kubernetes *rest.Config `json:"kubernetes"`
}

func Read(path string) (c Config, err error) {
Expand All @@ -32,6 +29,7 @@ func Read(path string) (c Config, err error) {
if err := decoder.Decode(&c); err != nil {
return c, fmt.Errorf("Failed to load the config file: %v\n", err)
}

return c, nil
}

Expand Down
65 changes: 65 additions & 0 deletions src/networkcontroller/network_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package networkcontroller

import (
"time"

pb "github.com/linkernetworks/network-controller/messages"
"github.com/linkernetworks/vortex/src/entity"
"github.com/linkernetworks/vortex/src/kubernetes"
"golang.org/x/net/context"
"google.golang.org/grpc"
)

type NetworkController struct {
KubeCtl *kubernetes.KubeCtl
ClientCtl pb.NetworkControlClient
Network entity.Network
Context context.Context
}

func New(kubeCtl *kubernetes.KubeCtl, network entity.Network) (*NetworkController, error) {
nodeIP, err := kubeCtl.GetNodeExternalIP(network.NodeName)
if err != nil {
return nil, err
}

// Set up a connection to the server.
conn, err := grpc.Dial(nodeIP+":50051", grpc.WithInsecure())
if err != nil {
return nil, err
}

ctx, _ := context.WithTimeout(context.Background(), time.Second)

return &NetworkController{
KubeCtl: kubeCtl,
ClientCtl: pb.NewNetworkControlClient(conn),
Network: network,
Context: ctx,
}, nil
}

func (nc *NetworkController) CreateNetwork() error {
_, err := nc.ClientCtl.CreateBridge(
nc.Context,
&pb.CreateBridgeRequest{
BridgeName: nc.Network.BridgeName,
})
if err != nil {
return err
}

for _, port := range nc.Network.PhysicalPorts {
_, err := nc.ClientCtl.AddPort(
nc.Context,
&pb.AddPortRequest{
BridgeName: nc.Network.BridgeName,
IfaceName: port.Name,
})
if err != nil {
return err
}
}

return nil
}
109 changes: 109 additions & 0 deletions src/networkcontroller/network_controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package networkcontroller

import (
"fmt"
"github.com/linkernetworks/vortex/src/entity"
"github.com/linkernetworks/vortex/src/kubernetes"
"github.com/moby/moby/pkg/namesgenerator"
"github.com/stretchr/testify/suite"
"math/rand"
"os"
"os/exec"
"runtime"
"testing"
"time"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fakeclientset "k8s.io/client-go/kubernetes/fake"
)

func init() {
rand.Seed(time.Now().UnixNano())
}

type NetworkControllerTestSuite struct {
suite.Suite
kubectl *kubernetes.KubeCtl
ifName string
nodeName string
}

func (suite *NetworkControllerTestSuite) SetupSuite() {
// init fakeclient
fakeclient := fakeclientset.NewSimpleClientset()
namespace := "default"
suite.kubectl = kubernetes.New(fakeclient, namespace)

//Create a fake clinet
//Init
nodeAddr := corev1.NodeAddress{
Type: "ExternalIP",
Address: "127.0.0.1",
}

suite.nodeName = namesgenerator.GetRandomName(0)[0:8]
node := corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: suite.nodeName,
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{nodeAddr},
},
}
_, err := suite.kubectl.Clientset.CoreV1().Nodes().Create(&node)
suite.NoError(err)

//There's a length limit of link name
suite.ifName = namesgenerator.GetRandomName(0)[0:8]
pName := namesgenerator.GetRandomName(0)[0:8]
//Create a veth for testing
err = exec.Command("ip", "link", "add", suite.ifName, "type", "veth", "peer", "name", pName).Run()
suite.NoError(err)
}

func TestNetworkControllerSuite(t *testing.T) {
if runtime.GOOS != "linux" {
fmt.Println("We only testing the ovs function on Linux Host")
t.Skip()
return
}
if _, defined := os.LookupEnv("TEST_GRPC"); !defined {
t.SkipNow()
return
}
suite.Run(t, new(NetworkControllerTestSuite))
}

func (suite *NetworkControllerTestSuite) TestNewNetworkController() {
network := entity.Network{
NodeName: suite.nodeName,
}

_, err := New(suite.kubectl, network)
suite.NoError(err)
}

func (suite *NetworkControllerTestSuite) TestCreateNetwork() {
//Parameters
eth1 := entity.PhysicalPort{
Name: suite.ifName,
MTU: 1500,
VlanTags: []int{2043, 2143, 2243},
}

tName := namesgenerator.GetRandomName(0)
network := entity.Network{
BridgeName: tName,
BridgeType: "ovs",
NodeName: suite.nodeName,
PhysicalPorts: []entity.PhysicalPort{eth1},
}

nc, err := New(suite.kubectl, network)
suite.NoError(err)
err = nc.CreateNetwork()
suite.NoError(err)

defer exec.Command("ovs-vsctl", "del-br", tName).Run()
}
18 changes: 16 additions & 2 deletions src/server/handler_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import (
"github.com/linkernetworks/vortex/src/entity"
response "github.com/linkernetworks/vortex/src/net/http"
"github.com/linkernetworks/vortex/src/net/http/query"
"github.com/linkernetworks/vortex/src/networkcontroller"
"github.com/linkernetworks/vortex/src/web"
mgo "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)

func createNetworkHandler(ctx *web.Context) {
as, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

network := entity.Network{}
if err := req.ReadEntity(&network); err != nil {
Expand All @@ -25,7 +26,7 @@ func createNetworkHandler(ctx *web.Context) {
return
}

session := as.Mongo.NewSession()
session := sp.Mongo.NewSession()
defer session.Close()
session.C(entity.NetworkCollectionName).EnsureIndex(mgo.Index{
Key: []string{"bridgeName", "nodeName"},
Expand All @@ -42,6 +43,19 @@ func createNetworkHandler(ctx *web.Context) {
}
}

nc, err := networkcontroller.New(sp.KubeCtl, network)
if err != nil {
logger.Errorf("Failed to new network controller: %s", err.Error())
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
}

if err := nc.CreateNetwork(); err != nil {
logger.Errorf("Failed to create network: %s", err.Error())
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
}

network.ID = bson.NewObjectId()
network.CreatedAt = timeutils.Now()
if err := session.Insert(entity.NetworkCollectionName, &network); err != nil {
Expand Down
Loading

0 comments on commit 7069fbe

Please sign in to comment.