github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/core/network/discovery_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package network_test
     5  
     6  import (
     7  	"errors"
     8  	"net"
     9  
    10  	"github.com/juju/collections/set"
    11  	"github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	"go.uber.org/mock/gomock"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/core/network"
    17  )
    18  
    19  type networkConfigSuite struct {
    20  	testing.IsolationSuite
    21  
    22  	source *MockConfigSource
    23  
    24  	ovsBridges            set.Strings
    25  	defaultRouteGatewayIP net.IP
    26  	defaultRouteDevice    string
    27  	bridgePorts           map[string][]string
    28  }
    29  
    30  var _ = gc.Suite(&networkConfigSuite{})
    31  
    32  func (s *networkConfigSuite) SetUpTest(c *gc.C) {
    33  	s.IsolationSuite.SetUpTest(c)
    34  
    35  	s.ovsBridges = set.NewStrings()
    36  	s.defaultRouteGatewayIP = net.ParseIP("1.2.3.4")
    37  	s.defaultRouteDevice = "eth0"
    38  	s.bridgePorts = make(map[string][]string)
    39  }
    40  
    41  func (s *networkConfigSuite) TestGetObservedNetworkConfigInterfacesError(c *gc.C) {
    42  	defer s.setupMocks(c).Finish()
    43  
    44  	s.source.EXPECT().Interfaces().Return(nil, errors.New("boom"))
    45  
    46  	observedConfig, err := network.GetObservedNetworkConfig(s.source)
    47  	c.Check(err, gc.ErrorMatches, "detecting network interfaces: boom")
    48  	c.Check(observedConfig, gc.IsNil)
    49  }
    50  
    51  func (s *networkConfigSuite) TestGetObservedNetworkConfigInterfaceAddressesError(c *gc.C) {
    52  	ctrl := s.setupMocks(c)
    53  	defer ctrl.Finish()
    54  
    55  	nic := NewMockConfigSourceNIC(ctrl)
    56  	exp := nic.EXPECT()
    57  	exp.Name().Return("eth0").MinTimes(1)
    58  	exp.Type().Return(network.EthernetDevice).MinTimes(1)
    59  	exp.IsUp().Return(true)
    60  	exp.Index().Return(2)
    61  	exp.HardwareAddr().Return(net.HardwareAddr{})
    62  	exp.MTU().Return(1500)
    63  	exp.Addresses().Return(nil, errors.New("bam"))
    64  
    65  	s.source.EXPECT().Interfaces().Return([]network.ConfigSourceNIC{nic}, nil)
    66  
    67  	observedConfig, err := network.GetObservedNetworkConfig(s.source)
    68  	c.Check(err, gc.ErrorMatches, `detecting addresses for "eth0": bam`)
    69  	c.Check(observedConfig, gc.IsNil)
    70  }
    71  
    72  func (s *networkConfigSuite) TestGetObservedNetworkConfigNilAddressError(c *gc.C) {
    73  	ctrl := s.setupMocks(c)
    74  	defer ctrl.Finish()
    75  
    76  	nic := NewMockConfigSourceNIC(ctrl)
    77  	exp := nic.EXPECT()
    78  	exp.Name().Return("eth1").MinTimes(1)
    79  	exp.Type().Return(network.EthernetDevice).MinTimes(1)
    80  	exp.IsUp().Return(true)
    81  	exp.Index().Return(2)
    82  	exp.HardwareAddr().Return(parseMAC(c, "aa:bb:cc:dd:ee:ff"))
    83  	exp.MTU().Return(1500)
    84  	exp.Addresses().Return([]network.ConfigSourceAddr{nil}, nil)
    85  
    86  	s.source.EXPECT().Interfaces().Return([]network.ConfigSourceNIC{nic}, nil)
    87  
    88  	observedConfig, err := network.GetObservedNetworkConfig(s.source)
    89  	c.Check(err, gc.ErrorMatches, `cannot parse nil address on interface "eth1"`)
    90  	c.Check(observedConfig, gc.IsNil)
    91  }
    92  
    93  func (s *networkConfigSuite) TestGetObservedNetworkConfigNoInterfaceAddresses(c *gc.C) {
    94  	ctrl := s.setupMocks(c)
    95  	defer ctrl.Finish()
    96  
    97  	nic := NewMockConfigSourceNIC(ctrl)
    98  	exp := nic.EXPECT()
    99  
   100  	// Note that eth1 is not the default gateway.
   101  	exp.Name().Return("eth1").MinTimes(1)
   102  	exp.Type().Return(network.EthernetDevice).MinTimes(1)
   103  	exp.IsUp().Return(true)
   104  	exp.Index().Return(2)
   105  	exp.HardwareAddr().Return(parseMAC(c, "aa:bb:cc:dd:ee:ff"))
   106  	exp.MTU().Return(1500)
   107  	exp.Addresses().Return(nil, nil)
   108  
   109  	s.source.EXPECT().Interfaces().Return([]network.ConfigSourceNIC{nic}, nil)
   110  
   111  	observedConfig, err := network.GetObservedNetworkConfig(s.source)
   112  	c.Assert(err, jc.ErrorIsNil)
   113  
   114  	c.Check(observedConfig, jc.DeepEquals, network.InterfaceInfos{{
   115  		DeviceIndex:   2,
   116  		MACAddress:    "aa:bb:cc:dd:ee:ff",
   117  		MTU:           1500,
   118  		InterfaceName: "eth1",
   119  		InterfaceType: "ethernet",
   120  		ConfigType:    "manual",
   121  		Origin:        network.OriginMachine,
   122  	}})
   123  }
   124  
   125  func (s *networkConfigSuite) TestGetObservedNetworkConfigDefaultGatewayWithAddresses(c *gc.C) {
   126  	ctrl := s.setupMocks(c)
   127  	defer ctrl.Finish()
   128  
   129  	ip1, ipNet1, err := net.ParseCIDR("1.2.3.4/24")
   130  	c.Assert(err, jc.ErrorIsNil)
   131  
   132  	addr1 := NewMockConfigSourceAddr(ctrl)
   133  	addr1.EXPECT().IP().Return(ip1)
   134  	addr1.EXPECT().IPNet().Return(ipNet1)
   135  	addr1.EXPECT().IsSecondary().Return(false)
   136  
   137  	// Not the address not in CIDR form will result in config without a CIDR.
   138  	addr2 := NewMockConfigSourceAddr(ctrl)
   139  	addr2.EXPECT().IP().Return(net.ParseIP("559c:f8c5:812a:fa1f:21fe:5613:3f20:b081"))
   140  	addr2.EXPECT().IPNet().Return(nil)
   141  	addr2.EXPECT().IsSecondary().Return(true)
   142  
   143  	nic := NewMockConfigSourceNIC(ctrl)
   144  	exp := nic.EXPECT()
   145  
   146  	// eth0 matches the device returned as the default gateway.
   147  	exp.Name().Return("eth0").MinTimes(1)
   148  	exp.Type().Return(network.EthernetDevice).MinTimes(1)
   149  	exp.IsUp().Return(true)
   150  	exp.Index().Return(2)
   151  	exp.HardwareAddr().Return(parseMAC(c, "aa:bb:cc:dd:ee:ff"))
   152  	exp.MTU().Return(1500)
   153  	exp.Addresses().Return([]network.ConfigSourceAddr{addr1, addr2}, nil)
   154  
   155  	s.source.EXPECT().Interfaces().Return([]network.ConfigSourceNIC{nic}, nil)
   156  
   157  	observedConfig, err := network.GetObservedNetworkConfig(s.source)
   158  	c.Assert(err, jc.ErrorIsNil)
   159  
   160  	c.Check(observedConfig, jc.DeepEquals, network.InterfaceInfos{
   161  		{
   162  			DeviceIndex:      2,
   163  			MACAddress:       "aa:bb:cc:dd:ee:ff",
   164  			MTU:              1500,
   165  			InterfaceName:    "eth0",
   166  			InterfaceType:    "ethernet",
   167  			ConfigType:       "static",
   168  			IsDefaultGateway: true,
   169  			GatewayAddress:   network.NewMachineAddress("1.2.3.4").AsProviderAddress(),
   170  			Origin:           network.OriginMachine,
   171  			Addresses: []network.ProviderAddress{
   172  				network.NewMachineAddress(
   173  					"1.2.3.4",
   174  					network.WithCIDR("1.2.3.0/24"),
   175  					network.WithConfigType("static"),
   176  					network.WithScope("public"),
   177  				).AsProviderAddress(),
   178  				network.NewMachineAddress(
   179  					"559c:f8c5:812a:fa1f:21fe:5613:3f20:b081",
   180  					network.WithConfigType("static"),
   181  					network.WithSecondary(true),
   182  					network.WithScope("public"),
   183  				).AsProviderAddress(),
   184  			},
   185  		},
   186  	})
   187  }
   188  
   189  func (s *networkConfigSuite) TestGetObservedNetworkConfigForOVSDevice(c *gc.C) {
   190  	s.ovsBridges.Add("ovsbr0")
   191  
   192  	ctrl := s.setupMocks(c)
   193  	defer ctrl.Finish()
   194  
   195  	nic := NewMockConfigSourceNIC(ctrl)
   196  	exp := nic.EXPECT()
   197  
   198  	exp.Name().Return("ovsbr0").MinTimes(1)
   199  	exp.Type().Return(network.BridgeDevice).MinTimes(1)
   200  	exp.IsUp().Return(true)
   201  	exp.Index().Return(2)
   202  	exp.HardwareAddr().Return(parseMAC(c, "aa:bb:cc:dd:ee:ff"))
   203  	exp.MTU().Return(1500)
   204  	exp.Addresses().Return(nil, nil)
   205  
   206  	s.source.EXPECT().Interfaces().Return([]network.ConfigSourceNIC{nic}, nil)
   207  
   208  	observedConfig, err := network.GetObservedNetworkConfig(s.source)
   209  	c.Assert(err, jc.ErrorIsNil)
   210  
   211  	c.Check(observedConfig, jc.DeepEquals, network.InterfaceInfos{{
   212  		DeviceIndex:     2,
   213  		MACAddress:      "aa:bb:cc:dd:ee:ff",
   214  		MTU:             1500,
   215  		InterfaceName:   "ovsbr0",
   216  		InterfaceType:   "bridge",
   217  		VirtualPortType: "openvswitch",
   218  		ConfigType:      "manual",
   219  		Origin:          network.OriginMachine,
   220  	}})
   221  }
   222  
   223  func (s *networkConfigSuite) TestGetObservedNetworkConfigBridgePortsHaveParentSet(c *gc.C) {
   224  	s.bridgePorts["br-eth1"] = []string{"eth1"}
   225  
   226  	ctrl := s.setupMocks(c)
   227  	defer ctrl.Finish()
   228  
   229  	nic1 := NewMockConfigSourceNIC(ctrl)
   230  	exp1 := nic1.EXPECT()
   231  
   232  	exp1.Name().Return("eth1").MinTimes(1)
   233  	exp1.Type().Return(network.EthernetDevice).MinTimes(1)
   234  	exp1.IsUp().Return(true)
   235  	exp1.Index().Return(2)
   236  	exp1.HardwareAddr().Return(parseMAC(c, "aa:bb:cc:dd:ee:ff"))
   237  	exp1.MTU().Return(1500)
   238  	exp1.Addresses().Return(nil, nil)
   239  
   240  	nic2 := NewMockConfigSourceNIC(ctrl)
   241  	exp2 := nic2.EXPECT()
   242  
   243  	exp2.Name().Return("br-eth1").MinTimes(1)
   244  	exp2.Type().Return(network.BridgeDevice).MinTimes(1)
   245  	exp2.IsUp().Return(true)
   246  	exp2.Index().Return(3)
   247  	exp2.HardwareAddr().Return(parseMAC(c, "aa:bb:cc:dd:ee:ff"))
   248  	exp2.MTU().Return(1500)
   249  	exp2.Addresses().Return(nil, nil)
   250  
   251  	s.source.EXPECT().Interfaces().Return([]network.ConfigSourceNIC{nic1, nic2}, nil)
   252  
   253  	observedConfig, err := network.GetObservedNetworkConfig(s.source)
   254  	c.Assert(err, jc.ErrorIsNil)
   255  
   256  	c.Check(observedConfig, jc.DeepEquals, network.InterfaceInfos{
   257  		{
   258  			DeviceIndex:         2,
   259  			MACAddress:          "aa:bb:cc:dd:ee:ff",
   260  			MTU:                 1500,
   261  			InterfaceName:       "eth1",
   262  			InterfaceType:       "ethernet",
   263  			ParentInterfaceName: "br-eth1",
   264  			ConfigType:          "manual",
   265  			Origin:              network.OriginMachine,
   266  		},
   267  		{
   268  			DeviceIndex:   3,
   269  			MACAddress:    "aa:bb:cc:dd:ee:ff",
   270  			MTU:           1500,
   271  			InterfaceName: "br-eth1",
   272  			InterfaceType: "bridge",
   273  			ConfigType:    "manual",
   274  			Origin:        network.OriginMachine,
   275  		},
   276  	})
   277  }
   278  
   279  func (s *networkConfigSuite) setupMocks(c *gc.C) *gomock.Controller {
   280  	ctrl := gomock.NewController(c)
   281  
   282  	s.source = NewMockConfigSource(ctrl)
   283  	exp := s.source.EXPECT()
   284  	exp.OvsManagedBridges().Return(s.ovsBridges, nil).MaxTimes(1)
   285  	exp.DefaultRoute().Return(s.defaultRouteGatewayIP, s.defaultRouteDevice, nil).MaxTimes(1)
   286  
   287  	if len(s.bridgePorts) == 0 {
   288  		exp.GetBridgePorts(gomock.Any()).Return(nil).AnyTimes()
   289  	} else {
   290  		for brName, ports := range s.bridgePorts {
   291  			exp.GetBridgePorts(brName).Return(ports)
   292  		}
   293  	}
   294  
   295  	return ctrl
   296  }
   297  
   298  func parseMAC(c *gc.C, val string) net.HardwareAddr {
   299  	mac, err := net.ParseMAC(val)
   300  	c.Assert(err, jc.ErrorIsNil)
   301  	return mac
   302  }