Skip to content

Commit 5f7a24a

Browse files
author
Fawad Khaliq
authored
Merge pull request #44 from plumgrid/sagheer-dev
adding new bridge option along with support for metaconfig
2 parents 14c8669 + de49687 commit 5f7a24a

5 files changed

Lines changed: 130 additions & 15 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ PLUGIN_VERSION=git-$(shell git rev-parse --short=12 HEAD)
77

88
$(PLUGIN_EXE): plugin/main.go plugin/driver/*.go
99
go get -tags netgo ./$(@D)
10-
go build -ldflags "-extldflags \"-static\" -X main.version $(PLUGIN_VERSION)" -tags netgo -o $@ ./$(@D)
10+
go build -ldflags "-extldflags \"-static\" -X main.version=$(PLUGIN_VERSION)" -tags netgo -o $@ ./$(@D)
1111
@strings $@ | grep cgo_stub\\\.go >/dev/null || { \
1212
rm $@; \
1313
echo "\nGo standard library is built without the 'netgo' build tag."; \

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ this is entirely optional and depending on your use case, you may use it.
3535
$ docker network create --subnet=10.0.0.0/24 -d plumgrid -o router=router-1 net1
3636
```
3737

38+
You can also choose to link the network to a specific bridge in PLUMgrid virtual domain,
39+
this also is optional and can be used depending upon your use case.
40+
```
41+
$ docker network create --subnet=10.0.0.0/24 -d plumgrid -o bridge=bridge-1 net1
42+
```
43+
3844
Run your containers using the Docker CLI
3945
```
4046
$ docker run -itd --name=cont1 --net=net1 busybox

plugin/driver/driver.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
Log "github.com/Sirupsen/logrus"
2828
"github.com/docker/libnetwork/drivers/remote/api"
29+
"github.com/docker/libnetwork/netlabel"
2930
docker "github.com/fsouza/go-dockerclient"
3031

3132
"github.com/gorilla/mux"
@@ -128,13 +129,25 @@ func (driver *driver) createNetwork(w http.ResponseWriter, r *http.Request) {
128129
}
129130
Log.Infof("Create network request %+v", &create)
130131

131-
domainid := create.Options["com.docker.network.generic"].(map[string]interface{})["domain"]
132+
domainid := create.Options[netlabel.GenericData].(map[string]interface{})["domain"]
132133
if domainid == nil {
133134
domainid = default_vd
134135
}
135136
DomainCreate(domainid.(string))
136-
router := create.Options["com.docker.network.generic"].(map[string]interface{})["router"]
137+
137138
gatewayip := create.IPv4Data[0].Gateway.IP.String()
139+
neName := create.Options[netlabel.GenericData].(map[string]interface{})["bridge"]
140+
141+
if neName != nil {
142+
neID := GetNeId(neName.(string), domainid.(string))
143+
AddNetworkInfo(create.NetworkID, neID)
144+
AddGatewayInfo(create.NetworkID, domainid.(string), gatewayip)
145+
emptyResponse(w)
146+
147+
return
148+
}
149+
150+
router := create.Options[netlabel.GenericData].(map[string]interface{})["router"]
138151
BridgeCreate(create.NetworkID, domainid.(string), gatewayip)
139152

140153
if router != nil {
@@ -160,7 +173,7 @@ func (driver *driver) deleteNetwork(w http.ResponseWriter, r *http.Request) {
160173
}
161174
Log.Infof("Delete network request: %+v", &delete)
162175

163-
domainid := FindDomainFromNetwork(delete.NetworkID)
176+
domainid, _ := FindDomainFromNetwork(delete.NetworkID)
164177
if domainid == "" {
165178
domainid = default_vd
166179
}
@@ -229,7 +242,7 @@ func (driver *driver) joinEndpoint(w http.ResponseWriter, r *http.Request) {
229242

230243
netID := j.NetworkID
231244
endID := j.EndpointID
232-
domainid := FindDomainFromNetwork(netID)
245+
domainid, bridgeID := FindDomainFromNetwork(netID)
233246
if domainid == "" {
234247
domainid = default_vd
235248
}
@@ -270,7 +283,7 @@ func (driver *driver) joinEndpoint(w http.ResponseWriter, r *http.Request) {
270283
Log.Infof("output of cmd: %+v\n", out1.String())
271284

272285
//second command {up the port on plumgrid}
273-
cmdStr2 := "sudo /opt/pg/bin/ifc_ctl gateway ifup " + if_local_name + " access_container cont_" + endID[:2] + " " + mac[:17] + " pgtag2=bridge-" + netID[:10] + " pgtag1=" + domainid
286+
cmdStr2 := "sudo /opt/pg/bin/ifc_ctl gateway ifup " + if_local_name + " access_container cont_" + endID[:2] + " " + mac[:17] + " pgtag2=" + bridgeID + " pgtag1=" + domainid
274287
Log.Infof("third cmd: %s", cmdStr2)
275288
cmd2 := exec.Command("/bin/sh", "-c", cmdStr2)
276289
var out2 bytes.Buffer
@@ -296,6 +309,8 @@ func (driver *driver) joinEndpoint(w http.ResponseWriter, r *http.Request) {
296309
Gateway: gatewayIP,
297310
}
298311

312+
AddMetaconfig(domainid, bridgeID, j.SandboxKey[22:], endID, mac[:17])
313+
299314
objectResponse(w, res)
300315
Log.Infof("Join endpoint %s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)
301316
}
@@ -309,6 +324,8 @@ func (driver *driver) leaveEndpoint(w http.ResponseWriter, r *http.Request) {
309324
}
310325
Log.Infof("Leave request: %+v", &l)
311326

327+
domainid, bridgeID := FindDomainFromNetwork(l.NetworkID)
328+
312329
if_local_name := "tap" + l.EndpointID[:5]
313330

314331
//first command {adding port on plumgrid}
@@ -339,6 +356,9 @@ func (driver *driver) leaveEndpoint(w http.ResponseWriter, r *http.Request) {
339356
if err := netlink.LinkDel(local); err != nil {
340357
Log.Warningf("unable to delete veth on leave: %s", err)
341358
}
359+
360+
RemoveMetaconfig(domainid, bridgeID, l.EndpointID)
361+
342362
emptyResponse(w)
343363
Log.Infof("Leave %s:%s", l.NetworkID, l.EndpointID)
344364
}

plugin/driver/pg_helper.go

Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func BridgeCreate(ID string, domainid string, gatewayip string) {
2727
"action_text": "create_and_link_ifc(DYN_1)"}
2828
},
2929
"ifc": {},
30+
"metadata": "` + ID + `",
3031
"mobility": "true",
3132
"ne_description": "PLUMgrid Bridge",
3233
"ne_dname": "net-` + ID[:10] + `",
@@ -45,7 +46,7 @@ func BridgeCreate(ID string, domainid string, gatewayip string) {
4546
"rules` + ID + `": {
4647
"add_context": "",
4748
"criteria": "pgtag2",
48-
"match": "bridge-` + ID[:10] + `"
49+
"match": "bri` + ID + `"
4950
}
5051
}
5152
}`)
@@ -57,6 +58,13 @@ func BridgeCreate(ID string, domainid string, gatewayip string) {
5758
RestCall("PUT", url, data)
5859
}
5960

61+
func AddGatewayInfo(ID string, domainid string, gatewayip string) {
62+
63+
url := "/0/connectivity/domain_prop/" + domainid + "/ne/brii" + ID
64+
data := []byte(`{"ne_metadata": "` + gatewayip + `"}`)
65+
RestCall("PUT", url, data)
66+
}
67+
6068
func BridgeDelete(ID string, domainid string) {
6169

6270
url := "/0/connectivity/domain_prop/" + domainid + "/ne/brii" + ID
@@ -69,7 +77,7 @@ func BridgeDelete(ID string, domainid string) {
6977
RestCall("DELETE", url, nil)
7078
}
7179

72-
func FindDomainFromNetwork(ID string) (domainid string) {
80+
func AddNetworkInfo(dNetwork string, neID string) {
7381

7482
url := "/0/connectivity/domain?configonly=true&level=3"
7583
body, _ := RestCall("GET", url, nil)
@@ -80,12 +88,36 @@ func FindDomainFromNetwork(ID string) (domainid string) {
8088
}
8189
for domains, domain_val := range domain_data {
8290
if nes, ok := domain_val.(map[string]interface{})["ne"]; ok {
83-
if _, ok := nes.(map[string]interface{})["bri"+ID]; ok {
84-
domainid = domains
91+
if ne, ok := nes.(map[string]interface{})[neID]; ok {
92+
ne.(map[string]interface{})["metadata"] = dNetwork
93+
ne_data, _ := json.Marshal(ne)
94+
RestCall("PUT", "/0/connectivity/domain/"+domains+"/ne/"+neID, ne_data)
8595
break
8696
}
8797
}
8898
}
99+
}
100+
101+
func FindDomainFromNetwork(ID string) (domainid string, netid string) {
102+
103+
url := "/0/connectivity/domain?configonly=true&level=3"
104+
body, _ := RestCall("GET", url, nil)
105+
var domain_data map[string]interface{}
106+
err := json.Unmarshal([]byte(body), &domain_data)
107+
if err != nil {
108+
panic(err)
109+
}
110+
for domains, domain_val := range domain_data {
111+
if nes, ok := domain_val.(map[string]interface{})["ne"]; ok {
112+
for ne, data := range nes.(map[string]interface{}) {
113+
if data.(map[string]interface{})["metadata"] == ID {
114+
domainid = domains
115+
netid = ne
116+
break
117+
}
118+
}
119+
}
120+
}
89121
return
90122
}
91123

@@ -121,12 +153,12 @@ func DomainCreate(domainID string) {
121153
data := []byte(`{"containers": {
122154
"` + domainID + `": {
123155
"enable": "True",
124-
"qos_marking": "9",
125156
"context": "` + domainID + `",
126-
"type": "Gold",
127-
"property": "Container ` + domainID + ` Property",
128157
"domains": {}, "rules": {}}}}`)
158+
RestCall("PUT", url, data)
129159

160+
url = "/0/tenant_manager/metaconfig/" + domainID
161+
data = []byte(`{}`)
130162
RestCall("PUT", url, data)
131163

132164
url = "/0/tunnel_service/vnd_config/" + domainID
@@ -178,7 +210,10 @@ func DomainDelete(domainID string) {
178210
url = "/0/tunnel_service/vnd_config/" + domainID
179211
RestCall("DELETE", url, nil)
180212

181-
url = "/0/tenant_manager/tenants" + "/" + domainID
213+
url = "/0/tenant_manager/metaconfig/" + domainID
214+
RestCall("DELETE", url, nil)
215+
216+
url = "/0/tenant_manager/tenants/" + domainID
182217
RestCall("DELETE", url, nil)
183218
}
184219
}
@@ -295,3 +330,57 @@ func CheckNeChildList(NeID string, DomainID string, childList string) {
295330
return
296331
}
297332
}
333+
334+
func AddMetaconfig(domainID string, netID string, deviceID string, endpointID string, macaddr string) {
335+
336+
url := "/0/tenant_manager/metaconfig/" + domainID + "?configonly=true"
337+
body, _ := RestCall("GET", url, nil)
338+
var tm_data map[string]interface{}
339+
err := json.Unmarshal([]byte(body), &tm_data)
340+
if err != nil {
341+
panic(err)
342+
}
343+
344+
for device, _ := range tm_data["workloads"].(map[string]interface{}) {
345+
if device == deviceID {
346+
url = "/0/tenant_manager/metaconfig/" + domainID + "/workloads/" + deviceID + "/prop/" + endpointID
347+
data := []byte(`{"phy_address": "` + macaddr + `",
348+
"hint": "` + netID + `"}`)
349+
RestCall("PUT", url, data)
350+
return
351+
}
352+
}
353+
354+
url = "/0/tenant_manager/metaconfig/" + domainID + "/workloads/" + deviceID
355+
data := []byte(`{"ne_type": "container",
356+
"prop": {
357+
"` + endpointID + `": {
358+
"phy_address": "` + macaddr + `",
359+
"hint": "` + netID + `"}}}`)
360+
RestCall("PUT", url, data)
361+
}
362+
363+
func RemoveMetaconfig(domainID string, netID string, endpointID string) {
364+
365+
url := "/0/tenant_manager/metaconfig/" + domainID + "?configonly=true"
366+
body, _ := RestCall("GET", url, nil)
367+
var tm_data map[string]interface{}
368+
err := json.Unmarshal([]byte(body), &tm_data)
369+
if err != nil {
370+
panic(err)
371+
}
372+
373+
for device, prop := range tm_data["workloads"].(map[string]interface{}) {
374+
for endpoint, _ := range prop.(map[string]interface{})["prop"].(map[string]interface{}) {
375+
if endpoint == endpointID {
376+
if len(prop.(map[string]interface{})["prop"].(map[string]interface{})) < 2 {
377+
url = "/0/tenant_manager/metaconfig/" + domainID + "/workloads/" + device
378+
RestCall("DELETE", url, nil)
379+
return
380+
}
381+
url = "/0/tenant_manager/metaconfig/" + domainID + "/workloads/" + device + "/prop/" + endpoint
382+
RestCall("DELETE", url, nil)
383+
}
384+
}
385+
}
386+
}

plugin/driver/rest_conn.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func RestHelper(method string, uri string, data []byte) ([]byte, error) {
7777
url := "https://" + vip
7878

7979
rest_url := url + uri
80-
Log.Info("URL:>", rest_url)
80+
Log.Infof("%s call on %s", method, rest_url)
8181

8282
req, err := http.NewRequest(method, rest_url, bytes.NewBuffer(data))
8383
req.Header.Set("Accept", "application/json")

0 commit comments

Comments
 (0)