feat: don't use CNS for CNI DEL command in windows multitenancy (#1216)
* feat: don't use CNS for CNI DEL command in windows multitenancy * go fmt * go fmt take 2 * fix: don't fallback to CNS for getNetwork or deleteHostNCApipaEndpoint, handle errNetworkNotFound * test: add test for FindNetworkIDFromNetNs * fix: getNetworkName needs to fallback to CNS when not found in state file for ADD * fix: simplify the deleteHostNCApipaEndpoint function * fix: linter * fix: cnm should compile * fix: always return retriable error for endpoint deletion failure * fix: handle npe in cns/hnsclient by not using that package * fix: logging * fix: don't try cns if there is no multitenancy client * fix: don't call CNS twice during ADD cmd * fix: use hns wrapper, add some logging, don't return error when endpoint is already deleted
This commit is contained in:
Родитель
494308df4e
Коммит
580c3e4072
|
@ -1,3 +1,4 @@
|
|||
//go:build unit || integration
|
||||
// +build unit integration
|
||||
|
||||
package client
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// +build linux
|
||||
// +build integration
|
||||
//go:build linux && integration
|
||||
// +build linux,integration
|
||||
|
||||
package client
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build unit
|
||||
// +build unit
|
||||
|
||||
package client
|
||||
|
|
|
@ -453,7 +453,7 @@ func (plugin *NetPlugin) Add(args *cniSkel.CmdArgs) error {
|
|||
}
|
||||
|
||||
// Initialize values from network config.
|
||||
networkID, err := plugin.getNetworkName(k8sPodName, k8sNamespace, args.IfName, nwCfg)
|
||||
networkID, err := plugin.getNetworkName(k8sPodName, k8sNamespace, args.IfName, args.Netns, cnsNetworkConfig, nwCfg)
|
||||
if err != nil {
|
||||
log.Printf("[cni-net] Failed to extract network name from network config. error: %v", err)
|
||||
return err
|
||||
|
@ -843,7 +843,7 @@ func (plugin *NetPlugin) Get(args *cniSkel.CmdArgs) error {
|
|||
}
|
||||
|
||||
// Initialize values from network config.
|
||||
if networkId, err = plugin.getNetworkName(k8sPodName, k8sNamespace, args.IfName, nwCfg); err != nil {
|
||||
if networkId, err = plugin.getNetworkName(k8sPodName, k8sNamespace, args.IfName, args.Netns, nil, nwCfg); err != nil {
|
||||
// TODO: Ideally we should return from here only.
|
||||
log.Printf("[cni-net] Failed to extract network name from network config. error: %v", err)
|
||||
}
|
||||
|
@ -962,14 +962,13 @@ func (plugin *NetPlugin) Delete(args *cniSkel.CmdArgs) error {
|
|||
plugin.ipamInvoker = NewAzureIpamInvoker(plugin, &nwInfo)
|
||||
}
|
||||
}
|
||||
// Initialize values from network config.
|
||||
networkID, err = plugin.getNetworkName(k8sPodName, k8sNamespace, args.IfName, nwCfg)
|
||||
|
||||
// If error is not found error, then we ignore it, to comply with CNI SPEC.
|
||||
// Initialize values from network config.
|
||||
networkID, err = plugin.getNetworkName(k8sPodName, k8sNamespace, args.IfName, args.Netns, nil, nwCfg)
|
||||
if err != nil {
|
||||
log.Printf("[cni-net] Failed to extract network name from network config. error: %v", err)
|
||||
|
||||
if !cnscli.IsNotFound(err) {
|
||||
// If error is not found error, then we ignore it, to comply with CNI SPEC.
|
||||
if !network.IsNetworkNotFoundError(err) {
|
||||
err = plugin.Errorf("Failed to extract network name from network config. error: %v", err)
|
||||
return err
|
||||
}
|
||||
|
@ -1013,19 +1012,15 @@ func (plugin *NetPlugin) Delete(args *cniSkel.CmdArgs) error {
|
|||
return err
|
||||
}
|
||||
|
||||
cnsclient, err := cnscli.New(nwCfg.CNSUrl, defaultRequestTimeout)
|
||||
if err != nil {
|
||||
log.Printf("failed to initialized cns client with URL %s: %v", nwCfg.CNSUrl, err.Error())
|
||||
return plugin.Errorf(err.Error())
|
||||
}
|
||||
|
||||
// schedule send metric before attempting delete
|
||||
defer sendMetricFunc()
|
||||
telemetry.LogAndSendEvent(plugin.tb, fmt.Sprintf("Deleting endpoint:%v", endpointID))
|
||||
// Delete the endpoint.
|
||||
if err = plugin.nm.DeleteEndpoint(cnsclient, networkID, endpointID); err != nil {
|
||||
err = plugin.Errorf("Failed to delete endpoint: %v", err)
|
||||
return err
|
||||
if err = plugin.nm.DeleteEndpoint(networkID, endpointID); err != nil {
|
||||
// return a retriable error so the container runtime will retry this DEL later
|
||||
// the implementation of this function returns nil if the endpoint doens't exist, so
|
||||
// we don't have to check that here
|
||||
return plugin.RetriableError(fmt.Errorf("failed to delete endpoint: %w", err))
|
||||
}
|
||||
|
||||
if !nwCfg.MultiTenancy {
|
||||
|
|
|
@ -135,7 +135,7 @@ func updateSubnetPrefix(cnsNetworkConfig *cns.GetNetworkContainerResponse, subne
|
|||
return nil
|
||||
}
|
||||
|
||||
func (plugin *NetPlugin) getNetworkName(podName, podNs, ifName string, nwCfg *cni.NetworkConfig) (string, error) {
|
||||
func (plugin *NetPlugin) getNetworkName(_, _, _, _ string, _ *cns.GetNetworkContainerResponse, nwCfg *cni.NetworkConfig) (string, error) {
|
||||
return nwCfg.Name, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//+build linux
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package network
|
||||
|
||||
|
|
|
@ -1060,7 +1060,7 @@ func TestGetNetworkName(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
nwName, _ := plugin.getNetworkName("", "", "", &tt.nwCfg)
|
||||
nwName, _ := plugin.getNetworkName("", "", "", "", nil, &tt.nwCfg)
|
||||
require.Equal(t, tt.nwCfg.Name, nwName)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
|
@ -160,42 +159,45 @@ func updateSubnetPrefix(cnsNwConfig *cns.GetNetworkContainerResponse, subnetPref
|
|||
return nil
|
||||
}
|
||||
|
||||
func (plugin *NetPlugin) getNetworkName(podName, podNs, ifName string, nwCfg *cni.NetworkConfig) (string, error) {
|
||||
var (
|
||||
networkName string
|
||||
err error
|
||||
cnsNetworkConfig *cns.GetNetworkContainerResponse
|
||||
)
|
||||
|
||||
networkName = nwCfg.Name
|
||||
err = nil
|
||||
|
||||
if nwCfg.MultiTenancy {
|
||||
determineWinVer()
|
||||
if len(strings.TrimSpace(podName)) == 0 || len(strings.TrimSpace(podNs)) == 0 {
|
||||
err = fmt.Errorf("POD info cannot be empty. PodName: %s, PodNamespace: %s", podName, podNs)
|
||||
return networkName, err
|
||||
}
|
||||
|
||||
_, cnsNetworkConfig, _, err = plugin.multitenancyClient.GetContainerNetworkConfiguration(context.TODO(), nwCfg, podName, podNs, ifName)
|
||||
if err != nil {
|
||||
log.Printf(
|
||||
"GetContainerNetworkConfiguration failed for podname %v namespace %v with error %v",
|
||||
podName,
|
||||
podNs,
|
||||
err)
|
||||
} else {
|
||||
var subnet net.IPNet
|
||||
if err = updateSubnetPrefix(cnsNetworkConfig, &subnet); err == nil {
|
||||
// networkName will look like ~ azure-vlan1-172-28-1-0_24
|
||||
networkName = strings.Replace(subnet.String(), ".", "-", -1)
|
||||
networkName = strings.Replace(networkName, "/", "_", -1)
|
||||
networkName = fmt.Sprintf("%s-vlan%v-%v", nwCfg.Name, cnsNetworkConfig.MultiTenancyInfo.ID, networkName)
|
||||
}
|
||||
}
|
||||
func (plugin *NetPlugin) getNetworkName(podName, podNs, ifName, netNs string, cnsResponse *cns.GetNetworkContainerResponse, nwCfg *cni.NetworkConfig) (string, error) {
|
||||
// For singletenancy, the network name is simply the nwCfg.Name
|
||||
if !nwCfg.MultiTenancy {
|
||||
return nwCfg.Name, nil
|
||||
}
|
||||
|
||||
return networkName, err
|
||||
// in multitenancy case, the network name will be in the state file or can be built from cnsResponse
|
||||
determineWinVer()
|
||||
if len(strings.TrimSpace(netNs)) == 0 || len(strings.TrimSpace(podName)) == 0 || len(strings.TrimSpace(podNs)) == 0 {
|
||||
return "", fmt.Errorf("POD info cannot be empty. PodName: %s, PodNamespace: %s, NetNs: %s", podName, podNs, netNs)
|
||||
}
|
||||
|
||||
// First try to build the network name from the cnsResponse if present
|
||||
// This will happen during ADD call
|
||||
if cnsResponse != nil {
|
||||
var subnet net.IPNet
|
||||
if err := updateSubnetPrefix(cnsResponse, &subnet); err != nil {
|
||||
log.Printf("Error updating subnet prefix: %v", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
// networkName will look like ~ azure-vlan1-172-28-1-0_24
|
||||
networkSuffix := strings.Replace(subnet.String(), ".", "-", -1)
|
||||
networkSuffix = strings.Replace(networkSuffix, "/", "_", -1)
|
||||
networkName := fmt.Sprintf("%s-vlan%v-%v", nwCfg.Name, cnsResponse.MultiTenancyInfo.ID, networkSuffix)
|
||||
|
||||
return networkName, nil
|
||||
}
|
||||
|
||||
// If no cnsResponse was present, try to get the network name from the state file
|
||||
// This will happen during DEL call
|
||||
networkName, err := plugin.nm.FindNetworkIDFromNetNs(netNs)
|
||||
if err != nil {
|
||||
log.Printf("Error getting network name from state: %v.", err)
|
||||
return "", fmt.Errorf("error getting network name from state: %w", err)
|
||||
|
||||
}
|
||||
|
||||
return networkName, nil
|
||||
}
|
||||
|
||||
func setupInfraVnetRoutingForMultitenancy(
|
||||
|
|
|
@ -183,7 +183,7 @@ func TestSetEndpointOptions(t *testing.T) {
|
|||
ID: 1,
|
||||
},
|
||||
CnetAddressSpace: []cns.IPSubnet{
|
||||
cns.IPSubnet{
|
||||
{
|
||||
IPAddress: "192.168.0.4",
|
||||
PrefixLength: 24,
|
||||
},
|
||||
|
@ -221,7 +221,7 @@ func TestSetPoliciesFromNwCfg(t *testing.T) {
|
|||
nwCfg: cni.NetworkConfig{
|
||||
RuntimeConfig: cni.RuntimeConfig{
|
||||
PortMappings: []cni.PortMapping{
|
||||
cni.PortMapping{
|
||||
{
|
||||
Protocol: "tcp",
|
||||
HostIp: "19.268.0.4",
|
||||
HostPort: 8000,
|
||||
|
|
|
@ -150,6 +150,13 @@ func (plugin *Plugin) Errorf(format string, args ...interface{}) *cniTypes.Error
|
|||
return plugin.Error(fmt.Errorf(format, args...))
|
||||
}
|
||||
|
||||
// RetriableError logs and returns a CNI error with the TryAgainLater error code
|
||||
func (plugin *Plugin) RetriableError(err error) *cniTypes.Error {
|
||||
tryAgainErr := cniTypes.NewError(cniTypes.ErrTryAgainLater, err.Error(), "")
|
||||
log.Printf("[%v] %+v.", plugin.Name, tryAgainErr.Error())
|
||||
return tryAgainErr
|
||||
}
|
||||
|
||||
// Initialize key-value store
|
||||
func (plugin *Plugin) InitializeKeyValueStore(config *common.PluginConfig) error {
|
||||
// Create the key value store.
|
||||
|
|
|
@ -271,12 +271,8 @@ func (plugin *netPlugin) deleteEndpoint(w http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
cnscli, err := cnsclient.New("", defaultCNSTimeout)
|
||||
if err != nil {
|
||||
log.Errorf("failed to init CNS client", err)
|
||||
}
|
||||
// Process request.
|
||||
err = plugin.nm.DeleteEndpoint(cnscli, req.NetworkID, req.EndpointID)
|
||||
err = plugin.nm.DeleteEndpoint(req.NetworkID, req.EndpointID)
|
||||
if err != nil {
|
||||
plugin.SendErrorResponse(w, err)
|
||||
return
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package network
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
|
@ -12,7 +13,7 @@ var (
|
|||
errSubnetNotFound = fmt.Errorf("Subnet not found")
|
||||
errNetworkModeInvalid = fmt.Errorf("Network mode is invalid")
|
||||
errNetworkExists = fmt.Errorf("Network already exists")
|
||||
errNetworkNotFound = fmt.Errorf("Network not found")
|
||||
errNetworkNotFound = &networkNotFoundError{}
|
||||
errEndpointExists = fmt.Errorf("Endpoint already exists")
|
||||
errEndpointNotFound = fmt.Errorf("Endpoint not found")
|
||||
errNamespaceNotFound = fmt.Errorf("Namespace not found")
|
||||
|
@ -20,3 +21,13 @@ var (
|
|||
errEndpointInUse = fmt.Errorf("Endpoint is already joined to a sandbox")
|
||||
errEndpointNotInUse = fmt.Errorf("Endpoint is not joined to a sandbox")
|
||||
)
|
||||
|
||||
type networkNotFoundError struct{}
|
||||
|
||||
func (n *networkNotFoundError) Error() string {
|
||||
return "Network not found"
|
||||
}
|
||||
|
||||
func IsNetworkNotFoundError(err error) bool {
|
||||
return errors.Is(err, errNetworkNotFound)
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ func (nw *network) newEndpoint(cli apipaClient, nl netlink.NetlinkInterface, plc
|
|||
}
|
||||
|
||||
// DeleteEndpoint deletes an existing endpoint from the network.
|
||||
func (nw *network) deleteEndpoint(cli apipaClient, nl netlink.NetlinkInterface, plc platform.ExecClient, endpointID string) error {
|
||||
func (nw *network) deleteEndpoint(nl netlink.NetlinkInterface, plc platform.ExecClient, endpointID string) error {
|
||||
var err error
|
||||
|
||||
log.Printf("[net] Deleting endpoint %v from network %v.", endpointID, nw.Id)
|
||||
|
@ -142,7 +142,7 @@ func (nw *network) deleteEndpoint(cli apipaClient, nl netlink.NetlinkInterface,
|
|||
}
|
||||
|
||||
// Call the platform implementation.
|
||||
err = nw.deleteEndpointImpl(cli, nl, plc, ep)
|
||||
err = nw.deleteEndpointImpl(nl, plc, ep)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ func (nw *network) newEndpointImpl(_ apipaClient, nl netlink.NetlinkInterface, p
|
|||
}
|
||||
|
||||
// deleteEndpointImpl deletes an existing endpoint from the network.
|
||||
func (nw *network) deleteEndpointImpl(_ apipaClient, nl netlink.NetlinkInterface, plc platform.ExecClient, ep *endpoint) error {
|
||||
func (nw *network) deleteEndpointImpl(nl netlink.NetlinkInterface, plc platform.ExecClient, ep *endpoint) error {
|
||||
var epClient EndpointClient
|
||||
|
||||
// Delete the veth pair by deleting one of the peer interfaces.
|
||||
|
|
|
@ -38,6 +38,10 @@ const (
|
|||
|
||||
// Container interface name prefix
|
||||
containerIfNamePrefix = "vEthernet"
|
||||
|
||||
// hostNCApipaEndpointName indicates the prefix for the name of the apipa endpoint used for
|
||||
// the host container connectivity
|
||||
hostNCApipaEndpointNamePrefix = "HostNCApipaEndpoint"
|
||||
)
|
||||
|
||||
type AzureHNSEndpointClient interface {
|
||||
|
@ -280,11 +284,33 @@ func (nw *network) configureHcnEndpoint(epInfo *EndpointInfo) (*hcn.HostComputeE
|
|||
return hcnEndpoint, nil
|
||||
}
|
||||
|
||||
func (nw *network) deleteHostNCApipaEndpoint(cli apipaClient, networkContainerID string) error {
|
||||
log.Printf("[net] Deleting HostNCApipaEndpoint for network container: %s", networkContainerID)
|
||||
err := cli.DeleteHostNCApipaEndpoint(context.TODO(), networkContainerID)
|
||||
log.Printf("[net] Completed HostNCApipaEndpoint deletion for network container: %s"+
|
||||
" with error: %v", networkContainerID, err)
|
||||
func (nw *network) deleteHostNCApipaEndpoint(networkContainerID string) error {
|
||||
// TODO: this code is duplicated in cns/hnsclient, but that code has logging messages that require a CNSLogger,
|
||||
// which makes is hard to use in this package. We should refactor this into a common package with no logging deps
|
||||
// so it can be called in both places
|
||||
|
||||
// HostNCApipaEndpoint name is derived from NC ID
|
||||
endpointName := fmt.Sprintf("%s-%s", hostNCApipaEndpointNamePrefix, networkContainerID)
|
||||
log.Printf("[net] Deleting HostNCApipaEndpoint: %s for NC: %s", endpointName, networkContainerID)
|
||||
|
||||
// Check if the endpoint exists
|
||||
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.
|
||||
if _, endpointNotFound := err.(hcn.EndpointNotFoundError); !endpointNotFound {
|
||||
return fmt.Errorf("[net] deleteEndpointByNameHnsV2 failed due to error with GetEndpointByName: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("[net] Delete called on the Endpoint: %s which doesn't exist. Error: %v", endpointName, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := hnsv2.DeleteEndpoint(endpoint); err != nil {
|
||||
return fmt.Errorf("failed to delete HostNCApipa endpoint: %+v: %w", endpoint, err)
|
||||
}
|
||||
|
||||
log.Printf("[net] Successfully deleted HostNCApipa endpoint: %+v", endpoint)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -313,7 +339,7 @@ func (nw *network) createHostNCApipaEndpoint(cli apipaClient, epInfo *EndpointIn
|
|||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
nw.deleteHostNCApipaEndpoint(cli, epInfo.NetworkContainerID)
|
||||
nw.deleteHostNCApipaEndpoint(epInfo.NetworkContainerID)
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -415,13 +441,13 @@ func (nw *network) newEndpointImplHnsV2(cli apipaClient, epInfo *EndpointInfo) (
|
|||
}
|
||||
|
||||
// deleteEndpointImpl deletes an existing endpoint from the network.
|
||||
func (nw *network) deleteEndpointImpl(cli apipaClient, _ netlink.NetlinkInterface, _ platform.ExecClient, ep *endpoint) error {
|
||||
func (nw *network) deleteEndpointImpl(_ netlink.NetlinkInterface, _ platform.ExecClient, ep *endpoint) error {
|
||||
if useHnsV2, err := UseHnsV2(ep.NetNs); useHnsV2 {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nw.deleteEndpointImplHnsV2(cli, ep)
|
||||
return nw.deleteEndpointImplHnsV2(ep)
|
||||
}
|
||||
|
||||
return nw.deleteEndpointImplHnsV1(ep)
|
||||
|
@ -447,14 +473,14 @@ func (nw *network) deleteEndpointImplHnsV1(ep *endpoint) error {
|
|||
}
|
||||
|
||||
// deleteEndpointImplHnsV2 deletes an existing endpoint from the network using HNS v2.
|
||||
func (nw *network) deleteEndpointImplHnsV2(cli apipaClient, ep *endpoint) error {
|
||||
func (nw *network) deleteEndpointImplHnsV2(ep *endpoint) error {
|
||||
var (
|
||||
hcnEndpoint *hcn.HostComputeEndpoint
|
||||
err error
|
||||
)
|
||||
|
||||
if ep.AllowInboundFromHostToNC || ep.AllowInboundFromNCToHost {
|
||||
if err = nw.deleteHostNCApipaEndpoint(cli, ep.NetworkContainerID); err != nil {
|
||||
if err = nw.deleteHostNCApipaEndpoint(ep.NetworkContainerID); err != nil {
|
||||
log.Errorf("[net] Failed to delete HostNCApipaEndpoint due to error: %v", err)
|
||||
return err
|
||||
}
|
||||
|
@ -462,8 +488,16 @@ func (nw *network) deleteEndpointImplHnsV2(cli apipaClient, ep *endpoint) error
|
|||
|
||||
log.Printf("[net] Deleting hcn endpoint with id: %s", ep.HnsId)
|
||||
|
||||
if hcnEndpoint, err = hnsv2.GetEndpointByID(ep.HnsId); err != nil {
|
||||
return fmt.Errorf("Failed to get hcn endpoint with id: %s due to err: %v", ep.HnsId, err)
|
||||
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.
|
||||
if _, endpointNotFound := err.(hcn.EndpointNotFoundError); !endpointNotFound {
|
||||
return fmt.Errorf("Failed to get hcn endpoint with id: %s due to err: %w", ep.HnsId, err)
|
||||
}
|
||||
|
||||
log.Printf("[net] Delete called on the Endpoint: %s which doesn't exist. Error: %v", ep.HnsId, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove this endpoint from the namespace
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
// Copyright 2017 Microsoft. All rights reserved.
|
||||
// MIT License
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Azure/azure-container-networking/network/hnswrapper"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-container-networking/network/hnswrapper"
|
||||
)
|
||||
|
||||
func TestNewAndDeleteEndpointImplHnsV2(t *testing.T){
|
||||
func TestNewAndDeleteEndpointImplHnsV2(t *testing.T) {
|
||||
nw := &network{
|
||||
Endpoints: map[string]*endpoint{},
|
||||
}
|
||||
|
@ -22,29 +24,29 @@ func TestNewAndDeleteEndpointImplHnsV2(t *testing.T){
|
|||
hnsv2 = hnswrapper.Hnsv2wrapperFake{}
|
||||
|
||||
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",
|
||||
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)
|
||||
endpoint, err := nw.newEndpointImplHnsV2(nil, epInfo)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("+%v", err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = nw.deleteEndpointImplHnsV2(nil, endpoint)
|
||||
err = nw.deleteEndpointImplHnsV2(endpoint)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("+%v", err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,3 +72,7 @@ func (f Hnsv2wrapper) ListEndpointsOfNetwork(networkId string) ([]hcn.HostComput
|
|||
func (f Hnsv2wrapper) ApplyEndpointPolicy(endpoint *hcn.HostComputeEndpoint, requestType hcn.RequestType, endpointPolicy hcn.PolicyEndpointRequest) error {
|
||||
return endpoint.ApplyPolicy(requestType, endpointPolicy)
|
||||
}
|
||||
|
||||
func (f Hnsv2wrapper) GetEndpointByName(endpointName string) (*hcn.HostComputeEndpoint, error) {
|
||||
return hcn.GetEndpointByName(endpointName)
|
||||
}
|
||||
|
|
|
@ -285,6 +285,10 @@ func (f Hnsv2wrapperFake) ApplyEndpointPolicy(endpoint *hcn.HostComputeEndpoint,
|
|||
return nil
|
||||
}
|
||||
|
||||
func (Hnsv2wrapperFake) GetEndpointByName(endpointName string) (*hcn.HostComputeEndpoint, error) {
|
||||
return nil, hcn.EndpointNotFoundError{EndpointName: endpointName}
|
||||
}
|
||||
|
||||
type FakeHNSCache struct {
|
||||
networks map[string]*FakeHostComputeNetwork
|
||||
endpoints map[string]*FakeHostComputeEndpoint
|
||||
|
|
|
@ -24,4 +24,5 @@ type HnsV2WrapperInterface interface {
|
|||
GetEndpointByID(endpointId string) (*hcn.HostComputeEndpoint, error)
|
||||
ListEndpointsOfNetwork(networkId string) ([]hcn.HostComputeEndpoint, error)
|
||||
ApplyEndpointPolicy(endpoint *hcn.HostComputeEndpoint, requestType hcn.RequestType, endpointPolicy hcn.PolicyEndpointRequest) error
|
||||
GetEndpointByName(endpointName string) (*hcn.HostComputeEndpoint, error)
|
||||
}
|
||||
|
|
|
@ -74,9 +74,11 @@ type NetworkManager interface {
|
|||
CreateNetwork(nwInfo *NetworkInfo) error
|
||||
DeleteNetwork(networkID string) error
|
||||
GetNetworkInfo(networkID string) (NetworkInfo, error)
|
||||
// FindNetworkIDFromNetNs returns the network name that contains an endpoint created for this netNS, errNetworkNotFound if no network is found
|
||||
FindNetworkIDFromNetNs(netNs string) (string, error)
|
||||
|
||||
CreateEndpoint(client apipaClient, networkID string, epInfo *EndpointInfo) error
|
||||
DeleteEndpoint(cli apipaClient, networkID string, endpointID string) error
|
||||
DeleteEndpoint(networkID string, endpointID string) error
|
||||
GetEndpointInfo(networkID string, endpointID string) (*EndpointInfo, error)
|
||||
GetAllEndpoints(networkID string) (map[string]*EndpointInfo, error)
|
||||
GetEndpointInfoBasedOnPODDetails(networkID string, podName string, podNameSpace string, doExactMatchForPodName bool) (*EndpointInfo, error)
|
||||
|
@ -352,7 +354,7 @@ func (nm *networkManager) CreateEndpoint(cli apipaClient, networkID string, epIn
|
|||
}
|
||||
|
||||
// DeleteEndpoint deletes an existing container endpoint.
|
||||
func (nm *networkManager) DeleteEndpoint(cli apipaClient, networkID string, endpointID string) error {
|
||||
func (nm *networkManager) DeleteEndpoint(networkID, endpointID string) error {
|
||||
nm.Lock()
|
||||
defer nm.Unlock()
|
||||
|
||||
|
@ -361,7 +363,7 @@ func (nm *networkManager) DeleteEndpoint(cli apipaClient, networkID string, endp
|
|||
return err
|
||||
}
|
||||
|
||||
err = nw.deleteEndpoint(cli, nm.netlink, nm.plClient, endpointID)
|
||||
err = nw.deleteEndpoint(nm.netlink, nm.plClient, endpointID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ func (nm *MockNetworkManager) CreateEndpoint(_ apipaClient, networkID string, ep
|
|||
}
|
||||
|
||||
// DeleteEndpoint mock
|
||||
func (nm *MockNetworkManager) DeleteEndpoint(_ apipaClient, networkID string, endpointID string) error {
|
||||
func (nm *MockNetworkManager) DeleteEndpoint(networkID, endpointID string) error {
|
||||
delete(nm.TestEndpointInfoMap, endpointID)
|
||||
return nil
|
||||
}
|
||||
|
@ -104,3 +104,13 @@ func (nm *MockNetworkManager) GetNumberOfEndpoints(ifName string, networkID stri
|
|||
func (nm *MockNetworkManager) SetupNetworkUsingState(networkMonitor *cnms.NetworkMonitor) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nm *MockNetworkManager) FindNetworkIDFromNetNs(netNs string) (string, error) {
|
||||
// based on the GetAllEndpoints func above, it seems that this mock is only intended to be used with
|
||||
// one network, so just return the network here if it exists
|
||||
for network := range nm.TestNetworkInfoMap {
|
||||
return network, nil
|
||||
}
|
||||
|
||||
return "", errNetworkNotFound
|
||||
}
|
||||
|
|
|
@ -244,3 +244,26 @@ func (nm *networkManager) getNetwork(networkId string) (*network, error) {
|
|||
|
||||
return nil, errNetworkNotFound
|
||||
}
|
||||
|
||||
// getNetworkIDForNetNs finds the network that contains the endpoint that was created for this netNs. Returns
|
||||
// and errNetworkNotFound if the netNs is not found in any network
|
||||
func (nm *networkManager) FindNetworkIDFromNetNs(netNs string) (string, error) {
|
||||
log.Printf("Querying state for network for NetNs [%s]", netNs)
|
||||
|
||||
// Look through the external interfaces
|
||||
for _, iface := range nm.ExternalInterfaces {
|
||||
// Look through the networks
|
||||
for _, network := range iface.Networks {
|
||||
// Network may have multiple endpoints, so look through all of them
|
||||
for _, endpoint := range network.Endpoints {
|
||||
// If the netNs matches for this endpoint, return the network ID (which is the name)
|
||||
if endpoint.NetNs == netNs {
|
||||
log.Printf("Found network [%s] for NetNS [%s]", network.Id, netNs)
|
||||
return network.Id, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", errNetworkNotFound
|
||||
}
|
||||
|
|
|
@ -213,4 +213,48 @@ var _ = Describe("Test Network", func() {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Test FindNetworkIDFromNetNs", func() {
|
||||
Context("When network exists", func() {
|
||||
It("Should be returned", func() {
|
||||
netNs := "989c079b-45a6-485f-8f9e-88b05d6c55c4"
|
||||
networkID := "byovnetbridge-vlan1-10-128-8-0_23"
|
||||
nm := &networkManager{
|
||||
ExternalInterfaces: map[string]*externalInterface{
|
||||
networkID: {
|
||||
Name: networkID,
|
||||
Networks: map[string]*network{
|
||||
"byovnetbridge-vlan1-10-128-8-0_23": {
|
||||
Id: "byovnetbridge-vlan1-10-128-8-0_23",
|
||||
Endpoints: map[string]*endpoint{
|
||||
"a591be2a-eth0": {
|
||||
Id: "a591be2a-eth0",
|
||||
NetNs: netNs,
|
||||
},
|
||||
},
|
||||
NetNs: "aaac079b-45a6-485f-8f9e-88b05d6c55c4",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
got, err := nm.FindNetworkIDFromNetNs(netNs)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(got).To(Equal(networkID))
|
||||
})
|
||||
})
|
||||
|
||||
Context("When network does not exist", func() {
|
||||
It("Should return an errNetworkNotFound", func() {
|
||||
nm := &networkManager{
|
||||
ExternalInterfaces: make(map[string]*externalInterface),
|
||||
}
|
||||
|
||||
_, err := nm.FindNetworkIDFromNetNs("989c079b-45a6-485f-8f9e-88b05d6c55c4")
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(IsNetworkNotFoundError(err)).To(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
// Copyright 2017 Microsoft. All rights reserved.
|
||||
// MIT License
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Azure/azure-container-networking/network/hnswrapper"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-container-networking/network/hnswrapper"
|
||||
)
|
||||
|
||||
func TestNewAndDeleteNetworkImplHnsV2(t *testing.T){
|
||||
func TestNewAndDeleteNetworkImplHnsV2(t *testing.T) {
|
||||
nm := &networkManager{
|
||||
ExternalInterfaces: map[string]*externalInterface{},
|
||||
}
|
||||
|
@ -23,7 +25,7 @@ func TestNewAndDeleteNetworkImplHnsV2(t *testing.T){
|
|||
nwInfo := &NetworkInfo{
|
||||
Id: "d3e97a83-ba4c-45d5-ba88-dc56757ece28",
|
||||
MasterIfName: "eth0",
|
||||
Mode: "bridge",
|
||||
Mode: "bridge",
|
||||
}
|
||||
|
||||
extInterface := &externalInterface{
|
||||
|
@ -31,7 +33,7 @@ func TestNewAndDeleteNetworkImplHnsV2(t *testing.T){
|
|||
Subnets: []string{"subnet1", "subnet2"},
|
||||
}
|
||||
|
||||
network,err := nm.newNetworkImplHnsV2(nwInfo,extInterface)
|
||||
network, err := nm.newNetworkImplHnsV2(nwInfo, extInterface)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("+%v", err)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//+build linux
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package network
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче