github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/provider/maas/maas_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package maas
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/json"
     9  	"fmt"
    10  	"path/filepath"
    11  	"strconv"
    12  
    13  	"github.com/juju/gomaasapi"
    14  	jc "github.com/juju/testing/checkers"
    15  	"github.com/juju/utils"
    16  	"github.com/juju/utils/arch"
    17  	"github.com/juju/utils/series"
    18  	"github.com/juju/utils/set"
    19  	gc "gopkg.in/check.v1"
    20  
    21  	"github.com/juju/juju/cloud"
    22  	"github.com/juju/juju/environs"
    23  	"github.com/juju/juju/environs/config"
    24  	sstesting "github.com/juju/juju/environs/simplestreams/testing"
    25  	envtesting "github.com/juju/juju/environs/testing"
    26  	envtools "github.com/juju/juju/environs/tools"
    27  	"github.com/juju/juju/instance"
    28  	"github.com/juju/juju/juju/keys"
    29  	"github.com/juju/juju/network"
    30  	coretesting "github.com/juju/juju/testing"
    31  	jujuversion "github.com/juju/juju/version"
    32  )
    33  
    34  const maas2VersionResponse = `{"version": "unknown", "subversion": "", "capabilities": ["networks-management", "static-ipaddresses", "ipv6-deployment-ubuntu", "devices-management", "storage-deployment-ubuntu", "network-deployment-ubuntu"]}`
    35  
    36  type baseProviderSuite struct {
    37  	coretesting.FakeJujuXDGDataHomeSuite
    38  	envtesting.ToolsFixture
    39  	controllerUUID string
    40  }
    41  
    42  func (suite *baseProviderSuite) setupFakeTools(c *gc.C) {
    43  	suite.PatchValue(&keys.JujuPublicKey, sstesting.SignedMetadataPublicKey)
    44  	storageDir := c.MkDir()
    45  	toolsDir := filepath.Join(storageDir, "tools")
    46  	suite.PatchValue(&envtools.DefaultBaseURL, utils.MakeFileURL(toolsDir))
    47  	suite.UploadFakeToolsToDirectory(c, storageDir, "released", "released")
    48  }
    49  
    50  func (s *baseProviderSuite) SetUpSuite(c *gc.C) {
    51  	s.FakeJujuXDGDataHomeSuite.SetUpSuite(c)
    52  	restoreTimeouts := envtesting.PatchAttemptStrategies(&shortAttempt)
    53  	restoreFinishBootstrap := envtesting.DisableFinishBootstrap()
    54  	s.AddCleanup(func(*gc.C) {
    55  		restoreFinishBootstrap()
    56  		restoreTimeouts()
    57  	})
    58  }
    59  
    60  func (s *baseProviderSuite) SetUpTest(c *gc.C) {
    61  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    62  	s.ToolsFixture.SetUpTest(c)
    63  	s.PatchValue(&jujuversion.Current, coretesting.FakeVersionNumber)
    64  	s.PatchValue(&arch.HostArch, func() string { return arch.AMD64 })
    65  	s.PatchValue(&series.HostSeries, func() string { return series.LatestLts() })
    66  }
    67  
    68  func (s *baseProviderSuite) TearDownTest(c *gc.C) {
    69  	s.ToolsFixture.TearDownTest(c)
    70  	s.FakeJujuXDGDataHomeSuite.TearDownTest(c)
    71  }
    72  
    73  func (s *baseProviderSuite) TearDownSuite(c *gc.C) {
    74  	s.FakeJujuXDGDataHomeSuite.TearDownSuite(c)
    75  }
    76  
    77  type providerSuite struct {
    78  	baseProviderSuite
    79  	testMAASObject *gomaasapi.TestMAASObject
    80  }
    81  
    82  func spaceJSON(space gomaasapi.CreateSpace) *bytes.Buffer {
    83  	var out bytes.Buffer
    84  	err := json.NewEncoder(&out).Encode(space)
    85  	if err != nil {
    86  		panic(err)
    87  	}
    88  	return &out
    89  }
    90  
    91  func (s *providerSuite) SetUpSuite(c *gc.C) {
    92  	s.baseProviderSuite.SetUpSuite(c)
    93  	s.testMAASObject = gomaasapi.NewTestMAAS("1.0")
    94  }
    95  
    96  func (s *providerSuite) SetUpTest(c *gc.C) {
    97  	s.baseProviderSuite.SetUpTest(c)
    98  	mockCapabilities := func(*gomaasapi.MAASObject, string) (set.Strings, error) {
    99  		return set.NewStrings("network-deployment-ubuntu"), nil
   100  	}
   101  	mockGetController := func(string, string) (gomaasapi.Controller, error) {
   102  		return nil, gomaasapi.NewUnsupportedVersionError("oops")
   103  	}
   104  	s.PatchValue(&GetCapabilities, mockCapabilities)
   105  	s.PatchValue(&GetMAAS2Controller, mockGetController)
   106  	// Creating a space ensures that the spaces endpoint won't 404.
   107  	s.testMAASObject.TestServer.NewSpace(spaceJSON(gomaasapi.CreateSpace{Name: "space-0"}))
   108  }
   109  
   110  func (s *providerSuite) TearDownTest(c *gc.C) {
   111  	s.baseProviderSuite.TearDownTest(c)
   112  	s.testMAASObject.TestServer.Clear()
   113  }
   114  
   115  func (s *providerSuite) TearDownSuite(c *gc.C) {
   116  	s.baseProviderSuite.TearDownSuite(c)
   117  	s.testMAASObject.Close()
   118  }
   119  
   120  var maasEnvAttrs = coretesting.Attrs{
   121  	"name": "test-env",
   122  	"type": "maas",
   123  	config.ResourceTagsKey: map[string]string{
   124  		"claude": "rains",
   125  	},
   126  }
   127  
   128  // makeEnviron creates a functional maasEnviron for a test.
   129  func (suite *providerSuite) makeEnviron() *maasEnviron {
   130  	cred := cloud.NewCredential(cloud.OAuth1AuthType, map[string]string{
   131  		"maas-oauth": "a:b:c",
   132  	})
   133  	cloud := environs.CloudSpec{
   134  		Type:       "maas",
   135  		Name:       "maas",
   136  		Endpoint:   suite.testMAASObject.TestServer.URL,
   137  		Credential: &cred,
   138  	}
   139  	attrs := coretesting.FakeConfig().Merge(maasEnvAttrs)
   140  	suite.controllerUUID = coretesting.FakeControllerConfig().ControllerUUID()
   141  	cfg, err := config.New(config.NoDefaults, attrs)
   142  	if err != nil {
   143  		panic(err)
   144  	}
   145  	env, err := NewEnviron(cloud, cfg)
   146  	if err != nil {
   147  		panic(err)
   148  	}
   149  	return env
   150  }
   151  
   152  func (suite *providerSuite) addNode(jsonText string) instance.Id {
   153  	node := suite.testMAASObject.TestServer.NewNode(jsonText)
   154  	resourceURI, _ := node.GetField("resource_uri")
   155  	return instance.Id(resourceURI)
   156  }
   157  
   158  func (suite *providerSuite) getInstance(systemId string) *maas1Instance {
   159  	input := fmt.Sprintf(`{"system_id": %q}`, systemId)
   160  	node := suite.testMAASObject.TestServer.NewNode(input)
   161  	statusGetter := func(instance.Id) (string, string) {
   162  		return "unknown", "FAKE"
   163  	}
   164  	return &maas1Instance{&node, nil, statusGetter}
   165  }
   166  
   167  func (suite *providerSuite) getNetwork(name string, id int, vlanTag int) *gomaasapi.MAASObject {
   168  	var vlan string
   169  	if vlanTag == 0 {
   170  		vlan = "null"
   171  	} else {
   172  		vlan = fmt.Sprintf("%d", vlanTag)
   173  	}
   174  	var input string
   175  	input = fmt.Sprintf(`{"name": %q, "ip":"192.168.%d.1", "netmask": "255.255.255.0",`+
   176  		`"vlan_tag": %s, "description": "%s_%d_%d" }`, name, id, vlan, name, id, vlanTag)
   177  	network := suite.testMAASObject.TestServer.NewNetwork(input)
   178  	return &network
   179  }
   180  
   181  func createSubnetInfo(subnetID, spaceID, ipRange uint) network.SubnetInfo {
   182  	return network.SubnetInfo{
   183  		CIDR:            fmt.Sprintf("192.168.%d.0/24", ipRange),
   184  		ProviderId:      network.Id(strconv.Itoa(int(subnetID))),
   185  		SpaceProviderId: network.Id(fmt.Sprintf("%d", spaceID)),
   186  	}
   187  }
   188  
   189  func createSubnet(ipRange, spaceAndNICID uint) gomaasapi.CreateSubnet {
   190  	space := fmt.Sprintf("space-%d", spaceAndNICID)
   191  	return createSubnetWithSpace(ipRange, spaceAndNICID, space)
   192  }
   193  
   194  func createSubnetWithSpace(ipRange, NICID uint, space string) gomaasapi.CreateSubnet {
   195  	var s gomaasapi.CreateSubnet
   196  	s.DNSServers = []string{"192.168.1.2"}
   197  	s.Name = fmt.Sprintf("maas-eth%d", NICID)
   198  	s.Space = space
   199  	s.GatewayIP = fmt.Sprintf("192.168.%v.1", ipRange)
   200  	s.CIDR = fmt.Sprintf("192.168.%v.0/24", ipRange)
   201  	return s
   202  }
   203  
   204  func (suite *providerSuite) addSubnet(c *gc.C, ipRange, spaceAndNICID uint, systemID string) uint {
   205  	space := fmt.Sprintf("space-%d", spaceAndNICID)
   206  	return suite.addSubnetWithSpace(c, ipRange, spaceAndNICID, space, systemID)
   207  }
   208  
   209  func (suite *providerSuite) addSubnetWithSpace(c *gc.C, ipRange, NICID uint, space string, systemID string) uint {
   210  	out := bytes.Buffer{}
   211  	err := json.NewEncoder(&out).Encode(createSubnetWithSpace(ipRange, NICID, space))
   212  	c.Assert(err, jc.ErrorIsNil)
   213  	subnet := suite.testMAASObject.TestServer.NewSubnet(&out)
   214  	c.Assert(err, jc.ErrorIsNil)
   215  
   216  	other := gomaasapi.AddressRange{}
   217  	other.Start = fmt.Sprintf("192.168.%d.139", ipRange)
   218  	other.End = fmt.Sprintf("192.168.%d.149", ipRange)
   219  	other.Purpose = []string{"not-the-dynamic-range"}
   220  	suite.testMAASObject.TestServer.AddFixedAddressRange(subnet.ID, other)
   221  
   222  	ar := gomaasapi.AddressRange{}
   223  	ar.Start = fmt.Sprintf("192.168.%d.10", ipRange)
   224  	ar.End = fmt.Sprintf("192.168.%d.138", ipRange)
   225  	ar.Purpose = []string{"something", "dynamic-range"}
   226  	suite.testMAASObject.TestServer.AddFixedAddressRange(subnet.ID, ar)
   227  	if systemID != "" {
   228  		var nni gomaasapi.NodeNetworkInterface
   229  		nni.Name = subnet.Name
   230  		nni.Links = append(nni.Links, gomaasapi.NetworkLink{
   231  			ID:     uint(1),
   232  			Mode:   "auto",
   233  			Subnet: subnet,
   234  		})
   235  		suite.testMAASObject.TestServer.SetNodeNetworkLink(systemID, nni)
   236  	}
   237  	return subnet.ID
   238  }