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