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