github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/api/common/network_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"net"
    11  	"os"
    12  	"path/filepath"
    13  
    14  	"github.com/juju/testing"
    15  	jc "github.com/juju/testing/checkers"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/api/common"
    19  	"github.com/juju/juju/apiserver/params"
    20  	"github.com/juju/juju/network"
    21  	"github.com/juju/juju/state"
    22  	coretesting "github.com/juju/juju/testing"
    23  )
    24  
    25  type NetworkSuite struct {
    26  	coretesting.BaseSuite
    27  
    28  	stubConfigSource *stubNetworkConfigSource
    29  }
    30  
    31  var _ = gc.Suite(&NetworkSuite{})
    32  
    33  func (s *NetworkSuite) SetUpTest(c *gc.C) {
    34  	s.BaseSuite.SetUpTest(c)
    35  	s.stubConfigSource = &stubNetworkConfigSource{
    36  		Stub:                  &testing.Stub{},
    37  		fakeSysClassNetPath:   c.MkDir(),
    38  		interfaces:            exampleObservedInterfaces,
    39  		interfaceAddrs:        exampleObservedInterfaceAddrs,
    40  		defaultRouteGatewayIP: net.ParseIP("1.2.3.4"),
    41  		defaultRouteDevice:    "eth1",
    42  	}
    43  }
    44  
    45  func mustParseMAC(value string) net.HardwareAddr {
    46  	parsedMAC, err := net.ParseMAC(value)
    47  	if err != nil {
    48  		panic(fmt.Sprintf("cannot parse MAC %q: %v", value, err))
    49  	}
    50  	return parsedMAC
    51  }
    52  
    53  var exampleObservedInterfaces = []net.Interface{{
    54  	Index: 1,
    55  	MTU:   65536,
    56  	Name:  "lo",
    57  	Flags: net.FlagUp | net.FlagLoopback,
    58  }, {
    59  	Index:        2,
    60  	MTU:          1500,
    61  	Name:         "eth0",
    62  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f0"),
    63  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
    64  }, {
    65  	Index:        10,
    66  	MTU:          1500,
    67  	Name:         "br-eth0",
    68  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f0"),
    69  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
    70  }, {
    71  	Index:        11,
    72  	MTU:          1500,
    73  	Name:         "br-eth1",
    74  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f1"),
    75  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
    76  }, {
    77  	Index:        3,
    78  	MTU:          1500,
    79  	Name:         "eth1",
    80  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f1"),
    81  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
    82  }, {
    83  	Index:        12,
    84  	MTU:          1500,
    85  	Name:         "br-eth0.100",
    86  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f0"),
    87  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
    88  }, {
    89  	Index:        13,
    90  	MTU:          1500,
    91  	Name:         "eth0.100",
    92  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f0"),
    93  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
    94  }, {
    95  	Index:        14,
    96  	MTU:          1500,
    97  	Name:         "br-eth0.250",
    98  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f0"),
    99  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   100  }, {
   101  	Index:        15,
   102  	MTU:          1500,
   103  	Name:         "eth0.250",
   104  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f0"),
   105  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   106  }, {
   107  	Index:        16,
   108  	MTU:          1500,
   109  	Name:         "br-eth0.50",
   110  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f0"),
   111  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   112  }, {
   113  	Index:        17,
   114  	MTU:          1500,
   115  	Name:         "eth0.50",
   116  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f0"),
   117  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   118  }, {
   119  	Index:        18,
   120  	MTU:          1500,
   121  	Name:         "br-eth1.11",
   122  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f1"),
   123  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   124  }, {
   125  	Index:        19,
   126  	MTU:          1500,
   127  	Name:         "eth1.11",
   128  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f1"),
   129  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   130  }, {
   131  	Index:        20,
   132  	MTU:          1500,
   133  	Name:         "br-eth1.12",
   134  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f1"),
   135  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   136  }, {
   137  	Index:        21,
   138  	MTU:          1500,
   139  	Name:         "eth1.12",
   140  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f1"),
   141  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   142  }, {
   143  	Index:        22,
   144  	MTU:          1500,
   145  	Name:         "br-eth1.13",
   146  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f1"),
   147  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   148  }, {
   149  	Index:        23,
   150  	MTU:          1500,
   151  	Name:         "eth1.13",
   152  	HardwareAddr: mustParseMAC("aa:bb:cc:dd:ee:f1"),
   153  	Flags:        net.FlagUp | net.FlagBroadcast | net.FlagMulticast,
   154  }}
   155  
   156  type fakeAddr string
   157  
   158  func (f fakeAddr) Network() string { return "" }
   159  func (f fakeAddr) String() string  { return string(f) }
   160  
   161  var _ net.Addr = (*fakeAddr)(nil)
   162  
   163  var exampleObservedInterfaceAddrs = map[string][]net.Addr{
   164  	"eth0":        {fakeAddr("fe80::5054:ff:fedd:eef0/64")},
   165  	"eth1":        {fakeAddr("fe80::5054:ff:fedd:eef1/64")},
   166  	"eth0.50":     {fakeAddr("fe80::5054:ff:fedd:eef0:50/64")},
   167  	"eth0.100":    {fakeAddr("fe80::5054:ff:fedd:eef0:100/64")},
   168  	"eth0.25":     {fakeAddr("fe80::5054:ff:fedd:eef0:25/64")},
   169  	"eth1.11":     {fakeAddr("fe80::5054:ff:fedd:eef1:11/64")},
   170  	"eth1.12":     {fakeAddr("fe80::5054:ff:fedd:eef1:12/64")},
   171  	"eth1.13":     {fakeAddr("fe80::5054:ff:fedd:eef1:13/64")},
   172  	"lo":          {fakeAddr("127.0.0.1/8"), fakeAddr("::1/128")},
   173  	"br-eth0":     {fakeAddr("10.20.19.100/24"), fakeAddr("10.20.19.123/24"), fakeAddr("fe80::5054:ff:fedd:eef0/64")},
   174  	"br-eth1":     {fakeAddr("10.20.19.105/24"), fakeAddr("fe80::5054:ff:fedd:eef1/64")},
   175  	"br-eth0.50":  {fakeAddr("10.50.19.100/24"), fakeAddr("fe80::5054:ff:fedd:eef0/64")},
   176  	"br-eth0.100": {fakeAddr("10.100.19.100/24"), fakeAddr("fe80::5054:ff:fedd:eef0/64")},
   177  	"br-eth0.250": {fakeAddr("10.250.19.100/24"), fakeAddr("fe80::5054:ff:fedd:eef0/64")},
   178  	"br-eth1.11":  {fakeAddr("10.11.19.101/24"), fakeAddr("fe80::5054:ff:fedd:eef1/64")},
   179  	"br-eth1.12":  {fakeAddr("10.12.19.101/24"), fakeAddr("fe80::5054:ff:fedd:eef1/64")},
   180  	"br-eth1.13":  {fakeAddr("10.13.19.101/24"), fakeAddr("fe80::5054:ff:fedd:eef1/64")},
   181  }
   182  
   183  var expectedObservedNetworkConfigs = []params.NetworkConfig{{
   184  	DeviceIndex:   1,
   185  	InterfaceName: "lo",
   186  	InterfaceType: string(network.LoopbackInterface),
   187  	MACAddress:    "",
   188  	CIDR:          "127.0.0.0/8",
   189  	Address:       "127.0.0.1",
   190  	MTU:           65536,
   191  	ConfigType:    string(network.ConfigLoopback),
   192  }, {
   193  	DeviceIndex:   10,
   194  	InterfaceName: "br-eth0",
   195  	InterfaceType: string(network.BridgeInterface),
   196  	MACAddress:    "aa:bb:cc:dd:ee:f0",
   197  	CIDR:          "10.20.19.0/24",
   198  	Address:       "10.20.19.100",
   199  	MTU:           1500,
   200  	ConfigType:    string(network.ConfigStatic),
   201  }, {
   202  	DeviceIndex:   10,
   203  	InterfaceName: "br-eth0",
   204  	InterfaceType: string(network.BridgeInterface),
   205  	MACAddress:    "aa:bb:cc:dd:ee:f0",
   206  	CIDR:          "10.20.19.0/24",
   207  	Address:       "10.20.19.123",
   208  	MTU:           1500,
   209  	ConfigType:    string(network.ConfigStatic),
   210  }, {
   211  	DeviceIndex:   12,
   212  	InterfaceName: "br-eth0.100",
   213  	InterfaceType: string(network.BridgeInterface),
   214  	MACAddress:    "aa:bb:cc:dd:ee:f0",
   215  	CIDR:          "10.100.19.0/24",
   216  	Address:       "10.100.19.100",
   217  	MTU:           1500,
   218  }, {
   219  	DeviceIndex:   14,
   220  	InterfaceName: "br-eth0.250",
   221  	InterfaceType: string(network.BridgeInterface),
   222  	MACAddress:    "aa:bb:cc:dd:ee:f0",
   223  	CIDR:          "10.250.19.0/24",
   224  	Address:       "10.250.19.100",
   225  	MTU:           1500,
   226  	ConfigType:    string(network.ConfigStatic),
   227  }, {
   228  	DeviceIndex:   16,
   229  	InterfaceName: "br-eth0.50",
   230  	InterfaceType: string(network.BridgeInterface),
   231  	MACAddress:    "aa:bb:cc:dd:ee:f0",
   232  	CIDR:          "10.50.19.0/24",
   233  	Address:       "10.50.19.100",
   234  	MTU:           1500,
   235  	ConfigType:    string(network.ConfigStatic),
   236  }, {
   237  	DeviceIndex:         2,
   238  	InterfaceName:       "eth0",
   239  	ParentInterfaceName: "br-eth0",
   240  	InterfaceType:       string(network.EthernetInterface),
   241  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   242  	MTU:                 1500,
   243  	ConfigType:          string(network.ConfigManual),
   244  }, {
   245  	DeviceIndex:         13,
   246  	InterfaceName:       "eth0.100",
   247  	ParentInterfaceName: "br-eth0.100",
   248  	InterfaceType:       string(network.VLAN_8021QInterface),
   249  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   250  	MTU:                 1500,
   251  	ConfigType:          string(network.ConfigManual),
   252  }, {
   253  	DeviceIndex:         15,
   254  	InterfaceName:       "eth0.250",
   255  	ParentInterfaceName: "br-eth0.250",
   256  	InterfaceType:       string(network.VLAN_8021QInterface),
   257  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   258  	MTU:                 1500,
   259  	ConfigType:          string(network.ConfigManual),
   260  }, {
   261  	DeviceIndex:         17,
   262  	InterfaceName:       "eth0.50",
   263  	ParentInterfaceName: "br-eth0.50",
   264  	InterfaceType:       string(network.VLAN_8021QInterface),
   265  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   266  	MTU:                 1500,
   267  	ConfigType:          string(network.ConfigManual),
   268  }, {
   269  	DeviceIndex:   11,
   270  	InterfaceName: "br-eth1",
   271  	InterfaceType: string(network.BridgeInterface),
   272  	MACAddress:    "aa:bb:cc:dd:ee:f1",
   273  	CIDR:          "10.20.19.0/24",
   274  	Address:       "10.20.19.105",
   275  	MTU:           1500,
   276  	ConfigType:    string(network.ConfigStatic),
   277  }, {
   278  	DeviceIndex:   18,
   279  	InterfaceName: "br-eth1.11",
   280  	InterfaceType: string(network.BridgeInterface),
   281  	MACAddress:    "aa:bb:cc:dd:ee:f1",
   282  	CIDR:          "10.11.19.0/24",
   283  	Address:       "10.11.19.101",
   284  	MTU:           1500,
   285  	ConfigType:    string(network.ConfigStatic),
   286  }, {
   287  	DeviceIndex:   20,
   288  	InterfaceName: "br-eth1.12",
   289  	InterfaceType: string(network.BridgeInterface),
   290  	MACAddress:    "aa:bb:cc:dd:ee:f1",
   291  	CIDR:          "10.12.19.0/24",
   292  	Address:       "10.12.19.101",
   293  	MTU:           1500,
   294  	ConfigType:    string(network.ConfigStatic),
   295  }, {
   296  	DeviceIndex:   22,
   297  	InterfaceName: "br-eth1.13",
   298  	InterfaceType: string(network.BridgeInterface),
   299  	MACAddress:    "aa:bb:cc:dd:ee:f1",
   300  	CIDR:          "10.13.19.0/24",
   301  	Address:       "10.13.19.101",
   302  	MTU:           1500,
   303  	ConfigType:    string(network.ConfigStatic),
   304  }, {
   305  	DeviceIndex:         3,
   306  	InterfaceName:       "eth1",
   307  	ParentInterfaceName: "br-eth1",
   308  	InterfaceType:       string(network.EthernetInterface),
   309  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   310  	MTU:                 1500,
   311  	ConfigType:          string(network.ConfigManual),
   312  }, {
   313  	DeviceIndex:         19,
   314  	InterfaceName:       "eth1.11",
   315  	ParentInterfaceName: "br-eth1.11",
   316  	InterfaceType:       string(network.VLAN_8021QInterface),
   317  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   318  	MTU:                 1500,
   319  	ConfigType:          string(network.ConfigManual),
   320  }, {
   321  	DeviceIndex:         21,
   322  	InterfaceName:       "eth1.12",
   323  	ParentInterfaceName: "br-eth1.12",
   324  	InterfaceType:       string(network.VLAN_8021QInterface),
   325  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   326  	MTU:                 1500,
   327  	ConfigType:          string(network.ConfigManual),
   328  }, {
   329  	DeviceIndex:         23,
   330  	InterfaceName:       "eth1.13",
   331  	ParentInterfaceName: "br-eth1.13",
   332  	InterfaceType:       string(network.VLAN_8021QInterface),
   333  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   334  	MTU:                 1500,
   335  	ConfigType:          string(network.ConfigManual),
   336  }}
   337  
   338  var expectedProviderNetworkConfigs = []params.NetworkConfig{{
   339  	InterfaceName:       "eth0",
   340  	InterfaceType:       string(network.EthernetInterface),
   341  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   342  	CIDR:                "10.20.19.0/24",
   343  	Address:             "10.20.19.100",
   344  	MTU:                 1500,
   345  	ConfigType:          string(network.ConfigStatic),
   346  	ParentInterfaceName: "",
   347  	ProviderId:          "3",
   348  	ProviderSubnetId:    "3",
   349  	ProviderVLANId:      "5001",
   350  	VLANTag:             0,
   351  	ProviderAddressId:   "1287",
   352  }, {
   353  	InterfaceName:       "eth0",
   354  	InterfaceType:       string(network.EthernetInterface),
   355  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   356  	CIDR:                "10.20.19.0/24",
   357  	Address:             "10.20.19.123",
   358  	MTU:                 1500,
   359  	ConfigType:          string(network.ConfigStatic),
   360  	ParentInterfaceName: "",
   361  	ProviderId:          "3",
   362  	ProviderSubnetId:    "3",
   363  	ProviderVLANId:      "5001",
   364  	VLANTag:             0,
   365  	ProviderAddressId:   "1288",
   366  }, {
   367  	InterfaceName:       "eth0.100",
   368  	InterfaceType:       string(network.VLAN_8021QInterface),
   369  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   370  	CIDR:                "10.100.19.0/24",
   371  	Address:             "10.100.19.100",
   372  	MTU:                 1500,
   373  	ConfigType:          string(network.ConfigStatic),
   374  	ParentInterfaceName: "eth0",
   375  	ProviderId:          "516",
   376  	ProviderSubnetId:    "6",
   377  	ProviderVLANId:      "5005",
   378  	VLANTag:             100,
   379  	ProviderAddressId:   "1292",
   380  }, {
   381  	InterfaceName:       "eth0.250",
   382  	InterfaceType:       string(network.VLAN_8021QInterface),
   383  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   384  	CIDR:                "10.250.19.0/24",
   385  	Address:             "10.250.19.100",
   386  	MTU:                 1500,
   387  	ConfigType:          string(network.ConfigStatic),
   388  	ParentInterfaceName: "eth0",
   389  	ProviderId:          "517",
   390  	ProviderSubnetId:    "8",
   391  	ProviderVLANId:      "5008",
   392  	VLANTag:             250,
   393  	ProviderAddressId:   "1294",
   394  }, {
   395  	InterfaceName:       "eth0.50",
   396  	InterfaceType:       string(network.VLAN_8021QInterface),
   397  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   398  	CIDR:                "10.50.19.0/24",
   399  	Address:             "10.50.19.100",
   400  	MTU:                 1500,
   401  	ConfigType:          string(network.ConfigStatic),
   402  	ParentInterfaceName: "eth0",
   403  	ProviderId:          "515",
   404  	ProviderSubnetId:    "5",
   405  	ProviderVLANId:      "5004",
   406  	VLANTag:             50,
   407  	ProviderAddressId:   "1290",
   408  }, {
   409  	InterfaceName:       "eth1",
   410  	InterfaceType:       string(network.EthernetInterface),
   411  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   412  	CIDR:                "10.20.19.0/24",
   413  	Address:             "10.20.19.105",
   414  	MTU:                 1500,
   415  	ConfigType:          string(network.ConfigStatic),
   416  	ParentInterfaceName: "",
   417  	ProviderId:          "245",
   418  	ProviderSubnetId:    "3",
   419  	ProviderVLANId:      "5001",
   420  	VLANTag:             0,
   421  	ProviderAddressId:   "1295",
   422  }, {
   423  	InterfaceName:       "eth1.11",
   424  	InterfaceType:       string(network.VLAN_8021QInterface),
   425  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   426  	CIDR:                "10.11.19.0/24",
   427  	Address:             "10.11.19.101",
   428  	MTU:                 1500,
   429  	ConfigType:          string(network.ConfigStatic),
   430  	ParentInterfaceName: "eth1",
   431  	ProviderId:          "518",
   432  	ProviderSubnetId:    "9",
   433  	ProviderVLANId:      "5013",
   434  	VLANTag:             11,
   435  	ProviderAddressId:   "1298",
   436  }, {
   437  	InterfaceName:       "eth1.12",
   438  	InterfaceType:       string(network.VLAN_8021QInterface),
   439  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   440  	CIDR:                "10.12.19.0/24",
   441  	Address:             "10.12.19.101",
   442  	MTU:                 1500,
   443  	ConfigType:          string(network.ConfigStatic),
   444  	ParentInterfaceName: "eth1",
   445  	ProviderId:          "519",
   446  	ProviderSubnetId:    "10",
   447  	ProviderVLANId:      "5014",
   448  	VLANTag:             12,
   449  	ProviderAddressId:   "1300",
   450  }, {
   451  	InterfaceName:       "eth1.13",
   452  	InterfaceType:       string(network.VLAN_8021QInterface),
   453  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   454  	CIDR:                "10.13.19.0/24",
   455  	Address:             "10.13.19.101",
   456  	MTU:                 1500,
   457  	ConfigType:          string(network.ConfigStatic),
   458  	ParentInterfaceName: "eth1",
   459  	ProviderId:          "520",
   460  	ProviderSubnetId:    "11",
   461  	ProviderVLANId:      "5015",
   462  	VLANTag:             13,
   463  	ProviderAddressId:   "1302",
   464  }}
   465  
   466  var expectedFinalNetworkConfigs = []params.NetworkConfig{{
   467  	DeviceIndex:         1,
   468  	InterfaceName:       "lo",
   469  	InterfaceType:       string(network.LoopbackInterface),
   470  	CIDR:                "127.0.0.0/8",
   471  	Address:             "127.0.0.1",
   472  	MTU:                 65536,
   473  	ConfigType:          string(network.ConfigLoopback),
   474  	ParentInterfaceName: "",
   475  }, {
   476  	DeviceIndex:         10,
   477  	InterfaceName:       "br-eth0",
   478  	InterfaceType:       string(network.BridgeInterface),
   479  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   480  	CIDR:                "10.20.19.0/24",
   481  	Address:             "10.20.19.100",
   482  	MTU:                 1500,
   483  	ConfigType:          string(network.ConfigStatic),
   484  	ParentInterfaceName: "",
   485  	ProviderSubnetId:    "3",
   486  	ProviderVLANId:      "5001",
   487  	VLANTag:             0,
   488  	ProviderAddressId:   "1287",
   489  }, {
   490  	DeviceIndex:         10,
   491  	InterfaceName:       "br-eth0",
   492  	InterfaceType:       string(network.BridgeInterface),
   493  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   494  	CIDR:                "10.20.19.0/24",
   495  	Address:             "10.20.19.123",
   496  	MTU:                 1500,
   497  	ConfigType:          string(network.ConfigStatic),
   498  	ParentInterfaceName: "",
   499  	ProviderSubnetId:    "3",
   500  	ProviderVLANId:      "5001",
   501  	VLANTag:             0,
   502  	ProviderAddressId:   "1288",
   503  }, {
   504  	DeviceIndex:         12,
   505  	InterfaceName:       "br-eth0.100",
   506  	InterfaceType:       string(network.BridgeInterface),
   507  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   508  	CIDR:                "10.100.19.0/24",
   509  	Address:             "10.100.19.100",
   510  	MTU:                 1500,
   511  	ConfigType:          string(network.ConfigStatic),
   512  	ParentInterfaceName: "",
   513  	ProviderSubnetId:    "6",
   514  	ProviderVLANId:      "5005",
   515  	VLANTag:             100,
   516  	ProviderAddressId:   "1292",
   517  }, {
   518  	DeviceIndex:         14,
   519  	InterfaceName:       "br-eth0.250",
   520  	InterfaceType:       string(network.BridgeInterface),
   521  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   522  	CIDR:                "10.250.19.0/24",
   523  	Address:             "10.250.19.100",
   524  	MTU:                 1500,
   525  	ConfigType:          string(network.ConfigStatic),
   526  	ParentInterfaceName: "",
   527  	ProviderSubnetId:    "8",
   528  	ProviderVLANId:      "5008",
   529  	VLANTag:             250,
   530  	ProviderAddressId:   "1294",
   531  }, {
   532  	DeviceIndex:         16,
   533  	InterfaceName:       "br-eth0.50",
   534  	InterfaceType:       string(network.BridgeInterface),
   535  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   536  	CIDR:                "10.50.19.0/24",
   537  	Address:             "10.50.19.100",
   538  	MTU:                 1500,
   539  	ConfigType:          string(network.ConfigStatic),
   540  	ParentInterfaceName: "",
   541  	ProviderSubnetId:    "5",
   542  	ProviderVLANId:      "5004",
   543  	VLANTag:             50,
   544  	ProviderAddressId:   "1290",
   545  }, {
   546  	DeviceIndex:         2,
   547  	InterfaceName:       "eth0",
   548  	InterfaceType:       string(network.EthernetInterface),
   549  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   550  	MTU:                 1500,
   551  	ConfigType:          string(network.ConfigManual),
   552  	ParentInterfaceName: "br-eth0",
   553  	ProviderId:          "3",
   554  	ProviderSubnetId:    "3",
   555  	ProviderVLANId:      "5001",
   556  	VLANTag:             0,
   557  }, {
   558  	DeviceIndex:         13,
   559  	InterfaceName:       "eth0.100",
   560  	InterfaceType:       string(network.VLAN_8021QInterface),
   561  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   562  	MTU:                 1500,
   563  	ConfigType:          string(network.ConfigManual),
   564  	ParentInterfaceName: "br-eth0.100",
   565  	ProviderId:          "516",
   566  	ProviderSubnetId:    "6",
   567  	ProviderVLANId:      "5005",
   568  	VLANTag:             100,
   569  }, {
   570  	DeviceIndex:         15,
   571  	InterfaceName:       "eth0.250",
   572  	InterfaceType:       string(network.VLAN_8021QInterface),
   573  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   574  	MTU:                 1500,
   575  	ConfigType:          string(network.ConfigManual),
   576  	ParentInterfaceName: "br-eth0.250",
   577  	ProviderId:          "517",
   578  	ProviderSubnetId:    "8",
   579  	ProviderVLANId:      "5008",
   580  	VLANTag:             250,
   581  }, {
   582  	DeviceIndex:         17,
   583  	InterfaceName:       "eth0.50",
   584  	InterfaceType:       string(network.VLAN_8021QInterface),
   585  	MACAddress:          "aa:bb:cc:dd:ee:f0",
   586  	MTU:                 1500,
   587  	ConfigType:          string(network.ConfigManual),
   588  	ParentInterfaceName: "br-eth0.50",
   589  	ProviderId:          "515",
   590  	ProviderSubnetId:    "5",
   591  	ProviderVLANId:      "5004",
   592  	VLANTag:             50,
   593  }, {
   594  	DeviceIndex:         11,
   595  	InterfaceName:       "br-eth1",
   596  	InterfaceType:       string(network.BridgeInterface),
   597  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   598  	CIDR:                "10.20.19.0/24",
   599  	Address:             "10.20.19.105",
   600  	MTU:                 1500,
   601  	ConfigType:          string(network.ConfigStatic),
   602  	ParentInterfaceName: "",
   603  	ProviderSubnetId:    "3",
   604  	ProviderVLANId:      "5001",
   605  	VLANTag:             0,
   606  	ProviderAddressId:   "1295",
   607  }, {
   608  	DeviceIndex:         18,
   609  	InterfaceName:       "br-eth1.11",
   610  	InterfaceType:       string(network.BridgeInterface),
   611  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   612  	CIDR:                "10.11.19.0/24",
   613  	Address:             "10.11.19.101",
   614  	MTU:                 1500,
   615  	ConfigType:          string(network.ConfigStatic),
   616  	ParentInterfaceName: "",
   617  	ProviderSubnetId:    "9",
   618  	ProviderVLANId:      "5013",
   619  	VLANTag:             11,
   620  	ProviderAddressId:   "1298",
   621  }, {
   622  	DeviceIndex:         20,
   623  	InterfaceName:       "br-eth1.12",
   624  	InterfaceType:       string(network.BridgeInterface),
   625  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   626  	CIDR:                "10.12.19.0/24",
   627  	Address:             "10.12.19.101",
   628  	MTU:                 1500,
   629  	ConfigType:          string(network.ConfigStatic),
   630  	ParentInterfaceName: "",
   631  	ProviderSubnetId:    "10",
   632  	ProviderVLANId:      "5014",
   633  	VLANTag:             12,
   634  	ProviderAddressId:   "1300",
   635  }, {
   636  	DeviceIndex:         22,
   637  	InterfaceName:       "br-eth1.13",
   638  	InterfaceType:       string(network.BridgeInterface),
   639  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   640  	CIDR:                "10.13.19.0/24",
   641  	Address:             "10.13.19.101",
   642  	MTU:                 1500,
   643  	ParentInterfaceName: "",
   644  	ConfigType:          string(network.ConfigStatic),
   645  	ProviderSubnetId:    "11",
   646  	ProviderVLANId:      "5015",
   647  	VLANTag:             13,
   648  	ProviderAddressId:   "1302",
   649  }, {
   650  	DeviceIndex:         3,
   651  	InterfaceName:       "eth1",
   652  	InterfaceType:       string(network.EthernetInterface),
   653  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   654  	MTU:                 1500,
   655  	ConfigType:          string(network.ConfigManual),
   656  	ParentInterfaceName: "br-eth1",
   657  	ProviderId:          "245",
   658  	ProviderSubnetId:    "3",
   659  	ProviderVLANId:      "5001",
   660  	VLANTag:             0,
   661  }, {
   662  	DeviceIndex:         19,
   663  	InterfaceName:       "eth1.11",
   664  	InterfaceType:       string(network.VLAN_8021QInterface),
   665  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   666  	MTU:                 1500,
   667  	ConfigType:          string(network.ConfigManual),
   668  	ParentInterfaceName: "br-eth1.11",
   669  	ProviderId:          "518",
   670  	ProviderSubnetId:    "9",
   671  	ProviderVLANId:      "5013",
   672  	VLANTag:             11,
   673  }, {
   674  	DeviceIndex:         21,
   675  	InterfaceName:       "eth1.12",
   676  	InterfaceType:       string(network.VLAN_8021QInterface),
   677  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   678  	MTU:                 1500,
   679  	ConfigType:          string(network.ConfigManual),
   680  	ParentInterfaceName: "br-eth1.12",
   681  	ProviderId:          "519",
   682  	ProviderSubnetId:    "10",
   683  	ProviderVLANId:      "5014",
   684  	VLANTag:             12,
   685  }, {
   686  	DeviceIndex:         23,
   687  	InterfaceName:       "eth1.13",
   688  	InterfaceType:       string(network.VLAN_8021QInterface),
   689  	MACAddress:          "aa:bb:cc:dd:ee:f1",
   690  	MTU:                 1500,
   691  	ConfigType:          string(network.ConfigManual),
   692  	ParentInterfaceName: "br-eth1.13",
   693  	ProviderId:          "520",
   694  	ProviderSubnetId:    "11",
   695  	ProviderVLANId:      "5015",
   696  	VLANTag:             13,
   697  }}
   698  
   699  var expectedLinkLayerDeviceArgsWithFinalNetworkConfig = []state.LinkLayerDeviceArgs{{
   700  	Name:        "lo",
   701  	MTU:         65536,
   702  	Type:        state.LoopbackDevice,
   703  	IsAutoStart: true,
   704  	IsUp:        true,
   705  }, {
   706  	Name:        "br-eth0",
   707  	MTU:         1500,
   708  	Type:        state.BridgeDevice,
   709  	MACAddress:  "aa:bb:cc:dd:ee:f0",
   710  	IsAutoStart: true,
   711  	IsUp:        true,
   712  }, {
   713  	Name:        "br-eth0.100",
   714  	MTU:         1500,
   715  	Type:        state.BridgeDevice,
   716  	MACAddress:  "aa:bb:cc:dd:ee:f0",
   717  	IsAutoStart: true,
   718  	IsUp:        true,
   719  	ParentName:  "",
   720  }, {
   721  	Name:        "br-eth0.250",
   722  	MTU:         1500,
   723  	Type:        state.BridgeDevice,
   724  	MACAddress:  "aa:bb:cc:dd:ee:f0",
   725  	IsAutoStart: true,
   726  	IsUp:        true,
   727  	ParentName:  "",
   728  }, {
   729  	Name:        "br-eth0.50",
   730  	MTU:         1500,
   731  	Type:        state.BridgeDevice,
   732  	MACAddress:  "aa:bb:cc:dd:ee:f0",
   733  	IsAutoStart: true,
   734  	IsUp:        true,
   735  	ParentName:  "",
   736  }, {
   737  	Name:        "eth0",
   738  	MTU:         1500,
   739  	ProviderID:  "3",
   740  	Type:        state.EthernetDevice,
   741  	MACAddress:  "aa:bb:cc:dd:ee:f0",
   742  	IsAutoStart: true,
   743  	IsUp:        true,
   744  	ParentName:  "br-eth0",
   745  }, {
   746  	Name:        "eth0.100",
   747  	MTU:         1500,
   748  	ProviderID:  "516",
   749  	Type:        state.VLAN_8021QDevice,
   750  	MACAddress:  "aa:bb:cc:dd:ee:f0",
   751  	IsAutoStart: true,
   752  	IsUp:        true,
   753  	ParentName:  "br-eth0.100",
   754  }, {
   755  	Name:        "eth0.250",
   756  	MTU:         1500,
   757  	ProviderID:  "517",
   758  	Type:        state.VLAN_8021QDevice,
   759  	MACAddress:  "aa:bb:cc:dd:ee:f0",
   760  	IsAutoStart: true,
   761  	IsUp:        true,
   762  	ParentName:  "br-eth0.250",
   763  }, {
   764  	Name:        "eth0.50",
   765  	MTU:         1500,
   766  	ProviderID:  "515",
   767  	Type:        state.VLAN_8021QDevice,
   768  	MACAddress:  "aa:bb:cc:dd:ee:f0",
   769  	IsAutoStart: true,
   770  	IsUp:        true,
   771  	ParentName:  "br-eth0.50",
   772  }, {
   773  	Name:        "br-eth1",
   774  	MTU:         1500,
   775  	Type:        state.BridgeDevice,
   776  	MACAddress:  "aa:bb:cc:dd:ee:f1",
   777  	IsAutoStart: true,
   778  	IsUp:        true,
   779  }, {
   780  	Name:        "br-eth1.11",
   781  	MTU:         1500,
   782  	Type:        state.BridgeDevice,
   783  	MACAddress:  "aa:bb:cc:dd:ee:f1",
   784  	IsAutoStart: true,
   785  	IsUp:        true,
   786  	ParentName:  "",
   787  }, {
   788  	Name:        "br-eth1.12",
   789  	MTU:         1500,
   790  	Type:        state.BridgeDevice,
   791  	MACAddress:  "aa:bb:cc:dd:ee:f1",
   792  	IsAutoStart: true,
   793  	IsUp:        true,
   794  	ParentName:  "",
   795  }, {
   796  	Name:        "br-eth1.13",
   797  	MTU:         1500,
   798  	Type:        state.BridgeDevice,
   799  	MACAddress:  "aa:bb:cc:dd:ee:f1",
   800  	IsAutoStart: true,
   801  	IsUp:        true,
   802  	ParentName:  "",
   803  }, {
   804  	Name:        "eth1",
   805  	MTU:         1500,
   806  	ProviderID:  "245",
   807  	Type:        state.EthernetDevice,
   808  	MACAddress:  "aa:bb:cc:dd:ee:f1",
   809  	IsAutoStart: true,
   810  	IsUp:        true,
   811  	ParentName:  "br-eth1",
   812  }, {
   813  	Name:        "eth1.11",
   814  	MTU:         1500,
   815  	ProviderID:  "518",
   816  	Type:        state.VLAN_8021QDevice,
   817  	MACAddress:  "aa:bb:cc:dd:ee:f1",
   818  	IsAutoStart: true,
   819  	IsUp:        true,
   820  	ParentName:  "br-eth1.11",
   821  }, {
   822  	Name:        "eth1.12",
   823  	MTU:         1500,
   824  	ProviderID:  "519",
   825  	Type:        state.VLAN_8021QDevice,
   826  	MACAddress:  "aa:bb:cc:dd:ee:f1",
   827  	IsAutoStart: true,
   828  	IsUp:        true,
   829  	ParentName:  "br-eth1.12",
   830  }, {
   831  	Name:        "eth1.13",
   832  	MTU:         1500,
   833  	ProviderID:  "520",
   834  	Type:        state.VLAN_8021QDevice,
   835  	MACAddress:  "aa:bb:cc:dd:ee:f1",
   836  	IsAutoStart: true,
   837  	IsUp:        true,
   838  	ParentName:  "br-eth1.13",
   839  }}
   840  
   841  var expectedLinkLayerDeviceAdressesWithFinalNetworkConfig = []state.LinkLayerDeviceAddress{{
   842  	DeviceName:   "lo",
   843  	ConfigMethod: state.LoopbackAddress,
   844  	CIDRAddress:  "127.0.0.1/8",
   845  }, {
   846  	DeviceName:   "br-eth0",
   847  	ConfigMethod: state.StaticAddress,
   848  	CIDRAddress:  "10.20.19.100/24",
   849  	ProviderID:   "1287",
   850  }, {
   851  	DeviceName:   "br-eth0",
   852  	ConfigMethod: state.StaticAddress,
   853  	CIDRAddress:  "10.20.19.123/24",
   854  	ProviderID:   "1288",
   855  }, {
   856  	DeviceName:   "br-eth0.100",
   857  	ConfigMethod: state.StaticAddress,
   858  	CIDRAddress:  "10.100.19.100/24",
   859  	ProviderID:   "1292",
   860  }, {
   861  	DeviceName:   "br-eth0.250",
   862  	ConfigMethod: state.StaticAddress,
   863  	CIDRAddress:  "10.250.19.100/24",
   864  	ProviderID:   "1294",
   865  }, {
   866  	DeviceName:   "br-eth0.50",
   867  	ConfigMethod: state.StaticAddress,
   868  	CIDRAddress:  "10.50.19.100/24",
   869  	ProviderID:   "1290",
   870  }, {
   871  	DeviceName:   "br-eth1",
   872  	ConfigMethod: state.StaticAddress,
   873  	CIDRAddress:  "10.20.19.105/24",
   874  	ProviderID:   "1295",
   875  }, {
   876  	DeviceName:   "br-eth1.11",
   877  	ConfigMethod: state.StaticAddress,
   878  	CIDRAddress:  "10.11.19.101/24",
   879  	ProviderID:   "1298",
   880  }, {
   881  	DeviceName:   "br-eth1.12",
   882  	ConfigMethod: state.StaticAddress,
   883  	CIDRAddress:  "10.12.19.101/24",
   884  	ProviderID:   "1300",
   885  }, {
   886  	DeviceName:   "br-eth1.13",
   887  	ConfigMethod: state.StaticAddress,
   888  	CIDRAddress:  "10.13.19.101/24",
   889  	ProviderID:   "1302",
   890  }}
   891  
   892  func (s *NetworkSuite) TestGetObservedNetworkConfigInterfacesError(c *gc.C) {
   893  	s.stubConfigSource.SetErrors(errors.New("no interfaces"))
   894  
   895  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
   896  	c.Check(err, gc.ErrorMatches, "cannot get network interfaces: no interfaces")
   897  	c.Check(observedConfig, gc.IsNil)
   898  
   899  	s.stubConfigSource.CheckCallNames(c, "Interfaces")
   900  }
   901  
   902  func (s *NetworkSuite) TestGetObservedNetworkConfigInterfaceAddressesError(c *gc.C) {
   903  	s.stubConfigSource.SetErrors(
   904  		nil,                        // Interfaces
   905  		nil,                        // DefaultRoute
   906  		errors.New("no addresses"), // InterfaceAddressses
   907  	)
   908  
   909  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
   910  	c.Check(err, gc.ErrorMatches, `cannot get interface "lo" addresses: no addresses`)
   911  	c.Check(observedConfig, gc.IsNil)
   912  
   913  	s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
   914  	s.stubConfigSource.CheckCall(c, 3, "InterfaceAddresses", "lo")
   915  }
   916  
   917  func (s *NetworkSuite) TestGetObservedNetworkConfigNoInterfaceAddresses(c *gc.C) {
   918  	s.stubConfigSource.interfaces = exampleObservedInterfaces[3:4] // only br-eth1
   919  	s.stubConfigSource.interfaceAddrs = make(map[string][]net.Addr)
   920  	s.stubConfigSource.makeSysClassNetInterfacePath(c, "br-eth1", "bridge")
   921  
   922  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
   923  	c.Check(err, jc.ErrorIsNil)
   924  	c.Check(observedConfig, jc.DeepEquals, []params.NetworkConfig{{
   925  		DeviceIndex:   11,
   926  		MACAddress:    "aa:bb:cc:dd:ee:f1",
   927  		MTU:           1500,
   928  		InterfaceName: "br-eth1",
   929  		InterfaceType: "bridge",
   930  		ConfigType:    "manual",
   931  	}})
   932  
   933  	s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
   934  	s.stubConfigSource.CheckCall(c, 3, "InterfaceAddresses", "br-eth1")
   935  }
   936  
   937  func (s *NetworkSuite) TestGetObservedNetworkConfigLoopbackInfrerred(c *gc.C) {
   938  	s.stubConfigSource.interfaces = exampleObservedInterfaces[0:1] // only lo
   939  	s.stubConfigSource.makeSysClassNetInterfacePath(c, "lo", "")
   940  
   941  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
   942  	c.Check(err, jc.ErrorIsNil)
   943  	c.Check(observedConfig, jc.DeepEquals, []params.NetworkConfig{{
   944  		DeviceIndex:   1,
   945  		CIDR:          "127.0.0.0/8",
   946  		Address:       "127.0.0.1",
   947  		MTU:           65536,
   948  		InterfaceName: "lo",
   949  		InterfaceType: "loopback", // inferred from the flags.
   950  		ConfigType:    "loopback", // since it is a loopback
   951  	}, {
   952  		DeviceIndex:   1,
   953  		CIDR:          "::1/128",
   954  		Address:       "::1",
   955  		MTU:           65536,
   956  		InterfaceName: "lo",
   957  		InterfaceType: "loopback",
   958  		ConfigType:    "loopback",
   959  	}})
   960  
   961  	s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
   962  	s.stubConfigSource.CheckCall(c, 3, "InterfaceAddresses", "lo")
   963  }
   964  
   965  func (s *NetworkSuite) TestGetObservedNetworkConfigVLANInfrerred(c *gc.C) {
   966  	s.stubConfigSource.interfaces = exampleObservedInterfaces[6:7] // only eth0.100
   967  	s.stubConfigSource.interfaceAddrs = map[string][]net.Addr{
   968  		"eth0.100": {
   969  			fakeAddr("fe80::5054:ff:fedd:eef0:100/64"),
   970  			fakeAddr("10.100.19.123/24"),
   971  		},
   972  	}
   973  	s.stubConfigSource.makeSysClassNetInterfacePath(c, "eth0.100", "vlan")
   974  
   975  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
   976  	c.Check(err, jc.ErrorIsNil)
   977  	c.Check(observedConfig, jc.DeepEquals, []params.NetworkConfig{{
   978  		DeviceIndex:   13,
   979  		MACAddress:    "aa:bb:cc:dd:ee:f0",
   980  		MTU:           1500,
   981  		InterfaceName: "eth0.100",
   982  		InterfaceType: "802.1q",
   983  		ConfigType:    "manual", // the IPv6 address treated as empty.
   984  	}, {
   985  		DeviceIndex:   13,
   986  		CIDR:          "10.100.19.0/24",
   987  		Address:       "10.100.19.123",
   988  		MACAddress:    "aa:bb:cc:dd:ee:f0",
   989  		MTU:           1500,
   990  		InterfaceName: "eth0.100",
   991  		InterfaceType: "802.1q",
   992  		ConfigType:    "static",
   993  	}})
   994  
   995  	s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
   996  	s.stubConfigSource.CheckCall(c, 3, "InterfaceAddresses", "eth0.100")
   997  }
   998  
   999  func (s *NetworkSuite) TestGetObservedNetworkConfigEthernetInfrerred(c *gc.C) {
  1000  	s.stubConfigSource.interfaces = exampleObservedInterfaces[1:2] // only eth0
  1001  	s.stubConfigSource.makeSysClassNetInterfacePath(c, "eth0", "")
  1002  
  1003  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
  1004  	c.Check(err, jc.ErrorIsNil)
  1005  	c.Check(observedConfig, jc.DeepEquals, []params.NetworkConfig{{
  1006  		DeviceIndex:   2,
  1007  		MACAddress:    "aa:bb:cc:dd:ee:f0",
  1008  		MTU:           1500,
  1009  		InterfaceName: "eth0",
  1010  		InterfaceType: "ethernet",
  1011  		ConfigType:    "manual", // the IPv6 address treated as empty.
  1012  	}})
  1013  
  1014  	s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
  1015  	s.stubConfigSource.CheckCall(c, 3, "InterfaceAddresses", "eth0")
  1016  }
  1017  
  1018  func (s *NetworkSuite) TestGetObservedNetworkConfigBridgePortsHaveParentSet(c *gc.C) {
  1019  	s.stubConfigSource.interfaces = exampleObservedInterfaces[1:5] // eth0, br-eth0, br-eth1, eth1
  1020  	br0Path := s.stubConfigSource.makeSysClassNetInterfacePath(c, "br-eth0", "bridge")
  1021  	// "extra" added below to verify bridge ports which are discovered, but not
  1022  	// found as interfaces from the source will be ignored.
  1023  	s.stubConfigSource.makeSysClassNetBridgePorts(c, br0Path, "eth0", "extra")
  1024  	br1Path := s.stubConfigSource.makeSysClassNetInterfacePath(c, "br-eth1", "bridge")
  1025  	s.stubConfigSource.makeSysClassNetBridgePorts(c, br1Path, "eth1")
  1026  
  1027  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
  1028  	c.Check(err, jc.ErrorIsNil)
  1029  	c.Check(observedConfig, jc.DeepEquals, []params.NetworkConfig{{
  1030  		DeviceIndex:         2,
  1031  		MACAddress:          "aa:bb:cc:dd:ee:f0",
  1032  		MTU:                 1500,
  1033  		InterfaceName:       "eth0",
  1034  		InterfaceType:       "ethernet",
  1035  		ParentInterfaceName: "br-eth0",
  1036  		ConfigType:          "manual",
  1037  	}, {
  1038  		DeviceIndex:   10,
  1039  		CIDR:          "10.20.19.0/24",
  1040  		Address:       "10.20.19.100",
  1041  		MACAddress:    "aa:bb:cc:dd:ee:f0",
  1042  		MTU:           1500,
  1043  		InterfaceName: "br-eth0",
  1044  		InterfaceType: "bridge",
  1045  		ConfigType:    "static",
  1046  	}, {
  1047  		DeviceIndex:   10,
  1048  		CIDR:          "10.20.19.0/24",
  1049  		Address:       "10.20.19.123",
  1050  		MACAddress:    "aa:bb:cc:dd:ee:f0",
  1051  		MTU:           1500,
  1052  		InterfaceName: "br-eth0",
  1053  		InterfaceType: "bridge",
  1054  		ConfigType:    "static",
  1055  	}, {
  1056  		DeviceIndex:   10,
  1057  		MACAddress:    "aa:bb:cc:dd:ee:f0",
  1058  		MTU:           1500,
  1059  		InterfaceName: "br-eth0",
  1060  		InterfaceType: "bridge",
  1061  		ConfigType:    "manual",
  1062  	}, {
  1063  		DeviceIndex:   11,
  1064  		CIDR:          "10.20.19.0/24",
  1065  		Address:       "10.20.19.105",
  1066  		MACAddress:    "aa:bb:cc:dd:ee:f1",
  1067  		MTU:           1500,
  1068  		InterfaceName: "br-eth1",
  1069  		InterfaceType: "bridge",
  1070  		ConfigType:    "static",
  1071  	}, {
  1072  		DeviceIndex:   11,
  1073  		MACAddress:    "aa:bb:cc:dd:ee:f1",
  1074  		MTU:           1500,
  1075  		InterfaceName: "br-eth1",
  1076  		InterfaceType: "bridge",
  1077  		ConfigType:    "manual",
  1078  	}, {
  1079  		DeviceIndex:         3,
  1080  		MACAddress:          "aa:bb:cc:dd:ee:f1",
  1081  		MTU:                 1500,
  1082  		InterfaceName:       "eth1",
  1083  		InterfaceType:       "ethernet",
  1084  		ParentInterfaceName: "br-eth1",
  1085  		ConfigType:          "manual",
  1086  		GatewayAddress:      "1.2.3.4",
  1087  		IsDefaultGateway:    true,
  1088  	}})
  1089  
  1090  	s.stubConfigSource.CheckCallNames(c,
  1091  		"Interfaces",
  1092  		"DefaultRoute",
  1093  		"SysClassNetPath",
  1094  		"InterfaceAddresses", // eth0
  1095  		"InterfaceAddresses", // br-eth0
  1096  		"InterfaceAddresses", // br-eth1
  1097  		"InterfaceAddresses", // eth1
  1098  	)
  1099  	s.stubConfigSource.CheckCall(c, 3, "InterfaceAddresses", "eth0")
  1100  	s.stubConfigSource.CheckCall(c, 4, "InterfaceAddresses", "br-eth0")
  1101  	s.stubConfigSource.CheckCall(c, 5, "InterfaceAddresses", "br-eth1")
  1102  	s.stubConfigSource.CheckCall(c, 6, "InterfaceAddresses", "eth1")
  1103  }
  1104  
  1105  func (s *NetworkSuite) TestGetObservedNetworkConfigAddressNotInCIDRFormat(c *gc.C) {
  1106  	s.stubConfigSource.interfaces = exampleObservedInterfaces[1:2] // only eth0
  1107  	s.stubConfigSource.makeSysClassNetInterfacePath(c, "eth0", "")
  1108  	// Simulate running on Windows, where net.InterfaceAddrs() returns
  1109  	// non-CIDR-formatted addresses.
  1110  	s.stubConfigSource.interfaceAddrs = map[string][]net.Addr{
  1111  		"eth0": {fakeAddr("10.20.19.42")},
  1112  	}
  1113  
  1114  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
  1115  	c.Check(err, jc.ErrorIsNil)
  1116  	c.Check(observedConfig, jc.DeepEquals, []params.NetworkConfig{{
  1117  		DeviceIndex:   2,
  1118  		Address:       "10.20.19.42", // just Address, no CIDR as netmask cannot be inferred.
  1119  		MACAddress:    "aa:bb:cc:dd:ee:f0",
  1120  		MTU:           1500,
  1121  		InterfaceName: "eth0",
  1122  		InterfaceType: "ethernet",
  1123  		ConfigType:    "static",
  1124  	}})
  1125  
  1126  	s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
  1127  	s.stubConfigSource.CheckCall(c, 3, "InterfaceAddresses", "eth0")
  1128  }
  1129  
  1130  func (s *NetworkSuite) TestGetObservedNetworkConfigEmptyAddressValue(c *gc.C) {
  1131  	s.stubConfigSource.interfaces = exampleObservedInterfaces[1:2] // only eth0
  1132  	s.stubConfigSource.makeSysClassNetInterfacePath(c, "eth0", "")
  1133  	s.stubConfigSource.interfaceAddrs = map[string][]net.Addr{
  1134  		"eth0": {fakeAddr("")},
  1135  	}
  1136  
  1137  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
  1138  	c.Check(err, jc.ErrorIsNil)
  1139  	c.Check(observedConfig, jc.DeepEquals, []params.NetworkConfig{{
  1140  		DeviceIndex:   2,
  1141  		MACAddress:    "aa:bb:cc:dd:ee:f0",
  1142  		MTU:           1500,
  1143  		InterfaceName: "eth0",
  1144  		InterfaceType: "ethernet",
  1145  		ConfigType:    "manual",
  1146  	}})
  1147  
  1148  	s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
  1149  	s.stubConfigSource.CheckCall(c, 3, "InterfaceAddresses", "eth0")
  1150  }
  1151  
  1152  func (s *NetworkSuite) TestGetObservedNetworkConfigInvalidAddressValue(c *gc.C) {
  1153  	s.stubConfigSource.interfaces = exampleObservedInterfaces[1:2] // only eth0
  1154  	s.stubConfigSource.makeSysClassNetInterfacePath(c, "eth0", "")
  1155  	s.stubConfigSource.interfaceAddrs = map[string][]net.Addr{
  1156  		"eth0": {fakeAddr("invalid")},
  1157  	}
  1158  
  1159  	observedConfig, err := common.GetObservedNetworkConfig(s.stubConfigSource)
  1160  	c.Check(err, gc.ErrorMatches, `cannot parse IP address "invalid" on interface "eth0"`)
  1161  	c.Check(observedConfig, gc.IsNil)
  1162  
  1163  	s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
  1164  	s.stubConfigSource.CheckCall(c, 3, "InterfaceAddresses", "eth0")
  1165  }
  1166  
  1167  type stubNetworkConfigSource struct {
  1168  	*testing.Stub
  1169  
  1170  	fakeSysClassNetPath   string
  1171  	interfaces            []net.Interface
  1172  	interfaceAddrs        map[string][]net.Addr
  1173  	defaultRouteGatewayIP net.IP
  1174  	defaultRouteDevice    string
  1175  }
  1176  
  1177  // makeSysClassNetInterfacePath creates a subdir for the given interfaceName,
  1178  // and a uevent file there with the given devtype set. Returns the created path.
  1179  func (s *stubNetworkConfigSource) makeSysClassNetInterfacePath(c *gc.C, interfaceName, devType string) string {
  1180  	interfacePath := filepath.Join(s.fakeSysClassNetPath, interfaceName)
  1181  	err := os.Mkdir(interfacePath, 0755)
  1182  	c.Assert(err, jc.ErrorIsNil)
  1183  
  1184  	var contents string
  1185  	if devType == "" {
  1186  		contents = fmt.Sprintf(`
  1187  IFINDEX=42
  1188  INTERFACE=%s
  1189  `, interfaceName)
  1190  	} else {
  1191  		contents = fmt.Sprintf(`
  1192  IFINDEX=42
  1193  INTERFACE=%s
  1194  DEVTYPE=%s
  1195  `, interfaceName, devType)
  1196  	}
  1197  	ueventPath := filepath.Join(interfacePath, "uevent")
  1198  	err = ioutil.WriteFile(ueventPath, []byte(contents), 0644)
  1199  	c.Assert(err, jc.ErrorIsNil)
  1200  
  1201  	return interfacePath
  1202  }
  1203  
  1204  // makeSysClassNetBridgePorts creates a "brif" subdir in the given
  1205  // interfacePath, and one file for each entry in the given ports, named the same
  1206  // as the port value. Needed to simulate the FS structure network.GetBridgePorts()
  1207  // can handle.
  1208  func (s *stubNetworkConfigSource) makeSysClassNetBridgePorts(c *gc.C, interfacePath string, ports ...string) {
  1209  	brifPath := filepath.Join(interfacePath, "brif")
  1210  	err := os.Mkdir(brifPath, 0755)
  1211  	c.Assert(err, jc.ErrorIsNil)
  1212  
  1213  	for _, portName := range ports {
  1214  		portPath := filepath.Join(brifPath, portName)
  1215  		err = ioutil.WriteFile(portPath, []byte("#empty"), 0644)
  1216  		c.Assert(err, jc.ErrorIsNil)
  1217  	}
  1218  }
  1219  
  1220  // SysClassNetPath implements NetworkConfigSource.
  1221  func (s *stubNetworkConfigSource) SysClassNetPath() string {
  1222  	s.AddCall("SysClassNetPath")
  1223  	return s.fakeSysClassNetPath
  1224  }
  1225  
  1226  // Interfaces implements NetworkConfigSource.
  1227  func (s *stubNetworkConfigSource) Interfaces() ([]net.Interface, error) {
  1228  	s.AddCall("Interfaces")
  1229  	if err := s.NextErr(); err != nil {
  1230  		return nil, err
  1231  	}
  1232  	return s.interfaces, nil
  1233  }
  1234  
  1235  // InterfaceAddresses implements NetworkConfigSource.
  1236  func (s *stubNetworkConfigSource) InterfaceAddresses(name string) ([]net.Addr, error) {
  1237  	s.AddCall("InterfaceAddresses", name)
  1238  	if err := s.NextErr(); err != nil {
  1239  		return nil, err
  1240  	}
  1241  	return s.interfaceAddrs[name], nil
  1242  }
  1243  
  1244  // DefaultRoute implements NetworkConfigSource.
  1245  func (s *stubNetworkConfigSource) DefaultRoute() (net.IP, string, error) {
  1246  	s.AddCall("DefaultRoute")
  1247  	if err := s.NextErr(); err != nil {
  1248  		return nil, "", err
  1249  	}
  1250  	return s.defaultRouteGatewayIP, s.defaultRouteDevice, nil
  1251  }