123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- package hcsshim
- import (
- "encoding/json"
- "fmt"
- "net"
- "github.com/Sirupsen/logrus"
- )
- type NatPolicy struct {
- Type string
- Protocol string
- InternalPort uint16
- ExternalPort uint16
- }
- type QosPolicy struct {
- Type string
- MaximumOutgoingBandwidthInBytes uint64
- }
- type VlanPolicy struct {
- Type string
- VLAN uint
- }
- type VsidPolicy struct {
- Type string
- VSID uint
- }
- type PaPolicy struct {
- Type string
- PA string
- }
- // Subnet is assoicated with a network and represents a list
- // of subnets available to the network
- type Subnet struct {
- AddressPrefix string `json:",omitempty"`
- GatewayAddress string `json:",omitempty"`
- Policies []json.RawMessage `json:",omitempty"`
- }
- // MacPool is assoicated with a network and represents a list
- // of macaddresses available to the network
- type MacPool struct {
- StartMacAddress string `json:",omitempty"`
- EndMacAddress string `json:",omitempty"`
- }
- // HNSNetwork represents a network in HNS
- type HNSNetwork struct {
- Id string `json:"ID,omitempty"`
- Name string `json:",omitempty"`
- Type string `json:",omitempty"`
- NetworkAdapterName string `json:",omitempty"`
- SourceMac string `json:",omitempty"`
- Policies []json.RawMessage `json:",omitempty"`
- MacPools []MacPool `json:",omitempty"`
- Subnets []Subnet `json:",omitempty"`
- DNSSuffix string `json:",omitempty"`
- DNSServerList string `json:",omitempty"`
- DNSServerCompartment uint32 `json:",omitempty"`
- ManagementIP string `json:",omitempty"`
- }
- // HNSEndpoint represents a network endpoint in HNS
- type HNSEndpoint struct {
- Id string `json:"ID,omitempty"`
- Name string `json:",omitempty"`
- VirtualNetwork string `json:",omitempty"`
- VirtualNetworkName string `json:",omitempty"`
- Policies []json.RawMessage `json:",omitempty"`
- MacAddress string `json:",omitempty"`
- IPAddress net.IP `json:",omitempty"`
- DNSSuffix string `json:",omitempty"`
- DNSServerList string `json:",omitempty"`
- GatewayAddress string `json:",omitempty"`
- EnableInternalDNS bool `json:",omitempty"`
- DisableICC bool `json:",omitempty"`
- PrefixLength uint8 `json:",omitempty"`
- IsRemoteEndpoint bool `json:",omitempty"`
- }
- type hnsNetworkResponse struct {
- Success bool
- Error string
- Output HNSNetwork
- }
- type hnsResponse struct {
- Success bool
- Error string
- Output json.RawMessage
- }
- func hnsCall(method, path, request string, returnResponse interface{}) error {
- var responseBuffer *uint16
- logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request)
- err := _hnsCall(method, path, request, &responseBuffer)
- if err != nil {
- return makeError(err, "hnsCall ", "")
- }
- response := convertAndFreeCoTaskMemString(responseBuffer)
- hnsresponse := &hnsResponse{}
- if err = json.Unmarshal([]byte(response), &hnsresponse); err != nil {
- return err
- }
- if !hnsresponse.Success {
- return fmt.Errorf("HNS failed with error : %s", hnsresponse.Error)
- }
- if len(hnsresponse.Output) == 0 {
- return nil
- }
- logrus.Debugf("Network Response : %s", hnsresponse.Output)
- err = json.Unmarshal(hnsresponse.Output, returnResponse)
- if err != nil {
- return err
- }
- return nil
- }
- // HNSNetworkRequest makes a call into HNS to update/query a single network
- func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
- var network HNSNetwork
- err := hnsCall(method, "/networks/"+path, request, &network)
- if err != nil {
- return nil, err
- }
- return &network, nil
- }
- // HNSListNetworkRequest makes a HNS call to query the list of available networks
- func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
- var network []HNSNetwork
- err := hnsCall(method, "/networks/"+path, request, &network)
- if err != nil {
- return nil, err
- }
- return network, nil
- }
- // HNSEndpointRequest makes a HNS call to modify/query a network endpoint
- func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
- endpoint := &HNSEndpoint{}
- err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
- if err != nil {
- return nil, err
- }
- return endpoint, nil
- }
- // HNSListEndpointRequest makes a HNS call to query the list of available endpoints
- func HNSListEndpointRequest() ([]HNSEndpoint, error) {
- var endpoint []HNSEndpoint
- err := hnsCall("GET", "/endpoints/", "", &endpoint)
- if err != nil {
- return nil, err
- }
- return endpoint, nil
- }
- // HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
- func HotAttachEndpoint(containerID string, endpointID string) error {
- return modifyNetworkEndpoint(containerID, endpointID, Add)
- }
- // HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
- func HotDetachEndpoint(containerID string, endpointID string) error {
- return modifyNetworkEndpoint(containerID, endpointID, Remove)
- }
- // ModifyContainer corresponding to the container id, by sending a request
- func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
- container, err := OpenContainer(id)
- if err != nil {
- if IsNotExist(err) {
- return ErrComputeSystemDoesNotExist
- }
- return getInnerError(err)
- }
- defer container.Close()
- err = container.Modify(request)
- if err != nil {
- if IsNotSupported(err) {
- return ErrPlatformNotSupported
- }
- return getInnerError(err)
- }
- return nil
- }
- func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {
- requestMessage := &ResourceModificationRequestResponse{
- Resource: Network,
- Request: request,
- Data: endpointID,
- }
- err := modifyContainer(containerID, requestMessage)
- if err != nil {
- return err
- }
- return nil
- }
- // GetHNSNetworkByID
- func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
- return HNSNetworkRequest("GET", networkID, "")
- }
- // GetHNSNetworkName filtered by Name
- func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
- hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
- if err != nil {
- return nil, err
- }
- for _, hnsnetwork := range hsnnetworks {
- if hnsnetwork.Name == networkName {
- return &hnsnetwork, nil
- }
- }
- return nil, fmt.Errorf("Network %v not found", networkName)
- }
- // Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
- func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
- jsonString, err := json.Marshal(endpoint)
- if err != nil {
- return nil, err
- }
- return HNSEndpointRequest("POST", "", string(jsonString))
- }
- // Create Endpoint by sending EndpointRequest to HNS
- func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
- return HNSEndpointRequest("DELETE", endpoint.Id, "")
- }
- // GetHNSEndpointByID
- func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
- return HNSEndpointRequest("GET", endpointID, "")
- }
- // GetHNSNetworkName filtered by Name
- func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
- hnsResponse, err := HNSListEndpointRequest()
- if err != nil {
- return nil, err
- }
- for _, hnsEndpoint := range hnsResponse {
- if hnsEndpoint.Name == endpointName {
- return &hnsEndpoint, nil
- }
- }
- return nil, fmt.Errorf("Endpoint %v not found", endpointName)
- }
|