Signed-off-by: Aidan Hobson Sayers <aidanhs@cantab.net>
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"io/ioutil" |
| 7 | 7 |
"net/http" |
| 8 |
+ "strconv" |
|
| 8 | 9 |
"strings" |
| 9 | 10 |
|
| 10 | 11 |
"github.com/docker/libnetwork" |
| ... | ... |
@@ -276,22 +277,33 @@ func procCreateNetwork(c libnetwork.NetworkController, vars map[string]string, b |
| 276 | 276 |
|
| 277 | 277 |
err := json.Unmarshal(body, &create) |
| 278 | 278 |
if err != nil {
|
| 279 |
- return "", &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest}
|
|
| 279 |
+ return nil, &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest}
|
|
| 280 | 280 |
} |
| 281 | 281 |
processCreateDefaults(c, &create) |
| 282 | 282 |
|
| 283 | 283 |
options := []libnetwork.NetworkOption{}
|
| 284 |
- if len(create.NetworkOpts) > 0 {
|
|
| 285 |
- if _, ok := create.NetworkOpts[netlabel.Internal]; ok {
|
|
| 284 |
+ if val, ok := create.NetworkOpts[netlabel.Internal]; ok {
|
|
| 285 |
+ internal, err := strconv.ParseBool(val) |
|
| 286 |
+ if err != nil {
|
|
| 287 |
+ return nil, &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest}
|
|
| 288 |
+ } |
|
| 289 |
+ if internal {
|
|
| 286 | 290 |
options = append(options, libnetwork.NetworkOptionInternalNetwork()) |
| 287 | 291 |
} |
| 288 | 292 |
} |
| 293 |
+ if val, ok := create.NetworkOpts[netlabel.EnableIPv6]; ok {
|
|
| 294 |
+ enableIPv6, err := strconv.ParseBool(val) |
|
| 295 |
+ if err != nil {
|
|
| 296 |
+ return nil, &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest}
|
|
| 297 |
+ } |
|
| 298 |
+ options = append(options, libnetwork.NetworkOptionEnableIPv6(enableIPv6)) |
|
| 299 |
+ } |
|
| 289 | 300 |
if len(create.DriverOpts) > 0 {
|
| 290 | 301 |
options = append(options, libnetwork.NetworkOptionDriverOpts(create.DriverOpts)) |
| 291 | 302 |
} |
| 292 | 303 |
nw, err := c.NewNetwork(create.NetworkType, create.Name, options...) |
| 293 | 304 |
if err != nil {
|
| 294 |
- return "", convertNetworkError(err) |
|
| 305 |
+ return nil, convertNetworkError(err) |
|
| 295 | 306 |
} |
| 296 | 307 |
|
| 297 | 308 |
return nw.ID(), &createdResponse |
| ... | ... |
@@ -225,11 +225,13 @@ func TestCreateDeleteNetwork(t *testing.T) {
|
| 225 | 225 |
t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp)
|
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 |
- ops := map[string]string{
|
|
| 229 |
- bridge.BridgeName: "abc", |
|
| 228 |
+ dops := map[string]string{
|
|
| 229 |
+ bridge.BridgeName: "abc", |
|
| 230 |
+ } |
|
| 231 |
+ nops := map[string]string{
|
|
| 230 | 232 |
netlabel.EnableIPv6: "true", |
| 231 | 233 |
} |
| 232 |
- nc := networkCreate{Name: "network_1", NetworkType: bridgeNetType, DriverOpts: ops}
|
|
| 234 |
+ nc := networkCreate{Name: "network_1", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops}
|
|
| 233 | 235 |
goodBody, err := json.Marshal(nc) |
| 234 | 236 |
if err != nil {
|
| 235 | 237 |
t.Fatal(err) |
| ... | ... |
@@ -257,29 +259,6 @@ func TestCreateDeleteNetwork(t *testing.T) {
|
| 257 | 257 |
if errRsp != &successResponse {
|
| 258 | 258 |
t.Fatalf("Unexepected failure: %v", errRsp)
|
| 259 | 259 |
} |
| 260 |
- |
|
| 261 |
- // Create with labels |
|
| 262 |
- labels := map[string]string{
|
|
| 263 |
- netlabel.EnableIPv6: "true", |
|
| 264 |
- bridge.BridgeName: "abc", |
|
| 265 |
- } |
|
| 266 |
- nc = networkCreate{Name: "network_2", NetworkType: bridgeNetType, DriverOpts: labels}
|
|
| 267 |
- goodBody, err = json.Marshal(nc) |
|
| 268 |
- if err != nil {
|
|
| 269 |
- t.Fatal(err) |
|
| 270 |
- } |
|
| 271 |
- |
|
| 272 |
- _, errRsp = procCreateNetwork(c, vars, goodBody) |
|
| 273 |
- if errRsp != &createdResponse {
|
|
| 274 |
- t.Fatalf("Unexepected failure: %v", errRsp)
|
|
| 275 |
- } |
|
| 276 |
- |
|
| 277 |
- vars[urlNwName] = "network_2" |
|
| 278 |
- _, errRsp = procDeleteNetwork(c, vars, nil) |
|
| 279 |
- if errRsp != &successResponse {
|
|
| 280 |
- t.Fatalf("Unexepected failure: %v", errRsp)
|
|
| 281 |
- } |
|
| 282 |
- |
|
| 283 | 260 |
} |
| 284 | 261 |
|
| 285 | 262 |
func TestGetNetworksAndEndpoints(t *testing.T) {
|
| ... | ... |
@@ -1830,14 +1809,16 @@ func TestEndToEnd(t *testing.T) {
|
| 1830 | 1830 |
|
| 1831 | 1831 |
handleRequest := NewHTTPHandler(c) |
| 1832 | 1832 |
|
| 1833 |
- ops := map[string]string{
|
|
| 1834 |
- bridge.BridgeName: "cdef", |
|
| 1833 |
+ dops := map[string]string{
|
|
| 1834 |
+ bridge.BridgeName: "cdef", |
|
| 1835 |
+ netlabel.DriverMTU: "1460", |
|
| 1836 |
+ } |
|
| 1837 |
+ nops := map[string]string{
|
|
| 1835 | 1838 |
netlabel.EnableIPv6: "true", |
| 1836 |
- netlabel.DriverMTU: "1460", |
|
| 1837 | 1839 |
} |
| 1838 | 1840 |
|
| 1839 | 1841 |
// Create network |
| 1840 |
- nc := networkCreate{Name: "network-fiftyfive", NetworkType: bridgeNetType, DriverOpts: ops}
|
|
| 1842 |
+ nc := networkCreate{Name: "network-fiftyfive", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops}
|
|
| 1841 | 1843 |
body, err := json.Marshal(nc) |
| 1842 | 1844 |
if err != nil {
|
| 1843 | 1845 |
t.Fatal(err) |
| ... | ... |
@@ -43,6 +43,7 @@ func (cli *NetworkCli) CmdNetworkCreate(chain string, args ...string) error {
|
| 43 | 43 |
cmd := cli.Subcmd(chain, "create", "NETWORK-NAME", "Creates a new network with a name specified by the user", false) |
| 44 | 44 |
flDriver := cmd.String([]string{"d", "-driver"}, "", "Driver to manage the Network")
|
| 45 | 45 |
flInternal := cmd.Bool([]string{"-internal"}, false, "Config the network to be internal")
|
| 46 |
+ flIPv6 := cmd.Bool([]string{"-ipv6"}, false, "Enable IPv6 on the network")
|
|
| 46 | 47 |
cmd.Require(flag.Exact, 1) |
| 47 | 48 |
err := cmd.ParseFlags(args, true) |
| 48 | 49 |
if err != nil {
|
| ... | ... |
@@ -52,6 +53,9 @@ func (cli *NetworkCli) CmdNetworkCreate(chain string, args ...string) error {
|
| 52 | 52 |
if *flInternal {
|
| 53 | 53 |
networkOpts[netlabel.Internal] = "true" |
| 54 | 54 |
} |
| 55 |
+ if *flIPv6 {
|
|
| 56 |
+ networkOpts[netlabel.EnableIPv6] = "true" |
|
| 57 |
+ } |
|
| 55 | 58 |
// Construct network create request body |
| 56 | 59 |
var driverOpts []string |
| 57 | 60 |
nc := networkCreate{Name: cmd.Arg(0), NetworkType: *flDriver, DriverOpts: driverOpts, NetworkOpts: networkOpts}
|
| ... | ... |
@@ -5,8 +5,6 @@ import ( |
| 5 | 5 |
"strconv" |
| 6 | 6 |
|
| 7 | 7 |
"github.com/docker/libnetwork/drivers/bridge" |
| 8 |
- "github.com/docker/libnetwork/netlabel" |
|
| 9 |
- "github.com/docker/libnetwork/options" |
|
| 10 | 8 |
) |
| 11 | 9 |
|
| 12 | 10 |
func (c *controller) createGWNetwork() (Network, error) {
|
| ... | ... |
@@ -17,10 +15,9 @@ func (c *controller) createGWNetwork() (Network, error) {
|
| 17 | 17 |
} |
| 18 | 18 |
|
| 19 | 19 |
n, err := c.NewNetwork("bridge", libnGWNetwork,
|
| 20 |
- NetworkOptionGeneric(options.Generic{
|
|
| 21 |
- netlabel.GenericData: netOption, |
|
| 22 |
- netlabel.EnableIPv6: false, |
|
| 23 |
- })) |
|
| 20 |
+ NetworkOptionDriverOpts(netOption), |
|
| 21 |
+ NetworkOptionEnableIPv6(false), |
|
| 22 |
+ ) |
|
| 24 | 23 |
|
| 25 | 24 |
if err != nil {
|
| 26 | 25 |
return nil, fmt.Errorf("error creating external connectivity network: %v", err)
|
| ... | ... |
@@ -45,10 +45,6 @@ func TestCreateFullOptions(t *testing.T) {
|
| 45 | 45 |
br, _ := types.ParseCIDR("172.16.0.1/16")
|
| 46 | 46 |
defgw, _ := types.ParseCIDR("172.16.0.100/16")
|
| 47 | 47 |
|
| 48 |
- netConfig := &networkConfiguration{
|
|
| 49 |
- BridgeName: DefaultBridgeName, |
|
| 50 |
- EnableIPv6: true, |
|
| 51 |
- } |
|
| 52 | 48 |
genericOption := make(map[string]interface{})
|
| 53 | 49 |
genericOption[netlabel.GenericData] = config |
| 54 | 50 |
|
| ... | ... |
@@ -57,7 +53,10 @@ func TestCreateFullOptions(t *testing.T) {
|
| 57 | 57 |
} |
| 58 | 58 |
|
| 59 | 59 |
netOption := make(map[string]interface{})
|
| 60 |
- netOption[netlabel.GenericData] = netConfig |
|
| 60 |
+ netOption[netlabel.EnableIPv6] = true |
|
| 61 |
+ netOption[netlabel.GenericData] = &networkConfiguration{
|
|
| 62 |
+ BridgeName: DefaultBridgeName, |
|
| 63 |
+ } |
|
| 61 | 64 |
|
| 62 | 65 |
ipdList := []driverapi.IPAMData{
|
| 63 | 66 |
driverapi.IPAMData{
|
| ... | ... |
@@ -118,15 +117,15 @@ func TestCreateFullOptionsLabels(t *testing.T) {
|
| 118 | 118 |
gwV6, _ := types.ParseCIDR(gwV6s) |
| 119 | 119 |
|
| 120 | 120 |
labels := map[string]string{
|
| 121 |
- BridgeName: DefaultBridgeName, |
|
| 122 |
- DefaultBridge: "true", |
|
| 123 |
- netlabel.EnableIPv6: "true", |
|
| 124 |
- EnableICC: "true", |
|
| 125 |
- EnableIPMasquerade: "true", |
|
| 126 |
- DefaultBindingIP: bndIPs, |
|
| 121 |
+ BridgeName: DefaultBridgeName, |
|
| 122 |
+ DefaultBridge: "true", |
|
| 123 |
+ EnableICC: "true", |
|
| 124 |
+ EnableIPMasquerade: "true", |
|
| 125 |
+ DefaultBindingIP: bndIPs, |
|
| 127 | 126 |
} |
| 128 | 127 |
|
| 129 | 128 |
netOption := make(map[string]interface{})
|
| 129 |
+ netOption[netlabel.EnableIPv6] = true |
|
| 130 | 130 |
netOption[netlabel.GenericData] = labels |
| 131 | 131 |
|
| 132 | 132 |
ipdList := getIPv4Data(t) |
| ... | ... |
@@ -783,13 +782,13 @@ func TestSetDefaultGw(t *testing.T) {
|
| 783 | 783 |
|
| 784 | 784 |
config := &networkConfiguration{
|
| 785 | 785 |
BridgeName: DefaultBridgeName, |
| 786 |
- EnableIPv6: true, |
|
| 787 | 786 |
AddressIPv6: subnetv6, |
| 788 | 787 |
DefaultGatewayIPv4: gw4, |
| 789 | 788 |
DefaultGatewayIPv6: gw6, |
| 790 | 789 |
} |
| 791 | 790 |
|
| 792 | 791 |
genericOption := make(map[string]interface{})
|
| 792 |
+ genericOption[netlabel.EnableIPv6] = true |
|
| 793 | 793 |
genericOption[netlabel.GenericData] = config |
| 794 | 794 |
|
| 795 | 795 |
err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
| ... | ... |
@@ -269,9 +269,9 @@ func TestBridge(t *testing.T) {
|
| 269 | 269 |
} |
| 270 | 270 |
|
| 271 | 271 |
netOption := options.Generic{
|
| 272 |
+ netlabel.EnableIPv6: true, |
|
| 272 | 273 |
netlabel.GenericData: options.Generic{
|
| 273 | 274 |
"BridgeName": "testnetwork", |
| 274 |
- "EnableIPv6": true, |
|
| 275 | 275 |
"EnableICC": true, |
| 276 | 276 |
"EnableIPMasquerade": true, |
| 277 | 277 |
}, |
| ... | ... |
@@ -323,7 +323,6 @@ func TestBridgeIpv6FromMac(t *testing.T) {
|
| 323 | 323 |
netOption := options.Generic{
|
| 324 | 324 |
netlabel.GenericData: options.Generic{
|
| 325 | 325 |
"BridgeName": "testipv6mac", |
| 326 |
- "EnableIPv6": true, |
|
| 327 | 326 |
"EnableICC": true, |
| 328 | 327 |
"EnableIPMasquerade": true, |
| 329 | 328 |
}, |
| ... | ... |
@@ -333,6 +332,7 @@ func TestBridgeIpv6FromMac(t *testing.T) {
|
| 333 | 333 |
|
| 334 | 334 |
network, err := controller.NewNetwork(bridgeNetType, "testipv6mac", |
| 335 | 335 |
libnetwork.NetworkOptionGeneric(netOption), |
| 336 |
+ libnetwork.NetworkOptionEnableIPv6(true), |
|
| 336 | 337 |
libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4ConfList, ipamV6ConfList, nil), |
| 337 | 338 |
libnetwork.NetworkOptionDeferIPv6Alloc(true)) |
| 338 | 339 |
if err != nil {
|
| ... | ... |
@@ -1008,7 +1008,6 @@ func TestEndpointJoin(t *testing.T) {
|
| 1008 | 1008 |
netOption := options.Generic{
|
| 1009 | 1009 |
netlabel.GenericData: options.Generic{
|
| 1010 | 1010 |
"BridgeName": "testnetwork1", |
| 1011 |
- "EnableIPv6": true, |
|
| 1012 | 1011 |
"EnableICC": true, |
| 1013 | 1012 |
"EnableIPMasquerade": true, |
| 1014 | 1013 |
}, |
| ... | ... |
@@ -1016,6 +1015,7 @@ func TestEndpointJoin(t *testing.T) {
|
| 1016 | 1016 |
ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe90::/64", Gateway: "fe90::22"}}
|
| 1017 | 1017 |
n1, err := controller.NewNetwork(bridgeNetType, "testnetwork1", |
| 1018 | 1018 |
libnetwork.NetworkOptionGeneric(netOption), |
| 1019 |
+ libnetwork.NetworkOptionEnableIPv6(true), |
|
| 1019 | 1020 |
libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", nil, ipamV6ConfList, nil), |
| 1020 | 1021 |
libnetwork.NetworkOptionDeferIPv6Alloc(true)) |
| 1021 | 1022 |
if err != nil {
|
| ... | ... |
@@ -4,7 +4,6 @@ import ( |
| 4 | 4 |
"encoding/json" |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"net" |
| 7 |
- "strconv" |
|
| 8 | 7 |
"strings" |
| 9 | 8 |
"sync" |
| 10 | 9 |
|
| ... | ... |
@@ -476,9 +475,17 @@ type NetworkOption func(n *network) |
| 476 | 476 |
// in a Dictionary of Key-Value pair |
| 477 | 477 |
func NetworkOptionGeneric(generic map[string]interface{}) NetworkOption {
|
| 478 | 478 |
return func(n *network) {
|
| 479 |
- n.generic = generic |
|
| 480 |
- if _, ok := generic[netlabel.EnableIPv6]; ok {
|
|
| 481 |
- n.enableIPv6 = generic[netlabel.EnableIPv6].(bool) |
|
| 479 |
+ if n.generic == nil {
|
|
| 480 |
+ n.generic = make(map[string]interface{})
|
|
| 481 |
+ } |
|
| 482 |
+ if val, ok := generic[netlabel.EnableIPv6]; ok {
|
|
| 483 |
+ n.enableIPv6 = val.(bool) |
|
| 484 |
+ } |
|
| 485 |
+ if val, ok := generic[netlabel.Internal]; ok {
|
|
| 486 |
+ n.internal = val.(bool) |
|
| 487 |
+ } |
|
| 488 |
+ for k, v := range generic {
|
|
| 489 |
+ n.generic[k] = v |
|
| 482 | 490 |
} |
| 483 | 491 |
} |
| 484 | 492 |
} |
| ... | ... |
@@ -490,14 +497,25 @@ func NetworkOptionPersist(persist bool) NetworkOption {
|
| 490 | 490 |
} |
| 491 | 491 |
} |
| 492 | 492 |
|
| 493 |
+// NetworkOptionEnableIPv6 returns an option setter to explicitly configure IPv6 |
|
| 494 |
+func NetworkOptionEnableIPv6(enableIPv6 bool) NetworkOption {
|
|
| 495 |
+ return func(n *network) {
|
|
| 496 |
+ if n.generic == nil {
|
|
| 497 |
+ n.generic = make(map[string]interface{})
|
|
| 498 |
+ } |
|
| 499 |
+ n.enableIPv6 = enableIPv6 |
|
| 500 |
+ n.generic[netlabel.EnableIPv6] = enableIPv6 |
|
| 501 |
+ } |
|
| 502 |
+} |
|
| 503 |
+ |
|
| 493 | 504 |
// NetworkOptionInternalNetwork returns an option setter to config the network |
| 494 | 505 |
// to be internal which disables default gateway service |
| 495 | 506 |
func NetworkOptionInternalNetwork() NetworkOption {
|
| 496 | 507 |
return func(n *network) {
|
| 497 |
- n.internal = true |
|
| 498 | 508 |
if n.generic == nil {
|
| 499 | 509 |
n.generic = make(map[string]interface{})
|
| 500 | 510 |
} |
| 511 |
+ n.internal = true |
|
| 501 | 512 |
n.generic[netlabel.Internal] = true |
| 502 | 513 |
} |
| 503 | 514 |
} |
| ... | ... |
@@ -526,13 +544,6 @@ func NetworkOptionDriverOpts(opts map[string]string) NetworkOption {
|
| 526 | 526 |
} |
| 527 | 527 |
// Store the options |
| 528 | 528 |
n.generic[netlabel.GenericData] = opts |
| 529 |
- // Decode and store the endpoint options of libnetwork interest |
|
| 530 |
- if val, ok := opts[netlabel.EnableIPv6]; ok {
|
|
| 531 |
- var err error |
|
| 532 |
- if n.enableIPv6, err = strconv.ParseBool(val); err != nil {
|
|
| 533 |
- log.Warnf("Failed to parse %s' value: %s (%s)", netlabel.EnableIPv6, val, err.Error())
|
|
| 534 |
- } |
|
| 535 |
- } |
|
| 536 | 529 |
} |
| 537 | 530 |
} |
| 538 | 531 |
|