network.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // Copyright 2015 go-dockerclient authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package docker
  5. import (
  6. "bytes"
  7. "encoding/json"
  8. "errors"
  9. "fmt"
  10. "net/http"
  11. )
  12. // ErrNetworkAlreadyExists is the error returned by CreateNetwork when the
  13. // network already exists.
  14. var ErrNetworkAlreadyExists = errors.New("network already exists")
  15. // Network represents a network.
  16. //
  17. // See https://goo.gl/6GugX3 for more details.
  18. type Network struct {
  19. Name string
  20. ID string `json:"Id"`
  21. Scope string
  22. Driver string
  23. IPAM IPAMOptions
  24. Containers map[string]Endpoint
  25. Options map[string]string
  26. Internal bool
  27. EnableIPv6 bool `json:"EnableIPv6"`
  28. }
  29. // Endpoint contains network resources allocated and used for a container in a network
  30. //
  31. // See https://goo.gl/6GugX3 for more details.
  32. type Endpoint struct {
  33. Name string
  34. ID string `json:"EndpointID"`
  35. MacAddress string
  36. IPv4Address string
  37. IPv6Address string
  38. }
  39. // ListNetworks returns all networks.
  40. //
  41. // See https://goo.gl/6GugX3 for more details.
  42. func (c *Client) ListNetworks() ([]Network, error) {
  43. resp, err := c.do("GET", "/networks", doOptions{})
  44. if err != nil {
  45. return nil, err
  46. }
  47. defer resp.Body.Close()
  48. var networks []Network
  49. if err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {
  50. return nil, err
  51. }
  52. return networks, nil
  53. }
  54. // NetworkFilterOpts is an aggregation of key=value that Docker
  55. // uses to filter networks
  56. type NetworkFilterOpts map[string]map[string]bool
  57. // FilteredListNetworks returns all networks with the filters applied
  58. //
  59. // See goo.gl/zd2mx4 for more details.
  60. func (c *Client) FilteredListNetworks(opts NetworkFilterOpts) ([]Network, error) {
  61. params := bytes.NewBuffer(nil)
  62. if err := json.NewEncoder(params).Encode(&opts); err != nil {
  63. return nil, err
  64. }
  65. path := "/networks?filters=" + params.String()
  66. resp, err := c.do("GET", path, doOptions{})
  67. if err != nil {
  68. return nil, err
  69. }
  70. defer resp.Body.Close()
  71. var networks []Network
  72. if err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {
  73. return nil, err
  74. }
  75. return networks, nil
  76. }
  77. // NetworkInfo returns information about a network by its ID.
  78. //
  79. // See https://goo.gl/6GugX3 for more details.
  80. func (c *Client) NetworkInfo(id string) (*Network, error) {
  81. path := "/networks/" + id
  82. resp, err := c.do("GET", path, doOptions{})
  83. if err != nil {
  84. if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
  85. return nil, &NoSuchNetwork{ID: id}
  86. }
  87. return nil, err
  88. }
  89. defer resp.Body.Close()
  90. var network Network
  91. if err := json.NewDecoder(resp.Body).Decode(&network); err != nil {
  92. return nil, err
  93. }
  94. return &network, nil
  95. }
  96. // CreateNetworkOptions specify parameters to the CreateNetwork function and
  97. // (for now) is the expected body of the "create network" http request message
  98. //
  99. // See https://goo.gl/6GugX3 for more details.
  100. type CreateNetworkOptions struct {
  101. Name string `json:"Name"`
  102. CheckDuplicate bool `json:"CheckDuplicate"`
  103. Driver string `json:"Driver"`
  104. IPAM IPAMOptions `json:"IPAM"`
  105. Options map[string]interface{} `json:"Options"`
  106. Internal bool `json:"Internal"`
  107. EnableIPv6 bool `json:"EnableIPv6"`
  108. }
  109. // IPAMOptions controls IP Address Management when creating a network
  110. //
  111. // See https://goo.gl/T8kRVH for more details.
  112. type IPAMOptions struct {
  113. Driver string `json:"Driver"`
  114. Config []IPAMConfig `json:"Config"`
  115. }
  116. // IPAMConfig represents IPAM configurations
  117. //
  118. // See https://goo.gl/T8kRVH for more details.
  119. type IPAMConfig struct {
  120. Subnet string `json:",omitempty"`
  121. IPRange string `json:",omitempty"`
  122. Gateway string `json:",omitempty"`
  123. AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"`
  124. }
  125. // CreateNetwork creates a new network, returning the network instance,
  126. // or an error in case of failure.
  127. //
  128. // See https://goo.gl/6GugX3 for more details.
  129. func (c *Client) CreateNetwork(opts CreateNetworkOptions) (*Network, error) {
  130. resp, err := c.do(
  131. "POST",
  132. "/networks/create",
  133. doOptions{
  134. data: opts,
  135. },
  136. )
  137. if err != nil {
  138. if e, ok := err.(*Error); ok && e.Status == http.StatusConflict {
  139. return nil, ErrNetworkAlreadyExists
  140. }
  141. return nil, err
  142. }
  143. defer resp.Body.Close()
  144. type createNetworkResponse struct {
  145. ID string
  146. }
  147. var (
  148. network Network
  149. cnr createNetworkResponse
  150. )
  151. if err := json.NewDecoder(resp.Body).Decode(&cnr); err != nil {
  152. return nil, err
  153. }
  154. network.Name = opts.Name
  155. network.ID = cnr.ID
  156. network.Driver = opts.Driver
  157. return &network, nil
  158. }
  159. // RemoveNetwork removes a network or returns an error in case of failure.
  160. //
  161. // See https://goo.gl/6GugX3 for more details.
  162. func (c *Client) RemoveNetwork(id string) error {
  163. resp, err := c.do("DELETE", "/networks/"+id, doOptions{})
  164. if err != nil {
  165. if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
  166. return &NoSuchNetwork{ID: id}
  167. }
  168. return err
  169. }
  170. resp.Body.Close()
  171. return nil
  172. }
  173. // NetworkConnectionOptions specify parameters to the ConnectNetwork and
  174. // DisconnectNetwork function.
  175. //
  176. // See https://goo.gl/RV7BJU for more details.
  177. type NetworkConnectionOptions struct {
  178. Container string
  179. // EndpointConfig is only applicable to the ConnectNetwork call
  180. EndpointConfig *EndpointConfig `json:"EndpointConfig,omitempty"`
  181. // Force is only applicable to the DisconnectNetwork call
  182. Force bool
  183. }
  184. // EndpointConfig stores network endpoint details
  185. //
  186. // See https://goo.gl/RV7BJU for more details.
  187. type EndpointConfig struct {
  188. IPAMConfig *EndpointIPAMConfig
  189. Links []string
  190. Aliases []string
  191. }
  192. // EndpointIPAMConfig represents IPAM configurations for an
  193. // endpoint
  194. //
  195. // See https://goo.gl/RV7BJU for more details.
  196. type EndpointIPAMConfig struct {
  197. IPv4Address string `json:",omitempty"`
  198. IPv6Address string `json:",omitempty"`
  199. }
  200. // ConnectNetwork adds a container to a network or returns an error in case of
  201. // failure.
  202. //
  203. // See https://goo.gl/6GugX3 for more details.
  204. func (c *Client) ConnectNetwork(id string, opts NetworkConnectionOptions) error {
  205. resp, err := c.do("POST", "/networks/"+id+"/connect", doOptions{data: opts})
  206. if err != nil {
  207. if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
  208. return &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}
  209. }
  210. return err
  211. }
  212. resp.Body.Close()
  213. return nil
  214. }
  215. // DisconnectNetwork removes a container from a network or returns an error in
  216. // case of failure.
  217. //
  218. // See https://goo.gl/6GugX3 for more details.
  219. func (c *Client) DisconnectNetwork(id string, opts NetworkConnectionOptions) error {
  220. resp, err := c.do("POST", "/networks/"+id+"/disconnect", doOptions{data: opts})
  221. if err != nil {
  222. if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
  223. return &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}
  224. }
  225. return err
  226. }
  227. resp.Body.Close()
  228. return nil
  229. }
  230. // NoSuchNetwork is the error returned when a given network does not exist.
  231. type NoSuchNetwork struct {
  232. ID string
  233. }
  234. func (err *NoSuchNetwork) Error() string {
  235. return fmt.Sprintf("No such network: %s", err.ID)
  236. }
  237. // NoSuchNetworkOrContainer is the error returned when a given network or
  238. // container does not exist.
  239. type NoSuchNetworkOrContainer struct {
  240. NetworkID string
  241. ContainerID string
  242. }
  243. func (err *NoSuchNetworkOrContainer) Error() string {
  244. return fmt.Sprintf("No such network (%s) or container (%s)", err.NetworkID, err.ContainerID)
  245. }