Signed-off-by: David Calavera <david.calavera@gmail.com>
| ... | ... |
@@ -1,6 +1,8 @@ |
| 1 | 1 |
package network |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "github.com/docker/engine-api/types" |
|
| 5 |
+ "github.com/docker/engine-api/types/filters" |
|
| 4 | 6 |
"github.com/docker/engine-api/types/network" |
| 5 | 7 |
"github.com/docker/libnetwork" |
| 6 | 8 |
) |
| ... | ... |
@@ -11,8 +13,8 @@ type Backend interface {
|
| 11 | 11 |
FindNetwork(idName string) (libnetwork.Network, error) |
| 12 | 12 |
GetNetworkByName(idName string) (libnetwork.Network, error) |
| 13 | 13 |
GetNetworksByID(partialID string) []libnetwork.Network |
| 14 |
- GetAllNetworks() []libnetwork.Network |
|
| 15 |
- CreateNetwork(name, driver string, ipam network.IPAM, options map[string]string, labels map[string]string, internal bool, enableIPv6 bool) (libnetwork.Network, error) |
|
| 14 |
+ FilterNetworks(netFilters filters.Args) ([]libnetwork.Network, error) |
|
| 15 |
+ CreateNetwork(types.NetworkCreate) (*types.NetworkCreateResponse, error) |
|
| 16 | 16 |
ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error |
| 17 | 17 |
DisconnectContainerFromNetwork(containerName string, network libnetwork.Network, force bool) error |
| 18 | 18 |
DeleteNetwork(name string) error |
| 19 | 19 |
deleted file mode 100644 |
| ... | ... |
@@ -1,110 +0,0 @@ |
| 1 |
-package network |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "fmt" |
|
| 5 |
- "regexp" |
|
| 6 |
- "strings" |
|
| 7 |
- |
|
| 8 |
- "github.com/docker/docker/runconfig" |
|
| 9 |
- "github.com/docker/engine-api/types/filters" |
|
| 10 |
- "github.com/docker/libnetwork" |
|
| 11 |
-) |
|
| 12 |
- |
|
| 13 |
-type filterHandler func([]libnetwork.Network, string) ([]libnetwork.Network, error) |
|
| 14 |
- |
|
| 15 |
-var ( |
|
| 16 |
- // supportedFilters predefined some supported filter handler function |
|
| 17 |
- supportedFilters = map[string]filterHandler{
|
|
| 18 |
- "type": filterNetworkByType, |
|
| 19 |
- "name": filterNetworkByName, |
|
| 20 |
- "id": filterNetworkByID, |
|
| 21 |
- } |
|
| 22 |
- |
|
| 23 |
- // acceptFilters is an acceptable filter flag list |
|
| 24 |
- // generated for validation. e.g. |
|
| 25 |
- // acceptedFilters = map[string]bool{
|
|
| 26 |
- // "type": true, |
|
| 27 |
- // "name": true, |
|
| 28 |
- // "id": true, |
|
| 29 |
- // } |
|
| 30 |
- acceptedFilters = func() map[string]bool {
|
|
| 31 |
- ret := make(map[string]bool) |
|
| 32 |
- for k := range supportedFilters {
|
|
| 33 |
- ret[k] = true |
|
| 34 |
- } |
|
| 35 |
- return ret |
|
| 36 |
- }() |
|
| 37 |
-) |
|
| 38 |
- |
|
| 39 |
-func filterNetworkByType(nws []libnetwork.Network, netType string) (retNws []libnetwork.Network, err error) {
|
|
| 40 |
- switch netType {
|
|
| 41 |
- case "builtin": |
|
| 42 |
- for _, nw := range nws {
|
|
| 43 |
- if runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 44 |
- retNws = append(retNws, nw) |
|
| 45 |
- } |
|
| 46 |
- } |
|
| 47 |
- case "custom": |
|
| 48 |
- for _, nw := range nws {
|
|
| 49 |
- if !runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 50 |
- retNws = append(retNws, nw) |
|
| 51 |
- } |
|
| 52 |
- } |
|
| 53 |
- default: |
|
| 54 |
- return nil, fmt.Errorf("Invalid filter: 'type'='%s'", netType)
|
|
| 55 |
- } |
|
| 56 |
- return retNws, nil |
|
| 57 |
-} |
|
| 58 |
- |
|
| 59 |
-func filterNetworkByName(nws []libnetwork.Network, name string) (retNws []libnetwork.Network, err error) {
|
|
| 60 |
- for _, nw := range nws {
|
|
| 61 |
- // exact match (fast path) |
|
| 62 |
- if nw.Name() == name {
|
|
| 63 |
- retNws = append(retNws, nw) |
|
| 64 |
- continue |
|
| 65 |
- } |
|
| 66 |
- |
|
| 67 |
- // regexp match (slow path) |
|
| 68 |
- match, err := regexp.MatchString(name, nw.Name()) |
|
| 69 |
- if err != nil || !match {
|
|
| 70 |
- continue |
|
| 71 |
- } else {
|
|
| 72 |
- retNws = append(retNws, nw) |
|
| 73 |
- } |
|
| 74 |
- } |
|
| 75 |
- return retNws, nil |
|
| 76 |
-} |
|
| 77 |
- |
|
| 78 |
-func filterNetworkByID(nws []libnetwork.Network, id string) (retNws []libnetwork.Network, err error) {
|
|
| 79 |
- for _, nw := range nws {
|
|
| 80 |
- if strings.HasPrefix(nw.ID(), id) {
|
|
| 81 |
- retNws = append(retNws, nw) |
|
| 82 |
- } |
|
| 83 |
- } |
|
| 84 |
- return retNws, nil |
|
| 85 |
-} |
|
| 86 |
- |
|
| 87 |
-// filterAllNetworks filters network list according to user specified filter |
|
| 88 |
-// and returns user chosen networks |
|
| 89 |
-func filterNetworks(nws []libnetwork.Network, filter filters.Args) ([]libnetwork.Network, error) {
|
|
| 90 |
- // if filter is empty, return original network list |
|
| 91 |
- if filter.Len() == 0 {
|
|
| 92 |
- return nws, nil |
|
| 93 |
- } |
|
| 94 |
- |
|
| 95 |
- var displayNet []libnetwork.Network |
|
| 96 |
- for fkey, fhandler := range supportedFilters {
|
|
| 97 |
- errFilter := filter.WalkValues(fkey, func(fval string) error {
|
|
| 98 |
- passList, err := fhandler(nws, fval) |
|
| 99 |
- if err != nil {
|
|
| 100 |
- return err |
|
| 101 |
- } |
|
| 102 |
- displayNet = append(displayNet, passList...) |
|
| 103 |
- return nil |
|
| 104 |
- }) |
|
| 105 |
- if errFilter != nil {
|
|
| 106 |
- return nil, errFilter |
|
| 107 |
- } |
|
| 108 |
- } |
|
| 109 |
- return displayNet, nil |
|
| 110 |
-} |
| ... | ... |
@@ -2,13 +2,11 @@ package network |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"encoding/json" |
| 5 |
- "fmt" |
|
| 6 | 5 |
"net/http" |
| 7 | 6 |
|
| 8 | 7 |
"golang.org/x/net/context" |
| 9 | 8 |
|
| 10 | 9 |
"github.com/docker/docker/api/server/httputils" |
| 11 |
- "github.com/docker/docker/runconfig" |
|
| 12 | 10 |
"github.com/docker/engine-api/types" |
| 13 | 11 |
"github.com/docker/engine-api/types/filters" |
| 14 | 12 |
"github.com/docker/engine-api/types/network" |
| ... | ... |
@@ -26,21 +24,14 @@ func (n *networkRouter) getNetworksList(ctx context.Context, w http.ResponseWrit |
| 26 | 26 |
return err |
| 27 | 27 |
} |
| 28 | 28 |
|
| 29 |
- if netFilters.Len() != 0 {
|
|
| 30 |
- if err := netFilters.Validate(acceptedFilters); err != nil {
|
|
| 31 |
- return err |
|
| 32 |
- } |
|
| 33 |
- } |
|
| 34 |
- |
|
| 35 | 29 |
list := []*types.NetworkResource{}
|
| 36 | 30 |
|
| 37 |
- nwList := n.backend.GetAllNetworks() |
|
| 38 |
- displayable, err := filterNetworks(nwList, netFilters) |
|
| 31 |
+ nwList, err := n.backend.FilterNetworks(netFilters) |
|
| 39 | 32 |
if err != nil {
|
| 40 | 33 |
return err |
| 41 | 34 |
} |
| 42 | 35 |
|
| 43 |
- for _, nw := range displayable {
|
|
| 36 |
+ for _, nw := range nwList {
|
|
| 44 | 37 |
list = append(list, buildNetworkResource(nw)) |
| 45 | 38 |
} |
| 46 | 39 |
|
| ... | ... |
@@ -61,7 +52,6 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r |
| 61 | 61 |
|
| 62 | 62 |
func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| 63 | 63 |
var create types.NetworkCreate |
| 64 |
- var warning string |
|
| 65 | 64 |
|
| 66 | 65 |
if err := httputils.ParseForm(r); err != nil {
|
| 67 | 66 |
return err |
| ... | ... |
@@ -75,31 +65,12 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr |
| 75 | 75 |
return err |
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 |
- if runconfig.IsPreDefinedNetwork(create.Name) {
|
|
| 79 |
- return httputils.WriteJSON(w, http.StatusForbidden, |
|
| 80 |
- fmt.Sprintf("%s is a pre-defined network and cannot be created", create.Name))
|
|
| 81 |
- } |
|
| 82 |
- |
|
| 83 |
- nw, err := n.backend.GetNetworkByName(create.Name) |
|
| 84 |
- if _, ok := err.(libnetwork.ErrNoSuchNetwork); err != nil && !ok {
|
|
| 85 |
- return err |
|
| 86 |
- } |
|
| 87 |
- if nw != nil {
|
|
| 88 |
- if create.CheckDuplicate {
|
|
| 89 |
- return libnetwork.NetworkNameError(create.Name) |
|
| 90 |
- } |
|
| 91 |
- warning = fmt.Sprintf("Network with name %s (id : %s) already exists", nw.Name(), nw.ID())
|
|
| 92 |
- } |
|
| 93 |
- |
|
| 94 |
- nw, err = n.backend.CreateNetwork(create.Name, create.Driver, create.IPAM, create.Options, create.Labels, create.Internal, create.EnableIPv6) |
|
| 78 |
+ nw, err := n.backend.CreateNetwork(create) |
|
| 95 | 79 |
if err != nil {
|
| 96 | 80 |
return err |
| 97 | 81 |
} |
| 98 | 82 |
|
| 99 |
- return httputils.WriteJSON(w, http.StatusCreated, &types.NetworkCreateResponse{
|
|
| 100 |
- ID: nw.ID(), |
|
| 101 |
- Warning: warning, |
|
| 102 |
- }) |
|
| 83 |
+ return httputils.WriteJSON(w, http.StatusCreated, nw) |
|
| 103 | 84 |
} |
| 104 | 85 |
|
| 105 | 86 |
func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| ... | ... |
@@ -6,8 +6,11 @@ import ( |
| 6 | 6 |
"net/http" |
| 7 | 7 |
"strings" |
| 8 | 8 |
|
| 9 |
+ netsettings "github.com/docker/docker/daemon/network" |
|
| 9 | 10 |
"github.com/docker/docker/errors" |
| 10 | 11 |
"github.com/docker/docker/runconfig" |
| 12 |
+ "github.com/docker/engine-api/types" |
|
| 13 |
+ "github.com/docker/engine-api/types/filters" |
|
| 11 | 14 |
"github.com/docker/engine-api/types/network" |
| 12 | 15 |
"github.com/docker/libnetwork" |
| 13 | 16 |
) |
| ... | ... |
@@ -77,8 +80,8 @@ func (daemon *Daemon) GetNetworksByID(partialID string) []libnetwork.Network {
|
| 77 | 77 |
return list |
| 78 | 78 |
} |
| 79 | 79 |
|
| 80 |
-// GetAllNetworks returns a list containing all networks |
|
| 81 |
-func (daemon *Daemon) GetAllNetworks() []libnetwork.Network {
|
|
| 80 |
+// getAllNetworks returns a list containing all networks |
|
| 81 |
+func (daemon *Daemon) getAllNetworks() []libnetwork.Network {
|
|
| 82 | 82 |
c := daemon.netController |
| 83 | 83 |
list := []libnetwork.Network{}
|
| 84 | 84 |
l := func(nw libnetwork.Network) bool {
|
| ... | ... |
@@ -91,12 +94,33 @@ func (daemon *Daemon) GetAllNetworks() []libnetwork.Network {
|
| 91 | 91 |
} |
| 92 | 92 |
|
| 93 | 93 |
// CreateNetwork creates a network with the given name, driver and other optional parameters |
| 94 |
-func (daemon *Daemon) CreateNetwork(name, driver string, ipam network.IPAM, netOption map[string]string, labels map[string]string, internal bool, enableIPv6 bool) (libnetwork.Network, error) {
|
|
| 94 |
+func (daemon *Daemon) CreateNetwork(create types.NetworkCreate) (*types.NetworkCreateResponse, error) {
|
|
| 95 |
+ if runconfig.IsPreDefinedNetwork(create.Name) {
|
|
| 96 |
+ err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name)
|
|
| 97 |
+ return nil, errors.NewErrorWithStatusCode(err, http.StatusForbidden) |
|
| 98 |
+ } |
|
| 99 |
+ |
|
| 100 |
+ var warning string |
|
| 101 |
+ nw, err := daemon.GetNetworkByName(create.Name) |
|
| 102 |
+ if err != nil {
|
|
| 103 |
+ if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok {
|
|
| 104 |
+ return nil, err |
|
| 105 |
+ } |
|
| 106 |
+ } |
|
| 107 |
+ if nw != nil {
|
|
| 108 |
+ if create.CheckDuplicate {
|
|
| 109 |
+ return nil, libnetwork.NetworkNameError(create.Name) |
|
| 110 |
+ } |
|
| 111 |
+ warning = fmt.Sprintf("Network with name %s (id : %s) already exists", nw.Name(), nw.ID())
|
|
| 112 |
+ } |
|
| 113 |
+ |
|
| 95 | 114 |
c := daemon.netController |
| 115 |
+ driver := create.Driver |
|
| 96 | 116 |
if driver == "" {
|
| 97 | 117 |
driver = c.Config().Daemon.DefaultDriver |
| 98 | 118 |
} |
| 99 | 119 |
|
| 120 |
+ ipam := create.IPAM |
|
| 100 | 121 |
v4Conf, v6Conf, err := getIpamConfig(ipam.Config) |
| 101 | 122 |
if err != nil {
|
| 102 | 123 |
return nil, err |
| ... | ... |
@@ -104,20 +128,23 @@ func (daemon *Daemon) CreateNetwork(name, driver string, ipam network.IPAM, netO |
| 104 | 104 |
|
| 105 | 105 |
nwOptions := []libnetwork.NetworkOption{
|
| 106 | 106 |
libnetwork.NetworkOptionIpam(ipam.Driver, "", v4Conf, v6Conf, ipam.Options), |
| 107 |
- libnetwork.NetworkOptionEnableIPv6(enableIPv6), |
|
| 108 |
- libnetwork.NetworkOptionDriverOpts(netOption), |
|
| 109 |
- libnetwork.NetworkOptionLabels(labels), |
|
| 107 |
+ libnetwork.NetworkOptionEnableIPv6(create.EnableIPv6), |
|
| 108 |
+ libnetwork.NetworkOptionDriverOpts(create.Options), |
|
| 109 |
+ libnetwork.NetworkOptionLabels(create.Labels), |
|
| 110 | 110 |
} |
| 111 |
- if internal {
|
|
| 111 |
+ if create.Internal {
|
|
| 112 | 112 |
nwOptions = append(nwOptions, libnetwork.NetworkOptionInternalNetwork()) |
| 113 | 113 |
} |
| 114 |
- n, err := c.NewNetwork(driver, name, nwOptions...) |
|
| 114 |
+ n, err := c.NewNetwork(driver, create.Name, nwOptions...) |
|
| 115 | 115 |
if err != nil {
|
| 116 | 116 |
return nil, err |
| 117 | 117 |
} |
| 118 | 118 |
|
| 119 | 119 |
daemon.LogNetworkEvent(n, "create") |
| 120 |
- return n, nil |
|
| 120 |
+ return &types.NetworkCreateResponse{
|
|
| 121 |
+ ID: n.ID(), |
|
| 122 |
+ Warning: warning, |
|
| 123 |
+ }, nil |
|
| 121 | 124 |
} |
| 122 | 125 |
|
| 123 | 126 |
func getIpamConfig(data []network.IPAMConfig) ([]*libnetwork.IpamConf, []*libnetwork.IpamConf, error) {
|
| ... | ... |
@@ -203,3 +230,13 @@ func (daemon *Daemon) DeleteNetwork(networkID string) error {
|
| 203 | 203 |
daemon.LogNetworkEvent(nw, "destroy") |
| 204 | 204 |
return nil |
| 205 | 205 |
} |
| 206 |
+ |
|
| 207 |
+func (daemon *Daemon) FilterNetworks(netFilters filters.Args) ([]libnetwork.Network, error) {
|
|
| 208 |
+ if netFilters.Len() != 0 {
|
|
| 209 |
+ if err := netFilters.Validate(netsettings.AcceptedFilters); err != nil {
|
|
| 210 |
+ return nil, err |
|
| 211 |
+ } |
|
| 212 |
+ } |
|
| 213 |
+ nwList := daemon.getAllNetworks() |
|
| 214 |
+ return netsettings.FilterNetworks(nwList, netFilters) |
|
| 215 |
+} |
| 206 | 216 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,110 @@ |
| 0 |
+package network |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "regexp" |
|
| 5 |
+ "strings" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/docker/docker/runconfig" |
|
| 8 |
+ "github.com/docker/engine-api/types/filters" |
|
| 9 |
+ "github.com/docker/libnetwork" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+type filterHandler func([]libnetwork.Network, string) ([]libnetwork.Network, error) |
|
| 13 |
+ |
|
| 14 |
+var ( |
|
| 15 |
+ // supportedFilters predefined some supported filter handler function |
|
| 16 |
+ supportedFilters = map[string]filterHandler{
|
|
| 17 |
+ "type": filterNetworkByType, |
|
| 18 |
+ "name": filterNetworkByName, |
|
| 19 |
+ "id": filterNetworkByID, |
|
| 20 |
+ } |
|
| 21 |
+ |
|
| 22 |
+ // acceptFilters is an acceptable filter flag list |
|
| 23 |
+ // generated for validation. e.g. |
|
| 24 |
+ // acceptedFilters = map[string]bool{
|
|
| 25 |
+ // "type": true, |
|
| 26 |
+ // "name": true, |
|
| 27 |
+ // "id": true, |
|
| 28 |
+ // } |
|
| 29 |
+ AcceptedFilters = func() map[string]bool {
|
|
| 30 |
+ ret := make(map[string]bool) |
|
| 31 |
+ for k := range supportedFilters {
|
|
| 32 |
+ ret[k] = true |
|
| 33 |
+ } |
|
| 34 |
+ return ret |
|
| 35 |
+ }() |
|
| 36 |
+) |
|
| 37 |
+ |
|
| 38 |
+func filterNetworkByType(nws []libnetwork.Network, netType string) (retNws []libnetwork.Network, err error) {
|
|
| 39 |
+ switch netType {
|
|
| 40 |
+ case "builtin": |
|
| 41 |
+ for _, nw := range nws {
|
|
| 42 |
+ if runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 43 |
+ retNws = append(retNws, nw) |
|
| 44 |
+ } |
|
| 45 |
+ } |
|
| 46 |
+ case "custom": |
|
| 47 |
+ for _, nw := range nws {
|
|
| 48 |
+ if !runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 49 |
+ retNws = append(retNws, nw) |
|
| 50 |
+ } |
|
| 51 |
+ } |
|
| 52 |
+ default: |
|
| 53 |
+ return nil, fmt.Errorf("Invalid filter: 'type'='%s'", netType)
|
|
| 54 |
+ } |
|
| 55 |
+ return retNws, nil |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+func filterNetworkByName(nws []libnetwork.Network, name string) (retNws []libnetwork.Network, err error) {
|
|
| 59 |
+ for _, nw := range nws {
|
|
| 60 |
+ // exact match (fast path) |
|
| 61 |
+ if nw.Name() == name {
|
|
| 62 |
+ retNws = append(retNws, nw) |
|
| 63 |
+ continue |
|
| 64 |
+ } |
|
| 65 |
+ |
|
| 66 |
+ // regexp match (slow path) |
|
| 67 |
+ match, err := regexp.MatchString(name, nw.Name()) |
|
| 68 |
+ if err != nil || !match {
|
|
| 69 |
+ continue |
|
| 70 |
+ } else {
|
|
| 71 |
+ retNws = append(retNws, nw) |
|
| 72 |
+ } |
|
| 73 |
+ } |
|
| 74 |
+ return retNws, nil |
|
| 75 |
+} |
|
| 76 |
+ |
|
| 77 |
+func filterNetworkByID(nws []libnetwork.Network, id string) (retNws []libnetwork.Network, err error) {
|
|
| 78 |
+ for _, nw := range nws {
|
|
| 79 |
+ if strings.HasPrefix(nw.ID(), id) {
|
|
| 80 |
+ retNws = append(retNws, nw) |
|
| 81 |
+ } |
|
| 82 |
+ } |
|
| 83 |
+ return retNws, nil |
|
| 84 |
+} |
|
| 85 |
+ |
|
| 86 |
+// FilterAllNetworks filters network list according to user specified filter |
|
| 87 |
+// and returns user chosen networks |
|
| 88 |
+func FilterNetworks(nws []libnetwork.Network, filter filters.Args) ([]libnetwork.Network, error) {
|
|
| 89 |
+ // if filter is empty, return original network list |
|
| 90 |
+ if filter.Len() == 0 {
|
|
| 91 |
+ return nws, nil |
|
| 92 |
+ } |
|
| 93 |
+ |
|
| 94 |
+ var displayNet []libnetwork.Network |
|
| 95 |
+ for fkey, fhandler := range supportedFilters {
|
|
| 96 |
+ errFilter := filter.WalkValues(fkey, func(fval string) error {
|
|
| 97 |
+ passList, err := fhandler(nws, fval) |
|
| 98 |
+ if err != nil {
|
|
| 99 |
+ return err |
|
| 100 |
+ } |
|
| 101 |
+ displayNet = append(displayNet, passList...) |
|
| 102 |
+ return nil |
|
| 103 |
+ }) |
|
| 104 |
+ if errFilter != nil {
|
|
| 105 |
+ return nil, errFilter |
|
| 106 |
+ } |
|
| 107 |
+ } |
|
| 108 |
+ return displayNet, nil |
|
| 109 |
+} |
| ... | ... |
@@ -296,8 +296,8 @@ func createNetwork(c *check.C, config types.NetworkCreate, shouldSucceed bool) s |
| 296 | 296 |
return "" |
| 297 | 297 |
} |
| 298 | 298 |
|
| 299 |
- c.Assert(status, checker.Equals, http.StatusCreated) |
|
| 300 | 299 |
c.Assert(err, checker.IsNil) |
| 300 |
+ c.Assert(status, checker.Equals, http.StatusCreated) |
|
| 301 | 301 |
|
| 302 | 302 |
var nr types.NetworkCreateResponse |
| 303 | 303 |
err = json.Unmarshal(resp, &nr) |