...

Source file src/github.com/Microsoft/hcsshim/internal/hns/hnsendpoint.go

Documentation: github.com/Microsoft/hcsshim/internal/hns

     1  //go:build windows
     2  
     3  package hns
     4  
     5  import (
     6  	"encoding/json"
     7  	"net"
     8  	"strings"
     9  
    10  	"github.com/sirupsen/logrus"
    11  )
    12  
    13  // HNSEndpoint represents a network endpoint in HNS
    14  type HNSEndpoint struct {
    15  	Id                 string            `json:"ID,omitempty"`
    16  	Name               string            `json:",omitempty"`
    17  	VirtualNetwork     string            `json:",omitempty"`
    18  	VirtualNetworkName string            `json:",omitempty"`
    19  	Policies           []json.RawMessage `json:",omitempty"`
    20  	MacAddress         string            `json:",omitempty"`
    21  	IPAddress          net.IP            `json:",omitempty"`
    22  	IPv6Address        net.IP            `json:",omitempty"`
    23  	DNSSuffix          string            `json:",omitempty"`
    24  	DNSServerList      string            `json:",omitempty"`
    25  	DNSDomain          string            `json:",omitempty"`
    26  	GatewayAddress     string            `json:",omitempty"`
    27  	GatewayAddressV6   string            `json:",omitempty"`
    28  	EnableInternalDNS  bool              `json:",omitempty"`
    29  	DisableICC         bool              `json:",omitempty"`
    30  	PrefixLength       uint8             `json:",omitempty"`
    31  	IPv6PrefixLength   uint8             `json:",omitempty"`
    32  	IsRemoteEndpoint   bool              `json:",omitempty"`
    33  	EnableLowMetric    bool              `json:",omitempty"`
    34  	Namespace          *Namespace        `json:",omitempty"`
    35  	EncapOverhead      uint16            `json:",omitempty"`
    36  	SharedContainers   []string          `json:",omitempty"`
    37  }
    38  
    39  // SystemType represents the type of the system on which actions are done
    40  type SystemType string
    41  
    42  // SystemType const
    43  const (
    44  	ContainerType      SystemType = "Container"
    45  	VirtualMachineType SystemType = "VirtualMachine"
    46  	HostType           SystemType = "Host"
    47  )
    48  
    49  // EndpointAttachDetachRequest is the structure used to send request to the container to modify the system
    50  // Supported resource types are Network and Request Types are Add/Remove
    51  type EndpointAttachDetachRequest struct {
    52  	ContainerID    string     `json:"ContainerId,omitempty"`
    53  	SystemType     SystemType `json:"SystemType"`
    54  	CompartmentID  uint16     `json:"CompartmentId,omitempty"`
    55  	VirtualNICName string     `json:"VirtualNicName,omitempty"`
    56  }
    57  
    58  // EndpointResquestResponse is object to get the endpoint request response
    59  type EndpointResquestResponse struct {
    60  	Success bool
    61  	Error   string
    62  }
    63  
    64  // EndpointStats is the object that has stats for a given endpoint
    65  type EndpointStats struct {
    66  	BytesReceived          uint64 `json:"BytesReceived"`
    67  	BytesSent              uint64 `json:"BytesSent"`
    68  	DroppedPacketsIncoming uint64 `json:"DroppedPacketsIncoming"`
    69  	DroppedPacketsOutgoing uint64 `json:"DroppedPacketsOutgoing"`
    70  	EndpointID             string `json:"EndpointId"`
    71  	InstanceID             string `json:"InstanceId"`
    72  	PacketsReceived        uint64 `json:"PacketsReceived"`
    73  	PacketsSent            uint64 `json:"PacketsSent"`
    74  }
    75  
    76  // HNSEndpointRequest makes a HNS call to modify/query a network endpoint
    77  func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
    78  	endpoint := &HNSEndpoint{}
    79  	err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	return endpoint, nil
    85  }
    86  
    87  // HNSListEndpointRequest makes a HNS call to query the list of available endpoints
    88  func HNSListEndpointRequest() ([]HNSEndpoint, error) {
    89  	var endpoint []HNSEndpoint
    90  	err := hnsCall("GET", "/endpoints/", "", &endpoint)
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	return endpoint, nil
    96  }
    97  
    98  // hnsEndpointStatsRequest makes a HNS call to query the stats for a given endpoint ID
    99  func hnsEndpointStatsRequest(id string) (*EndpointStats, error) {
   100  	var stats EndpointStats
   101  	err := hnsCall("GET", "/endpointstats/"+id, "", &stats)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	return &stats, nil
   107  }
   108  
   109  // GetHNSEndpointByID get the Endpoint by ID
   110  func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
   111  	return HNSEndpointRequest("GET", endpointID, "")
   112  }
   113  
   114  // GetHNSEndpointStats get the stats for a n Endpoint by ID
   115  func GetHNSEndpointStats(endpointID string) (*EndpointStats, error) {
   116  	return hnsEndpointStatsRequest(endpointID)
   117  }
   118  
   119  // GetHNSEndpointByName gets the endpoint filtered by Name
   120  func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
   121  	hnsResponse, err := HNSListEndpointRequest()
   122  	if err != nil {
   123  		return nil, err
   124  	}
   125  	for _, hnsEndpoint := range hnsResponse {
   126  		if hnsEndpoint.Name == endpointName {
   127  			return &hnsEndpoint, nil
   128  		}
   129  	}
   130  	return nil, EndpointNotFoundError{EndpointName: endpointName}
   131  }
   132  
   133  type endpointAttachInfo struct {
   134  	SharedContainers json.RawMessage `json:",omitempty"`
   135  }
   136  
   137  func (endpoint *HNSEndpoint) IsAttached(vID string) (bool, error) {
   138  	attachInfo := endpointAttachInfo{}
   139  	err := hnsCall("GET", "/endpoints/"+endpoint.Id, "", &attachInfo)
   140  
   141  	// Return false allows us to just return the err
   142  	if err != nil {
   143  		return false, err
   144  	}
   145  
   146  	if strings.Contains(strings.ToLower(string(attachInfo.SharedContainers)), strings.ToLower(vID)) {
   147  		return true, nil
   148  	}
   149  
   150  	return false, nil
   151  }
   152  
   153  // Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
   154  func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
   155  	operation := "Create"
   156  	title := "hcsshim::HNSEndpoint::" + operation
   157  	logrus.Debugf(title+" id=%s", endpoint.Id)
   158  
   159  	jsonString, err := json.Marshal(endpoint)
   160  	if err != nil {
   161  		return nil, err
   162  	}
   163  	return HNSEndpointRequest("POST", "", string(jsonString))
   164  }
   165  
   166  // Delete Endpoint by sending EndpointRequest to HNS
   167  func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
   168  	operation := "Delete"
   169  	title := "hcsshim::HNSEndpoint::" + operation
   170  	logrus.Debugf(title+" id=%s", endpoint.Id)
   171  
   172  	return HNSEndpointRequest("DELETE", endpoint.Id, "")
   173  }
   174  
   175  // Update Endpoint
   176  func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
   177  	operation := "Update"
   178  	title := "hcsshim::HNSEndpoint::" + operation
   179  	logrus.Debugf(title+" id=%s", endpoint.Id)
   180  	jsonString, err := json.Marshal(endpoint)
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  	err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)
   185  
   186  	return endpoint, err
   187  }
   188  
   189  // ApplyACLPolicy applies a set of ACL Policies on the Endpoint
   190  func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error {
   191  	operation := "ApplyACLPolicy"
   192  	title := "hcsshim::HNSEndpoint::" + operation
   193  	logrus.Debugf(title+" id=%s", endpoint.Id)
   194  
   195  	for _, policy := range policies {
   196  		if policy == nil {
   197  			continue
   198  		}
   199  		jsonString, err := json.Marshal(policy)
   200  		if err != nil {
   201  			return err
   202  		}
   203  		endpoint.Policies = append(endpoint.Policies, jsonString)
   204  	}
   205  
   206  	_, err := endpoint.Update()
   207  	return err
   208  }
   209  
   210  // ApplyProxyPolicy applies a set of Proxy Policies on the Endpoint
   211  func (endpoint *HNSEndpoint) ApplyProxyPolicy(policies ...*ProxyPolicy) error {
   212  	operation := "ApplyProxyPolicy"
   213  	title := "hcsshim::HNSEndpoint::" + operation
   214  	logrus.Debugf(title+" id=%s", endpoint.Id)
   215  
   216  	for _, policy := range policies {
   217  		if policy == nil {
   218  			continue
   219  		}
   220  		jsonString, err := json.Marshal(policy)
   221  		if err != nil {
   222  			return err
   223  		}
   224  		endpoint.Policies = append(endpoint.Policies, jsonString)
   225  	}
   226  
   227  	_, err := endpoint.Update()
   228  	return err
   229  }
   230  
   231  // ContainerAttach attaches an endpoint to container
   232  func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {
   233  	operation := "ContainerAttach"
   234  	title := "hcsshim::HNSEndpoint::" + operation
   235  	logrus.Debugf(title+" id=%s", endpoint.Id)
   236  
   237  	requestMessage := &EndpointAttachDetachRequest{
   238  		ContainerID:   containerID,
   239  		CompartmentID: compartmentID,
   240  		SystemType:    ContainerType,
   241  	}
   242  	response := &EndpointResquestResponse{}
   243  	jsonString, err := json.Marshal(requestMessage)
   244  	if err != nil {
   245  		return err
   246  	}
   247  	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
   248  }
   249  
   250  // ContainerDetach detaches an endpoint from container
   251  func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {
   252  	operation := "ContainerDetach"
   253  	title := "hcsshim::HNSEndpoint::" + operation
   254  	logrus.Debugf(title+" id=%s", endpoint.Id)
   255  
   256  	requestMessage := &EndpointAttachDetachRequest{
   257  		ContainerID: containerID,
   258  		SystemType:  ContainerType,
   259  	}
   260  	response := &EndpointResquestResponse{}
   261  
   262  	jsonString, err := json.Marshal(requestMessage)
   263  	if err != nil {
   264  		return err
   265  	}
   266  	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
   267  }
   268  
   269  // HostAttach attaches a nic on the host
   270  func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {
   271  	operation := "HostAttach"
   272  	title := "hcsshim::HNSEndpoint::" + operation
   273  	logrus.Debugf(title+" id=%s", endpoint.Id)
   274  	requestMessage := &EndpointAttachDetachRequest{
   275  		CompartmentID: compartmentID,
   276  		SystemType:    HostType,
   277  	}
   278  	response := &EndpointResquestResponse{}
   279  
   280  	jsonString, err := json.Marshal(requestMessage)
   281  	if err != nil {
   282  		return err
   283  	}
   284  	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
   285  }
   286  
   287  // HostDetach detaches a nic on the host
   288  func (endpoint *HNSEndpoint) HostDetach() error {
   289  	operation := "HostDetach"
   290  	title := "hcsshim::HNSEndpoint::" + operation
   291  	logrus.Debugf(title+" id=%s", endpoint.Id)
   292  	requestMessage := &EndpointAttachDetachRequest{
   293  		SystemType: HostType,
   294  	}
   295  	response := &EndpointResquestResponse{}
   296  
   297  	jsonString, err := json.Marshal(requestMessage)
   298  	if err != nil {
   299  		return err
   300  	}
   301  	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
   302  }
   303  
   304  // VirtualMachineNICAttach attaches a endpoint to a virtual machine
   305  func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {
   306  	operation := "VirtualMachineNicAttach"
   307  	title := "hcsshim::HNSEndpoint::" + operation
   308  	logrus.Debugf(title+" id=%s", endpoint.Id)
   309  	requestMessage := &EndpointAttachDetachRequest{
   310  		VirtualNICName: virtualMachineNICName,
   311  		SystemType:     VirtualMachineType,
   312  	}
   313  	response := &EndpointResquestResponse{}
   314  
   315  	jsonString, err := json.Marshal(requestMessage)
   316  	if err != nil {
   317  		return err
   318  	}
   319  	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
   320  }
   321  
   322  // VirtualMachineNICDetach detaches a endpoint  from a virtual machine
   323  func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {
   324  	operation := "VirtualMachineNicDetach"
   325  	title := "hcsshim::HNSEndpoint::" + operation
   326  	logrus.Debugf(title+" id=%s", endpoint.Id)
   327  
   328  	requestMessage := &EndpointAttachDetachRequest{
   329  		SystemType: VirtualMachineType,
   330  	}
   331  	response := &EndpointResquestResponse{}
   332  
   333  	jsonString, err := json.Marshal(requestMessage)
   334  	if err != nil {
   335  		return err
   336  	}
   337  	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
   338  }
   339  

View as plain text