hnsfuncs.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. package hcsshim
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net"
  6. "github.com/Sirupsen/logrus"
  7. )
  8. type NatPolicy struct {
  9. Type string
  10. Protocol string
  11. InternalPort uint16
  12. ExternalPort uint16
  13. }
  14. type QosPolicy struct {
  15. Type string
  16. MaximumOutgoingBandwidthInBytes uint64
  17. }
  18. type VlanPolicy struct {
  19. Type string
  20. VLAN uint
  21. }
  22. type VsidPolicy struct {
  23. Type string
  24. VSID uint
  25. }
  26. type PaPolicy struct {
  27. Type string
  28. PA string
  29. }
  30. // Subnet is assoicated with a network and represents a list
  31. // of subnets available to the network
  32. type Subnet struct {
  33. AddressPrefix string `json:",omitempty"`
  34. GatewayAddress string `json:",omitempty"`
  35. Policies []json.RawMessage `json:",omitempty"`
  36. }
  37. // MacPool is assoicated with a network and represents a list
  38. // of macaddresses available to the network
  39. type MacPool struct {
  40. StartMacAddress string `json:",omitempty"`
  41. EndMacAddress string `json:",omitempty"`
  42. }
  43. // HNSNetwork represents a network in HNS
  44. type HNSNetwork struct {
  45. Id string `json:"ID,omitempty"`
  46. Name string `json:",omitempty"`
  47. Type string `json:",omitempty"`
  48. NetworkAdapterName string `json:",omitempty"`
  49. SourceMac string `json:",omitempty"`
  50. Policies []json.RawMessage `json:",omitempty"`
  51. MacPools []MacPool `json:",omitempty"`
  52. Subnets []Subnet `json:",omitempty"`
  53. DNSSuffix string `json:",omitempty"`
  54. DNSServerList string `json:",omitempty"`
  55. DNSServerCompartment uint32 `json:",omitempty"`
  56. ManagementIP string `json:",omitempty"`
  57. }
  58. // HNSEndpoint represents a network endpoint in HNS
  59. type HNSEndpoint struct {
  60. Id string `json:"ID,omitempty"`
  61. Name string `json:",omitempty"`
  62. VirtualNetwork string `json:",omitempty"`
  63. VirtualNetworkName string `json:",omitempty"`
  64. Policies []json.RawMessage `json:",omitempty"`
  65. MacAddress string `json:",omitempty"`
  66. IPAddress net.IP `json:",omitempty"`
  67. DNSSuffix string `json:",omitempty"`
  68. DNSServerList string `json:",omitempty"`
  69. GatewayAddress string `json:",omitempty"`
  70. EnableInternalDNS bool `json:",omitempty"`
  71. DisableICC bool `json:",omitempty"`
  72. PrefixLength uint8 `json:",omitempty"`
  73. IsRemoteEndpoint bool `json:",omitempty"`
  74. }
  75. type hnsNetworkResponse struct {
  76. Success bool
  77. Error string
  78. Output HNSNetwork
  79. }
  80. type hnsResponse struct {
  81. Success bool
  82. Error string
  83. Output json.RawMessage
  84. }
  85. func hnsCall(method, path, request string, returnResponse interface{}) error {
  86. var responseBuffer *uint16
  87. logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request)
  88. err := _hnsCall(method, path, request, &responseBuffer)
  89. if err != nil {
  90. return makeError(err, "hnsCall ", "")
  91. }
  92. response := convertAndFreeCoTaskMemString(responseBuffer)
  93. hnsresponse := &hnsResponse{}
  94. if err = json.Unmarshal([]byte(response), &hnsresponse); err != nil {
  95. return err
  96. }
  97. if !hnsresponse.Success {
  98. return fmt.Errorf("HNS failed with error : %s", hnsresponse.Error)
  99. }
  100. if len(hnsresponse.Output) == 0 {
  101. return nil
  102. }
  103. logrus.Debugf("Network Response : %s", hnsresponse.Output)
  104. err = json.Unmarshal(hnsresponse.Output, returnResponse)
  105. if err != nil {
  106. return err
  107. }
  108. return nil
  109. }
  110. // HNSNetworkRequest makes a call into HNS to update/query a single network
  111. func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
  112. var network HNSNetwork
  113. err := hnsCall(method, "/networks/"+path, request, &network)
  114. if err != nil {
  115. return nil, err
  116. }
  117. return &network, nil
  118. }
  119. // HNSListNetworkRequest makes a HNS call to query the list of available networks
  120. func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
  121. var network []HNSNetwork
  122. err := hnsCall(method, "/networks/"+path, request, &network)
  123. if err != nil {
  124. return nil, err
  125. }
  126. return network, nil
  127. }
  128. // HNSEndpointRequest makes a HNS call to modify/query a network endpoint
  129. func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
  130. endpoint := &HNSEndpoint{}
  131. err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
  132. if err != nil {
  133. return nil, err
  134. }
  135. return endpoint, nil
  136. }
  137. // HNSListEndpointRequest makes a HNS call to query the list of available endpoints
  138. func HNSListEndpointRequest() ([]HNSEndpoint, error) {
  139. var endpoint []HNSEndpoint
  140. err := hnsCall("GET", "/endpoints/", "", &endpoint)
  141. if err != nil {
  142. return nil, err
  143. }
  144. return endpoint, nil
  145. }
  146. // HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
  147. func HotAttachEndpoint(containerID string, endpointID string) error {
  148. return modifyNetworkEndpoint(containerID, endpointID, Add)
  149. }
  150. // HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
  151. func HotDetachEndpoint(containerID string, endpointID string) error {
  152. return modifyNetworkEndpoint(containerID, endpointID, Remove)
  153. }
  154. // ModifyContainer corresponding to the container id, by sending a request
  155. func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
  156. container, err := OpenContainer(id)
  157. if err != nil {
  158. if IsNotExist(err) {
  159. return ErrComputeSystemDoesNotExist
  160. }
  161. return getInnerError(err)
  162. }
  163. defer container.Close()
  164. err = container.Modify(request)
  165. if err != nil {
  166. if IsNotSupported(err) {
  167. return ErrPlatformNotSupported
  168. }
  169. return getInnerError(err)
  170. }
  171. return nil
  172. }
  173. func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {
  174. requestMessage := &ResourceModificationRequestResponse{
  175. Resource: Network,
  176. Request: request,
  177. Data: endpointID,
  178. }
  179. err := modifyContainer(containerID, requestMessage)
  180. if err != nil {
  181. return err
  182. }
  183. return nil
  184. }
  185. // GetHNSNetworkByID
  186. func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
  187. return HNSNetworkRequest("GET", networkID, "")
  188. }
  189. // GetHNSNetworkName filtered by Name
  190. func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
  191. hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
  192. if err != nil {
  193. return nil, err
  194. }
  195. for _, hnsnetwork := range hsnnetworks {
  196. if hnsnetwork.Name == networkName {
  197. return &hnsnetwork, nil
  198. }
  199. }
  200. return nil, fmt.Errorf("Network %v not found", networkName)
  201. }
  202. // Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
  203. func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
  204. jsonString, err := json.Marshal(endpoint)
  205. if err != nil {
  206. return nil, err
  207. }
  208. return HNSEndpointRequest("POST", "", string(jsonString))
  209. }
  210. // Create Endpoint by sending EndpointRequest to HNS
  211. func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
  212. return HNSEndpointRequest("DELETE", endpoint.Id, "")
  213. }
  214. // GetHNSEndpointByID
  215. func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
  216. return HNSEndpointRequest("GET", endpointID, "")
  217. }
  218. // GetHNSNetworkName filtered by Name
  219. func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
  220. hnsResponse, err := HNSListEndpointRequest()
  221. if err != nil {
  222. return nil, err
  223. }
  224. for _, hnsEndpoint := range hnsResponse {
  225. if hnsEndpoint.Name == endpointName {
  226. return &hnsEndpoint, nil
  227. }
  228. }
  229. return nil, fmt.Errorf("Endpoint %v not found", endpointName)
  230. }