github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/maas/interfaces_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package maas
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"text/template"
    10  
    11  	"github.com/juju/gomaasapi"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  
    15  	"github.com/juju/juju/network"
    16  )
    17  
    18  ////////////////////////////////////////////////////////////////////////////////
    19  // New (1.9 and later) environs.NetworkInterfaces() implementation tests follow.
    20  
    21  type interfacesSuite struct {
    22  	providerSuite
    23  }
    24  
    25  var _ = gc.Suite(&interfacesSuite{})
    26  
    27  func newAddressOnSpaceWithId(space string, id network.Id, address string) network.Address {
    28  	newAddress := network.NewAddressOnSpace(space, address)
    29  	newAddress.SpaceProviderId = id
    30  	return newAddress
    31  }
    32  
    33  const exampleInterfaceSetJSON = `
    34  [
    35  	{
    36  		"name": "eth0",
    37  		"links": [
    38  			{
    39  				"subnet": {
    40  					"dns_servers": ["10.20.19.2", "10.20.19.3"],
    41  					"name": "pxe",
    42  					"space": "default",
    43  					"vlan": {
    44  						"name": "untagged",
    45  						"vid": 0,
    46  						"mtu": 1500,
    47  						"fabric": "managed",
    48  						"id": 5001,
    49  						"resource_uri": "/MAAS/api/1.0/vlans/5001/"
    50  					},
    51  					"gateway_ip": "10.20.19.2",
    52  					"cidr": "10.20.19.0/24",
    53  					"id": 3,
    54  					"resource_uri": "/MAAS/api/1.0/subnets/3/"
    55  				},
    56  				"ip_address": "10.20.19.103",
    57  				"id": 436,
    58  				"mode": "static"
    59  			},
    60  			{
    61  				"subnet": {
    62  					"dns_servers": ["10.20.19.2", "10.20.19.3"],
    63  					"name": "pxe",
    64  					"space": "default",
    65  					"vlan": {
    66  						"name": "untagged",
    67  						"vid": 0,
    68  						"mtu": 1500,
    69  						"fabric": "managed",
    70  						"id": 5001,
    71  						"resource_uri": "/MAAS/api/1.0/vlans/5001/"
    72  					},
    73  					"gateway_ip": "10.20.19.2",
    74  					"cidr": "10.20.19.0/24",
    75  					"id": 3,
    76  					"resource_uri": "/MAAS/api/1.0/subnets/3/"
    77  				},
    78  				"ip_address": "10.20.19.104",
    79  				"id": 437,
    80  				"mode": "static"
    81  			}
    82  		],
    83  		"tags": [],
    84  		"vlan": {
    85  			"name": "untagged",
    86  			"vid": 0,
    87  			"mtu": 1500,
    88  			"fabric": "managed",
    89  			"id": 5001,
    90  			"resource_uri": "/MAAS/api/1.0/vlans/5001/"
    91  		},
    92  		"enabled": true,
    93  		"id": 91,
    94  		"discovered": [
    95  			{
    96  				"subnet": {
    97  					"dns_servers": [],
    98  					"name": "pxe",
    99  					"space": "default",
   100  					"vlan": {
   101  						"name": "untagged",
   102  						"vid": 0,
   103  						"mtu": 1500,
   104  						"fabric": "managed",
   105  						"id": 5001,
   106  						"resource_uri": "/MAAS/api/1.0/vlans/5001/"
   107  					},
   108  					"gateway_ip": "10.20.19.2",
   109  					"cidr": "10.20.19.0/24",
   110  					"id": 3,
   111  					"resource_uri": "/MAAS/api/1.0/subnets/3/"
   112  				},
   113  				"ip_address": "10.20.19.20"
   114  			}
   115  		],
   116  		"mac_address": "52:54:00:70:9b:fe",
   117  		"parents": [],
   118  		"effective_mtu": 1500,
   119  		"params": {},
   120  		"type": "physical",
   121  		"children": [
   122  			"eth0.100",
   123  			"eth0.250",
   124  			"eth0.50"
   125  		],
   126  		"resource_uri": "/MAAS/api/1.0/nodes/node-18489434-9eb0-11e5-bdef-00163e40c3b6/interfaces/91/"
   127  	},
   128  	{
   129  		"name": "eth0.50",
   130  		"links": [
   131  			{
   132  				"subnet": {
   133  					"dns_servers": [],
   134  					"name": "admin",
   135  					"space": "admin",
   136  					"vlan": {
   137  						"name": "admin",
   138  						"vid": 50,
   139  						"mtu": 1500,
   140  						"fabric": "managed",
   141  						"id": 5004,
   142  						"resource_uri": "/MAAS/api/1.0/vlans/5004/"
   143  					},
   144  					"gateway_ip": "10.50.19.2",
   145  					"cidr": "10.50.19.0/24",
   146  					"id": 5,
   147  					"resource_uri": "/MAAS/api/1.0/subnets/5/"
   148  				},
   149  				"ip_address": "10.50.19.103",
   150  				"id": 517,
   151  				"mode": "static"
   152  			}
   153  		],
   154  		"tags": [],
   155  		"vlan": {
   156  			"name": "admin",
   157  			"vid": 50,
   158  			"mtu": 1500,
   159  			"fabric": "managed",
   160  			"id": 5004,
   161  			"resource_uri": "/MAAS/api/1.0/vlans/5004/"
   162  		},
   163  		"enabled": true,
   164  		"id": 150,
   165  		"discovered": null,
   166  		"mac_address": "52:54:00:70:9b:fe",
   167  		"parents": [
   168  			"eth0"
   169  		],
   170  		"effective_mtu": 1500,
   171  		"params": {},
   172  		"type": "vlan",
   173  		"children": [],
   174  		"resource_uri": "/MAAS/api/1.0/nodes/node-18489434-9eb0-11e5-bdef-00163e40c3b6/interfaces/150/"
   175  	},
   176  	{
   177  		"name": "eth0.100",
   178  		"links": [
   179  			{
   180  				"subnet": {
   181  					"dns_servers": [],
   182  					"name": "public",
   183  					"space": "public",
   184  					"vlan": {
   185  						"name": "public",
   186  						"vid": 100,
   187  						"mtu": 1500,
   188  						"fabric": "managed",
   189  						"id": 5005,
   190  						"resource_uri": "/MAAS/api/1.0/vlans/5005/"
   191  					},
   192  					"gateway_ip": "10.100.19.2",
   193  					"cidr": "10.100.19.0/24",
   194  					"id": 6,
   195  					"resource_uri": "/MAAS/api/1.0/subnets/6/"
   196  				},
   197  				"ip_address": "10.100.19.103",
   198  				"id": 519,
   199  				"mode": "static"
   200  			}
   201  		],
   202  		"tags": [],
   203  		"vlan": {
   204  			"name": "public",
   205  			"vid": 100,
   206  			"mtu": 1500,
   207  			"fabric": "managed",
   208  			"id": 5005,
   209  			"resource_uri": "/MAAS/api/1.0/vlans/5005/"
   210  		},
   211  		"enabled": true,
   212  		"id": 151,
   213  		"discovered": null,
   214  		"mac_address": "52:54:00:70:9b:fe",
   215  		"parents": [
   216  			"eth0"
   217  		],
   218  		"effective_mtu": 1500,
   219  		"params": {},
   220  		"type": "vlan",
   221  		"children": [],
   222  		"resource_uri": "/MAAS/api/1.0/nodes/node-18489434-9eb0-11e5-bdef-00163e40c3b6/interfaces/151/"
   223  	},
   224  	{
   225  		"name": "eth0.250",
   226  		"links": [
   227  			{
   228  				"subnet": {
   229  					"dns_servers": [],
   230  					"name": "storage",
   231  					"space": "storage",
   232  					"vlan": {
   233  						"name": "storage",
   234  						"vid": 250,
   235  						"mtu": 1500,
   236  						"fabric": "managed",
   237  						"id": 5008,
   238  						"resource_uri": "/MAAS/api/1.0/vlans/5008/"
   239  					},
   240  					"gateway_ip": "10.250.19.2",
   241  					"cidr": "10.250.19.0/24",
   242  					"id": 8,
   243  					"resource_uri": "/MAAS/api/1.0/subnets/8/"
   244  				},
   245  				"ip_address": "10.250.19.103",
   246  				"id": 523,
   247  				"mode": "static"
   248  			}
   249  		],
   250  		"tags": [],
   251  		"vlan": {
   252  			"name": "storage",
   253  			"vid": 250,
   254  			"mtu": 1500,
   255  			"fabric": "managed",
   256  			"id": 5008,
   257  			"resource_uri": "/MAAS/api/1.0/vlans/5008/"
   258  		},
   259  		"enabled": true,
   260  		"id": 152,
   261  		"discovered": null,
   262  		"mac_address": "52:54:00:70:9b:fe",
   263  		"parents": [
   264  			"eth0"
   265  		],
   266  		"effective_mtu": 1500,
   267  		"params": {},
   268  		"type": "vlan",
   269  		"children": [],
   270  		"resource_uri": "/MAAS/api/1.0/nodes/node-18489434-9eb0-11e5-bdef-00163e40c3b6/interfaces/152/"
   271  	}
   272  ]`
   273  
   274  func (s *interfacesSuite) TestParseInterfacesNoJSON(c *gc.C) {
   275  	result, err := parseInterfaces(nil)
   276  	c.Check(err, gc.ErrorMatches, "parsing interfaces: unexpected end of JSON input")
   277  	c.Check(result, gc.IsNil)
   278  }
   279  
   280  func (s *interfacesSuite) TestParseInterfacesBadJSON(c *gc.C) {
   281  	result, err := parseInterfaces([]byte("$bad"))
   282  	c.Check(err, gc.ErrorMatches, `parsing interfaces: invalid character '\$' .*`)
   283  	c.Check(result, gc.IsNil)
   284  }
   285  
   286  func (s *interfacesSuite) TestParseInterfacesExampleJSON(c *gc.C) {
   287  
   288  	vlan0 := maasVLAN{
   289  		ID:          5001,
   290  		Name:        "untagged",
   291  		VID:         0,
   292  		MTU:         1500,
   293  		Fabric:      "managed",
   294  		ResourceURI: "/MAAS/api/1.0/vlans/5001/",
   295  	}
   296  
   297  	vlan50 := maasVLAN{
   298  		ID:          5004,
   299  		Name:        "admin",
   300  		VID:         50,
   301  		MTU:         1500,
   302  		Fabric:      "managed",
   303  		ResourceURI: "/MAAS/api/1.0/vlans/5004/",
   304  	}
   305  
   306  	vlan100 := maasVLAN{
   307  		ID:          5005,
   308  		Name:        "public",
   309  		VID:         100,
   310  		MTU:         1500,
   311  		Fabric:      "managed",
   312  		ResourceURI: "/MAAS/api/1.0/vlans/5005/",
   313  	}
   314  
   315  	vlan250 := maasVLAN{
   316  		ID:          5008,
   317  		Name:        "storage",
   318  		VID:         250,
   319  		MTU:         1500,
   320  		Fabric:      "managed",
   321  		ResourceURI: "/MAAS/api/1.0/vlans/5008/",
   322  	}
   323  
   324  	subnetPXE := maasSubnet{
   325  		ID:          3,
   326  		Name:        "pxe",
   327  		Space:       "default",
   328  		VLAN:        vlan0,
   329  		GatewayIP:   "10.20.19.2",
   330  		DNSServers:  []string{"10.20.19.2", "10.20.19.3"},
   331  		CIDR:        "10.20.19.0/24",
   332  		ResourceURI: "/MAAS/api/1.0/subnets/3/",
   333  	}
   334  
   335  	expected := []maasInterface{{
   336  		ID:          91,
   337  		Name:        "eth0",
   338  		Type:        "physical",
   339  		Enabled:     true,
   340  		MACAddress:  "52:54:00:70:9b:fe",
   341  		VLAN:        vlan0,
   342  		EffectveMTU: 1500,
   343  		Links: []maasInterfaceLink{{
   344  			ID:        436,
   345  			Subnet:    &subnetPXE,
   346  			IPAddress: "10.20.19.103",
   347  			Mode:      "static",
   348  		}, {
   349  			ID:        437,
   350  			Subnet:    &subnetPXE,
   351  			IPAddress: "10.20.19.104",
   352  			Mode:      "static",
   353  		}},
   354  		Parents:     []string{},
   355  		Children:    []string{"eth0.100", "eth0.250", "eth0.50"},
   356  		ResourceURI: "/MAAS/api/1.0/nodes/node-18489434-9eb0-11e5-bdef-00163e40c3b6/interfaces/91/",
   357  	}, {
   358  		ID:          150,
   359  		Name:        "eth0.50",
   360  		Type:        "vlan",
   361  		Enabled:     true,
   362  		MACAddress:  "52:54:00:70:9b:fe",
   363  		VLAN:        vlan50,
   364  		EffectveMTU: 1500,
   365  		Links: []maasInterfaceLink{{
   366  			ID: 517,
   367  			Subnet: &maasSubnet{
   368  				ID:          5,
   369  				Name:        "admin",
   370  				Space:       "admin",
   371  				VLAN:        vlan50,
   372  				GatewayIP:   "10.50.19.2",
   373  				DNSServers:  []string{},
   374  				CIDR:        "10.50.19.0/24",
   375  				ResourceURI: "/MAAS/api/1.0/subnets/5/",
   376  			},
   377  			IPAddress: "10.50.19.103",
   378  			Mode:      "static",
   379  		}},
   380  		Parents:     []string{"eth0"},
   381  		Children:    []string{},
   382  		ResourceURI: "/MAAS/api/1.0/nodes/node-18489434-9eb0-11e5-bdef-00163e40c3b6/interfaces/150/",
   383  	}, {
   384  		ID:          151,
   385  		Name:        "eth0.100",
   386  		Type:        "vlan",
   387  		Enabled:     true,
   388  		MACAddress:  "52:54:00:70:9b:fe",
   389  		VLAN:        vlan100,
   390  		EffectveMTU: 1500,
   391  		Links: []maasInterfaceLink{{
   392  			ID: 519,
   393  			Subnet: &maasSubnet{
   394  				ID:          6,
   395  				Name:        "public",
   396  				Space:       "public",
   397  				VLAN:        vlan100,
   398  				GatewayIP:   "10.100.19.2",
   399  				DNSServers:  []string{},
   400  				CIDR:        "10.100.19.0/24",
   401  				ResourceURI: "/MAAS/api/1.0/subnets/6/",
   402  			},
   403  			IPAddress: "10.100.19.103",
   404  			Mode:      "static",
   405  		}},
   406  		Parents:     []string{"eth0"},
   407  		Children:    []string{},
   408  		ResourceURI: "/MAAS/api/1.0/nodes/node-18489434-9eb0-11e5-bdef-00163e40c3b6/interfaces/151/",
   409  	}, {
   410  		ID:          152,
   411  		Name:        "eth0.250",
   412  		Type:        "vlan",
   413  		Enabled:     true,
   414  		MACAddress:  "52:54:00:70:9b:fe",
   415  		VLAN:        vlan250,
   416  		EffectveMTU: 1500,
   417  		Links: []maasInterfaceLink{{
   418  			ID: 523,
   419  			Subnet: &maasSubnet{
   420  				ID:          8,
   421  				Name:        "storage",
   422  				Space:       "storage",
   423  				VLAN:        vlan250,
   424  				GatewayIP:   "10.250.19.2",
   425  				DNSServers:  []string{},
   426  				CIDR:        "10.250.19.0/24",
   427  				ResourceURI: "/MAAS/api/1.0/subnets/8/",
   428  			},
   429  			IPAddress: "10.250.19.103",
   430  			Mode:      "static",
   431  		}},
   432  		Parents:     []string{"eth0"},
   433  		Children:    []string{},
   434  		ResourceURI: "/MAAS/api/1.0/nodes/node-18489434-9eb0-11e5-bdef-00163e40c3b6/interfaces/152/",
   435  	}}
   436  
   437  	result, err := parseInterfaces([]byte(exampleInterfaceSetJSON))
   438  	c.Check(err, jc.ErrorIsNil)
   439  	c.Check(result, jc.DeepEquals, expected)
   440  }
   441  
   442  func (s *interfacesSuite) TestMAASObjectNetworkInterfaces(c *gc.C) {
   443  	nodeJSON := fmt.Sprintf(`{
   444          "system_id": "foo",
   445          "interface_set": %s
   446      }`, exampleInterfaceSetJSON)
   447  	obj := s.testMAASObject.TestServer.NewNode(nodeJSON)
   448  	subnetsMap := make(map[string]network.Id)
   449  	subnetsMap["10.250.19.0/24"] = network.Id("3")
   450  	subnetsMap["192.168.1.0/24"] = network.Id("0")
   451  
   452  	expected := []network.InterfaceInfo{{
   453  		DeviceIndex:       0,
   454  		MACAddress:        "52:54:00:70:9b:fe",
   455  		CIDR:              "10.20.19.0/24",
   456  		ProviderId:        "91",
   457  		ProviderSubnetId:  "3",
   458  		AvailabilityZones: nil,
   459  		VLANTag:           0,
   460  		ProviderVLANId:    "5001",
   461  		ProviderAddressId: "436",
   462  		InterfaceName:     "eth0",
   463  		InterfaceType:     "ethernet",
   464  		Disabled:          false,
   465  		NoAutoStart:       false,
   466  		ConfigType:        "static",
   467  		Address:           network.NewAddressOnSpace("default", "10.20.19.103"),
   468  		DNSServers:        network.NewAddressesOnSpace("default", "10.20.19.2", "10.20.19.3"),
   469  		DNSSearchDomains:  nil,
   470  		MTU:               1500,
   471  		GatewayAddress:    network.NewAddressOnSpace("default", "10.20.19.2"),
   472  	}, {
   473  		DeviceIndex:       0,
   474  		MACAddress:        "52:54:00:70:9b:fe",
   475  		CIDR:              "10.20.19.0/24",
   476  		ProviderId:        "91",
   477  		ProviderSubnetId:  "3",
   478  		AvailabilityZones: nil,
   479  		VLANTag:           0,
   480  		ProviderVLANId:    "5001",
   481  		ProviderAddressId: "437",
   482  		InterfaceName:     "eth0",
   483  		InterfaceType:     "ethernet",
   484  		Disabled:          false,
   485  		NoAutoStart:       false,
   486  		ConfigType:        "static",
   487  		Address:           network.NewAddressOnSpace("default", "10.20.19.104"),
   488  		DNSServers:        network.NewAddressesOnSpace("default", "10.20.19.2", "10.20.19.3"),
   489  		DNSSearchDomains:  nil,
   490  		MTU:               1500,
   491  		GatewayAddress:    network.NewAddressOnSpace("default", "10.20.19.2"),
   492  	}, {
   493  		DeviceIndex:         1,
   494  		MACAddress:          "52:54:00:70:9b:fe",
   495  		CIDR:                "10.50.19.0/24",
   496  		ProviderId:          "150",
   497  		ProviderSubnetId:    "5",
   498  		AvailabilityZones:   nil,
   499  		VLANTag:             50,
   500  		ProviderVLANId:      "5004",
   501  		ProviderAddressId:   "517",
   502  		InterfaceName:       "eth0.50",
   503  		ParentInterfaceName: "eth0",
   504  		InterfaceType:       "802.1q",
   505  		Disabled:            false,
   506  		NoAutoStart:         false,
   507  		ConfigType:          "static",
   508  		Address:             network.NewAddressOnSpace("admin", "10.50.19.103"),
   509  		DNSServers:          nil,
   510  		DNSSearchDomains:    nil,
   511  		MTU:                 1500,
   512  		GatewayAddress:      network.NewAddressOnSpace("admin", "10.50.19.2"),
   513  	}, {
   514  		DeviceIndex:         2,
   515  		MACAddress:          "52:54:00:70:9b:fe",
   516  		CIDR:                "10.100.19.0/24",
   517  		ProviderId:          "151",
   518  		ProviderSubnetId:    "6",
   519  		AvailabilityZones:   nil,
   520  		VLANTag:             100,
   521  		ProviderVLANId:      "5005",
   522  		ProviderAddressId:   "519",
   523  		InterfaceName:       "eth0.100",
   524  		ParentInterfaceName: "eth0",
   525  		InterfaceType:       "802.1q",
   526  		Disabled:            false,
   527  		NoAutoStart:         false,
   528  		ConfigType:          "static",
   529  		Address:             network.NewAddressOnSpace("public", "10.100.19.103"),
   530  		DNSServers:          nil,
   531  		DNSSearchDomains:    nil,
   532  		MTU:                 1500,
   533  		GatewayAddress:      network.NewAddressOnSpace("public", "10.100.19.2"),
   534  	}, {
   535  		DeviceIndex:         3,
   536  		MACAddress:          "52:54:00:70:9b:fe",
   537  		CIDR:                "10.250.19.0/24",
   538  		ProviderId:          "152",
   539  		ProviderSubnetId:    "8",
   540  		AvailabilityZones:   nil,
   541  		VLANTag:             250,
   542  		ProviderVLANId:      "5008",
   543  		ProviderAddressId:   "523",
   544  		ProviderSpaceId:     "3",
   545  		InterfaceName:       "eth0.250",
   546  		ParentInterfaceName: "eth0",
   547  		InterfaceType:       "802.1q",
   548  		Disabled:            false,
   549  		NoAutoStart:         false,
   550  		ConfigType:          "static",
   551  		Address:             newAddressOnSpaceWithId("storage", network.Id("3"), "10.250.19.103"),
   552  		DNSServers:          nil,
   553  		DNSSearchDomains:    nil,
   554  		MTU:                 1500,
   555  		GatewayAddress:      newAddressOnSpaceWithId("storage", network.Id("3"), "10.250.19.2"),
   556  	}}
   557  
   558  	infos, err := maasObjectNetworkInterfaces(&obj, subnetsMap)
   559  	c.Assert(err, jc.ErrorIsNil)
   560  	c.Check(infos, jc.DeepEquals, expected)
   561  }
   562  
   563  func (s *interfacesSuite) TestMAAS2NetworkInterfaces(c *gc.C) {
   564  	vlan0 := fakeVLAN{
   565  		id:  5001,
   566  		vid: 0,
   567  		mtu: 1500,
   568  	}
   569  
   570  	vlan50 := fakeVLAN{
   571  		id:  5004,
   572  		vid: 50,
   573  		mtu: 1500,
   574  	}
   575  
   576  	vlan100 := fakeVLAN{
   577  		id:  5005,
   578  		vid: 100,
   579  		mtu: 1500,
   580  	}
   581  
   582  	vlan250 := fakeVLAN{
   583  		id:  5008,
   584  		vid: 250,
   585  		mtu: 1500,
   586  	}
   587  
   588  	subnetPXE := fakeSubnet{
   589  		id:         3,
   590  		space:      "default",
   591  		vlan:       vlan0,
   592  		gateway:    "10.20.19.2",
   593  		cidr:       "10.20.19.0/24",
   594  		dnsServers: []string{"10.20.19.2", "10.20.19.3"},
   595  	}
   596  
   597  	exampleInterfaces := []gomaasapi.Interface{
   598  		&fakeInterface{
   599  			id:         91,
   600  			name:       "eth0",
   601  			type_:      "physical",
   602  			enabled:    true,
   603  			macAddress: "52:54:00:70:9b:fe",
   604  			vlan:       vlan0,
   605  			links: []gomaasapi.Link{
   606  				&fakeLink{
   607  					id:        436,
   608  					subnet:    &subnetPXE,
   609  					ipAddress: "10.20.19.103",
   610  					mode:      "static",
   611  				},
   612  				&fakeLink{
   613  					id:        437,
   614  					subnet:    &subnetPXE,
   615  					ipAddress: "10.20.19.104",
   616  					mode:      "static",
   617  				},
   618  			},
   619  			parents:  []string{},
   620  			children: []string{"eth0.100", "eth0.250", "eth0.50"},
   621  		},
   622  		&fakeInterface{
   623  			id:         150,
   624  			name:       "eth0.50",
   625  			type_:      "vlan",
   626  			enabled:    true,
   627  			macAddress: "52:54:00:70:9b:fe",
   628  			vlan:       vlan50,
   629  			links: []gomaasapi.Link{
   630  				&fakeLink{
   631  					id: 517,
   632  					subnet: &fakeSubnet{
   633  						id:         5,
   634  						space:      "admin",
   635  						vlan:       vlan50,
   636  						gateway:    "10.50.19.2",
   637  						cidr:       "10.50.19.0/24",
   638  						dnsServers: []string{},
   639  					},
   640  					ipAddress: "10.50.19.103",
   641  					mode:      "static",
   642  				},
   643  			},
   644  			parents:  []string{"eth0"},
   645  			children: []string{},
   646  		},
   647  		&fakeInterface{
   648  			id:         151,
   649  			name:       "eth0.100",
   650  			type_:      "vlan",
   651  			enabled:    true,
   652  			macAddress: "52:54:00:70:9b:fe",
   653  			vlan:       vlan100,
   654  			links: []gomaasapi.Link{
   655  				&fakeLink{
   656  					id: 519,
   657  					subnet: &fakeSubnet{
   658  						id:         6,
   659  						space:      "public",
   660  						vlan:       vlan100,
   661  						gateway:    "10.100.19.2",
   662  						cidr:       "10.100.19.0/24",
   663  						dnsServers: []string{},
   664  					},
   665  					ipAddress: "10.100.19.103",
   666  					mode:      "static",
   667  				},
   668  			},
   669  			parents:  []string{"eth0"},
   670  			children: []string{},
   671  		},
   672  		&fakeInterface{
   673  			id:         152,
   674  			name:       "eth0.250",
   675  			type_:      "vlan",
   676  			enabled:    true,
   677  			macAddress: "52:54:00:70:9b:fe",
   678  			vlan:       vlan250,
   679  			links: []gomaasapi.Link{
   680  				&fakeLink{
   681  					id: 523,
   682  					subnet: &fakeSubnet{
   683  						id:         8,
   684  						space:      "storage",
   685  						vlan:       vlan250,
   686  						gateway:    "10.250.19.2",
   687  						cidr:       "10.250.19.0/24",
   688  						dnsServers: []string{},
   689  					},
   690  					ipAddress: "10.250.19.103",
   691  					mode:      "static",
   692  				},
   693  			},
   694  			parents:  []string{"eth0"},
   695  			children: []string{},
   696  		},
   697  	}
   698  
   699  	subnetsMap := make(map[string]network.Id)
   700  	subnetsMap["10.250.19.0/24"] = network.Id("3")
   701  	subnetsMap["192.168.1.0/24"] = network.Id("0")
   702  
   703  	expected := []network.InterfaceInfo{{
   704  		DeviceIndex:       0,
   705  		MACAddress:        "52:54:00:70:9b:fe",
   706  		CIDR:              "10.20.19.0/24",
   707  		ProviderId:        "91",
   708  		ProviderSubnetId:  "3",
   709  		AvailabilityZones: nil,
   710  		VLANTag:           0,
   711  		ProviderVLANId:    "5001",
   712  		ProviderAddressId: "436",
   713  		InterfaceName:     "eth0",
   714  		InterfaceType:     "ethernet",
   715  		Disabled:          false,
   716  		NoAutoStart:       false,
   717  		ConfigType:        "static",
   718  		Address:           network.NewAddressOnSpace("default", "10.20.19.103"),
   719  		DNSServers:        network.NewAddressesOnSpace("default", "10.20.19.2", "10.20.19.3"),
   720  		DNSSearchDomains:  nil,
   721  		MTU:               1500,
   722  		GatewayAddress:    network.NewAddressOnSpace("default", "10.20.19.2"),
   723  	}, {
   724  		DeviceIndex:       0,
   725  		MACAddress:        "52:54:00:70:9b:fe",
   726  		CIDR:              "10.20.19.0/24",
   727  		ProviderId:        "91",
   728  		ProviderSubnetId:  "3",
   729  		AvailabilityZones: nil,
   730  		VLANTag:           0,
   731  		ProviderVLANId:    "5001",
   732  		ProviderAddressId: "437",
   733  		InterfaceName:     "eth0",
   734  		InterfaceType:     "ethernet",
   735  		Disabled:          false,
   736  		NoAutoStart:       false,
   737  		ConfigType:        "static",
   738  		Address:           network.NewAddressOnSpace("default", "10.20.19.104"),
   739  		DNSServers:        network.NewAddressesOnSpace("default", "10.20.19.2", "10.20.19.3"),
   740  		DNSSearchDomains:  nil,
   741  		MTU:               1500,
   742  		GatewayAddress:    network.NewAddressOnSpace("default", "10.20.19.2"),
   743  	}, {
   744  		DeviceIndex:         1,
   745  		MACAddress:          "52:54:00:70:9b:fe",
   746  		CIDR:                "10.50.19.0/24",
   747  		ProviderId:          "150",
   748  		ProviderSubnetId:    "5",
   749  		AvailabilityZones:   nil,
   750  		VLANTag:             50,
   751  		ProviderVLANId:      "5004",
   752  		ProviderAddressId:   "517",
   753  		InterfaceName:       "eth0.50",
   754  		ParentInterfaceName: "eth0",
   755  		InterfaceType:       "802.1q",
   756  		Disabled:            false,
   757  		NoAutoStart:         false,
   758  		ConfigType:          "static",
   759  		Address:             network.NewAddressOnSpace("admin", "10.50.19.103"),
   760  		DNSServers:          nil,
   761  		DNSSearchDomains:    nil,
   762  		MTU:                 1500,
   763  		GatewayAddress:      network.NewAddressOnSpace("admin", "10.50.19.2"),
   764  	}, {
   765  		DeviceIndex:         2,
   766  		MACAddress:          "52:54:00:70:9b:fe",
   767  		CIDR:                "10.100.19.0/24",
   768  		ProviderId:          "151",
   769  		ProviderSubnetId:    "6",
   770  		AvailabilityZones:   nil,
   771  		VLANTag:             100,
   772  		ProviderVLANId:      "5005",
   773  		ProviderAddressId:   "519",
   774  		InterfaceName:       "eth0.100",
   775  		ParentInterfaceName: "eth0",
   776  		InterfaceType:       "802.1q",
   777  		Disabled:            false,
   778  		NoAutoStart:         false,
   779  		ConfigType:          "static",
   780  		Address:             network.NewAddressOnSpace("public", "10.100.19.103"),
   781  		DNSServers:          nil,
   782  		DNSSearchDomains:    nil,
   783  		MTU:                 1500,
   784  		GatewayAddress:      network.NewAddressOnSpace("public", "10.100.19.2"),
   785  	}, {
   786  		DeviceIndex:         3,
   787  		MACAddress:          "52:54:00:70:9b:fe",
   788  		CIDR:                "10.250.19.0/24",
   789  		ProviderId:          "152",
   790  		ProviderSubnetId:    "8",
   791  		AvailabilityZones:   nil,
   792  		VLANTag:             250,
   793  		ProviderVLANId:      "5008",
   794  		ProviderAddressId:   "523",
   795  		ProviderSpaceId:     "3",
   796  		InterfaceName:       "eth0.250",
   797  		ParentInterfaceName: "eth0",
   798  		InterfaceType:       "802.1q",
   799  		Disabled:            false,
   800  		NoAutoStart:         false,
   801  		ConfigType:          "static",
   802  		Address:             newAddressOnSpaceWithId("storage", network.Id("3"), "10.250.19.103"),
   803  		DNSServers:          nil,
   804  		DNSSearchDomains:    nil,
   805  		MTU:                 1500,
   806  		GatewayAddress:      newAddressOnSpaceWithId("storage", network.Id("3"), "10.250.19.2"),
   807  	}}
   808  
   809  	instance := &maas2Instance{machine: &fakeMachine{interfaceSet: exampleInterfaces}}
   810  
   811  	infos, err := maas2NetworkInterfaces(instance, subnetsMap)
   812  	c.Assert(err, jc.ErrorIsNil)
   813  	c.Check(infos, jc.DeepEquals, expected)
   814  }
   815  
   816  const lshwXMLTemplate = `
   817  <?xml version="1.0" standalone="yes" ?>
   818  <!-- generated by lshw-B.02.16 -->
   819  <list>
   820  <node id="node1" claimed="true" class="system" handle="DMI:0001">
   821   <description>Computer</description>
   822   <product>VirtualBox ()</product>
   823   <width units="bits">64</width>
   824    <node id="core" claimed="true" class="bus" handle="DMI:0008">
   825     <description>Motherboard</description>
   826      <node id="pci" claimed="true" class="bridge" handle="PCIBUS:0000:00">
   827       <description>Host bridge</description>{{$list := .}}{{range $mac, $ifi := $list}}
   828        <node id="network{{if gt (len $list) 1}}:{{$ifi.DeviceIndex}}{{end}}"{{if $ifi.Disabled}} disabled="true"{{end}} claimed="true" class="network" handle="PCI:0000:00:03.0">
   829         <description>Ethernet interface</description>
   830         <product>82540EM Gigabit Ethernet Controller</product>
   831         <logicalname>{{$ifi.InterfaceName}}</logicalname>
   832         <serial>{{$mac}}</serial>
   833        </node>{{end}}
   834      </node>
   835    </node>
   836  </node>
   837  </list>
   838  `
   839  
   840  func (suite *environSuite) generateHWTemplate(netMacs map[string]ifaceInfo) (string, error) {
   841  	tmpl, err := template.New("test").Parse(lshwXMLTemplate)
   842  	if err != nil {
   843  		return "", err
   844  	}
   845  	var buf bytes.Buffer
   846  	err = tmpl.Execute(&buf, netMacs)
   847  	if err != nil {
   848  		return "", err
   849  	}
   850  	return string(buf.Bytes()), nil
   851  }