Enable network labels in Rest API

Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
Alessandro Boch 2015-10-06 13:51:39 -07:00
parent 02386e85d5
commit 2401496d2a
7 changed files with 73 additions and 98 deletions

View File

@ -8,7 +8,6 @@ import (
"strings" "strings"
"github.com/docker/libnetwork" "github.com/docker/libnetwork"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/types" "github.com/docker/libnetwork/types"
"github.com/gorilla/mux" "github.com/gorilla/mux"
) )
@ -52,9 +51,6 @@ const (
urlSbPID = "sandbox-partial-id" urlSbPID = "sandbox-partial-id"
urlCnID = "container-id" urlCnID = "container-id"
urlCnPID = "container-partial-id" urlCnPID = "container-partial-id"
// BridgeNetworkDriver is the built-in default for Network Driver
BridgeNetworkDriver = "bridge"
) )
// NewHTTPHandler creates and initialize the HTTP handler to serve the requests for libnetwork // NewHTTPHandler creates and initialize the HTTP handler to serve the requests for libnetwork
@ -222,16 +218,6 @@ func buildSandboxResource(sb libnetwork.Sandbox) *sandboxResource {
Options Parsers Options Parsers
*****************/ *****************/
func (nc *networkCreate) parseOptions() []libnetwork.NetworkOption {
var setFctList []libnetwork.NetworkOption
if nc.Options != nil {
setFctList = append(setFctList, libnetwork.NetworkOptionGeneric(nc.Options))
}
return setFctList
}
func (sc *sandboxCreate) parseOptions() []libnetwork.SandboxOption { func (sc *sandboxCreate) parseOptions() []libnetwork.SandboxOption {
var setFctList []libnetwork.SandboxOption var setFctList []libnetwork.SandboxOption
if sc.HostName != "" { if sc.HostName != "" {
@ -278,21 +264,6 @@ func processCreateDefaults(c libnetwork.NetworkController, nc *networkCreate) {
if nc.NetworkType == "" { if nc.NetworkType == "" {
nc.NetworkType = c.Config().Daemon.DefaultDriver nc.NetworkType = c.Config().Daemon.DefaultDriver
} }
if nc.NetworkType == BridgeNetworkDriver {
if nc.Options == nil {
nc.Options = make(map[string]interface{})
}
genericData, ok := nc.Options[netlabel.GenericData]
if !ok {
genericData = make(map[string]interface{})
}
gData := genericData.(map[string]interface{})
if _, ok := gData["BridgeName"]; !ok {
gData["BridgeName"] = nc.Name
}
nc.Options[netlabel.GenericData] = genericData
}
} }
/*************************** /***************************
@ -307,7 +278,7 @@ func procCreateNetwork(c libnetwork.NetworkController, vars map[string]string, b
} }
processCreateDefaults(c, &create) processCreateDefaults(c, &create)
nw, err := c.NewNetwork(create.NetworkType, create.Name, create.parseOptions()...) nw, err := c.NewNetwork(create.NetworkType, create.Name, libnetwork.NetworkOptionLabels(create.Labels))
if err != nil { if err != nil {
return "", convertNetworkError(err) return "", convertNetworkError(err)
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/docker/docker/pkg/reexec" "github.com/docker/docker/pkg/reexec"
"github.com/docker/libnetwork" "github.com/docker/libnetwork"
"github.com/docker/libnetwork/datastore" "github.com/docker/libnetwork/datastore"
"github.com/docker/libnetwork/drivers/bridge"
"github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/options" "github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/testutils" "github.com/docker/libnetwork/testutils"
@ -26,12 +27,6 @@ const (
bridgeName = "docker0" bridgeName = "docker0"
) )
func getEmptyGenericOption() map[string]interface{} {
genericOption := make(map[string]interface{})
genericOption[netlabel.GenericData] = options.Generic{}
return genericOption
}
func i2s(i interface{}) string { func i2s(i interface{}) string {
s, ok := i.(string) s, ok := i.(string)
if !ok { if !ok {
@ -111,6 +106,22 @@ func createTestNetwork(t *testing.T, network string) (libnetwork.NetworkControll
return c, nw return c, nw
} }
func getExposedPorts() []types.TransportPort {
return []types.TransportPort{
types.TransportPort{Proto: types.TCP, Port: uint16(5000)},
types.TransportPort{Proto: types.UDP, Port: uint16(400)},
types.TransportPort{Proto: types.TCP, Port: uint16(600)},
}
}
func getPortMapping() []types.PortBinding {
return []types.PortBinding{
types.PortBinding{Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)},
types.PortBinding{Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)},
types.PortBinding{Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)},
}
}
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
if reexec.Init() { if reexec.Init() {
return return
@ -214,15 +225,11 @@ func TestCreateDeleteNetwork(t *testing.T) {
t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp) t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp)
} }
ops := options.Generic{ ops := []string{
netlabel.EnableIPv6: true, bridge.BridgeName + "=abc",
netlabel.GenericData: map[string]string{ netlabel.EnableIPv6 + "=true",
"BridgeName": "abc",
"FixedCIDRv6": "fe80::1/64",
"AddressIP": "172.28.30.254/24",
},
} }
nc := networkCreate{Name: "network_1", NetworkType: bridgeNetType, Options: ops} nc := networkCreate{Name: "network_1", NetworkType: bridgeNetType, Labels: ops}
goodBody, err := json.Marshal(nc) goodBody, err := json.Marshal(nc)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -250,6 +257,29 @@ func TestCreateDeleteNetwork(t *testing.T) {
if errRsp != &successResponse { if errRsp != &successResponse {
t.Fatalf("Unexepected failure: %v", errRsp) t.Fatalf("Unexepected failure: %v", errRsp)
} }
// Create with labels
labels := []string{
netlabel.EnableIPv6 + "=true",
bridge.BridgeName + "=abc",
}
nc = networkCreate{Name: "network_2", NetworkType: bridgeNetType, Labels: labels}
goodBody, err = json.Marshal(nc)
if err != nil {
t.Fatal(err)
}
_, errRsp = procCreateNetwork(c, vars, goodBody)
if errRsp != &createdResponse {
t.Fatalf("Unexepected failure: %v", errRsp)
}
vars[urlNwName] = "network_2"
_, errRsp = procDeleteNetwork(c, vars, nil)
if errRsp != &successResponse {
t.Fatalf("Unexepected failure: %v", errRsp)
}
} }
func TestGetNetworksAndEndpoints(t *testing.T) { func TestGetNetworksAndEndpoints(t *testing.T) {
@ -264,13 +294,10 @@ func TestGetNetworksAndEndpoints(t *testing.T) {
} }
defer c.Stop() defer c.Stop()
ops := options.Generic{ ops := []string{
netlabel.GenericData: map[string]string{ bridge.BridgeName + "=api_test_nw",
"BridgeName": "api_test_nw",
},
} }
nc := networkCreate{Name: "sh", NetworkType: bridgeNetType, Labels: ops}
nc := networkCreate{Name: "sh", NetworkType: bridgeNetType, Options: ops}
body, err := json.Marshal(nc) body, err := json.Marshal(nc)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -288,16 +315,8 @@ func TestGetNetworksAndEndpoints(t *testing.T) {
ec1 := endpointCreate{ ec1 := endpointCreate{
Name: "ep1", Name: "ep1",
ExposedPorts: []types.TransportPort{ ExposedPorts: getExposedPorts(),
types.TransportPort{Proto: types.TCP, Port: uint16(5000)}, PortMapping: getPortMapping(),
types.TransportPort{Proto: types.UDP, Port: uint16(400)},
types.TransportPort{Proto: types.TCP, Port: uint16(600)},
},
PortMapping: []types.PortBinding{
types.PortBinding{Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)},
types.PortBinding{Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)},
types.PortBinding{Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)},
},
} }
b1, err := json.Marshal(ec1) b1, err := json.Marshal(ec1)
if err != nil { if err != nil {
@ -439,10 +458,10 @@ func TestGetNetworksAndEndpoints(t *testing.T) {
nr1 := i2n(inr1) nr1 := i2n(inr1)
delete(vars, urlNwName) delete(vars, urlNwName)
vars[urlNwID] = "cacca" vars[urlNwID] = "acacac"
_, errRsp = procGetNetwork(c, vars, nil) _, errRsp = procGetNetwork(c, vars, nil)
if errRsp == &successResponse { if errRsp == &successResponse {
t.Fatalf("Unexepected failure: %v", errRsp) t.Fatalf("Expected failure. Got: %v", errRsp)
} }
vars[urlNwID] = nid vars[urlNwID] = nid
inr2, errRsp := procGetNetwork(c, vars, nil) inr2, errRsp := procGetNetwork(c, vars, nil)
@ -827,16 +846,8 @@ func TestProcPublishUnpublishService(t *testing.T) {
sp := servicePublish{ sp := servicePublish{
Name: "web", Name: "web",
Network: "network", Network: "network",
ExposedPorts: []types.TransportPort{ ExposedPorts: getExposedPorts(),
types.TransportPort{Proto: types.TCP, Port: uint16(6000)}, PortMapping: getPortMapping(),
types.TransportPort{Proto: types.UDP, Port: uint16(500)},
types.TransportPort{Proto: types.TCP, Port: uint16(700)},
},
PortMapping: []types.PortBinding{
types.PortBinding{Proto: types.TCP, Port: uint16(1230), HostPort: uint16(37000)},
types.PortBinding{Proto: types.UDP, Port: uint16(1200), HostPort: uint16(36000)},
types.PortBinding{Proto: types.TCP, Port: uint16(1120), HostPort: uint16(35000)},
},
} }
b, err = json.Marshal(sp) b, err = json.Marshal(sp)
if err != nil { if err != nil {
@ -1330,6 +1341,7 @@ func TestJoinLeave(t *testing.T) {
t.Fatalf("Expected failure, got: %v", errRsp) t.Fatalf("Expected failure, got: %v", errRsp)
} }
// bad labels
vars[urlEpName] = "endpoint" vars[urlEpName] = "endpoint"
key, errRsp := procJoinEndpoint(c, vars, jlb) key, errRsp := procJoinEndpoint(c, vars, jlb)
if errRsp != &successResponse { if errRsp != &successResponse {
@ -1818,21 +1830,14 @@ func TestEndToEnd(t *testing.T) {
handleRequest := NewHTTPHandler(c) handleRequest := NewHTTPHandler(c)
ops := options.Generic{ ops := []string{
netlabel.EnableIPv6: true, bridge.BridgeName + "=cdef",
netlabel.GenericData: map[string]string{ netlabel.EnableIPv6 + "=true",
"BridgeName": "cdef", netlabel.DriverMTU + "=1460",
"FixedCIDRv6": "fe80:2000::1/64",
"EnableIPv6": "true",
"Mtu": "1460",
"EnableIPTables": "true",
"AddressIP": "172.28.30.254/16",
"EnableUserlandProxy": "true",
},
} }
// Create network // Create network
nc := networkCreate{Name: "network-fiftyfive", NetworkType: bridgeNetType, Options: ops} nc := networkCreate{Name: "network-fiftyfive", NetworkType: bridgeNetType, Labels: ops}
body, err := json.Marshal(nc) body, err := json.Marshal(nc)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -26,7 +26,6 @@ type sandboxResource struct {
ID string `json:"id"` ID string `json:"id"`
Key string `json:"key"` Key string `json:"key"`
ContainerID string `json:"container_id"` ContainerID string `json:"container_id"`
// will add more fields once labels change is in
} }
/*********** /***********
@ -37,7 +36,7 @@ type sandboxResource struct {
type networkCreate struct { type networkCreate struct {
Name string `json:"name"` Name string `json:"name"`
NetworkType string `json:"network_type"` NetworkType string `json:"network_type"`
Options map[string]interface{} `json:"options"` Labels []string `json:"labels"`
} }
// endpointCreate represents the body of the "create endpoint" http request message // endpointCreate represents the body of the "create endpoint" http request message

View File

@ -48,8 +48,8 @@ func (cli *NetworkCli) CmdNetworkCreate(chain string, args ...string) error {
} }
// Construct network create request body // Construct network create request body
ops := make(map[string]interface{}) var labels []string
nc := networkCreate{Name: cmd.Arg(0), NetworkType: *flDriver, Options: ops} nc := networkCreate{Name: cmd.Arg(0), NetworkType: *flDriver, Labels: labels}
obj, _, err := readBody(cli.call("POST", "/networks", nc, nil)) obj, _, err := readBody(cli.call("POST", "/networks", nc, nil))
if err != nil { if err != nil {
return err return err

View File

@ -36,7 +36,7 @@ type SandboxResource struct {
type networkCreate struct { type networkCreate struct {
Name string `json:"name"` Name string `json:"name"`
NetworkType string `json:"network_type"` NetworkType string `json:"network_type"`
Options map[string]interface{} `json:"options"` Labels []string `json:"labels"`
} }
// serviceCreate represents the body of the "publish service" http request message // serviceCreate represents the body of the "publish service" http request message

View File

@ -184,7 +184,7 @@ func createDefaultNetwork(c libnetwork.NetworkController) {
if nw != "" && d != "" { if nw != "" && d != "" {
// Bridge driver is special due to legacy reasons // Bridge driver is special due to legacy reasons
if d == "bridge" { if d == "bridge" {
genericOption[netlabel.GenericData] = map[string]interface{}{ genericOption[netlabel.GenericData] = map[string]string{
"BridgeName": "docker0", "BridgeName": "docker0",
"DefaultBridge": "true", "DefaultBridge": "true",
} }

View File

@ -122,7 +122,7 @@ func TestCreateFullOptionsLabels(t *testing.T) {
netOption := make(map[string]interface{}) netOption := make(map[string]interface{})
netOption[netlabel.GenericData] = labels netOption[netlabel.GenericData] = labels
err := d.CreateNetwork("dummy", netOption, nil, nil) err := d.CreateNetwork("dummy", netOption, getIPv4Data(t), nil)
if err != nil { if err != nil {
t.Fatalf("Failed to create bridge: %v", err) t.Fatalf("Failed to create bridge: %v", err)
} }