Merge branch 'master' into jainriya/npm-legacy-forwardport

This commit is contained in:
rejain456 2024-11-14 12:57:29 -08:00 коммит произвёл GitHub
Родитель ceab9b7087 5d4c4dc304
Коммит 5ed0b74510
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
28 изменённых файлов: 335 добавлений и 159 удалений

Просмотреть файл

@ -11,7 +11,7 @@ require (
github.com/golangci/golangci-lint v1.62.0
github.com/jstemmer/go-junit-report v1.0.0
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1
google.golang.org/protobuf v1.35.1
google.golang.org/protobuf v1.35.2
mvdan.cc/gofumpt v0.7.0
sigs.k8s.io/controller-tools v0.16.3
)

Просмотреть файл

@ -591,8 +591,8 @@ google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

Просмотреть файл

@ -27,7 +27,7 @@ WORKDIR /payload
COPY --from=azure-vnet /go/bin/* /payload/
COPY --from=azure-vnet /azure-container-networking/cni/azure-$OS.conflist /payload/azure.conflist
COPY --from=azure-vnet /azure-container-networking/cni/azure-$OS-swift.conflist /payload/azure-swift.conflist
COPY --from=azure-vnet /azure-container-networking/cni/azure-$OS-multitenancy-transparent-vlan.conflist /payload/azure-multitenancy-transparent-vlan.conflist
COPY --from=azure-vnet /azure-container-networking/cni/azure-linux-multitenancy-transparent-vlan.conflist /payload/azure-multitenancy-transparent-vlan.conflist
COPY --from=azure-vnet /azure-container-networking/cni/azure-$OS-swift-overlay.conflist /payload/azure-swift-overlay.conflist
COPY --from=azure-vnet /azure-container-networking/cni/azure-$OS-swift-overlay-dualstack.conflist /payload/azure-swift-overlay-dualstack.conflist
COPY --from=azure-vnet /azure-container-networking/cni/azure-$OS-multitenancy.conflist /payload/azure-multitenancy.conflist

Просмотреть файл

@ -1,52 +0,0 @@
{
"cniVersion": "0.3.0",
"name": "azure",
"plugins": [
{
"type": "azure-vnet",
"mode": "transparent-vlan",
"bridge": "azure0",
"multiTenancy":true,
"enableSnatOnHost":true,
"enableExactMatchForPodName": true,
"capabilities": {
"portMappings": true
},
"ipam": {
"type": "azure-cns"
},
"dns": {
"Nameservers": [
"10.0.0.10",
"168.63.129.16"
],
"Search": [
"svc.cluster.local"
]
},
"AdditionalArgs": [
{
"Name": "EndpointPolicy",
"Value": {
"Type": "OutBoundNAT",
"ExceptionList": [
"10.240.0.0/16",
"10.0.0.0/8"
]
}
},
{
"Name": "EndpointPolicy",
"Value": {
"Type": "ROUTE",
"DestinationPrefix": "10.0.0.0/8",
"NeedEncap": true
}
}
],
"windowsSettings": {
"hnsTimeoutDurationInSeconds" : 120
}
}
]
}

Просмотреть файл

@ -4,8 +4,6 @@
"plugins": [
{
"type": "azure-vnet",
"mode": "bridge",
"bridge": "azure0",
"multiTenancy":true,
"enableSnatOnHost":true,
"enableExactMatchForPodName": true,

Просмотреть файл

@ -5,7 +5,6 @@
"plugins": [
{
"type": "azure-vnet",
"bridge": "azure0",
"capabilities": {
"portMappings": true,
"dns": true

Просмотреть файл

@ -5,7 +5,6 @@
"plugins": [
{
"type": "azure-vnet",
"bridge": "azure0",
"capabilities": {
"portMappings": true,
"dns": true

Просмотреть файл

@ -5,7 +5,6 @@
"plugins": [
{
"type": "azure-vnet",
"bridge": "azure0",
"executionMode": "v4swift",
"capabilities": {
"portMappings": true,

Просмотреть файл

@ -5,8 +5,6 @@
"plugins": [
{
"type": "azure-vnet",
"mode": "bridge",
"bridge": "azure0",
"capabilities": {
"portMappings": true,
"dns": true
@ -45,4 +43,4 @@
]
}
]
}
}

Просмотреть файл

@ -899,6 +899,38 @@ func GetTestCNSResponseSecondaryWindows(macAddress string) map[string]network.In
}
}
func GetRawACLPolicy() (ret json.RawMessage) {
var data map[string]interface{}
formatted := []byte(`{
"Type": "ACL",
"Protocols": "6",
"Action": "Block",
"Direction": "Out",
"RemoteAddresses": "168.63.129.16/32",
"RemotePorts": "80",
"Priority": 200,
"RuleType": "Switch"
}`)
json.Unmarshal(formatted, &data) // nolint
minified, _ := json.Marshal(data) // nolint
ret = json.RawMessage(minified)
return ret
}
func GetRawOutBoundNATPolicy() (ret json.RawMessage) {
var data map[string]interface{}
formatted := []byte(`{
"Type": "OutBoundNAT",
"ExceptionList": [
"10.224.0.0/16"
]
}`)
json.Unmarshal(formatted, &data) // nolint
minified, _ := json.Marshal(data) // nolint
ret = json.RawMessage(minified)
return ret
}
// Happy path scenario for add and delete
func TestPluginWindowsAdd(t *testing.T) {
resources := GetTestResources()
@ -908,6 +940,20 @@ func TestPluginWindowsAdd(t *testing.T) {
MultiTenancy: true,
EnableExactMatchForPodName: true,
Master: "eth0",
// these are added to test that policies propagate to endpoint info
AdditionalArgs: []cni.KVPair{
{
Name: "EndpointPolicy",
Value: GetRawOutBoundNATPolicy(),
},
{
Name: "EndpointPolicy",
Value: GetRawACLPolicy(),
},
},
WindowsSettings: cni.WindowsSettings{ // included to test functionality
EnableLoopbackDSR: true,
},
}
nwCfg := cni.NetworkConfig{
CNIVersion: "0.3.0",
@ -1002,6 +1048,31 @@ func TestPluginWindowsAdd(t *testing.T) {
Gateway: net.ParseIP("20.0.0.1"),
},
},
EndpointPolicies: []policy.Policy{
{
Type: policy.EndpointPolicy,
Data: GetRawOutBoundNATPolicy(),
},
{
Type: policy.EndpointPolicy,
Data: GetRawACLPolicy(),
},
{
Type: policy.EndpointPolicy,
// if enabled we create a loopback dsr policy based on the cns ip config
Data: json.RawMessage(`{"Type":"LoopbackDSR","IPAddress":"20.0.0.10"}`),
},
},
NetworkPolicies: []policy.Policy{
{
Type: policy.EndpointPolicy,
Data: GetRawOutBoundNATPolicy(),
},
{
Type: policy.EndpointPolicy,
Data: GetRawACLPolicy(),
},
},
},
epIDRegex: `.*`,
},
@ -1047,6 +1118,30 @@ func TestPluginWindowsAdd(t *testing.T) {
Gateway: net.ParseIP("10.0.0.1"),
},
},
EndpointPolicies: []policy.Policy{
{
Type: policy.EndpointPolicy,
Data: GetRawOutBoundNATPolicy(),
},
{
Type: policy.EndpointPolicy,
Data: GetRawACLPolicy(),
},
{
Type: policy.EndpointPolicy,
Data: json.RawMessage(`{"Type":"LoopbackDSR","IPAddress":"10.0.0.10"}`),
},
},
NetworkPolicies: []policy.Policy{
{
Type: policy.EndpointPolicy,
Data: GetRawOutBoundNATPolicy(),
},
{
Type: policy.EndpointPolicy,
Data: GetRawACLPolicy(),
},
},
},
epIDRegex: `.*`,
},
@ -1211,6 +1306,37 @@ func TestPluginWindowsAdd(t *testing.T) {
require.NoError(t, err)
}
// confirm separate entities
// that is, if one is modified, the other should not be modified
epInfos := []*network.EndpointInfo{}
for _, val := range allEndpoints {
epInfos = append(epInfos, val)
}
if len(epInfos) > 1 {
// ensure the endpoint data and options are separate entities when in separate endpoint infos
epInfo1 := epInfos[0]
epInfo2 := epInfos[1]
epInfo1.Data["dummy"] = "dummy value"
epInfo1.Options["dummy"] = "another dummy value"
require.NotEqual(t, epInfo1.Data, epInfo2.Data)
require.NotEqual(t, epInfo1.Options, epInfo2.Options)
// ensure the endpoint policy slices are separate entities when in separate endpoint infos
if len(epInfo1.EndpointPolicies) > 0 {
epInfo1.EndpointPolicies[0] = policy.Policy{
Type: policy.ACLPolicy,
}
require.NotEqual(t, epInfo1.EndpointPolicies, epInfo2.EndpointPolicies)
}
// ensure the network policy slices are separate entities when in separate endpoint infos
if len(epInfo1.NetworkPolicies) > 0 {
epInfo1.NetworkPolicies[0] = policy.Policy{
Type: policy.ACLPolicy,
}
require.NotEqual(t, epInfo1.NetworkPolicies, epInfo2.NetworkPolicies)
}
}
// ensure deleted
require.Empty(t, allEndpoints)
})

Просмотреть файл

@ -33,5 +33,6 @@
"MellanoxMonitorIntervalSecs": 30,
"AZRSettings": {
"PopulateHomeAzCacheRetryIntervalSecs": 60
}
},
"MinTLSVersion": "TLS 1.2"
}

Просмотреть файл

@ -54,6 +54,7 @@ type CNSConfig struct {
WatchPods bool `json:"-"`
WireserverIP string
GRPCSettings GRPCSettings
MinTLSVersion string
}
type TelemetrySettings struct {
@ -229,6 +230,10 @@ func SetCNSConfigDefaults(config *CNSConfig) {
if config.GRPCSettings.Port == 0 {
config.GRPCSettings.Port = 8080
}
if config.MinTLSVersion == "" {
config.MinTLSVersion = "TLS 1.2"
}
config.GRPCSettings.Enable = false
config.WatchPods = config.EnableIPAMv2 || config.EnableSwiftV2
}

Просмотреть файл

@ -86,9 +86,10 @@ func TestReadConfigFromFile(t *testing.T) {
AZRSettings: AZRSettings{
PopulateHomeAzCacheRetryIntervalSecs: 60,
},
UseHTTPS: true,
UseMTLS: true,
WireserverIP: "168.63.129.16",
UseHTTPS: true,
UseMTLS: true,
WireserverIP: "168.63.129.16",
MinTLSVersion: "TLS 1.3",
},
wantErr: false,
},
@ -220,6 +221,7 @@ func TestSetCNSConfigDefaults(t *testing.T) {
IPAddress: "localhost",
Port: 8080,
},
MinTLSVersion: "TLS 1.2",
},
},
{
@ -250,6 +252,7 @@ func TestSetCNSConfigDefaults(t *testing.T) {
IPAddress: "192.168.1.1",
Port: 9090,
},
MinTLSVersion: "TLS 1.3",
},
want: CNSConfig{
ChannelMode: "Other",
@ -279,6 +282,7 @@ func TestSetCNSConfigDefaults(t *testing.T) {
IPAddress: "192.168.1.1",
Port: 9090,
},
MinTLSVersion: "TLS 1.3",
},
},
}

3
cns/configuration/testdata/good.json поставляемый
Просмотреть файл

@ -34,5 +34,6 @@
"WireserverIP": "168.63.129.16",
"AZRSettings": {
"PopulateHomeAzCacheRetryIntervalSecs": 60
}
},
"MinTLSVersion": "TLS 1.3"
}

Просмотреть файл

@ -237,6 +237,8 @@ func (k *K8sSWIFTv2Middleware) getIPConfig(ctx context.Context, podInfo cns.PodI
return nil, errors.Wrap(err, "failed to parse mtpnc subnetAddressSpace prefix")
}
podIPInfos = append(podIPInfos, podIPInfo)
// for windows scenario, it is required to add default route with gatewayIP from CNS
k.addDefaultRoute(&podIPInfo, interfaceInfo.GatewayIP)
}
}
}

Просмотреть файл

@ -101,3 +101,5 @@ func addRoutes(cidrs []string, gatewayIP string) []cns.Route {
func (k *K8sSWIFTv2Middleware) assignSubnetPrefixLengthFields(_ *cns.PodIpInfo, _ v1alpha1.InterfaceInfo, _ string) error {
return nil
}
func (k *K8sSWIFTv2Middleware) addDefaultRoute(*cns.PodIpInfo, string) {}

Просмотреть файл

@ -2,7 +2,6 @@ package middlewares
import (
"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/cns/logger"
"github.com/Azure/azure-container-networking/cns/middlewares/utils"
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
"github.com/pkg/errors"
@ -12,7 +11,15 @@ import (
// default route is set for secondary interface NIC(i.e,delegatedNIC)
func (k *K8sSWIFTv2Middleware) setRoutes(podIPInfo *cns.PodIpInfo) error {
if podIPInfo.NICType == cns.InfraNIC {
logger.Printf("[SWIFTv2Middleware] skip setting default route on InfraNIC interface")
// as a workaround, HNS will not set this dummy default route(0.0.0.0/0, nexthop:0.0.0.0) on infraVnet interface eth0
// the only usage for this dummy default is to bypass HNS setting default route on eth0
// TODO: Remove this once HNS fix is ready
route := cns.Route{
IPAddress: "0.0.0.0/0",
GatewayIPAddress: "0.0.0.0",
}
podIPInfo.Routes = append(podIPInfo.Routes, route)
podIPInfo.SkipDefaultRoutes = true
}
return nil
@ -42,3 +49,12 @@ func (k *K8sSWIFTv2Middleware) assignSubnetPrefixLengthFields(podIPInfo *cns.Pod
}
return nil
}
// add default route with gateway IP to podIPInfo
func (k *K8sSWIFTv2Middleware) addDefaultRoute(podIPInfo *cns.PodIpInfo, gwIP string) {
route := cns.Route{
IPAddress: "0.0.0.0/0",
GatewayIPAddress: gwIP,
}
podIPInfo.Routes = append(podIPInfo.Routes, route)
}

Просмотреть файл

@ -1,6 +1,7 @@
package middlewares
import (
"reflect"
"testing"
"github.com/Azure/azure-container-networking/cns"
@ -66,3 +67,36 @@ func TestAssignSubnetPrefixSuccess(t *testing.T) {
assert.Equal(t, ipInfo.HostPrimaryIPInfo.Gateway, intInfo.GatewayIP)
assert.Equal(t, ipInfo.HostPrimaryIPInfo.Subnet, intInfo.SubnetAddressSpace)
}
func TestAddDefaultRoute(t *testing.T) {
middleware := K8sSWIFTv2Middleware{Cli: mock.NewClient()}
podIPInfo := cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: "20.240.1.242",
PrefixLength: 32,
},
NICType: cns.DelegatedVMNIC,
MacAddress: "12:34:56:78:9a:bc",
}
gatewayIP := "20.240.1.1"
intInfo := v1alpha1.InterfaceInfo{
GatewayIP: gatewayIP,
SubnetAddressSpace: "20.240.1.0/16",
}
ipInfo := podIPInfo
middleware.addDefaultRoute(&ipInfo, intInfo.GatewayIP)
expectedRoutes := []cns.Route{
{
IPAddress: "0.0.0.0/0",
GatewayIPAddress: gatewayIP,
},
}
if !reflect.DeepEqual(ipInfo.Routes, expectedRoutes) {
t.Errorf("got '%+v', expected '%+v'", ipInfo.Routes, expectedRoutes)
}
}

Просмотреть файл

@ -28,6 +28,8 @@ const (
genericData = "com.microsoft.azure.network.generic"
)
var errTLSConfig = errors.New("unsupported TLS version name from config")
// Service defines Container Networking Service.
type Service struct {
*common.Service
@ -179,10 +181,14 @@ func getTLSConfigFromFile(tlsSettings localtls.TlsSettings) (*tls.Config, error)
PrivateKey: privateKey,
Leaf: leafCertificate,
}
minTLSVersionNumber, err := parseTLSVersionName(tlsSettings.MinTLSVersion)
if err != nil {
return nil, errors.Wrap(err, "parsing MinTLSVersion from config")
}
tlsConfig := &tls.Config{
MaxVersion: tls.VersionTLS13,
MinVersion: tls.VersionTLS12,
MinVersion: minTLSVersionNumber,
Certificates: []tls.Certificate{
tlsCert,
},
@ -226,8 +232,13 @@ func getTLSConfigFromKeyVault(tlsSettings localtls.TlsSettings, errChan chan<- e
errChan <- cr.Refresh(ctx, tlsSettings.KeyVaultCertificateRefreshInterval)
}()
minTLSVersionNumber, err := parseTLSVersionName(tlsSettings.MinTLSVersion)
if err != nil {
return nil, errors.Wrap(err, "parsing MinTLSVersion from config")
}
tlsConfig := tls.Config{
MinVersion: tls.VersionTLS12,
MinVersion: minTLSVersionNumber,
MaxVersion: tls.VersionTLS13,
GetCertificate: func(_ *tls.ClientHelloInfo) (*tls.Certificate, error) {
return cr.GetCertificate(), nil
@ -316,3 +327,16 @@ func (service *Service) SendErrorResponse(w http.ResponseWriter, errMsg error) {
err := acn.Encode(w, &resp)
logger.Errorf("[%s] %+v %s.", service.Name, &resp, err.Error())
}
// parseTLSVersionName returns the version number for the provided TLS version name
// (e.g. 0x0301)
func parseTLSVersionName(versionName string) (uint16, error) {
switch versionName {
case "TLS 1.2":
return tls.VersionTLS12, nil
case "TLS 1.3":
return tls.VersionTLS13, nil
default:
return 0, errors.Wrapf(errTLSConfig, "version name %s", versionName)
}
}

Просмотреть файл

@ -776,6 +776,7 @@ func main() {
MSIResourceID: cnsconfig.MSISettings.ResourceID,
KeyVaultCertificateRefreshInterval: time.Duration(cnsconfig.KeyVaultSettings.RefreshIntervalInHrs) * time.Hour,
UseMTLS: cnsconfig.UseMTLS,
MinTLSVersion: cnsconfig.MinTLSVersion,
}
}
@ -787,8 +788,7 @@ func main() {
}
// Setting the remote ARP MAC address to 12-34-56-78-9a-bc on windows for external traffic if HNS is enabled
execClient := platform.NewExecClient(nil)
err = platform.SetSdnRemoteArpMacAddress(execClient)
err = platform.SetSdnRemoteArpMacAddress(rootCtx)
if err != nil {
logger.Errorf("Failed to set remote ARP MAC address: %v", err)
return

Просмотреть файл

@ -76,6 +76,7 @@ func TestNewService(t *testing.T) {
TLSPort: "10091",
TLSSubjectName: "localhost",
TLSCertificatePath: testCertFilePath,
MinTLSVersion: "TLS 1.2",
}
svc, err := NewService(config.Name, config.Version, config.ChannelMode, config.Store)
@ -94,10 +95,13 @@ func TestNewService(t *testing.T) {
err = svc.StartListener(config)
require.NoError(t, err)
minTLSVersionNumber, err := parseTLSVersionName(config.TLSSettings.MinTLSVersion)
require.NoError(t, err)
tlsClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
MinVersion: minTLSVersionNumber,
MaxVersion: tls.VersionTLS13,
ServerName: config.TLSSettings.TLSSubjectName,
// #nosec G402 for test purposes only
@ -134,6 +138,7 @@ func TestNewService(t *testing.T) {
TLSSubjectName: "localhost",
TLSCertificatePath: testCertFilePath,
UseMTLS: true,
MinTLSVersion: "TLS 1.2",
}
svc, err := NewService(config.Name, config.Version, config.ChannelMode, config.Store)
@ -322,3 +327,31 @@ func createTestCertificate(t *testing.T) string {
return testCertFilePath
}
func TestTLSVersionNumber(t *testing.T) {
t.Run("unsupported ServerSettings.MinTLSVersion TLS 1.0", func(t *testing.T) {
versionNumber, err := parseTLSVersionName("TLS 1.0")
require.Equal(t, uint16(0), versionNumber)
require.Error(t, err)
require.ErrorContains(t, err, "unsupported TLS version name")
})
t.Run("unsupported ServerSettings.MinTLSVersion TLS 1.1", func(t *testing.T) {
versionNumber, err := parseTLSVersionName("TLS 1.1")
require.Equal(t, uint16(0), versionNumber)
require.Error(t, err)
require.ErrorContains(t, err, "unsupported TLS version name")
})
t.Run("unsupported ServerSettings.MinTLSVersion TLS 1.4", func(t *testing.T) {
versionNumber, err := parseTLSVersionName("TLS 1.4")
require.Equal(t, uint16(0), versionNumber)
require.Error(t, err)
require.ErrorContains(t, err, "unsupported TLS version name")
})
t.Run("valid ServerSettings.MinTLSVersion", func(t *testing.T) {
versionNumber, err := parseTLSVersionName("TLS 1.2")
require.Equal(t, uint16(tls.VersionTLS12), versionNumber)
require.NoError(t, err)
})
}

2
go.mod
Просмотреть файл

@ -41,7 +41,7 @@ require (
golang.org/x/sys v0.27.0
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/grpc v1.68.0
google.golang.org/protobuf v1.35.1
google.golang.org/protobuf v1.35.2
gopkg.in/natefinch/lumberjack.v2 v2.2.1
k8s.io/api v0.30.6
k8s.io/apiextensions-apiserver v0.30.1

4
go.sum
Просмотреть файл

@ -413,8 +413,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=

Просмотреть файл

@ -179,7 +179,7 @@ func (p *execClient) KillProcessByName(processName string) error {
// SetSdnRemoteArpMacAddress sets the regkey for SDNRemoteArpMacAddress needed for multitenancy
// This operation is specific to windows OS
func SetSdnRemoteArpMacAddress(_ ExecClient) error {
func SetSdnRemoteArpMacAddress(context.Context) error {
return nil
}

Просмотреть файл

@ -20,6 +20,9 @@ import (
"github.com/pkg/errors"
"go.uber.org/zap"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/mgr"
)
const (
@ -61,24 +64,10 @@ const (
// for vlan tagged arp requests
SDNRemoteArpMacAddress = "12-34-56-78-9a-bc"
// Command to get SDNRemoteArpMacAddress registry key
GetSdnRemoteArpMacAddressCommand = "(Get-ItemProperty " +
"-Path HKLM:\\SYSTEM\\CurrentControlSet\\Services\\hns\\State -Name SDNRemoteArpMacAddress).SDNRemoteArpMacAddress"
// Command to set SDNRemoteArpMacAddress registry key
SetSdnRemoteArpMacAddressCommand = "Set-ItemProperty " +
"-Path HKLM:\\SYSTEM\\CurrentControlSet\\Services\\hns\\State -Name SDNRemoteArpMacAddress -Value \"12-34-56-78-9a-bc\""
// Command to check if system has hns state path or not
CheckIfHNSStatePathExistsCommand = "Test-Path " +
"-Path HKLM:\\SYSTEM\\CurrentControlSet\\Services\\hns\\State"
// Command to fetch netadapter and pnp id
// TODO: can we replace this (and things in endpoint_windows) with other utils from "golang.org/x/sys/windows"?
GetMacAddressVFPPnpIDMapping = "Get-NetAdapter | Select-Object MacAddress, PnpDeviceID| Format-Table -HideTableHeaders"
// Command to restart HNS service
RestartHnsServiceCommand = "Restart-Service -Name hns"
// Interval between successive checks for mellanox adapter's PriorityVLANTag value
defaultMellanoxMonitorInterval = 30 * time.Second
@ -257,40 +246,73 @@ func (p *execClient) ExecutePowershellCommandWithContext(ctx context.Context, co
}
// SetSdnRemoteArpMacAddress sets the regkey for SDNRemoteArpMacAddress needed for multitenancy if hns is enabled
func SetSdnRemoteArpMacAddress(execClient ExecClient) error {
exists, err := execClient.ExecutePowershellCommand(CheckIfHNSStatePathExistsCommand)
func SetSdnRemoteArpMacAddress(ctx context.Context) error {
log.Printf("Setting SDNRemoteArpMacAddress regKey")
// open the registry key
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Services\hns\State`, registry.READ|registry.SET_VALUE)
if err != nil {
errMsg := fmt.Sprintf("Failed to check the existent of hns state path due to error %s", err.Error())
log.Printf(errMsg)
return errors.Errorf(errMsg)
if errors.Is(err, registry.ErrNotExist) {
return nil
}
return errors.Wrap(err, "could not open registry key")
}
if strings.EqualFold(exists, "false") {
log.Printf("hns state path does not exist, skip setting SdnRemoteArpMacAddress")
return nil
defer k.Close()
// check the key value
if v, _, _ := k.GetStringValue("SDNRemoteArpMacAddress"); v == SDNRemoteArpMacAddress {
log.Printf("SDNRemoteArpMacAddress regKey already set")
return nil // already set
}
if sdnRemoteArpMacAddressSet == false {
result, err := execClient.ExecutePowershellCommand(GetSdnRemoteArpMacAddressCommand)
if err = k.SetStringValue("SDNRemoteArpMacAddress", SDNRemoteArpMacAddress); err != nil {
return errors.Wrap(err, "could not set registry key")
}
log.Printf("SDNRemoteArpMacAddress regKey set successfully")
log.Printf("Restarting HNS service")
// connect to the service manager
m, err := mgr.Connect()
if err != nil {
return errors.Wrap(err, "could not connect to service manager")
}
defer m.Disconnect() //nolint:errcheck // ignore error
// open the HNS service
service, err := m.OpenService("hns")
if err != nil {
return errors.Wrap(err, "could not access service")
}
defer service.Close()
if err := restartService(ctx, service); err != nil {
return errors.Wrap(err, "could not restart service")
}
log.Printf("HNS service restarted successfully")
return nil
}
func restartService(ctx context.Context, s *mgr.Service) error {
// Stop the service
_, err := s.Control(svc.Stop)
if err != nil {
return errors.Wrap(err, "could not stop service")
}
// Wait for the service to stop
ticker := time.NewTicker(500 * time.Millisecond) //nolint:gomnd // 500ms
defer ticker.Stop()
for { // hacky cancellable do-while
status, err := s.Query()
if err != nil {
return err
return errors.Wrap(err, "could not query service status")
}
// Set the reg key if not already set or has incorrect value
if result != SDNRemoteArpMacAddress {
if _, err = execClient.ExecutePowershellCommand(SetSdnRemoteArpMacAddressCommand); err != nil {
log.Printf("Failed to set SDNRemoteArpMacAddress due to error %s", err.Error())
return err
}
log.Printf("[Azure CNS] SDNRemoteArpMacAddress regKey set successfully. Restarting hns service.")
if _, err := execClient.ExecutePowershellCommand(RestartHnsServiceCommand); err != nil {
log.Printf("Failed to Restart HNS Service due to error %s", err.Error())
return err
}
if status.State == svc.Stopped {
break
}
select {
case <-ctx.Done():
return errors.New("context cancelled")
case <-ticker.C:
}
sdnRemoteArpMacAddressSet = true
}
// Start the service again
if err := s.Start(); err != nil {
return errors.Wrap(err, "could not start service")
}
return nil
}

Просмотреть файл

@ -4,7 +4,6 @@ import (
"context"
"errors"
"os/exec"
"strings"
"testing"
"time"
@ -115,41 +114,6 @@ func TestExecuteCommandError(t *testing.T) {
require.ErrorIs(t, err, exec.ErrNotFound)
}
func TestSetSdnRemoteArpMacAddress_hnsNotEnabled(t *testing.T) {
mockExecClient := NewMockExecClient(false)
// testing skip setting SdnRemoteArpMacAddress when hns not enabled
mockExecClient.SetPowershellCommandResponder(func(_ string) (string, error) {
return "False", nil
})
err := SetSdnRemoteArpMacAddress(mockExecClient)
assert.NoError(t, err)
assert.Equal(t, false, sdnRemoteArpMacAddressSet)
// testing the scenario when there is an error in checking if hns is enabled or not
mockExecClient.SetPowershellCommandResponder(func(_ string) (string, error) {
return "", errTestFailure
})
err = SetSdnRemoteArpMacAddress(mockExecClient)
assert.ErrorAs(t, err, &errTestFailure)
assert.Equal(t, false, sdnRemoteArpMacAddressSet)
}
func TestSetSdnRemoteArpMacAddress_hnsEnabled(t *testing.T) {
mockExecClient := NewMockExecClient(false)
// happy path
mockExecClient.SetPowershellCommandResponder(func(cmd string) (string, error) {
if strings.Contains(cmd, "Test-Path") {
return "True", nil
}
return "", nil
})
err := SetSdnRemoteArpMacAddress(mockExecClient)
assert.NoError(t, err)
assert.Equal(t, true, sdnRemoteArpMacAddressSet)
// reset sdnRemoteArpMacAddressSet
sdnRemoteArpMacAddressSet = false
}
func TestFetchPnpIDMapping(t *testing.T) {
mockExecClient := NewMockExecClient(false)
// happy path

Просмотреть файл

@ -14,6 +14,7 @@ type TlsSettings struct {
MSIResourceID string
KeyVaultCertificateRefreshInterval time.Duration
UseMTLS bool
MinTLSVersion string
}
func GetTlsCertificateRetriever(settings TlsSettings) (TlsCertificateRetriever, error) {

Просмотреть файл

@ -124,7 +124,7 @@ func (v *Validator) ValidateStateFile(ctx context.Context) error {
}
func (v *Validator) validateIPs(ctx context.Context, stateFileIps stateFileIpsFunc, cmd []string, checkType, namespace, labelSelector, containerName string) error {
log.Printf("Validating %s state file", checkType)
log.Printf("Validating %s state file for %s on %s", checkType, v.cni, v.os)
nodes, err := acnk8s.GetNodeListByLabelSelector(ctx, v.clientset, nodeSelectorMap[v.os])
if err != nil {
return errors.Wrapf(err, "failed to get node list")