Browse code

client: refactor create network api implementation to wrap options/results

Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>

Austin Vazquez authored on 2025/10/22 21:39:57
Showing 10 changed files
... ...
@@ -5,7 +5,6 @@ import (
5 5
 	"io"
6 6
 	"net"
7 7
 
8
-	"github.com/moby/moby/api/types/network"
9 8
 	"github.com/moby/moby/api/types/system"
10 9
 )
11 10
 
... ...
@@ -116,7 +115,7 @@ type ImageAPIClient interface {
116 116
 // NetworkAPIClient defines API client methods for the networks
117 117
 type NetworkAPIClient interface {
118 118
 	NetworkConnect(ctx context.Context, network string, options NetworkConnectOptions) (NetworkConnectResult, error)
119
-	NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (network.CreateResponse, error)
119
+	NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (NetworkCreateResult, error)
120 120
 	NetworkDisconnect(ctx context.Context, network string, options NetworkDisconnectOptions) (NetworkDisconnectResult, error)
121 121
 	NetworkInspect(ctx context.Context, network string, options NetworkInspectOptions) (NetworkInspectResult, error)
122 122
 	NetworkList(ctx context.Context, options NetworkListOptions) (NetworkListResult, error)
... ...
@@ -7,8 +7,31 @@ import (
7 7
 	"github.com/moby/moby/api/types/network"
8 8
 )
9 9
 
10
+// NetworkCreateOptions holds options to create a network.
11
+type NetworkCreateOptions struct {
12
+	Driver     string            // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
13
+	Scope      string            // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
14
+	EnableIPv4 *bool             // EnableIPv4 represents whether to enable IPv4.
15
+	EnableIPv6 *bool             // EnableIPv6 represents whether to enable IPv6.
16
+	IPAM       *network.IPAM     // IPAM is the network's IP Address Management.
17
+	Internal   bool              // Internal represents if the network is used internal only.
18
+	Attachable bool              // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
19
+	Ingress    bool              // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
20
+	ConfigOnly bool              // ConfigOnly creates a config-only network. Config-only networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
21
+	ConfigFrom string            // ConfigFrom specifies the source which will provide the configuration for this network. The specified network must be a config-only network; see [CreateOptions.ConfigOnly].
22
+	Options    map[string]string // Options specifies the network-specific options to use for when creating the network.
23
+	Labels     map[string]string // Labels holds metadata specific to the network being created.
24
+}
25
+
26
+// NetworkCreateResult represents the result of a network create operation.
27
+type NetworkCreateResult struct {
28
+	ID string
29
+
30
+	Warning []string
31
+}
32
+
10 33
 // NetworkCreate creates a new network in the docker host.
11
-func (cli *Client) NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (network.CreateResponse, error) {
34
+func (cli *Client) NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (NetworkCreateResult, error) {
12 35
 	req := network.CreateRequest{
13 36
 		Name:       name,
14 37
 		Driver:     options.Driver,
... ...
@@ -20,18 +43,27 @@ func (cli *Client) NetworkCreate(ctx context.Context, name string, options Netwo
20 20
 		Attachable: options.Attachable,
21 21
 		Ingress:    options.Ingress,
22 22
 		ConfigOnly: options.ConfigOnly,
23
-		ConfigFrom: options.ConfigFrom,
24 23
 		Options:    options.Options,
25 24
 		Labels:     options.Labels,
26 25
 	}
27 26
 
27
+	if options.ConfigFrom != "" {
28
+		req.ConfigFrom = &network.ConfigReference{Network: options.ConfigFrom}
29
+	}
30
+
28 31
 	resp, err := cli.post(ctx, "/networks/create", nil, req, nil)
29 32
 	defer ensureReaderClosed(resp)
30 33
 	if err != nil {
31
-		return network.CreateResponse{}, err
34
+		return NetworkCreateResult{}, err
32 35
 	}
33 36
 
34 37
 	var response network.CreateResponse
35 38
 	err = json.NewDecoder(resp.Body).Decode(&response)
36
-	return response, err
39
+
40
+	var warnings []string
41
+	if response.Warning != "" {
42
+		warnings = []string{response.Warning}
43
+	}
44
+
45
+	return NetworkCreateResult{ID: response.ID, Warning: warnings}, err
37 46
 }
38 47
deleted file mode 100644
... ...
@@ -1,19 +0,0 @@
1
-package client
2
-
3
-import "github.com/moby/moby/api/types/network"
4
-
5
-// NetworkCreateOptions holds options to create a network.
6
-type NetworkCreateOptions struct {
7
-	Driver     string                   // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
8
-	Scope      string                   // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
9
-	EnableIPv4 *bool                    // EnableIPv4 represents whether to enable IPv4.
10
-	EnableIPv6 *bool                    // EnableIPv6 represents whether to enable IPv6.
11
-	IPAM       *network.IPAM            // IPAM is the network's IP Address Management.
12
-	Internal   bool                     // Internal represents if the network is used internal only.
13
-	Attachable bool                     // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
14
-	Ingress    bool                     // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
15
-	ConfigOnly bool                     // ConfigOnly creates a config-only network. Config-only networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
16
-	ConfigFrom *network.ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network. The specified network must be a config-only network; see [CreateOptions.ConfigOnly].
17
-	Options    map[string]string        // Options specifies the network-specific options to use for when creating the network.
18
-	Labels     map[string]string        // Labels holds metadata specific to the network being created.
19
-}
... ...
@@ -56,5 +56,6 @@ func TestNetworkCreate(t *testing.T) {
56 56
 	})
57 57
 	assert.NilError(t, err)
58 58
 	assert.Check(t, is.Equal(networkResponse.ID, "network_id"))
59
-	assert.Check(t, is.Equal(networkResponse.Warning, "warning"))
59
+	assert.Check(t, is.Len(networkResponse.Warning, 1))
60
+	assert.Check(t, is.Equal(networkResponse.Warning[0], "warning"))
60 61
 }
... ...
@@ -1027,13 +1027,13 @@ func (s *DockerSwarmSuite) TestAPINetworkInspectWithScope(c *testing.T) {
1027 1027
 	name := "test-scoped-network"
1028 1028
 	apiclient := d.NewClientT(c)
1029 1029
 
1030
-	resp, err := apiclient.NetworkCreate(ctx, name, client.NetworkCreateOptions{Driver: "overlay"})
1030
+	create, err := apiclient.NetworkCreate(ctx, name, client.NetworkCreateOptions{Driver: "overlay"})
1031 1031
 	assert.NilError(c, err)
1032 1032
 
1033
-	res, err := apiclient.NetworkInspect(ctx, name, client.NetworkInspectOptions{})
1033
+	inspect, err := apiclient.NetworkInspect(ctx, name, client.NetworkInspectOptions{})
1034 1034
 	assert.NilError(c, err)
1035
-	assert.Check(c, is.Equal("swarm", res.Network.Scope))
1036
-	assert.Check(c, is.Equal(resp.ID, res.Network.ID))
1035
+	assert.Check(c, is.Equal("swarm", inspect.Network.Scope))
1036
+	assert.Check(c, is.Equal(create.ID, inspect.Network.ID))
1037 1037
 
1038 1038
 	_, err = apiclient.NetworkInspect(ctx, name, client.NetworkInspectOptions{Scope: "local"})
1039 1039
 	assert.Check(c, is.ErrorType(err, cerrdefs.IsNotFound))
... ...
@@ -63,7 +63,7 @@ func WithConfigOnly(co bool) func(*client.NetworkCreateOptions) {
63 63
 // WithConfigFrom sets the ConfigOnly flag in the create network request
64 64
 func WithConfigFrom(name string) func(*client.NetworkCreateOptions) {
65 65
 	return func(n *client.NetworkCreateOptions) {
66
-		n.ConfigFrom = &network.ConfigReference{Network: name}
66
+		n.ConfigFrom = name
67 67
 	}
68 68
 }
69 69
 
... ...
@@ -155,9 +155,7 @@ func TestDefaultNetworkOpts(t *testing.T) {
155 155
 			networkName := "testnet"
156 156
 			networkId := network.CreateNoError(ctx, t, c, networkName, func(create *client.NetworkCreateOptions) {
157 157
 				if tc.configFrom {
158
-					create.ConfigFrom = &networktypes.ConfigReference{
159
-						Network: "from-net",
160
-					}
158
+					create.ConfigFrom = "from-net"
161 159
 				}
162 160
 			})
163 161
 			defer c.NetworkRemove(ctx, networkName, client.NetworkRemoveOptions{})
... ...
@@ -5,7 +5,6 @@ import (
5 5
 	"io"
6 6
 	"net"
7 7
 
8
-	"github.com/moby/moby/api/types/network"
9 8
 	"github.com/moby/moby/api/types/system"
10 9
 )
11 10
 
... ...
@@ -116,7 +115,7 @@ type ImageAPIClient interface {
116 116
 // NetworkAPIClient defines API client methods for the networks
117 117
 type NetworkAPIClient interface {
118 118
 	NetworkConnect(ctx context.Context, network string, options NetworkConnectOptions) (NetworkConnectResult, error)
119
-	NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (network.CreateResponse, error)
119
+	NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (NetworkCreateResult, error)
120 120
 	NetworkDisconnect(ctx context.Context, network string, options NetworkDisconnectOptions) (NetworkDisconnectResult, error)
121 121
 	NetworkInspect(ctx context.Context, network string, options NetworkInspectOptions) (NetworkInspectResult, error)
122 122
 	NetworkList(ctx context.Context, options NetworkListOptions) (NetworkListResult, error)
... ...
@@ -7,8 +7,31 @@ import (
7 7
 	"github.com/moby/moby/api/types/network"
8 8
 )
9 9
 
10
+// NetworkCreateOptions holds options to create a network.
11
+type NetworkCreateOptions struct {
12
+	Driver     string            // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
13
+	Scope      string            // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
14
+	EnableIPv4 *bool             // EnableIPv4 represents whether to enable IPv4.
15
+	EnableIPv6 *bool             // EnableIPv6 represents whether to enable IPv6.
16
+	IPAM       *network.IPAM     // IPAM is the network's IP Address Management.
17
+	Internal   bool              // Internal represents if the network is used internal only.
18
+	Attachable bool              // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
19
+	Ingress    bool              // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
20
+	ConfigOnly bool              // ConfigOnly creates a config-only network. Config-only networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
21
+	ConfigFrom string            // ConfigFrom specifies the source which will provide the configuration for this network. The specified network must be a config-only network; see [CreateOptions.ConfigOnly].
22
+	Options    map[string]string // Options specifies the network-specific options to use for when creating the network.
23
+	Labels     map[string]string // Labels holds metadata specific to the network being created.
24
+}
25
+
26
+// NetworkCreateResult represents the result of a network create operation.
27
+type NetworkCreateResult struct {
28
+	ID string
29
+
30
+	Warning []string
31
+}
32
+
10 33
 // NetworkCreate creates a new network in the docker host.
11
-func (cli *Client) NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (network.CreateResponse, error) {
34
+func (cli *Client) NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (NetworkCreateResult, error) {
12 35
 	req := network.CreateRequest{
13 36
 		Name:       name,
14 37
 		Driver:     options.Driver,
... ...
@@ -20,18 +43,27 @@ func (cli *Client) NetworkCreate(ctx context.Context, name string, options Netwo
20 20
 		Attachable: options.Attachable,
21 21
 		Ingress:    options.Ingress,
22 22
 		ConfigOnly: options.ConfigOnly,
23
-		ConfigFrom: options.ConfigFrom,
24 23
 		Options:    options.Options,
25 24
 		Labels:     options.Labels,
26 25
 	}
27 26
 
27
+	if options.ConfigFrom != "" {
28
+		req.ConfigFrom = &network.ConfigReference{Network: options.ConfigFrom}
29
+	}
30
+
28 31
 	resp, err := cli.post(ctx, "/networks/create", nil, req, nil)
29 32
 	defer ensureReaderClosed(resp)
30 33
 	if err != nil {
31
-		return network.CreateResponse{}, err
34
+		return NetworkCreateResult{}, err
32 35
 	}
33 36
 
34 37
 	var response network.CreateResponse
35 38
 	err = json.NewDecoder(resp.Body).Decode(&response)
36
-	return response, err
39
+
40
+	var warnings []string
41
+	if response.Warning != "" {
42
+		warnings = []string{response.Warning}
43
+	}
44
+
45
+	return NetworkCreateResult{ID: response.ID, Warning: warnings}, err
37 46
 }
38 47
deleted file mode 100644
... ...
@@ -1,19 +0,0 @@
1
-package client
2
-
3
-import "github.com/moby/moby/api/types/network"
4
-
5
-// NetworkCreateOptions holds options to create a network.
6
-type NetworkCreateOptions struct {
7
-	Driver     string                   // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
8
-	Scope      string                   // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
9
-	EnableIPv4 *bool                    // EnableIPv4 represents whether to enable IPv4.
10
-	EnableIPv6 *bool                    // EnableIPv6 represents whether to enable IPv6.
11
-	IPAM       *network.IPAM            // IPAM is the network's IP Address Management.
12
-	Internal   bool                     // Internal represents if the network is used internal only.
13
-	Attachable bool                     // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
14
-	Ingress    bool                     // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
15
-	ConfigOnly bool                     // ConfigOnly creates a config-only network. Config-only networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
16
-	ConfigFrom *network.ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network. The specified network must be a config-only network; see [CreateOptions.ConfigOnly].
17
-	Options    map[string]string        // Options specifies the network-specific options to use for when creating the network.
18
-	Labels     map[string]string        // Labels holds metadata specific to the network being created.
19
-}