package hcsshim | |
import ( | |
"encoding/json" | |
"net" | |
"github.com/sirupsen/logrus" | |
) | |
// 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"` | |
} | |
//SystemType represents the type of the system on which actions are done | |
type SystemType string | |
// SystemType const | |
const ( | |
ContainerType SystemType = "Container" | |
VirtualMachineType SystemType = "VirtualMachine" | |
HostType SystemType = "Host" | |
) | |
// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system | |
// Supported resource types are Network and Request Types are Add/Remove | |
type EndpointAttachDetachRequest struct { | |
ContainerID string `json:"ContainerId,omitempty"` | |
SystemType SystemType `json:"SystemType"` | |
CompartmentID uint16 `json:"CompartmentId,omitempty"` | |
VirtualNICName string `json:"VirtualNicName,omitempty"` | |
} | |
// EndpointResquestResponse is object to get the endpoint request response | |
type EndpointResquestResponse struct { | |
Success bool | |
Error string | |
} | |
// 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 | |
} | |
// GetHNSEndpointByID get the Endpoint by ID | |
func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) { | |
return HNSEndpointRequest("GET", endpointID, "") | |
} | |
// GetHNSEndpointByName gets the endpoint 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, EndpointNotFoundError{EndpointName: endpointName} | |
} | |
// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods | |
func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) { | |
operation := "Create" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
jsonString, err := json.Marshal(endpoint) | |
if err != nil { | |
return nil, err | |
} | |
return HNSEndpointRequest("POST", "", string(jsonString)) | |
} | |
// Delete Endpoint by sending EndpointRequest to HNS | |
func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) { | |
operation := "Delete" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
return HNSEndpointRequest("DELETE", endpoint.Id, "") | |
} | |
// Update Endpoint | |
func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) { | |
operation := "Update" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
jsonString, err := json.Marshal(endpoint) | |
if err != nil { | |
return nil, err | |
} | |
err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint) | |
return endpoint, err | |
} | |
// ContainerHotAttach attaches an endpoint to a running container | |
func (endpoint *HNSEndpoint) ContainerHotAttach(containerID string) error { | |
operation := "ContainerHotAttach" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID) | |
return modifyNetworkEndpoint(containerID, endpoint.Id, Add) | |
} | |
// ContainerHotDetach detaches an endpoint from a running container | |
func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error { | |
operation := "ContainerHotDetach" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID) | |
return modifyNetworkEndpoint(containerID, endpoint.Id, Remove) | |
} | |
// ApplyACLPolicy applies a set of ACL Policies on the Endpoint | |
func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error { | |
operation := "ApplyACLPolicy" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
for _, policy := range policies { | |
if policy == nil { | |
continue | |
} | |
jsonString, err := json.Marshal(policy) | |
if err != nil { | |
return err | |
} | |
endpoint.Policies = append(endpoint.Policies, jsonString) | |
} | |
_, err := endpoint.Update() | |
return err | |
} | |
// ContainerAttach attaches an endpoint to container | |
func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error { | |
operation := "ContainerAttach" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
requestMessage := &EndpointAttachDetachRequest{ | |
ContainerID: containerID, | |
CompartmentID: compartmentID, | |
SystemType: ContainerType, | |
} | |
response := &EndpointResquestResponse{} | |
jsonString, err := json.Marshal(requestMessage) | |
if err != nil { | |
return err | |
} | |
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response) | |
} | |
// ContainerDetach detaches an endpoint from container | |
func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error { | |
operation := "ContainerDetach" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
requestMessage := &EndpointAttachDetachRequest{ | |
ContainerID: containerID, | |
SystemType: ContainerType, | |
} | |
response := &EndpointResquestResponse{} | |
jsonString, err := json.Marshal(requestMessage) | |
if err != nil { | |
return err | |
} | |
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response) | |
} | |
// HostAttach attaches a nic on the host | |
func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error { | |
operation := "HostAttach" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
requestMessage := &EndpointAttachDetachRequest{ | |
CompartmentID: compartmentID, | |
SystemType: HostType, | |
} | |
response := &EndpointResquestResponse{} | |
jsonString, err := json.Marshal(requestMessage) | |
if err != nil { | |
return err | |
} | |
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response) | |
} | |
// HostDetach detaches a nic on the host | |
func (endpoint *HNSEndpoint) HostDetach() error { | |
operation := "HostDetach" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
requestMessage := &EndpointAttachDetachRequest{ | |
SystemType: HostType, | |
} | |
response := &EndpointResquestResponse{} | |
jsonString, err := json.Marshal(requestMessage) | |
if err != nil { | |
return err | |
} | |
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response) | |
} | |
// VirtualMachineNICAttach attaches a endpoint to a virtual machine | |
func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error { | |
operation := "VirtualMachineNicAttach" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
requestMessage := &EndpointAttachDetachRequest{ | |
VirtualNICName: virtualMachineNICName, | |
SystemType: VirtualMachineType, | |
} | |
response := &EndpointResquestResponse{} | |
jsonString, err := json.Marshal(requestMessage) | |
if err != nil { | |
return err | |
} | |
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response) | |
} | |
// VirtualMachineNICDetach detaches a endpoint from a virtual machine | |
func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error { | |
operation := "VirtualMachineNicDetach" | |
title := "HCSShim::HNSEndpoint::" + operation | |
logrus.Debugf(title+" id=%s", endpoint.Id) | |
requestMessage := &EndpointAttachDetachRequest{ | |
SystemType: VirtualMachineType, | |
} | |
response := &EndpointResquestResponse{} | |
jsonString, err := json.Marshal(requestMessage) | |
if err != nil { | |
return err | |
} | |
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response) | |
} |