...

Source file src/k8s.io/kubernetes/pkg/proxy/winkernel/hns_test.go

Documentation: k8s.io/kubernetes/pkg/proxy/winkernel

     1  //go:build windows
     2  // +build windows
     3  
     4  /*
     5  Copyright 2018 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package winkernel
    21  
    22  import (
    23  	"encoding/json"
    24  
    25  	"github.com/Microsoft/hcsshim/hcn"
    26  	"github.com/stretchr/testify/assert"
    27  
    28  	"strings"
    29  	"testing"
    30  
    31  	"github.com/google/go-cmp/cmp"
    32  )
    33  
    34  const (
    35  	sourceVip         = "192.168.1.2"
    36  	serviceVip        = "11.0.0.1"
    37  	addressPrefix     = "192.168.1.0/24"
    38  	gatewayAddress    = "192.168.1.1"
    39  	epMacAddress      = "00-11-22-33-44-55"
    40  	epIpAddress       = "192.168.1.3"
    41  	epIpv6Address     = "192::3"
    42  	epIpAddressB      = "192.168.1.4"
    43  	epIpAddressRemote = "192.168.2.3"
    44  	epPaAddress       = "10.0.0.3"
    45  	protocol          = 6
    46  	internalPort      = 80
    47  	externalPort      = 32440
    48  )
    49  
    50  func TestGetNetworkByName(t *testing.T) {
    51  	hns := hns{hcn: newHcnImpl()}
    52  	Network := mustTestNetwork(t)
    53  
    54  	network, err := hns.getNetworkByName(Network.Name)
    55  	if err != nil {
    56  		t.Error(err)
    57  	}
    58  
    59  	if !strings.EqualFold(network.id, Network.Id) {
    60  		t.Errorf("%v does not match %v", network.id, Network.Id)
    61  	}
    62  	err = Network.Delete()
    63  	if err != nil {
    64  		t.Error(err)
    65  	}
    66  }
    67  
    68  func TestGetAllEndpointsByNetwork(t *testing.T) {
    69  	hns := hns{hcn: newHcnImpl()}
    70  	Network := mustTestNetwork(t)
    71  
    72  	ipv4Config := &hcn.IpConfig{
    73  		IpAddress: epIpAddress,
    74  	}
    75  	ipv6Config := &hcn.IpConfig{
    76  		IpAddress: epIpv6Address,
    77  	}
    78  	Endpoint := &hcn.HostComputeEndpoint{
    79  		IpConfigurations: []hcn.IpConfig{*ipv4Config, *ipv6Config},
    80  		MacAddress:       epMacAddress,
    81  		SchemaVersion: hcn.SchemaVersion{
    82  			Major: 2,
    83  			Minor: 0,
    84  		},
    85  	}
    86  	Endpoint, err := Network.CreateEndpoint(Endpoint)
    87  	if err != nil {
    88  		t.Error(err)
    89  	}
    90  
    91  	mapEndpointsInfo, err := hns.getAllEndpointsByNetwork(Network.Name)
    92  	if err != nil {
    93  		t.Error(err)
    94  	}
    95  	endpointIpv4, ipv4EpPresent := mapEndpointsInfo[ipv4Config.IpAddress]
    96  	assert.True(t, ipv4EpPresent, "IPV4 endpoint is missing in Dualstack mode")
    97  	assert.Equal(t, endpointIpv4.ip, epIpAddress, "IPV4 IP is missing in Dualstack mode")
    98  
    99  	endpointIpv6, ipv6EpPresent := mapEndpointsInfo[ipv6Config.IpAddress]
   100  	assert.True(t, ipv6EpPresent, "IPV6 endpoint is missing in Dualstack mode")
   101  	assert.Equal(t, endpointIpv6.ip, epIpv6Address, "IPV6 IP is missing in Dualstack mode")
   102  
   103  	err = Endpoint.Delete()
   104  	if err != nil {
   105  		t.Error(err)
   106  	}
   107  	err = Network.Delete()
   108  	if err != nil {
   109  		t.Error(err)
   110  	}
   111  }
   112  
   113  func TestGetEndpointByID(t *testing.T) {
   114  	hns := hns{hcn: newHcnImpl()}
   115  	Network := mustTestNetwork(t)
   116  
   117  	ipConfig := &hcn.IpConfig{
   118  		IpAddress: epIpAddress,
   119  	}
   120  	Endpoint := &hcn.HostComputeEndpoint{
   121  		IpConfigurations: []hcn.IpConfig{*ipConfig},
   122  		MacAddress:       epMacAddress,
   123  		SchemaVersion: hcn.SchemaVersion{
   124  			Major: 2,
   125  			Minor: 0,
   126  		},
   127  	}
   128  
   129  	Endpoint, err := Network.CreateEndpoint(Endpoint)
   130  	if err != nil {
   131  		t.Error(err)
   132  	}
   133  
   134  	endpoint, err := hns.getEndpointByID(Endpoint.Id)
   135  	if err != nil {
   136  		t.Error(err)
   137  	}
   138  	if !strings.EqualFold(endpoint.hnsID, Endpoint.Id) {
   139  		t.Errorf("%v does not match %v", endpoint.hnsID, Endpoint.Id)
   140  	}
   141  
   142  	err = Endpoint.Delete()
   143  	if err != nil {
   144  		t.Error(err)
   145  	}
   146  	err = Network.Delete()
   147  	if err != nil {
   148  		t.Error(err)
   149  	}
   150  }
   151  
   152  func TestGetEndpointByIpAddressAndName(t *testing.T) {
   153  	hns := hns{hcn: newHcnImpl()}
   154  	Network := mustTestNetwork(t)
   155  
   156  	ipConfig := &hcn.IpConfig{
   157  		IpAddress: epIpAddress,
   158  	}
   159  	Endpoint := &hcn.HostComputeEndpoint{
   160  		IpConfigurations: []hcn.IpConfig{*ipConfig},
   161  		MacAddress:       epMacAddress,
   162  		SchemaVersion: hcn.SchemaVersion{
   163  			Major: 2,
   164  			Minor: 0,
   165  		},
   166  	}
   167  	Endpoint, err := Network.CreateEndpoint(Endpoint)
   168  	if err != nil {
   169  		t.Error(err)
   170  	}
   171  
   172  	endpoint, err := hns.getEndpointByIpAddress(Endpoint.IpConfigurations[0].IpAddress, Network.Name)
   173  	if err != nil {
   174  		t.Error(err)
   175  	}
   176  	if !strings.EqualFold(endpoint.hnsID, Endpoint.Id) {
   177  		t.Errorf("%v does not match %v", endpoint.hnsID, Endpoint.Id)
   178  	}
   179  	if endpoint.ip != Endpoint.IpConfigurations[0].IpAddress {
   180  		t.Errorf("%v does not match %v", endpoint.ip, Endpoint.IpConfigurations[0].IpAddress)
   181  	}
   182  
   183  	endpoint2, err := hns.getEndpointByName(Endpoint.Name)
   184  	if err != nil {
   185  		t.Error(err)
   186  	}
   187  	diff := cmp.Diff(endpoint, endpoint2)
   188  	if diff != "" {
   189  		t.Errorf("getEndpointByName(%s) returned a different endpoint. Diff: %s ", Endpoint.Name, diff)
   190  	}
   191  
   192  	err = Endpoint.Delete()
   193  	if err != nil {
   194  		t.Error(err)
   195  	}
   196  	err = Network.Delete()
   197  	if err != nil {
   198  		t.Error(err)
   199  	}
   200  }
   201  
   202  func TestCreateEndpointLocal(t *testing.T) {
   203  	hns := hns{hcn: newHcnImpl()}
   204  	Network := mustTestNetwork(t)
   205  
   206  	endpoint := &endpointInfo{
   207  		ip:         epIpAddress,
   208  		macAddress: epMacAddress,
   209  		isLocal:    true,
   210  	}
   211  
   212  	endpoint, err := hns.createEndpoint(endpoint, Network.Name)
   213  	if err != nil {
   214  		t.Error(err)
   215  	}
   216  	Endpoint, err := hcn.GetEndpointByID(endpoint.hnsID)
   217  	if err != nil {
   218  		t.Error(err)
   219  	}
   220  	if !strings.EqualFold(endpoint.hnsID, Endpoint.Id) {
   221  		t.Errorf("%v does not match %v", endpoint.hnsID, Endpoint.Id)
   222  	}
   223  	if endpoint.ip != Endpoint.IpConfigurations[0].IpAddress {
   224  		t.Errorf("%v does not match %v", endpoint.ip, Endpoint.IpConfigurations[0].IpAddress)
   225  	}
   226  	if endpoint.macAddress != Endpoint.MacAddress {
   227  		t.Errorf("%v does not match %v", endpoint.macAddress, Endpoint.MacAddress)
   228  	}
   229  
   230  	err = Endpoint.Delete()
   231  	if err != nil {
   232  		t.Error(err)
   233  	}
   234  	err = Network.Delete()
   235  	if err != nil {
   236  		t.Error(err)
   237  	}
   238  }
   239  
   240  func TestCreateEndpointRemote(t *testing.T) {
   241  	hns := hns{hcn: newHcnImpl()}
   242  	Network := mustTestNetwork(t)
   243  	providerAddress := epPaAddress
   244  
   245  	endpoint := &endpointInfo{
   246  		ip:              epIpAddressRemote,
   247  		macAddress:      epMacAddress,
   248  		isLocal:         false,
   249  		providerAddress: providerAddress,
   250  	}
   251  
   252  	endpoint, err := hns.createEndpoint(endpoint, Network.Name)
   253  	if err != nil {
   254  		t.Error(err)
   255  	}
   256  	Endpoint, err := hcn.GetEndpointByID(endpoint.hnsID)
   257  	if err != nil {
   258  		t.Error(err)
   259  	}
   260  	if !strings.EqualFold(endpoint.hnsID, Endpoint.Id) {
   261  		t.Errorf("%v does not match %v", endpoint.hnsID, Endpoint.Id)
   262  	}
   263  	if endpoint.ip != Endpoint.IpConfigurations[0].IpAddress {
   264  		t.Errorf("%v does not match %v", endpoint.ip, Endpoint.IpConfigurations[0].IpAddress)
   265  	}
   266  	if endpoint.macAddress != Endpoint.MacAddress {
   267  		t.Errorf("%v does not match %v", endpoint.macAddress, Endpoint.MacAddress)
   268  	}
   269  	if len(providerAddress) != 0 && endpoint.providerAddress != epPaAddress {
   270  		t.Errorf("%v does not match %v", endpoint.providerAddress, providerAddress)
   271  	}
   272  
   273  	err = Endpoint.Delete()
   274  	if err != nil {
   275  		t.Error(err)
   276  	}
   277  	err = Network.Delete()
   278  	if err != nil {
   279  		t.Error(err)
   280  	}
   281  }
   282  
   283  func TestDeleteEndpoint(t *testing.T) {
   284  	hns := hns{hcn: newHcnImpl()}
   285  	Network := mustTestNetwork(t)
   286  
   287  	ipConfig := &hcn.IpConfig{
   288  		IpAddress: epIpAddress,
   289  	}
   290  	Endpoint := &hcn.HostComputeEndpoint{
   291  		IpConfigurations: []hcn.IpConfig{*ipConfig},
   292  		MacAddress:       epMacAddress,
   293  		SchemaVersion: hcn.SchemaVersion{
   294  			Major: 2,
   295  			Minor: 0,
   296  		},
   297  	}
   298  	Endpoint, err := Network.CreateEndpoint(Endpoint)
   299  	if err != nil {
   300  		t.Error(err)
   301  	}
   302  	err = hns.deleteEndpoint(Endpoint.Id)
   303  	if err != nil {
   304  		t.Error(err)
   305  	}
   306  	// Endpoint should no longer exist so this should fail
   307  	Endpoint, err = hcn.GetEndpointByID(Endpoint.Id)
   308  	if err == nil {
   309  		t.Error(err)
   310  	}
   311  
   312  	err = Network.Delete()
   313  	if err != nil {
   314  		t.Error(err)
   315  	}
   316  }
   317  
   318  func TestGetLoadBalancerExisting(t *testing.T) {
   319  	hns := hns{hcn: newHcnImpl()}
   320  	Network := mustTestNetwork(t)
   321  	lbs := make(map[loadBalancerIdentifier]*(loadBalancerInfo))
   322  
   323  	ipConfig := &hcn.IpConfig{
   324  		IpAddress: epIpAddress,
   325  	}
   326  	Endpoint := &hcn.HostComputeEndpoint{
   327  		IpConfigurations: []hcn.IpConfig{*ipConfig},
   328  		MacAddress:       epMacAddress,
   329  		SchemaVersion: hcn.SchemaVersion{
   330  			Major: 2,
   331  			Minor: 0,
   332  		},
   333  	}
   334  	Endpoint, err := Network.CreateEndpoint(Endpoint)
   335  	if err != nil {
   336  		t.Error(err)
   337  	}
   338  
   339  	Endpoints := []hcn.HostComputeEndpoint{*Endpoint}
   340  	LoadBalancer, err := hcn.AddLoadBalancer(
   341  		Endpoints,
   342  		hcn.LoadBalancerFlagsNone,
   343  		hcn.LoadBalancerPortMappingFlagsNone,
   344  		sourceVip,
   345  		[]string{serviceVip},
   346  		protocol,
   347  		internalPort,
   348  		externalPort,
   349  	)
   350  	if err != nil {
   351  		t.Error(err)
   352  	}
   353  	endpoint := &endpointInfo{
   354  		ip:    Endpoint.IpConfigurations[0].IpAddress,
   355  		hnsID: Endpoint.Id,
   356  	}
   357  	endpoints := []endpointInfo{*endpoint}
   358  	hash, err := hashEndpoints(endpoints)
   359  	if err != nil {
   360  		t.Error(err)
   361  	}
   362  
   363  	// We populate this to ensure we test for getting existing load balancer
   364  	id := loadBalancerIdentifier{protocol: protocol, internalPort: internalPort, externalPort: externalPort, vip: serviceVip, endpointsHash: hash}
   365  	lbs[id] = &loadBalancerInfo{hnsID: LoadBalancer.Id}
   366  
   367  	lb, err := hns.getLoadBalancer(endpoints, loadBalancerFlags{}, sourceVip, serviceVip, protocol, internalPort, externalPort, lbs)
   368  
   369  	if err != nil {
   370  		t.Error(err)
   371  	}
   372  
   373  	if !strings.EqualFold(lb.hnsID, LoadBalancer.Id) {
   374  		t.Errorf("%v does not match %v", lb.hnsID, LoadBalancer.Id)
   375  	}
   376  
   377  	err = LoadBalancer.Delete()
   378  	if err != nil {
   379  		t.Error(err)
   380  	}
   381  	err = Endpoint.Delete()
   382  	if err != nil {
   383  		t.Error(err)
   384  	}
   385  	err = Network.Delete()
   386  	if err != nil {
   387  		t.Error(err)
   388  	}
   389  }
   390  
   391  func TestGetLoadBalancerNew(t *testing.T) {
   392  	hns := hns{hcn: newHcnImpl()}
   393  	Network := mustTestNetwork(t)
   394  	// We keep this empty to ensure we test for new load balancer creation.
   395  	lbs := make(map[loadBalancerIdentifier]*(loadBalancerInfo))
   396  
   397  	ipConfig := &hcn.IpConfig{
   398  		IpAddress: epIpAddress,
   399  	}
   400  	Endpoint := &hcn.HostComputeEndpoint{
   401  		IpConfigurations: []hcn.IpConfig{*ipConfig},
   402  		MacAddress:       epMacAddress,
   403  		SchemaVersion: hcn.SchemaVersion{
   404  			Major: 2,
   405  			Minor: 0,
   406  		},
   407  	}
   408  	Endpoint, err := Network.CreateEndpoint(Endpoint)
   409  	if err != nil {
   410  		t.Error(err)
   411  	}
   412  	endpoint := &endpointInfo{
   413  		ip:    Endpoint.IpConfigurations[0].IpAddress,
   414  		hnsID: Endpoint.Id,
   415  	}
   416  	endpoints := []endpointInfo{*endpoint}
   417  	lb, err := hns.getLoadBalancer(endpoints, loadBalancerFlags{}, sourceVip, serviceVip, protocol, internalPort, externalPort, lbs)
   418  	if err != nil {
   419  		t.Error(err)
   420  	}
   421  	LoadBalancer, err := hcn.GetLoadBalancerByID(lb.hnsID)
   422  	if err != nil {
   423  		t.Error(err)
   424  	}
   425  	if !strings.EqualFold(lb.hnsID, LoadBalancer.Id) {
   426  		t.Errorf("%v does not match %v", lb.hnsID, LoadBalancer.Id)
   427  	}
   428  	err = LoadBalancer.Delete()
   429  	if err != nil {
   430  		t.Error(err)
   431  	}
   432  
   433  	err = Endpoint.Delete()
   434  	if err != nil {
   435  		t.Error(err)
   436  	}
   437  	err = Network.Delete()
   438  	if err != nil {
   439  		t.Error(err)
   440  	}
   441  }
   442  
   443  func TestDeleteLoadBalancer(t *testing.T) {
   444  	hns := hns{hcn: newHcnImpl()}
   445  	Network := mustTestNetwork(t)
   446  
   447  	ipConfig := &hcn.IpConfig{
   448  		IpAddress: epIpAddress,
   449  	}
   450  	Endpoint := &hcn.HostComputeEndpoint{
   451  		IpConfigurations: []hcn.IpConfig{*ipConfig},
   452  		MacAddress:       epMacAddress,
   453  		SchemaVersion: hcn.SchemaVersion{
   454  			Major: 2,
   455  			Minor: 0,
   456  		},
   457  	}
   458  	Endpoint, err := Network.CreateEndpoint(Endpoint)
   459  	if err != nil {
   460  		t.Error(err)
   461  	}
   462  
   463  	Endpoints := []hcn.HostComputeEndpoint{*Endpoint}
   464  	LoadBalancer, err := hcn.AddLoadBalancer(
   465  		Endpoints,
   466  		hcn.LoadBalancerFlagsNone,
   467  		hcn.LoadBalancerPortMappingFlagsNone,
   468  		sourceVip,
   469  		[]string{serviceVip},
   470  		protocol,
   471  		internalPort,
   472  		externalPort,
   473  	)
   474  	if err != nil {
   475  		t.Error(err)
   476  	}
   477  	err = hns.deleteLoadBalancer(LoadBalancer.Id)
   478  	if err != nil {
   479  		t.Error(err)
   480  	}
   481  	// Load balancer should not longer exist
   482  	LoadBalancer, err = hcn.GetLoadBalancerByID(LoadBalancer.Id)
   483  	if err == nil {
   484  		t.Error(err)
   485  	}
   486  
   487  	err = Endpoint.Delete()
   488  	if err != nil {
   489  		t.Error(err)
   490  	}
   491  	err = Network.Delete()
   492  	if err != nil {
   493  		t.Error(err)
   494  	}
   495  }
   496  
   497  func mustTestNetwork(t *testing.T) *hcn.HostComputeNetwork {
   498  	network, err := createTestNetwork()
   499  	if err != nil {
   500  		t.Fatalf("cannot create test network: %v", err)
   501  	}
   502  	if network == nil {
   503  		t.Fatal("test network was nil without error")
   504  	}
   505  	return network
   506  }
   507  
   508  func TestHashEndpoints(t *testing.T) {
   509  	Network := mustTestNetwork(t)
   510  	// Create endpoint A
   511  	ipConfigA := &hcn.IpConfig{
   512  		IpAddress: epIpAddress,
   513  	}
   514  	endpointASpec := &hcn.HostComputeEndpoint{
   515  		IpConfigurations: []hcn.IpConfig{*ipConfigA},
   516  		MacAddress:       epMacAddress,
   517  		SchemaVersion: hcn.SchemaVersion{
   518  			Major: 2,
   519  			Minor: 0,
   520  		},
   521  	}
   522  	endpointA, err := Network.CreateEndpoint(endpointASpec)
   523  	if err != nil {
   524  		t.Error(err)
   525  	}
   526  	endpointInfoA := &endpointInfo{
   527  		ip:    endpointA.IpConfigurations[0].IpAddress,
   528  		hnsID: endpointA.Id,
   529  	}
   530  	// Create Endpoint B
   531  	ipConfigB := &hcn.IpConfig{
   532  		IpAddress: epIpAddressB,
   533  	}
   534  	endpointBSpec := &hcn.HostComputeEndpoint{
   535  		IpConfigurations: []hcn.IpConfig{*ipConfigB},
   536  		MacAddress:       epMacAddress,
   537  		SchemaVersion: hcn.SchemaVersion{
   538  			Major: 2,
   539  			Minor: 0,
   540  		},
   541  	}
   542  	endpointB, err := Network.CreateEndpoint(endpointBSpec)
   543  	if err != nil {
   544  		t.Error(err)
   545  	}
   546  	endpointInfoB := &endpointInfo{
   547  		ip:    endpointB.IpConfigurations[0].IpAddress,
   548  		hnsID: endpointB.Id,
   549  	}
   550  	endpoints := []endpointInfo{*endpointInfoA, *endpointInfoB}
   551  	endpointsReverse := []endpointInfo{*endpointInfoB, *endpointInfoA}
   552  	h1, err := hashEndpoints(endpoints)
   553  	if err != nil {
   554  		t.Error(err)
   555  	} else if len(h1) < 1 {
   556  		t.Error("HashEndpoints failed for endpoints", endpoints)
   557  	}
   558  
   559  	h2, err := hashEndpoints(endpointsReverse)
   560  	if err != nil {
   561  		t.Error(err)
   562  	}
   563  	if h1 != h2 {
   564  		t.Errorf("%x does not match %x", h1, h2)
   565  	}
   566  
   567  	// Clean up
   568  	err = endpointA.Delete()
   569  	if err != nil {
   570  		t.Error(err)
   571  	}
   572  	err = endpointB.Delete()
   573  	if err != nil {
   574  		t.Error(err)
   575  	}
   576  	err = Network.Delete()
   577  	if err != nil {
   578  		t.Error(err)
   579  	}
   580  }
   581  
   582  func createTestNetwork() (*hcn.HostComputeNetwork, error) {
   583  	network := &hcn.HostComputeNetwork{
   584  		Type: NETWORK_TYPE_OVERLAY,
   585  		Name: "TestOverlay",
   586  		MacPool: hcn.MacPool{
   587  			Ranges: []hcn.MacRange{
   588  				{
   589  					StartMacAddress: "00-15-5D-52-C0-00",
   590  					EndMacAddress:   "00-15-5D-52-CF-FF",
   591  				},
   592  			},
   593  		},
   594  		Ipams: []hcn.Ipam{
   595  			{
   596  				Type: "Static",
   597  				Subnets: []hcn.Subnet{
   598  					{
   599  						IpAddressPrefix: addressPrefix,
   600  						Routes: []hcn.Route{
   601  							{
   602  								NextHop:           gatewayAddress,
   603  								DestinationPrefix: "0.0.0.0/0",
   604  							},
   605  						},
   606  					},
   607  				},
   608  			},
   609  		},
   610  		SchemaVersion: hcn.SchemaVersion{
   611  			Major: 2,
   612  			Minor: 0,
   613  		},
   614  	}
   615  
   616  	vsid := &hcn.VsidPolicySetting{
   617  		IsolationId: 5000,
   618  	}
   619  	vsidJson, err := json.Marshal(vsid)
   620  	if err != nil {
   621  		return nil, err
   622  	}
   623  
   624  	sp := &hcn.SubnetPolicy{
   625  		Type: hcn.VSID,
   626  	}
   627  	sp.Settings = vsidJson
   628  
   629  	spJson, err := json.Marshal(sp)
   630  	if err != nil {
   631  		return nil, err
   632  	}
   633  
   634  	network.Ipams[0].Subnets[0].Policies = append(network.Ipams[0].Subnets[0].Policies, spJson)
   635  
   636  	return network.Create()
   637  }
   638  

View as plain text