Alegal/add timeout to hns calls (#1369)
* initial implemenation with timeout * initial implemenation with timeout hns * modify test * modify code slightly * updating to read in timeout flag and settings * updating to read in timeout settings * remove extra space * correct a typo * timeout value greater than zero for detection * add couple ut's and remove needless code * including timeout in hnsv1 * wip * address comments * address comments * supress linter errors and update conflist * fix linter and ensure we don't regress our tests * updating with p.r feedback * addressing comments * updating linter warning * update to address TM's comments * fix lint error * correct a linter spacing complaint * remove fmt.sprintf
This commit is contained in:
Родитель
b1ae762c89
Коммит
251edbfd04
|
@ -43,7 +43,10 @@
|
|||
"NeedEncap": true
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"windowsSettings": {
|
||||
"hnsTimeoutDurationInSeconds" : 120
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -43,7 +43,10 @@
|
|||
"NeedEncap": true
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"windowsSettings": {
|
||||
"hnsTimeoutDurationInSeconds" : 120
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -80,7 +80,8 @@ type NetworkConfig struct {
|
|||
}
|
||||
|
||||
type WindowsSettings struct {
|
||||
EnableLoopbackDSR bool `json:"enableLoopbackDSR,omitempty"`
|
||||
EnableLoopbackDSR bool `json:"enableLoopbackDSR,omitempty"`
|
||||
HnsTimeoutDurationInSeconds int `json:"hnsTimeoutDurationInSeconds,omitempty"`
|
||||
}
|
||||
|
||||
type K8SPodEnvArgs struct {
|
||||
|
|
|
@ -72,7 +72,6 @@ type NetPlugin struct {
|
|||
report *telemetry.CNIReport
|
||||
tb *telemetry.TelemetryBuffer
|
||||
nnsClient NnsClient
|
||||
hnsEndpointClient network.AzureHNSEndpointClient
|
||||
multitenancyClient MultitenancyClient
|
||||
}
|
||||
|
||||
|
@ -106,7 +105,6 @@ func NewPlugin(name string,
|
|||
config *common.PluginConfig,
|
||||
client NnsClient,
|
||||
multitenancyClient MultitenancyClient,
|
||||
azHnsClient network.AzureHNSEndpointClient,
|
||||
) (*NetPlugin, error) {
|
||||
// Setup base plugin.
|
||||
plugin, err := cni.NewPlugin(name, config.Version)
|
||||
|
@ -128,7 +126,6 @@ func NewPlugin(name string,
|
|||
nm: nm,
|
||||
nnsClient: client,
|
||||
multitenancyClient: multitenancyClient,
|
||||
hnsEndpointClient: azHnsClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -399,6 +396,7 @@ func (plugin *NetPlugin) Add(args *cniSkel.CmdArgs) error {
|
|||
return plugin.Errorf(errMsg)
|
||||
}
|
||||
|
||||
platformInit(nwCfg)
|
||||
if nwCfg.ExecutionMode == string(util.Baremetal) {
|
||||
var res *nnscontracts.ConfigureContainerNetworkingResponse
|
||||
log.Printf("Baremetal mode. Calling vnet agent for ADD")
|
||||
|
@ -898,6 +896,8 @@ func (plugin *NetPlugin) Delete(args *cniSkel.CmdArgs) error {
|
|||
telemetry.SendCNIMetric(&cniMetric, plugin.tb)
|
||||
}
|
||||
|
||||
platformInit(nwCfg)
|
||||
|
||||
log.Printf("Execution mode :%s", nwCfg.ExecutionMode)
|
||||
if nwCfg.ExecutionMode == string(util.Baremetal) {
|
||||
|
||||
|
|
|
@ -138,3 +138,5 @@ func (plugin *NetPlugin) getNetworkName(_ string, _ *IPAMAddResult, nwCfg *cni.N
|
|||
func getNATInfo(_ string, _ interface{}, _, _ bool) (natInfo []policy.NATInfo) {
|
||||
return natInfo
|
||||
}
|
||||
|
||||
func platformInit(cniConfig *cni.NetworkConfig) {}
|
||||
|
|
|
@ -69,7 +69,7 @@ func GetTestResources() *NetPlugin {
|
|||
pluginName := "testplugin"
|
||||
config := &common.PluginConfig{}
|
||||
grpcClient := &nns.MockGrpcClient{}
|
||||
plugin, _ := NewPlugin(pluginName, config, grpcClient, &Multitenancy{}, nil)
|
||||
plugin, _ := NewPlugin(pluginName, config, grpcClient, &Multitenancy{})
|
||||
plugin.report = &telemetry.CNIReport{}
|
||||
mockNetworkManager := acnnetwork.NewMockNetworkmanager()
|
||||
plugin.nm = mockNetworkManager
|
||||
|
@ -957,7 +957,7 @@ func TestNewPlugin(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
plugin, err := NewPlugin("test", &tt.config, nil, nil, nil)
|
||||
plugin, err := NewPlugin("test", &tt.config, nil, nil)
|
||||
if tt.wantErr {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, plugin)
|
||||
|
|
|
@ -49,15 +49,15 @@ func (plugin *NetPlugin) handleConsecutiveAdd(args *cniSkel.CmdArgs, endpointId
|
|||
return nil, err
|
||||
}
|
||||
|
||||
hnsEndpoint, err := plugin.hnsEndpointClient.GetHNSEndpointByName(endpointId)
|
||||
hnsEndpoint, err := network.Hnsv1.GetHNSEndpointByName(endpointId)
|
||||
if hnsEndpoint != nil {
|
||||
log.Printf("[net] Found existing endpoint through hcsshim: %+v", hnsEndpoint)
|
||||
endpoint, _ := plugin.hnsEndpointClient.GetHNSEndpointByID(hnsEndpoint.Id)
|
||||
isAttached, _ := plugin.hnsEndpointClient.IsAttached(endpoint, args.ContainerID)
|
||||
endpoint, _ := network.Hnsv1.GetHNSEndpointByID(hnsEndpoint.Id)
|
||||
isAttached, _ := network.Hnsv1.IsAttached(endpoint, args.ContainerID)
|
||||
// Attach endpoint if it's not attached yet.
|
||||
if !isAttached {
|
||||
log.Printf("[net] Attaching ep %v to container %v", hnsEndpoint.Id, args.ContainerID)
|
||||
err := plugin.hnsEndpointClient.HotAttachEndpoint(args.ContainerID, hnsEndpoint.Id)
|
||||
err := network.Hnsv1.HotAttachEndpoint(args.ContainerID, hnsEndpoint.Id)
|
||||
if err != nil {
|
||||
log.Printf("[cni-net] Failed to hot attach shared endpoint[%v] to container [%v], err:%v.", hnsEndpoint.Id, args.ContainerID, err)
|
||||
return nil, err
|
||||
|
@ -388,3 +388,11 @@ func getNATInfo(executionMode string, ncPrimaryIPIface interface{}, multitenancy
|
|||
|
||||
return natInfo
|
||||
}
|
||||
|
||||
func platformInit(cniConfig *cni.NetworkConfig) {
|
||||
if cniConfig.WindowsSettings.HnsTimeoutDurationInSeconds > 0 {
|
||||
log.Printf("Enabling timeout for Hns calls with a timeout value of : %v", cniConfig.WindowsSettings.HnsTimeoutDurationInSeconds)
|
||||
network.EnableHnsV1Timeout(cniConfig.WindowsSettings.HnsTimeoutDurationInSeconds)
|
||||
network.EnableHnsV2Timeout(cniConfig.WindowsSettings.HnsTimeoutDurationInSeconds)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ package network
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Azure/azure-container-networking/network/hnswrapper"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
|
@ -19,6 +20,10 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func init() {
|
||||
network.Hnsv2 = hnswrapper.NewHnsv2wrapperFake()
|
||||
network.Hnsv1 = hnswrapper.NewHnsv1wrapperFake()
|
||||
}
|
||||
// Test windows network policies is set
|
||||
func TestAddWithRunTimeNetPolicies(t *testing.T) {
|
||||
_, ipnetv4, _ := net.ParseCIDR("10.240.0.0/12")
|
||||
|
@ -87,7 +92,6 @@ func TestPluginSecondAddSamePodWindows(t *testing.T) {
|
|||
Plugin: plugin,
|
||||
nm: network.NewMockNetworkmanager(),
|
||||
ipamInvoker: NewMockIpamInvoker(false, false, false),
|
||||
hnsEndpointClient: network.NewMockHNSEndpoint(true, false),
|
||||
report: &telemetry.CNIReport{},
|
||||
tb: &telemetry.TelemetryBuffer{},
|
||||
},
|
||||
|
@ -107,7 +111,6 @@ func TestPluginSecondAddSamePodWindows(t *testing.T) {
|
|||
Plugin: plugin,
|
||||
nm: network.NewMockNetworkmanager(),
|
||||
ipamInvoker: NewMockIpamInvoker(false, false, false),
|
||||
hnsEndpointClient: network.NewMockHNSEndpoint(false, false),
|
||||
report: &telemetry.CNIReport{},
|
||||
tb: &telemetry.TelemetryBuffer{},
|
||||
},
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
"github.com/Azure/azure-container-networking/cni/network"
|
||||
"github.com/Azure/azure-container-networking/common"
|
||||
"github.com/Azure/azure-container-networking/log"
|
||||
acnnetwork "github.com/Azure/azure-container-networking/network"
|
||||
"github.com/Azure/azure-container-networking/nns"
|
||||
"github.com/Azure/azure-container-networking/platform"
|
||||
"github.com/Azure/azure-container-networking/store"
|
||||
|
@ -163,7 +162,6 @@ func rootExecute() error {
|
|||
&config,
|
||||
&nns.GrpcClient{},
|
||||
&network.Multitenancy{},
|
||||
&acnnetwork.AzureHNSEndpoint{},
|
||||
)
|
||||
if err != nil {
|
||||
printCNIError(fmt.Sprintf("Failed to create network plugin, err:%v.\n", err))
|
||||
|
|
|
@ -197,11 +197,11 @@ func (nw *network) getEndpointByPOD(podName string, podNameSpace string, doExact
|
|||
|
||||
func podNameMatches(source string, actualValue string, doExactMatch bool) bool {
|
||||
if doExactMatch {
|
||||
return (source == actualValue)
|
||||
return source == actualValue
|
||||
} else {
|
||||
// If exact match flag is disabled we just check if the existing podname field for an endpoint
|
||||
// starts with passed podname string.
|
||||
return (actualValue == GetPodNameWithoutSuffix(source))
|
||||
return actualValue == GetPodNameWithoutSuffix(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,24 +5,18 @@ package network
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-container-networking/log"
|
||||
"github.com/Azure/azure-container-networking/netlink"
|
||||
"github.com/Azure/azure-container-networking/network/hnswrapper"
|
||||
"github.com/Azure/azure-container-networking/network/policy"
|
||||
"github.com/Azure/azure-container-networking/platform"
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/Microsoft/hcsshim/hcn"
|
||||
)
|
||||
|
||||
// this hnsv2 variable is package level variable in network
|
||||
// we do this to avoid passing around os specific objects in platform agnostic code
|
||||
var hnsv2 hnswrapper.HnsV2WrapperInterface = hnswrapper.Hnsv2wrapper{}
|
||||
|
||||
const (
|
||||
// hcnSchemaVersionMajor indicates major version number for hcn schema
|
||||
hcnSchemaVersionMajor = 2
|
||||
|
@ -44,34 +38,6 @@ const (
|
|||
hostNCApipaEndpointNamePrefix = "HostNCApipaEndpoint"
|
||||
)
|
||||
|
||||
type AzureHNSEndpointClient interface {
|
||||
GetHNSEndpointByName(endpointName string) (*hcsshim.HNSEndpoint, error)
|
||||
GetHNSEndpointByID(endpointID string) (*hcsshim.HNSEndpoint, error)
|
||||
HotAttachEndpoint(containerID string, endpointID string) error
|
||||
IsAttached(hnsep *hcsshim.HNSEndpoint, containerID string) (bool, error)
|
||||
}
|
||||
|
||||
func (az AzureHNSEndpoint) GetHNSEndpointByName(endpointName string) (*hcsshim.HNSEndpoint, error) {
|
||||
return hcsshim.GetHNSEndpointByName(endpointName)
|
||||
}
|
||||
|
||||
func (az AzureHNSEndpoint) GetHNSEndpointByID(id string) (*hcsshim.HNSEndpoint, error) {
|
||||
return hcsshim.GetHNSEndpointByID(id)
|
||||
}
|
||||
|
||||
func (az AzureHNSEndpoint) HotAttachEndpoint(containerID, endpointID string) error {
|
||||
return hcsshim.HotAttachEndpoint(containerID, endpointID)
|
||||
}
|
||||
|
||||
func (az AzureHNSEndpoint) IsAttached(hnsep *hcsshim.HNSEndpoint, containerID string) (bool, error) {
|
||||
return hnsep.IsAttached(containerID)
|
||||
}
|
||||
|
||||
// HotAttachEndpoint is a wrapper of hcsshim's HotAttachEndpoint.
|
||||
func (endpoint *EndpointInfo) HotAttachEndpoint(containerID string) error {
|
||||
return hcsshim.HotAttachEndpoint(containerID, endpoint.Id)
|
||||
}
|
||||
|
||||
// ConstructEndpointID constructs endpoint name from netNsPath.
|
||||
func ConstructEndpointID(containerID string, netNsPath string, ifName string) (string, string) {
|
||||
if len(containerID) > 8 {
|
||||
|
@ -98,6 +64,7 @@ func ConstructEndpointID(containerID string, netNsPath string, ifName string) (s
|
|||
|
||||
// newEndpointImpl creates a new endpoint in the network.
|
||||
func (nw *network) newEndpointImpl(cli apipaClient, _ netlink.NetlinkInterface, _ platform.ExecClient, epInfo *EndpointInfo) (*endpoint, error) {
|
||||
|
||||
if useHnsV2, err := UseHnsV2(epInfo.NetNsPath); useHnsV2 {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -147,17 +114,8 @@ func (nw *network) newEndpointImplHnsV1(epInfo *EndpointInfo) (*endpoint, error)
|
|||
}
|
||||
}
|
||||
|
||||
// Marshal the request.
|
||||
buffer, err := json.Marshal(hnsEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hnsRequest := string(buffer)
|
||||
hnsResponse, err := Hnsv1.CreateEndpoint(hnsEndpoint, "")
|
||||
|
||||
// Create the HNS endpoint.
|
||||
log.Printf("[net] HNSEndpointRequest POST request:%+v", hnsRequest)
|
||||
hnsResponse, err := hcsshim.HNSEndpointRequest("POST", "", hnsRequest)
|
||||
log.Printf("[net] HNSEndpointRequest POST response:%+v err:%v.", hnsResponse, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -165,7 +123,7 @@ func (nw *network) newEndpointImplHnsV1(epInfo *EndpointInfo) (*endpoint, error)
|
|||
defer func() {
|
||||
if err != nil {
|
||||
log.Printf("[net] HNSEndpointRequest DELETE id:%v", hnsResponse.Id)
|
||||
hnsResponse, err := hcsshim.HNSEndpointRequest("DELETE", hnsResponse.Id, "")
|
||||
hnsResponse, err := Hnsv1.DeleteEndpoint(hnsResponse.Id)
|
||||
log.Printf("[net] HNSEndpointRequest DELETE response:%+v err:%v.", hnsResponse, err)
|
||||
}
|
||||
}()
|
||||
|
@ -176,7 +134,7 @@ func (nw *network) newEndpointImplHnsV1(epInfo *EndpointInfo) (*endpoint, error)
|
|||
} else {
|
||||
// Attach the endpoint.
|
||||
log.Printf("[net] Attaching endpoint %v to container %v.", hnsResponse.Id, epInfo.ContainerID)
|
||||
err = hcsshim.HotAttachEndpoint(epInfo.ContainerID, hnsResponse.Id)
|
||||
err = Hnsv1.HotAttachEndpoint(epInfo.ContainerID, hnsResponse.Id)
|
||||
if err != nil {
|
||||
log.Printf("[net] Failed to attach endpoint: %v.", err)
|
||||
return nil, err
|
||||
|
@ -294,7 +252,7 @@ func (nw *network) deleteHostNCApipaEndpoint(networkContainerID string) error {
|
|||
log.Printf("[net] Deleting HostNCApipaEndpoint: %s for NC: %s", endpointName, networkContainerID)
|
||||
|
||||
// Check if the endpoint exists
|
||||
endpoint, err := hnsv2.GetEndpointByName(endpointName)
|
||||
endpoint, err := Hnsv2.GetEndpointByName(endpointName)
|
||||
if err != nil {
|
||||
// If error is anything other than EndpointNotFoundError, return error.
|
||||
// else log the error but don't return error because endpoint is already deleted.
|
||||
|
@ -306,7 +264,7 @@ func (nw *network) deleteHostNCApipaEndpoint(networkContainerID string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if err := hnsv2.DeleteEndpoint(endpoint); err != nil {
|
||||
if err := Hnsv2.DeleteEndpoint(endpoint); err != nil {
|
||||
return fmt.Errorf("failed to delete HostNCApipa endpoint: %+v: %w", endpoint, err)
|
||||
}
|
||||
|
||||
|
@ -351,7 +309,7 @@ func (nw *network) createHostNCApipaEndpoint(cli apipaClient, epInfo *EndpointIn
|
|||
return nil
|
||||
}
|
||||
|
||||
// newEndpointImplHnsV2 creates a new endpoint in the network using HnsV2
|
||||
// newEndpointImplHnsV2 creates a new endpoint in the network using Hnsv2
|
||||
func (nw *network) newEndpointImplHnsV2(cli apipaClient, epInfo *EndpointInfo) (*endpoint, error) {
|
||||
hcnEndpoint, err := nw.configureHcnEndpoint(epInfo)
|
||||
if err != nil {
|
||||
|
@ -361,7 +319,7 @@ func (nw *network) newEndpointImplHnsV2(cli apipaClient, epInfo *EndpointInfo) (
|
|||
|
||||
// Create the HCN endpoint.
|
||||
log.Printf("[net] Creating hcn endpoint: %+v", hcnEndpoint)
|
||||
hnsResponse, err := hnsv2.CreateEndpoint(hcnEndpoint)
|
||||
hnsResponse, err := Hnsv2.CreateEndpoint(hcnEndpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to create endpoint: %s due to error: %v", hcnEndpoint.Name, err)
|
||||
}
|
||||
|
@ -371,24 +329,24 @@ func (nw *network) newEndpointImplHnsV2(cli apipaClient, epInfo *EndpointInfo) (
|
|||
defer func() {
|
||||
if err != nil {
|
||||
log.Printf("[net] Deleting hcn endpoint with id: %s", hnsResponse.Id)
|
||||
err = hnsv2.DeleteEndpoint(hnsResponse)
|
||||
err = Hnsv2.DeleteEndpoint(hnsResponse)
|
||||
log.Printf("[net] Completed hcn endpoint deletion for id: %s with error: %v", hnsResponse.Id, err)
|
||||
}
|
||||
}()
|
||||
|
||||
var namespace *hcn.HostComputeNamespace
|
||||
if namespace, err = hnsv2.GetNamespaceByID(epInfo.NetNsPath); err != nil {
|
||||
if namespace, err = Hnsv2.GetNamespaceByID(epInfo.NetNsPath); err != nil {
|
||||
return nil, fmt.Errorf("Failed to get hcn namespace: %s due to error: %v", epInfo.NetNsPath, err)
|
||||
}
|
||||
|
||||
if err = hnsv2.AddNamespaceEndpoint(namespace.Id, hnsResponse.Id); err != nil {
|
||||
if err = Hnsv2.AddNamespaceEndpoint(namespace.Id, hnsResponse.Id); err != nil {
|
||||
return nil, fmt.Errorf("[net] Failed to add endpoint: %s to hcn namespace: %s due to error: %v",
|
||||
hnsResponse.Id, namespace.Id, err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if errRemoveNsEp := hnsv2.RemoveNamespaceEndpoint(namespace.Id, hnsResponse.Id); errRemoveNsEp != nil {
|
||||
if errRemoveNsEp := Hnsv2.RemoveNamespaceEndpoint(namespace.Id, hnsResponse.Id); errRemoveNsEp != nil {
|
||||
log.Printf("[net] Failed to remove endpoint: %s from namespace: %s due to error: %v",
|
||||
hnsResponse.Id, hnsResponse.Id, errRemoveNsEp)
|
||||
}
|
||||
|
@ -456,7 +414,7 @@ func (nw *network) deleteEndpointImpl(_ netlink.NetlinkInterface, _ platform.Exe
|
|||
// deleteEndpointImplHnsV1 deletes an existing endpoint from the network using HNS v1.
|
||||
func (nw *network) deleteEndpointImplHnsV1(ep *endpoint) error {
|
||||
log.Printf("[net] HNSEndpointRequest DELETE id:%v", ep.HnsId)
|
||||
hnsResponse, err := hcsshim.HNSEndpointRequest("DELETE", ep.HnsId, "")
|
||||
hnsResponse, err := Hnsv1.DeleteEndpoint(ep.HnsId)
|
||||
log.Printf("[net] HNSEndpointRequest DELETE response:%+v err:%v.", hnsResponse, err)
|
||||
|
||||
// todo: may need to improve error handling if hns or hcsshim change their error bubbling.
|
||||
|
@ -488,7 +446,7 @@ func (nw *network) deleteEndpointImplHnsV2(ep *endpoint) error {
|
|||
|
||||
log.Printf("[net] Deleting hcn endpoint with id: %s", ep.HnsId)
|
||||
|
||||
hcnEndpoint, err = hnsv2.GetEndpointByID(ep.HnsId)
|
||||
hcnEndpoint, err = Hnsv2.GetEndpointByID(ep.HnsId)
|
||||
if err != nil {
|
||||
// If error is anything other than EndpointNotFoundError, return error.
|
||||
// else log the error but don't return error because endpoint is already deleted.
|
||||
|
@ -501,12 +459,12 @@ func (nw *network) deleteEndpointImplHnsV2(ep *endpoint) error {
|
|||
}
|
||||
|
||||
// Remove this endpoint from the namespace
|
||||
if err = hnsv2.RemoveNamespaceEndpoint(hcnEndpoint.HostComputeNamespace, hcnEndpoint.Id); err != nil {
|
||||
if err = Hnsv2.RemoveNamespaceEndpoint(hcnEndpoint.HostComputeNamespace, hcnEndpoint.Id); err != nil {
|
||||
log.Errorf("Failed to remove hcn endpoint: %s from namespace: %s due to error: %v", ep.HnsId,
|
||||
hcnEndpoint.HostComputeNamespace, err)
|
||||
}
|
||||
|
||||
if err = hnsv2.DeleteEndpoint(hcnEndpoint); err != nil {
|
||||
if err = Hnsv2.DeleteEndpoint(hcnEndpoint); err != nil {
|
||||
return fmt.Errorf("Failed to delete hcn endpoint: %s due to error: %v", ep.HnsId, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-container-networking/network/hnswrapper"
|
||||
)
|
||||
|
@ -21,7 +22,9 @@ func TestNewAndDeleteEndpointImplHnsV2(t *testing.T) {
|
|||
|
||||
// this hnsv2 variable overwrites the package level variable in network
|
||||
// we do this to avoid passing around os specific objects in platform agnostic code
|
||||
hnsv2 = hnswrapper.Hnsv2wrapperFake{}
|
||||
Hnsv2 = hnswrapper.Hnsv2wrapperwithtimeout{
|
||||
Hnsv2: hnswrapper.NewHnsv2wrapperFake(),
|
||||
}
|
||||
|
||||
epInfo := &EndpointInfo{
|
||||
Id: "753d3fb6-e9b3-49e2-a109-2acc5dda61f1",
|
||||
|
@ -50,3 +53,162 @@ func TestNewAndDeleteEndpointImplHnsV2(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewEndpointImplHnsv2Timesout(t *testing.T) {
|
||||
nw := &network{
|
||||
Endpoints: map[string]*endpoint{},
|
||||
}
|
||||
|
||||
// this hnsv2 variable overwrites the package level variable in network
|
||||
// we do this to avoid passing around os specific objects in platform agnostic code
|
||||
|
||||
hnsFake := hnswrapper.NewHnsv2wrapperFake()
|
||||
|
||||
hnsFake.Delay = 10 * time.Second
|
||||
|
||||
Hnsv2 = hnswrapper.Hnsv2wrapperwithtimeout{
|
||||
Hnsv2: hnsFake,
|
||||
HnsCallTimeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
epInfo := &EndpointInfo{
|
||||
Id: "753d3fb6-e9b3-49e2-a109-2acc5dda61f1",
|
||||
ContainerID: "545055c2-1462-42c8-b222-e75d0b291632",
|
||||
NetNsPath: "fakeNameSpace",
|
||||
IfName: "eth0",
|
||||
Data: make(map[string]interface{}),
|
||||
DNS: DNSInfo{
|
||||
Suffix: "10.0.0.0",
|
||||
Servers: []string{"10.0.0.1, 10.0.0.2"},
|
||||
Options: nil,
|
||||
},
|
||||
MacAddress: net.HardwareAddr("00:00:5e:00:53:01"),
|
||||
}
|
||||
_, err := nw.newEndpointImplHnsV2(nil, epInfo)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Failed to timeout HNS calls for creating endpoint")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDeleteEndpointImplHnsv2Timeout(t *testing.T) {
|
||||
nw := &network{
|
||||
Endpoints: map[string]*endpoint{},
|
||||
}
|
||||
|
||||
Hnsv2 = hnswrapper.NewHnsv2wrapperFake()
|
||||
|
||||
epInfo := &EndpointInfo{
|
||||
Id: "753d3fb6-e9b3-49e2-a109-2acc5dda61f1",
|
||||
ContainerID: "545055c2-1462-42c8-b222-e75d0b291632",
|
||||
NetNsPath: "fakeNameSpace",
|
||||
IfName: "eth0",
|
||||
Data: make(map[string]interface{}),
|
||||
DNS: DNSInfo{
|
||||
Suffix: "10.0.0.0",
|
||||
Servers: []string{"10.0.0.1, 10.0.0.2"},
|
||||
Options: nil,
|
||||
},
|
||||
MacAddress: net.HardwareAddr("00:00:5e:00:53:01"),
|
||||
}
|
||||
endpoint, err := nw.newEndpointImplHnsV2(nil, epInfo)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("+%v", err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
hnsFake := hnswrapper.NewHnsv2wrapperFake()
|
||||
|
||||
hnsFake.Delay = 10 * time.Second
|
||||
|
||||
Hnsv2 = hnswrapper.Hnsv2wrapperwithtimeout{
|
||||
Hnsv2: hnsFake,
|
||||
HnsCallTimeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
err = nw.deleteEndpointImplHnsV2(endpoint)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Failed to timeout HNS calls for deleting endpoint")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateEndpointImplHnsv1Timeout(t *testing.T) {
|
||||
nw := &network{
|
||||
Endpoints: map[string]*endpoint{},
|
||||
}
|
||||
|
||||
hnsFake := hnswrapper.NewHnsv1wrapperFake()
|
||||
|
||||
hnsFake.Delay = 10 * time.Second
|
||||
|
||||
Hnsv1 = hnswrapper.Hnsv1wrapperwithtimeout{
|
||||
Hnsv1: hnsFake,
|
||||
HnsCallTimeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
epInfo := &EndpointInfo{
|
||||
Id: "753d3fb6-e9b3-49e2-a109-2acc5dda61f1",
|
||||
ContainerID: "545055c2-1462-42c8-b222-e75d0b291632",
|
||||
NetNsPath: "fakeNameSpace",
|
||||
IfName: "eth0",
|
||||
Data: make(map[string]interface{}),
|
||||
DNS: DNSInfo{
|
||||
Suffix: "10.0.0.0",
|
||||
Servers: []string{"10.0.0.1, 10.0.0.2"},
|
||||
Options: nil,
|
||||
},
|
||||
MacAddress: net.HardwareAddr("00:00:5e:00:53:01"),
|
||||
}
|
||||
_, err := nw.newEndpointImplHnsV1(epInfo)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Failed to timeout HNS calls for creating endpoint")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDeleteEndpointImplHnsv1Timeout(t *testing.T) {
|
||||
nw := &network{
|
||||
Endpoints: map[string]*endpoint{},
|
||||
}
|
||||
|
||||
Hnsv1 = hnswrapper.NewHnsv1wrapperFake()
|
||||
|
||||
epInfo := &EndpointInfo{
|
||||
Id: "753d3fb6-e9b3-49e2-a109-2acc5dda61f1",
|
||||
ContainerID: "545055c2-1462-42c8-b222-e75d0b291632",
|
||||
NetNsPath: "fakeNameSpace",
|
||||
IfName: "eth0",
|
||||
Data: make(map[string]interface{}),
|
||||
DNS: DNSInfo{
|
||||
Suffix: "10.0.0.0",
|
||||
Servers: []string{"10.0.0.1, 10.0.0.2"},
|
||||
Options: nil,
|
||||
},
|
||||
MacAddress: net.HardwareAddr("00:00:5e:00:53:01"),
|
||||
}
|
||||
endpoint, err := nw.newEndpointImplHnsV1(epInfo)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("+%v", err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
hnsFake := hnswrapper.NewHnsv1wrapperFake()
|
||||
|
||||
hnsFake.Delay = 10 * time.Second
|
||||
|
||||
Hnsv1 = hnswrapper.Hnsv1wrapperwithtimeout{
|
||||
Hnsv1: hnsFake,
|
||||
HnsCallTimeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
err = nw.deleteEndpointImplHnsV1(endpoint)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Failed to timeout HNS calls for deleting endpoint")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
//go:build windows
|
||||
//+build windows
|
||||
|
||||
package hnswrapper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/Azure/azure-container-networking/log"
|
||||
"github.com/Microsoft/hcsshim"
|
||||
)
|
||||
|
||||
type Hnsv1wrapper struct {
|
||||
}
|
||||
|
||||
func (Hnsv1wrapper) CreateEndpoint(endpoint *hcsshim.HNSEndpoint, path string) (*hcsshim.HNSEndpoint, error) {
|
||||
// Marshal the request.
|
||||
buffer, err := json.Marshal(endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hnsRequest := string(buffer)
|
||||
|
||||
// Create the HNS endpoint.
|
||||
log.Printf("[net] HNSEndpointRequest POST request:%+v", hnsRequest)
|
||||
hnsResponse, err := hcsshim.HNSEndpointRequest("POST", path, hnsRequest)
|
||||
log.Printf("[net] HNSEndpointRequest POST response:%+v err:%v.", hnsResponse, err)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return hnsResponse, err
|
||||
}
|
||||
|
||||
func (Hnsv1wrapper) DeleteEndpoint(endpointId string) (*hcsshim.HNSEndpoint, error) {
|
||||
hnsResponse, err := hcsshim.HNSEndpointRequest("DELETE", endpointId, "")
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return hnsResponse, err
|
||||
|
||||
}
|
||||
|
||||
func (Hnsv1wrapper) CreateNetwork(network *hcsshim.HNSNetwork, path string) (*hcsshim.HNSNetwork, error) {
|
||||
// Marshal the request.
|
||||
buffer, err := json.Marshal(network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hnsRequest := string(buffer)
|
||||
|
||||
// Create the HNS network.
|
||||
log.Printf("[net] HNSNetworkRequest POST request:%+v", hnsRequest)
|
||||
hnsResponse, err := hcsshim.HNSNetworkRequest("POST", path, hnsRequest)
|
||||
log.Printf("[net] HNSNetworkRequest POST response:%+v err:%v.", hnsResponse, err)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return hnsResponse, nil
|
||||
}
|
||||
|
||||
func (Hnsv1wrapper) DeleteNetwork(networkId string) (*hcsshim.HNSNetwork, error) {
|
||||
hnsResponse, err := hcsshim.HNSNetworkRequest("DELETE", networkId, "")
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return hnsResponse, err
|
||||
}
|
||||
|
||||
func (Hnsv1wrapper) GetHNSEndpointByName(endpointName string) (*hcsshim.HNSEndpoint, error) {
|
||||
return hcsshim.GetHNSEndpointByName(endpointName)
|
||||
}
|
||||
|
||||
func (Hnsv1wrapper) GetHNSEndpointByID(id string) (*hcsshim.HNSEndpoint, error) {
|
||||
return hcsshim.GetHNSEndpointByID(id)
|
||||
}
|
||||
|
||||
func (Hnsv1wrapper) HotAttachEndpoint(containerID, endpointID string) error {
|
||||
return hcsshim.HotAttachEndpoint(containerID, endpointID)
|
||||
}
|
||||
|
||||
func (Hnsv1wrapper) IsAttached(endpoint *hcsshim.HNSEndpoint, containerID string) (bool, error) {
|
||||
return endpoint.IsAttached(containerID)
|
||||
}
|
||||
|
||||
func (w Hnsv1wrapper) GetHNSGlobals() (*hcsshim.HNSGlobals, error) {
|
||||
return hcsshim.GetHNSGlobals()
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package hnswrapper
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
)
|
||||
|
||||
type Hnsv1wrapperfake struct {
|
||||
Delay time.Duration
|
||||
}
|
||||
|
||||
func NewHnsv1wrapperFake() *Hnsv1wrapperfake {
|
||||
return &Hnsv1wrapperfake{}
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperfake) CreateEndpoint(endpoint *hcsshim.HNSEndpoint, path string) (*hcsshim.HNSEndpoint, error) {
|
||||
delayHnsCall(h.Delay)
|
||||
return &hcsshim.HNSEndpoint{}, nil
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperfake) DeleteEndpoint(endpointId string) (*hcsshim.HNSEndpoint, error) {
|
||||
delayHnsCall(h.Delay)
|
||||
return &hcsshim.HNSEndpoint{}, nil
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperfake) CreateNetwork(network *hcsshim.HNSNetwork, path string) (*hcsshim.HNSNetwork, error) {
|
||||
delayHnsCall(h.Delay)
|
||||
return &hcsshim.HNSNetwork{}, nil
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperfake) DeleteNetwork(networkId string) (*hcsshim.HNSNetwork, error) {
|
||||
delayHnsCall(h.Delay)
|
||||
return &hcsshim.HNSNetwork{}, nil
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperfake) GetHNSEndpointByName(endpointName string) (*hcsshim.HNSEndpoint, error) {
|
||||
delayHnsCall(h.Delay)
|
||||
return &hcsshim.HNSEndpoint{}, nil
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperfake) GetHNSEndpointByID(endpointID string) (*hcsshim.HNSEndpoint, error) {
|
||||
delayHnsCall(h.Delay)
|
||||
return &hcsshim.HNSEndpoint{}, nil
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperfake) HotAttachEndpoint(containerID string, endpointID string) error {
|
||||
delayHnsCall(h.Delay)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperfake) IsAttached(hnsep *hcsshim.HNSEndpoint, containerID string) (bool, error) {
|
||||
delayHnsCall(h.Delay)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperfake) GetHNSGlobals() (*hcsshim.HNSGlobals, error) {
|
||||
delayHnsCall(h.Delay)
|
||||
return &hcsshim.HNSGlobals{}, nil
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2017 Microsoft. All rights reserved.
|
||||
// MIT License
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package hnswrapper
|
||||
|
||||
import (
|
||||
"github.com/Microsoft/hcsshim"
|
||||
)
|
||||
|
||||
type HnsV1WrapperInterface interface {
|
||||
CreateEndpoint(endpoint *hcsshim.HNSEndpoint, path string) (*hcsshim.HNSEndpoint, error)
|
||||
DeleteEndpoint(endpointId string) (*hcsshim.HNSEndpoint, error)
|
||||
CreateNetwork(network *hcsshim.HNSNetwork, path string) (*hcsshim.HNSNetwork, error)
|
||||
DeleteNetwork(networkId string) (*hcsshim.HNSNetwork, error)
|
||||
GetHNSEndpointByName(endpointName string) (*hcsshim.HNSEndpoint, error)
|
||||
GetHNSEndpointByID(endpointID string) (*hcsshim.HNSEndpoint, error)
|
||||
HotAttachEndpoint(containerID string, endpointID string) error
|
||||
IsAttached(hnsep *hcsshim.HNSEndpoint, containerID string) (bool, error)
|
||||
GetHNSGlobals() (*hcsshim.HNSGlobals, error)
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package hnswrapper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/pkg/errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Hnsv1wrapperwithtimeout struct {
|
||||
Hnsv1 HnsV1WrapperInterface
|
||||
// hnsCallTimeout indicates the time to wait for hns calls before timing out
|
||||
HnsCallTimeout time.Duration
|
||||
}
|
||||
|
||||
type EndpointFuncResult struct {
|
||||
endpoint *hcsshim.HNSEndpoint
|
||||
Err error
|
||||
}
|
||||
|
||||
type NetworkFuncResult struct {
|
||||
network *hcsshim.HNSNetwork
|
||||
Err error
|
||||
}
|
||||
|
||||
type EndpointAttachedFuncResult struct {
|
||||
isAttached bool
|
||||
Err error
|
||||
}
|
||||
|
||||
type HnsGlobalFuncResult struct {
|
||||
HnsGlobals *hcsshim.HNSGlobals
|
||||
Err error
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperwithtimeout) CreateEndpoint(endpoint *hcsshim.HNSEndpoint, path string) (*hcsshim.HNSEndpoint, error) {
|
||||
r := make(chan EndpointFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
endpoint, err := h.Hnsv1.CreateEndpoint(endpoint, path)
|
||||
|
||||
r <- EndpointFuncResult{
|
||||
endpoint: endpoint,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.endpoint, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "CreateEndpoint timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperwithtimeout) DeleteEndpoint(endpointId string) (*hcsshim.HNSEndpoint, error) {
|
||||
r := make(chan EndpointFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
endpoint, err := h.Hnsv1.DeleteEndpoint(endpointId)
|
||||
|
||||
r <- EndpointFuncResult{
|
||||
endpoint: endpoint,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.endpoint, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "DeleteEndpoint timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperwithtimeout) CreateNetwork(network *hcsshim.HNSNetwork, path string) (*hcsshim.HNSNetwork, error) {
|
||||
r := make(chan NetworkFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
network, err := h.Hnsv1.CreateNetwork(network, path)
|
||||
|
||||
r <- NetworkFuncResult{
|
||||
network: network,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.network, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "CreateNetwork timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperwithtimeout) DeleteNetwork(networkId string) (*hcsshim.HNSNetwork, error) {
|
||||
r := make(chan NetworkFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
network, err := h.Hnsv1.DeleteNetwork(networkId)
|
||||
|
||||
r <- NetworkFuncResult{
|
||||
network: network,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.network, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "DeleteNetwork timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperwithtimeout) GetHNSEndpointByName(endpointName string) (*hcsshim.HNSEndpoint, error) {
|
||||
r := make(chan EndpointFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
endpoint, err := h.Hnsv1.GetHNSEndpointByName(endpointName)
|
||||
|
||||
r <- EndpointFuncResult{
|
||||
endpoint: endpoint,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.endpoint, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "GetHNSEndpointByName timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperwithtimeout) GetHNSEndpointByID(endpointID string) (*hcsshim.HNSEndpoint, error) {
|
||||
r := make(chan EndpointFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
endpoint, err := h.Hnsv1.GetHNSEndpointByName(endpointID)
|
||||
|
||||
r <- EndpointFuncResult{
|
||||
endpoint: endpoint,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.endpoint, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "GetHNSEndpointByID timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperwithtimeout) HotAttachEndpoint(containerID string, endpointID string) error {
|
||||
r := make(chan error)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
r <- h.Hnsv1.HotAttachEndpoint(containerID, endpointID)
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res
|
||||
case <-ctx.Done():
|
||||
return errors.Wrapf(ErrHNSCallTimeout, "HotAttachEndpoint timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperwithtimeout) IsAttached(hnsep *hcsshim.HNSEndpoint, containerID string) (bool, error) {
|
||||
r := make(chan EndpointAttachedFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
isAttached, err := h.Hnsv1.IsAttached(hnsep, containerID)
|
||||
|
||||
r <- EndpointAttachedFuncResult{
|
||||
isAttached: isAttached,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.isAttached, res.Err
|
||||
case <-ctx.Done():
|
||||
return false, errors.Wrapf(ErrHNSCallTimeout, "IsHnsEndpointAttached timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv1wrapperwithtimeout) GetHNSGlobals() (*hcsshim.HNSGlobals, error) {
|
||||
r := make(chan HnsGlobalFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
hnsGlobals, err := h.Hnsv1.GetHNSGlobals()
|
||||
|
||||
r <- HnsGlobalFuncResult{
|
||||
HnsGlobals: hnsGlobals,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.HnsGlobals, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "GetHNSGlobals timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Microsoft/hcsshim/hcn"
|
||||
)
|
||||
|
@ -28,6 +29,7 @@ func newErrorFakeHNS(errStr string) error {
|
|||
type Hnsv2wrapperFake struct {
|
||||
Cache FakeHNSCache
|
||||
*sync.Mutex
|
||||
Delay time.Duration
|
||||
}
|
||||
|
||||
func NewHnsv2wrapperFake() *Hnsv2wrapperFake {
|
||||
|
@ -40,21 +42,30 @@ func NewHnsv2wrapperFake() *Hnsv2wrapperFake {
|
|||
}
|
||||
}
|
||||
|
||||
func delayHnsCall(delay time.Duration){
|
||||
time.Sleep(delay)
|
||||
}
|
||||
|
||||
func (f Hnsv2wrapperFake) CreateNetwork(network *hcn.HostComputeNetwork) (*hcn.HostComputeNetwork, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
|
||||
delayHnsCall(f.Delay)
|
||||
f.Cache.networks[network.Name] = NewFakeHostComputeNetwork(network)
|
||||
return network, nil
|
||||
}
|
||||
|
||||
func (f Hnsv2wrapperFake) DeleteNetwork(network *hcn.HostComputeNetwork) error {
|
||||
delayHnsCall(f.Delay)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f Hnsv2wrapperFake) ModifyNetworkSettings(network *hcn.HostComputeNetwork, request *hcn.ModifyNetworkSettingRequest) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
|
||||
delayHnsCall(f.Delay)
|
||||
|
||||
networkCache, ok := f.Cache.networks[network.Name]
|
||||
if !ok {
|
||||
return nil
|
||||
|
@ -153,17 +164,20 @@ func (f Hnsv2wrapperFake) ModifyNetworkSettings(network *hcn.HostComputeNetwork,
|
|||
return nil
|
||||
}
|
||||
|
||||
func (Hnsv2wrapperFake) AddNetworkPolicy(network *hcn.HostComputeNetwork, networkPolicy hcn.PolicyNetworkRequest) error {
|
||||
func (f Hnsv2wrapperFake) AddNetworkPolicy(network *hcn.HostComputeNetwork, networkPolicy hcn.PolicyNetworkRequest) error {
|
||||
delayHnsCall(f.Delay)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (Hnsv2wrapperFake) RemoveNetworkPolicy(network *hcn.HostComputeNetwork, networkPolicy hcn.PolicyNetworkRequest) error {
|
||||
func (f Hnsv2wrapperFake) RemoveNetworkPolicy(network *hcn.HostComputeNetwork, networkPolicy hcn.PolicyNetworkRequest) error {
|
||||
delayHnsCall(f.Delay)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f Hnsv2wrapperFake) GetNetworkByName(networkName string) (*hcn.HostComputeNetwork, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
delayHnsCall(f.Delay)
|
||||
if network, ok := f.Cache.networks[networkName]; ok {
|
||||
return network.GetHCNObj(), nil
|
||||
}
|
||||
|
@ -173,6 +187,7 @@ func (f Hnsv2wrapperFake) GetNetworkByName(networkName string) (*hcn.HostCompute
|
|||
func (f Hnsv2wrapperFake) GetNetworkByID(networkID string) (*hcn.HostComputeNetwork, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
delayHnsCall(f.Delay)
|
||||
for _, network := range f.Cache.networks {
|
||||
if network.ID == networkID {
|
||||
return network.GetHCNObj(), nil
|
||||
|
@ -184,6 +199,7 @@ func (f Hnsv2wrapperFake) GetNetworkByID(networkID string) (*hcn.HostComputeNetw
|
|||
func (f Hnsv2wrapperFake) GetEndpointByID(endpointID string) (*hcn.HostComputeEndpoint, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
delayHnsCall(f.Delay)
|
||||
if ep, ok := f.Cache.endpoints[endpointID]; ok {
|
||||
return ep.GetHCNObj(), nil
|
||||
}
|
||||
|
@ -193,6 +209,7 @@ func (f Hnsv2wrapperFake) GetEndpointByID(endpointID string) (*hcn.HostComputeEn
|
|||
func (f Hnsv2wrapperFake) CreateEndpoint(endpoint *hcn.HostComputeEndpoint) (*hcn.HostComputeEndpoint, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
delayHnsCall(f.Delay)
|
||||
f.Cache.endpoints[endpoint.Id] = NewFakeHostComputeEndpoint(endpoint)
|
||||
return endpoint, nil
|
||||
}
|
||||
|
@ -200,26 +217,31 @@ func (f Hnsv2wrapperFake) CreateEndpoint(endpoint *hcn.HostComputeEndpoint) (*hc
|
|||
func (f Hnsv2wrapperFake) DeleteEndpoint(endpoint *hcn.HostComputeEndpoint) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
delayHnsCall(f.Delay)
|
||||
delete(f.Cache.endpoints, endpoint.Id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (Hnsv2wrapperFake) GetNamespaceByID(netNamespacePath string) (*hcn.HostComputeNamespace, error) {
|
||||
func (f Hnsv2wrapperFake) GetNamespaceByID(netNamespacePath string) (*hcn.HostComputeNamespace, error) {
|
||||
delayHnsCall(f.Delay)
|
||||
nameSpace := &hcn.HostComputeNamespace{Id: "ea37ac15-119e-477b-863b-cc23d6eeaa4d", NamespaceId: 1000}
|
||||
return nameSpace, nil
|
||||
}
|
||||
|
||||
func (Hnsv2wrapperFake) AddNamespaceEndpoint(namespaceId string, endpointId string) error {
|
||||
func (f Hnsv2wrapperFake) AddNamespaceEndpoint(namespaceId string, endpointId string) error {
|
||||
delayHnsCall(f.Delay)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (Hnsv2wrapperFake) RemoveNamespaceEndpoint(namespaceId string, endpointId string) error {
|
||||
func (f Hnsv2wrapperFake) RemoveNamespaceEndpoint(namespaceId string, endpointId string) error {
|
||||
delayHnsCall(f.Delay)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f Hnsv2wrapperFake) ListEndpointsOfNetwork(networkId string) ([]hcn.HostComputeEndpoint, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
delayHnsCall(f.Delay)
|
||||
endpoints := make([]hcn.HostComputeEndpoint, 0)
|
||||
for _, endpoint := range f.Cache.endpoints {
|
||||
if endpoint.HostComputeNetwork == networkId {
|
||||
|
@ -232,7 +254,7 @@ func (f Hnsv2wrapperFake) ListEndpointsOfNetwork(networkId string) ([]hcn.HostCo
|
|||
func (f Hnsv2wrapperFake) ApplyEndpointPolicy(endpoint *hcn.HostComputeEndpoint, requestType hcn.RequestType, endpointPolicy hcn.PolicyEndpointRequest) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
|
||||
delayHnsCall(f.Delay)
|
||||
epCache, ok := f.Cache.endpoints[endpoint.Id]
|
||||
if !ok {
|
||||
return newErrorFakeHNS(fmt.Sprintf("[FakeHNS] could not find endpoint %s", endpoint.Id))
|
||||
|
@ -285,7 +307,8 @@ func (f Hnsv2wrapperFake) ApplyEndpointPolicy(endpoint *hcn.HostComputeEndpoint,
|
|||
return nil
|
||||
}
|
||||
|
||||
func (Hnsv2wrapperFake) GetEndpointByName(endpointName string) (*hcn.HostComputeEndpoint, error) {
|
||||
func (f Hnsv2wrapperFake) GetEndpointByName(endpointName string) (*hcn.HostComputeEndpoint, error) {
|
||||
delayHnsCall(f.Delay)
|
||||
return nil, hcn.EndpointNotFoundError{EndpointName: endpointName}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,382 @@
|
|||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package hnswrapper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/Microsoft/hcsshim/hcn"
|
||||
)
|
||||
|
||||
// ErrHNSCallTimeout - hns call timeout
|
||||
var ErrHNSCallTimeout = errors.New("timed out calling hns")
|
||||
|
||||
type Hnsv2wrapperwithtimeout struct {
|
||||
Hnsv2 HnsV2WrapperInterface
|
||||
// hnsCallTimeout indicates the time to wait for hns calls before timing out
|
||||
HnsCallTimeout time.Duration
|
||||
}
|
||||
|
||||
type CreateEndpointFuncResult struct {
|
||||
endpoint *hcn.HostComputeEndpoint
|
||||
Err error
|
||||
}
|
||||
|
||||
type GetEndpointByIDFuncResult struct {
|
||||
endpoint *hcn.HostComputeEndpoint
|
||||
Err error
|
||||
}
|
||||
|
||||
type ListEndpointsFuncResult struct {
|
||||
endpoints []hcn.HostComputeEndpoint
|
||||
Err error
|
||||
}
|
||||
|
||||
type CreateNetworkFuncResult struct {
|
||||
network *hcn.HostComputeNetwork
|
||||
Err error
|
||||
}
|
||||
|
||||
type GetNamespaceByIDFuncResult struct {
|
||||
namespace *hcn.HostComputeNamespace
|
||||
Err error
|
||||
}
|
||||
|
||||
type GetNetworkByNameFuncResult struct {
|
||||
network *hcn.HostComputeNetwork
|
||||
Err error
|
||||
}
|
||||
|
||||
type GetNetworkByIDFuncResult struct {
|
||||
network *hcn.HostComputeNetwork
|
||||
Err error
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) CreateEndpoint(endpoint *hcn.HostComputeEndpoint) (*hcn.HostComputeEndpoint, error) {
|
||||
r := make(chan CreateEndpointFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
endpoint, err := h.Hnsv2.CreateEndpoint(endpoint)
|
||||
|
||||
r <- CreateEndpointFuncResult{
|
||||
endpoint: endpoint,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.endpoint, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "CreateEndpoint timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) DeleteEndpoint(endpoint *hcn.HostComputeEndpoint) error {
|
||||
r := make(chan error)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
r <- h.Hnsv2.DeleteEndpoint(endpoint)
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res
|
||||
case <-ctx.Done():
|
||||
return errors.Wrapf(ErrHNSCallTimeout, "DeleteEndpoint timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) CreateNetwork(network *hcn.HostComputeNetwork) (*hcn.HostComputeNetwork, error) {
|
||||
r := make(chan CreateNetworkFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
network, err := h.Hnsv2.CreateNetwork(network)
|
||||
|
||||
r <- CreateNetworkFuncResult{
|
||||
network: network,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.network, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "CreateNetwork timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) DeleteNetwork(network *hcn.HostComputeNetwork) error {
|
||||
r := make(chan error)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
r <- h.Hnsv2.DeleteNetwork(network)
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res
|
||||
case <-ctx.Done():
|
||||
return errors.Wrapf(ErrHNSCallTimeout, "DeleteNetwork timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) ModifyNetworkSettings(network *hcn.HostComputeNetwork, request *hcn.ModifyNetworkSettingRequest) error {
|
||||
r := make(chan error)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
r <- h.Hnsv2.ModifyNetworkSettings(network, request)
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res
|
||||
case <-ctx.Done():
|
||||
return errors.Wrapf(ErrHNSCallTimeout, "ModifyNetworkSettings timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) AddNetworkPolicy(network *hcn.HostComputeNetwork, networkPolicy hcn.PolicyNetworkRequest) error {
|
||||
r := make(chan error)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
r <- h.Hnsv2.AddNetworkPolicy(network, networkPolicy)
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res
|
||||
case <-ctx.Done():
|
||||
return errors.Wrapf(ErrHNSCallTimeout, "AddNetworkPolicy timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) RemoveNetworkPolicy(network *hcn.HostComputeNetwork, networkPolicy hcn.PolicyNetworkRequest) error {
|
||||
r := make(chan error)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
r <- h.Hnsv2.RemoveNetworkPolicy(network, networkPolicy)
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res
|
||||
case <-ctx.Done():
|
||||
return errors.Wrapf(ErrHNSCallTimeout, "RemoveNetworkPolicy timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) GetNamespaceByID(netNamespacePath string) (*hcn.HostComputeNamespace, error) {
|
||||
r := make(chan GetNamespaceByIDFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
namespace, err := h.Hnsv2.GetNamespaceByID(netNamespacePath)
|
||||
|
||||
r <- GetNamespaceByIDFuncResult{
|
||||
namespace: namespace,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.namespace, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "GetNamespaceByID timeout value is %v ", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) AddNamespaceEndpoint(namespaceId string, endpointId string) error {
|
||||
r := make(chan error)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
r <- h.Hnsv2.AddNamespaceEndpoint(namespaceId, endpointId)
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("AddNamespaceEndpoint %w , timeout value is %s seconds", ErrHNSCallTimeout, h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) RemoveNamespaceEndpoint(namespaceId string, endpointId string) error {
|
||||
r := make(chan error)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
r <- h.Hnsv2.RemoveNamespaceEndpoint(namespaceId, endpointId)
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res
|
||||
case <-ctx.Done():
|
||||
return errors.Wrapf(ErrHNSCallTimeout, "RemoveNamespaceEndpoint %w , timeout value is %s seconds", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) GetNetworkByName(networkName string) (*hcn.HostComputeNetwork, error) {
|
||||
r := make(chan GetNetworkByNameFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
network, err := h.Hnsv2.GetNetworkByName(networkName)
|
||||
|
||||
r <- GetNetworkByNameFuncResult{
|
||||
network: network,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.network, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "GetNetworkByName %w , timeout value is %s seconds", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) GetNetworkByID(networkId string) (*hcn.HostComputeNetwork, error) {
|
||||
r := make(chan GetNetworkByIDFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
network, err := h.Hnsv2.GetNetworkByID(networkId)
|
||||
|
||||
r <- GetNetworkByIDFuncResult{
|
||||
network: network,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.network, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "GetNetworkByID %w , timeout value is %s seconds", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) GetEndpointByID(endpointId string) (*hcn.HostComputeEndpoint, error) {
|
||||
r := make(chan GetEndpointByIDFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
endpoint, err := h.Hnsv2.GetEndpointByID(endpointId)
|
||||
|
||||
r <- GetEndpointByIDFuncResult{
|
||||
endpoint: endpoint,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.endpoint, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "GetEndpointByID %w , timeout value is %s seconds", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) ListEndpointsOfNetwork(networkId string) ([]hcn.HostComputeEndpoint, error) {
|
||||
r := make(chan ListEndpointsFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
go func() {
|
||||
endpoints, err := h.Hnsv2.ListEndpointsOfNetwork(networkId)
|
||||
|
||||
r <- ListEndpointsFuncResult{
|
||||
endpoints: endpoints,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.endpoints, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "ListEndpointsOfNetwork %w , timeout value is %s seconds", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) ApplyEndpointPolicy(endpoint *hcn.HostComputeEndpoint, requestType hcn.RequestType, endpointPolicy hcn.PolicyEndpointRequest) error {
|
||||
r := make(chan error)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
go func() {
|
||||
r <- h.Hnsv2.ApplyEndpointPolicy(endpoint, requestType, endpointPolicy)
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res
|
||||
case <-ctx.Done():
|
||||
return errors.Wrapf(ErrHNSCallTimeout, "ApplyEndpointPolicy %w , timeout value is %s seconds", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (h Hnsv2wrapperwithtimeout) GetEndpointByName(endpointName string) (*hcn.HostComputeEndpoint, error) {
|
||||
r := make(chan GetEndpointByIDFuncResult)
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), h.HnsCallTimeout)
|
||||
defer cancel()
|
||||
go func() {
|
||||
endpoint, err := h.Hnsv2.GetEndpointByName(endpointName)
|
||||
|
||||
r <- GetEndpointByIDFuncResult{
|
||||
endpoint: endpoint,
|
||||
Err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-r:
|
||||
return res.endpoint, res.Err
|
||||
case <-ctx.Done():
|
||||
return nil, errors.Wrapf(ErrHNSCallTimeout, "GetEndpointByName %w , timeout value is %s seconds", h.HnsCallTimeout.String())
|
||||
}
|
||||
}
|
|
@ -161,7 +161,7 @@ func (nm *networkManager) restore(isRehydrationRequired bool) error {
|
|||
for _, extIf := range nm.ExternalInterfaces {
|
||||
for _, nw := range extIf.Networks {
|
||||
log.Printf("[net] Deleting the network %s on reboot\n", nw.Id)
|
||||
nm.deleteNetwork(nw.Id)
|
||||
_ = nm.deleteNetwork(nw.Id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,11 +278,11 @@ func (nm *networkManager) CreateNetwork(nwInfo *NetworkInfo) error {
|
|||
}
|
||||
|
||||
// DeleteNetwork deletes an existing container network.
|
||||
func (nm *networkManager) DeleteNetwork(networkId string) error {
|
||||
func (nm *networkManager) DeleteNetwork(networkID string) error {
|
||||
nm.Lock()
|
||||
defer nm.Unlock()
|
||||
|
||||
err := nm.deleteNetwork(networkId)
|
||||
err := nm.deleteNetwork(networkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -208,18 +208,18 @@ func (nm *networkManager) newNetwork(nwInfo *NetworkInfo) (*network, error) {
|
|||
}
|
||||
|
||||
// DeleteNetwork deletes an existing container network.
|
||||
func (nm *networkManager) deleteNetwork(networkId string) error {
|
||||
func (nm *networkManager) deleteNetwork(networkID string) error {
|
||||
var err error
|
||||
|
||||
log.Printf("[net] Deleting network %v.", networkId)
|
||||
log.Printf("[net] Deleting network %v.", networkID)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
log.Printf("[net] Failed to delete network %v, err:%v.", networkId, err)
|
||||
log.Printf("[net] Failed to delete network %v, err:%v.", networkID, err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Find the network.
|
||||
nw, err := nm.getNetwork(networkId)
|
||||
nw, err := nm.getNetwork(networkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ func (nm *networkManager) deleteNetwork(networkId string) error {
|
|||
|
||||
// Remove the network object.
|
||||
if nw.extIf != nil {
|
||||
delete(nw.extIf.Networks, networkId)
|
||||
delete(nw.extIf.Networks, networkID)
|
||||
}
|
||||
|
||||
log.Printf("[net] Deleted network %+v.", nw)
|
||||
|
|
|
@ -11,6 +11,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-container-networking/network/hnswrapper"
|
||||
|
||||
"github.com/Azure/azure-container-networking/log"
|
||||
"github.com/Azure/azure-container-networking/network/policy"
|
||||
"github.com/Microsoft/hcsshim"
|
||||
|
@ -55,6 +57,26 @@ func UseHnsV2(netNs string) (bool, error) {
|
|||
return useHnsV2, err
|
||||
}
|
||||
|
||||
// Regarding this Hnsv2 and Hnv1 variable
|
||||
// this pattern is to avoid passing around os specific objects in platform agnostic code
|
||||
var Hnsv2 hnswrapper.HnsV2WrapperInterface = hnswrapper.Hnsv2wrapper{}
|
||||
|
||||
var Hnsv1 hnswrapper.HnsV1WrapperInterface = hnswrapper.Hnsv1wrapper{}
|
||||
|
||||
func EnableHnsV2Timeout(timeoutValue int) {
|
||||
if _, ok := Hnsv2.(hnswrapper.Hnsv2wrapperwithtimeout); !ok {
|
||||
var timeoutDuration = time.Duration(timeoutValue) * time.Second
|
||||
Hnsv2 = hnswrapper.Hnsv2wrapperwithtimeout{Hnsv2: hnswrapper.Hnsv2wrapper{}, HnsCallTimeout: timeoutDuration}
|
||||
}
|
||||
}
|
||||
|
||||
func EnableHnsV1Timeout(timeoutValue int) {
|
||||
if _, ok := Hnsv1.(hnswrapper.Hnsv1wrapperwithtimeout); !ok {
|
||||
var timeoutDuration = time.Duration(timeoutValue) * time.Second
|
||||
Hnsv1 = hnswrapper.Hnsv1wrapperwithtimeout{Hnsv1: hnswrapper.Hnsv1wrapper{}, HnsCallTimeout: timeoutDuration}
|
||||
}
|
||||
}
|
||||
|
||||
// newNetworkImplHnsV1 creates a new container network for HNSv1.
|
||||
func (nm *networkManager) newNetworkImplHnsV1(nwInfo *NetworkInfo, extIf *externalInterface) (*network, error) {
|
||||
var (
|
||||
|
@ -122,17 +144,7 @@ func (nm *networkManager) newNetworkImplHnsV1(nwInfo *NetworkInfo, extIf *extern
|
|||
hnsNetwork.Subnets = append(hnsNetwork.Subnets, hnsSubnet)
|
||||
}
|
||||
|
||||
// Marshal the request.
|
||||
buffer, err := json.Marshal(hnsNetwork)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hnsRequest := string(buffer)
|
||||
|
||||
// Create the HNS network.
|
||||
log.Printf("[net] HNSNetworkRequest POST request:%+v", hnsRequest)
|
||||
hnsResponse, err := hcsshim.HNSNetworkRequest("POST", "", hnsRequest)
|
||||
log.Printf("[net] HNSNetworkRequest POST response:%+v err:%v.", hnsResponse, err)
|
||||
hnsResponse, err := Hnsv1.CreateNetwork(hnsNetwork, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -140,7 +152,7 @@ func (nm *networkManager) newNetworkImplHnsV1(nwInfo *NetworkInfo, extIf *extern
|
|||
defer func() {
|
||||
if err != nil {
|
||||
log.Printf("[net] HNSNetworkRequest DELETE id:%v", hnsResponse.Id)
|
||||
hnsResponse, err := hcsshim.HNSNetworkRequest("DELETE", hnsResponse.Id, "")
|
||||
hnsResponse, err := Hnsv1.DeleteNetwork(hnsResponse.Id)
|
||||
log.Printf("[net] HNSNetworkRequest DELETE response:%+v err:%v.", hnsResponse, err)
|
||||
}
|
||||
}()
|
||||
|
@ -162,7 +174,7 @@ func (nm *networkManager) newNetworkImplHnsV1(nwInfo *NetworkInfo, extIf *extern
|
|||
NetNs: nwInfo.NetNs,
|
||||
}
|
||||
|
||||
globals, err := hcsshim.GetHNSGlobals()
|
||||
globals, err := Hnsv1.GetHNSGlobals()
|
||||
if err != nil || globals.Version.Major <= hcsshim.HNSVersion1803.Major {
|
||||
// err would be not nil for windows 1709 & below
|
||||
// Sleep for 10 seconds as a workaround for windows 1803 & below
|
||||
|
@ -312,13 +324,13 @@ func (nm *networkManager) newNetworkImplHnsV2(nwInfo *NetworkInfo, extIf *extern
|
|||
}
|
||||
|
||||
// check if network exists, only create the network does not exist
|
||||
hnsResponse, err := hnsv2.GetNetworkByName(hcnNetwork.Name)
|
||||
hnsResponse, err := Hnsv2.GetNetworkByName(hcnNetwork.Name)
|
||||
|
||||
if err != nil {
|
||||
// if network not found, create the HNS network.
|
||||
if errors.As(err, &hcn.NetworkNotFoundError{}) {
|
||||
log.Printf("[net] Creating hcn network: %+v", hcnNetwork)
|
||||
hnsResponse, err = hnsv2.CreateNetwork(hcnNetwork)
|
||||
hnsResponse, err = Hnsv2.CreateNetwork(hcnNetwork)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to create hcn network: %s due to error: %v", hcnNetwork.Name, err)
|
||||
|
@ -361,10 +373,8 @@ func (nm *networkManager) newNetworkImpl(nwInfo *NetworkInfo, extIf *externalInt
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nm.newNetworkImplHnsV2(nwInfo, extIf)
|
||||
}
|
||||
|
||||
return nm.newNetworkImplHnsV1(nwInfo, extIf)
|
||||
}
|
||||
|
||||
|
@ -374,33 +384,31 @@ func (nm *networkManager) deleteNetworkImpl(nw *network) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nm.deleteNetworkImplHnsV2(nw)
|
||||
}
|
||||
|
||||
return nm.deleteNetworkImplHnsV1(nw)
|
||||
}
|
||||
|
||||
// DeleteNetworkImplHnsV1 deletes an existing container network using HnsV1.
|
||||
func (nm *networkManager) deleteNetworkImplHnsV1(nw *network) error {
|
||||
log.Printf("[net] HNSNetworkRequest DELETE id:%v", nw.HnsId)
|
||||
hnsResponse, err := hcsshim.HNSNetworkRequest("DELETE", nw.HnsId, "")
|
||||
hnsResponse, err := Hnsv1.DeleteNetwork(nw.HnsId)
|
||||
log.Printf("[net] HNSNetworkRequest DELETE response:%+v err:%v.", hnsResponse, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteNetworkImplHnsV2 deletes an existing container network using HnsV2.
|
||||
// DeleteNetworkImplHnsV2 deletes an existing container network using Hnsv2.
|
||||
func (nm *networkManager) deleteNetworkImplHnsV2(nw *network) error {
|
||||
var hcnNetwork *hcn.HostComputeNetwork
|
||||
var err error
|
||||
log.Printf("[net] Deleting hcn network with id: %s", nw.HnsId)
|
||||
|
||||
if hcnNetwork, err = hnsv2.GetNetworkByID(nw.HnsId); err != nil {
|
||||
if hcnNetwork, err = Hnsv2.GetNetworkByID(nw.HnsId); err != nil {
|
||||
return fmt.Errorf("Failed to get hcn network with id: %s due to err: %v", nw.HnsId, err)
|
||||
}
|
||||
|
||||
if err = hnsv2.DeleteNetwork(hcnNetwork); err != nil {
|
||||
if err = Hnsv2.DeleteNetwork(hcnNetwork); err != nil {
|
||||
return fmt.Errorf("Failed to delete hcn network: %s due to error: %v", nw.HnsId, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ package network
|
|||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-container-networking/network/hnswrapper"
|
||||
|
||||
|
@ -22,7 +23,7 @@ func TestNewAndDeleteNetworkImplHnsV2(t *testing.T) {
|
|||
|
||||
// this hnsv2 variable overwrites the package level variable in network
|
||||
// we do this to avoid passing around os specific objects in platform agnostic code
|
||||
hnsv2 = hnswrapper.NewHnsv2wrapperFake()
|
||||
Hnsv2 = hnswrapper.NewHnsv2wrapperFake()
|
||||
|
||||
nwInfo := &NetworkInfo{
|
||||
Id: "d3e97a83-ba4c-45d5-ba88-dc56757ece28",
|
||||
|
@ -57,13 +58,13 @@ func TestSuccesfulNetworkCreationWhenAlreadyExists(t *testing.T) {
|
|||
|
||||
// this hnsv2 variable overwrites the package level variable in network
|
||||
// we do this to avoid passing around os specific objects in platform agnostic code
|
||||
hnsv2 = hnswrapper.NewHnsv2wrapperFake()
|
||||
Hnsv2 = hnswrapper.NewHnsv2wrapperFake()
|
||||
|
||||
network := &hcn.HostComputeNetwork{
|
||||
Name: "azure-vlan1-172-28-1-0_24",
|
||||
}
|
||||
|
||||
_, err := hnsv2.CreateNetwork(network)
|
||||
_, err := Hnsv2.CreateNetwork(network)
|
||||
|
||||
// network name is derived from network info id
|
||||
nwInfo := &NetworkInfo{
|
||||
|
@ -84,3 +85,149 @@ func TestSuccesfulNetworkCreationWhenAlreadyExists(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewNetworkImplHnsV2WithTimeout(t *testing.T) {
|
||||
nm := &networkManager{
|
||||
ExternalInterfaces: map[string]*externalInterface{},
|
||||
}
|
||||
|
||||
hnsFake := hnswrapper.NewHnsv2wrapperFake()
|
||||
|
||||
hnsFake.Delay = 15 * time.Second
|
||||
|
||||
Hnsv2 = hnswrapper.Hnsv2wrapperwithtimeout{
|
||||
Hnsv2: hnsFake,
|
||||
HnsCallTimeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
nwInfo := &NetworkInfo{
|
||||
Id: "d3e97a83-ba4c-45d5-ba88-dc56757ece28",
|
||||
MasterIfName: "eth0",
|
||||
Mode: "bridge",
|
||||
}
|
||||
|
||||
extInterface := &externalInterface{
|
||||
Name: "eth0",
|
||||
Subnets: []string{"subnet1", "subnet2"},
|
||||
}
|
||||
|
||||
_, err := nm.newNetworkImplHnsV2(nwInfo, extInterface)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Failed to timeout HNS calls for creating network")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteNetworkImplHnsV2WithTimeout(t *testing.T) {
|
||||
nm := &networkManager{
|
||||
ExternalInterfaces: map[string]*externalInterface{},
|
||||
}
|
||||
|
||||
nwInfo := &NetworkInfo{
|
||||
Id: "d3e97a83-ba4c-45d5-ba88-dc56757ece28",
|
||||
MasterIfName: "eth0",
|
||||
Mode: "bridge",
|
||||
}
|
||||
|
||||
extInterface := &externalInterface{
|
||||
Name: "eth0",
|
||||
Subnets: []string{"subnet1", "subnet2"},
|
||||
}
|
||||
|
||||
Hnsv2 = hnswrapper.NewHnsv2wrapperFake()
|
||||
|
||||
network, err := nm.newNetworkImplHnsV2(nwInfo, extInterface)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("+%v", err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
hnsFake := hnswrapper.NewHnsv2wrapperFake()
|
||||
|
||||
hnsFake.Delay = 10 * time.Second
|
||||
|
||||
Hnsv2 = hnswrapper.Hnsv2wrapperwithtimeout{
|
||||
Hnsv2: hnsFake,
|
||||
HnsCallTimeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
err = nm.deleteNetworkImplHnsV2(network)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Failed to timeout HNS calls for deleting network")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewNetworkImplHnsV1WithTimeout(t *testing.T) {
|
||||
nm := &networkManager{
|
||||
ExternalInterfaces: map[string]*externalInterface{},
|
||||
}
|
||||
|
||||
hnsFake := hnswrapper.NewHnsv1wrapperFake()
|
||||
|
||||
hnsFake.Delay = 10 * time.Second
|
||||
|
||||
Hnsv1 = hnswrapper.Hnsv1wrapperwithtimeout{
|
||||
Hnsv1: hnsFake,
|
||||
HnsCallTimeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
nwInfo := &NetworkInfo{
|
||||
Id: "d3e97a83-ba4c-45d5-ba88-dc56757ece28",
|
||||
MasterIfName: "eth0",
|
||||
Mode: "bridge",
|
||||
}
|
||||
|
||||
extInterface := &externalInterface{
|
||||
Name: "eth0",
|
||||
Subnets: []string{"subnet1", "subnet2"},
|
||||
}
|
||||
|
||||
_, err := nm.newNetworkImplHnsV1(nwInfo, extInterface)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Failed to timeout HNS calls for creating network")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteNetworkImplHnsV1WithTimeout(t *testing.T) {
|
||||
nm := &networkManager{
|
||||
ExternalInterfaces: map[string]*externalInterface{},
|
||||
}
|
||||
|
||||
nwInfo := &NetworkInfo{
|
||||
Id: "d3e97a83-ba4c-45d5-ba88-dc56757ece28",
|
||||
MasterIfName: "eth0",
|
||||
Mode: "bridge",
|
||||
}
|
||||
|
||||
extInterface := &externalInterface{
|
||||
Name: "eth0",
|
||||
Subnets: []string{"subnet1", "subnet2"},
|
||||
}
|
||||
|
||||
Hnsv1 = hnswrapper.NewHnsv1wrapperFake()
|
||||
|
||||
network, err := nm.newNetworkImplHnsV1(nwInfo, extInterface)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("+%v", err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
hnsFake := hnswrapper.NewHnsv1wrapperFake()
|
||||
|
||||
hnsFake.Delay = 10 * time.Second
|
||||
|
||||
Hnsv1 = hnswrapper.Hnsv1wrapperwithtimeout{
|
||||
Hnsv1: hnsFake,
|
||||
HnsCallTimeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
err = nm.deleteNetworkImplHnsV1(network)
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Failed to timeout HNS calls for deleting network")
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче