Skip to content

Commit 0713c83

Browse files
authored
Merge pull request #1187 from rudyfly/network-connect
feature: add network connect for container
2 parents 1632d81 + ecba8a4 commit 0713c83

File tree

13 files changed

+535
-13
lines changed

13 files changed

+535
-13
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
![pouchcontainer-logo-800](https://user-images.githubusercontent.com/6755791/39180769-55f3b742-47ea-11e8-8762-78aeedcbba78.png)
1111

12-
1312
## Main Links
1413

1514
- [Introduction](#introduction)

apis/server/network_bridge.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,26 @@ func (s *Server) deleteNetwork(ctx context.Context, rw http.ResponseWriter, req
7777
return nil
7878
}
7979

80+
func (s *Server) connectToNetwork(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
81+
networkIDOrName := mux.Vars(req)["id"]
82+
connectConfig := &types.NetworkConnect{}
83+
84+
// decode request body
85+
if err := json.NewDecoder(req.Body).Decode(connectConfig); err != nil {
86+
return httputils.NewHTTPError(err, http.StatusBadRequest)
87+
}
88+
// validate request body
89+
if err := connectConfig.Validate(strfmt.NewFormats()); err != nil {
90+
return httputils.NewHTTPError(err, http.StatusBadRequest)
91+
}
92+
93+
if err := s.ContainerMgr.Connect(ctx, connectConfig.Container, networkIDOrName, connectConfig.EndpointConfig); err != nil {
94+
return err
95+
}
96+
rw.WriteHeader(http.StatusOK)
97+
return nil
98+
}
99+
80100
func (s *Server) disconnectNetwork(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
81101
network := &types.NetworkDisconnect{}
82102
// decode request body

apis/server/router.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ func initRoute(s *Server) http.Handler {
6868
s.addRoute(r, http.MethodDelete, "/volumes/{name:.*}", s.removeVolume)
6969

7070
// network
71+
7172
s.addRoute(r, http.MethodGet, "/networks", s.listNetwork)
7273
s.addRoute(r, http.MethodPost, "/networks/create", s.createNetwork)
7374
s.addRoute(r, http.MethodGet, "/networks/{name:.*}", s.getNetwork)
7475
s.addRoute(r, http.MethodDelete, "/networks/{name:.*}", s.deleteNetwork)
76+
s.addRoute(r, http.MethodPost, "/networks/{id:.*}/connect", s.connectToNetwork)
7577
s.addRoute(r, http.MethodPost, "/networks/{name:.*}/disconnect", s.disconnectNetwork)
7678

7779
// metrics

apis/swagger.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,40 @@ paths:
10861086
$ref: "#/responses/500ErrorResponse"
10871087
tags: ["Network"]
10881088

1089+
/networks/{id}/connect:
1090+
post:
1091+
summary: "Connect a container to a network"
1092+
operationId: "NetworkConnect"
1093+
consumes:
1094+
- "application/json"
1095+
responses:
1096+
200:
1097+
description: "No error"
1098+
400:
1099+
description: "bad parameter"
1100+
schema:
1101+
$ref: "#/definitions/Error"
1102+
404:
1103+
description: "Network or container not found"
1104+
schema:
1105+
$ref: "#/responses/404ErrorResponse"
1106+
500:
1107+
description: "Server error"
1108+
schema:
1109+
$ref: "#/responses/500ErrorResponse"
1110+
parameters:
1111+
- name: "id"
1112+
in: "path"
1113+
description: "Network ID or name"
1114+
required: true
1115+
type: "string"
1116+
- name: "container"
1117+
in: "body"
1118+
required: true
1119+
schema:
1120+
$ref: "#/definitions/NetworkConnect"
1121+
tags: ["Network"]
1122+
10891123
/networks/{id}/disconnect:
10901124
post:
10911125
summary: "Disconnect a container from a network"
@@ -3135,6 +3169,16 @@ definitions:
31353169
MaximumRetryCount:
31363170
type: "integer"
31373171

3172+
NetworkConnect:
3173+
type: "object"
3174+
description: "contains the request for the remote API: POST /networks/{id:.*}/connect"
3175+
properties:
3176+
Container:
3177+
type: "string"
3178+
description: "The ID or name of the container to connect to the network."
3179+
EndpointConfig:
3180+
$ref: "#/definitions/EndpointSettings"
3181+
31383182
NetworkCreateConfig:
31393183
type: "object"
31403184
description: "contains the request for the remote API: POST /networks/create"

apis/types/network_connect.go

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/network.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func (n *NetworkCommand) Init(c *Cli) {
4141
c.AddCommand(n, &NetworkRemoveCommand{})
4242
c.AddCommand(n, &NetworkInspectCommand{})
4343
c.AddCommand(n, &NetworkListCommand{})
44+
c.AddCommand(n, &NetworkConnectCommand{})
4445
c.AddCommand(n, &NetworkDisconnectCommand{})
4546
}
4647

@@ -377,6 +378,91 @@ e495f50913 net1 bridge
377378
`
378379
}
379380

381+
// networkConnectDescription is used to describe network connect command in detail and auto generate command doc.
382+
var networkConnectDescription = "Connect a container to a network in pouchd. " +
383+
"It must specify network's name and container's name."
384+
385+
// NetworkConnectCommand is used to implement 'network connect' command.
386+
type NetworkConnectCommand struct {
387+
baseCommand
388+
389+
ipAddress string
390+
ipv6Address string
391+
links []string
392+
aliases []string
393+
linklocalips []string
394+
}
395+
396+
// Init initializes NetworkConnectCommand command.
397+
func (n *NetworkConnectCommand) Init(c *Cli) {
398+
n.cli = c
399+
400+
n.cmd = &cobra.Command{
401+
Use: "connect [OPTIONS] NETWORK CONTAINER",
402+
Short: "Connect a container to a network",
403+
Long: networkConnectDescription,
404+
Args: cobra.ExactArgs(2),
405+
RunE: func(cmd *cobra.Command, args []string) error {
406+
return n.runNetworkConnect(args)
407+
},
408+
Example: networkConnectExample(),
409+
}
410+
411+
n.addFlags()
412+
}
413+
414+
// addFlags adds flags for specific command.
415+
func (n *NetworkConnectCommand) addFlags() {
416+
flagSet := n.cmd.Flags()
417+
418+
flagSet.StringVar(&n.ipAddress, "ip", "", "IP Address")
419+
flagSet.StringVar(&n.ipv6Address, "ip6", "", "IPv6 Address")
420+
flagSet.StringSliceVar(&n.links, "link", []string{}, "Add link to another container")
421+
flagSet.StringSliceVar(&n.aliases, "alias", []string{}, "Add network-scoped alias for the container")
422+
flagSet.StringSliceVar(&n.linklocalips, "link-local-ip", []string{}, "Add a link-local address for the container")
423+
}
424+
425+
// runNetworkConnect is the entry of NetworkConnectCommand command.
426+
func (n *NetworkConnectCommand) runNetworkConnect(args []string) error {
427+
network := args[0]
428+
container := args[1]
429+
if network == "" {
430+
return fmt.Errorf("network name cannot be empty")
431+
}
432+
if container == "" {
433+
return fmt.Errorf("container name cannot be empty")
434+
}
435+
436+
networkReq := &types.NetworkConnect{
437+
Container: container,
438+
EndpointConfig: &types.EndpointSettings{
439+
IPAMConfig: &types.EndpointIPAMConfig{
440+
IPV4Address: n.ipAddress,
441+
IPV6Address: n.ipv6Address,
442+
LinkLocalIps: n.linklocalips,
443+
},
444+
Links: n.links,
445+
Aliases: n.aliases,
446+
},
447+
}
448+
449+
ctx := context.Background()
450+
apiClient := n.cli.Client()
451+
err := apiClient.NetworkConnect(ctx, network, networkReq)
452+
if err != nil {
453+
return err
454+
}
455+
fmt.Printf("container %s is connected to network %s\n", container, network)
456+
457+
return nil
458+
}
459+
460+
// networkConnectExample shows examples in network connect command, and is used in auto-generated cli docs.
461+
func networkConnectExample() string {
462+
return `$ pouch network connect net1 container1
463+
container container1 is connected to network net1`
464+
}
465+
380466
// networkDisconnectDescription is used to describe network disconnect command in detail and auto generate comand doc.
381467
var networkDisconnectDescription = "Disconnect a container from a network"
382468

client/interface.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,6 @@ type NetworkAPIClient interface {
7070
NetworkRemove(ctx context.Context, networkID string) error
7171
NetworkInspect(ctx context.Context, networkID string) (*types.NetworkInspectResp, error)
7272
NetworkList(ctx context.Context) ([]types.NetworkResource, error)
73+
NetworkConnect(ctx context.Context, network string, req *types.NetworkConnect) error
7374
NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error
7475
}

client/network_connect.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package client
2+
3+
import (
4+
"context"
5+
6+
"github.com/alibaba/pouch/apis/types"
7+
)
8+
9+
// NetworkConnect connects a container to a network.
10+
func (client *APIClient) NetworkConnect(ctx context.Context, network string, req *types.NetworkConnect) error {
11+
resp, err := client.post(ctx, "/networks/"+network+"/connect", nil, req, nil)
12+
if err != nil {
13+
return err
14+
}
15+
16+
ensureCloseReader(resp)
17+
return nil
18+
}

0 commit comments

Comments
 (0)