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 }