github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/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 "path/filepath" 12 "strconv" 13 "time" 14 15 "github.com/juju/gomaasapi" 16 jc "github.com/juju/testing/checkers" 17 "github.com/juju/utils" 18 "github.com/juju/utils/arch" 19 "github.com/juju/utils/series" 20 "github.com/juju/utils/set" 21 gc "gopkg.in/check.v1" 22 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/feature" 28 "github.com/juju/juju/instance" 29 "github.com/juju/juju/juju" 30 "github.com/juju/juju/network" 31 coretesting "github.com/juju/juju/testing" 32 jujuversion "github.com/juju/juju/version" 33 ) 34 35 const maas2VersionResponse = `{"version": "unknown", "subversion": "", "capabilities": ["networks-management", "static-ipaddresses", "ipv6-deployment-ubuntu", "devices-management", "storage-deployment-ubuntu", "network-deployment-ubuntu"]}` 36 37 type baseProviderSuite struct { 38 coretesting.FakeJujuXDGDataHomeSuite 39 envtesting.ToolsFixture 40 } 41 42 func (suite *baseProviderSuite) setupFakeTools(c *gc.C) { 43 suite.PatchValue(&juju.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 s.PatchValue(&nodeDeploymentTimeout, func(*maasEnviron) time.Duration { 59 return coretesting.ShortWait 60 }) 61 } 62 63 func (s *baseProviderSuite) SetUpTest(c *gc.C) { 64 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 65 s.ToolsFixture.SetUpTest(c) 66 s.PatchValue(&jujuversion.Current, coretesting.FakeVersionNumber) 67 s.PatchValue(&arch.HostArch, func() string { return arch.AMD64 }) 68 s.PatchValue(&series.HostSeries, func() string { return series.LatestLts() }) 69 s.SetFeatureFlags(feature.AddressAllocation) 70 } 71 72 func (s *baseProviderSuite) TearDownTest(c *gc.C) { 73 s.ToolsFixture.TearDownTest(c) 74 s.FakeJujuXDGDataHomeSuite.TearDownTest(c) 75 } 76 77 func (s *baseProviderSuite) TearDownSuite(c *gc.C) { 78 s.FakeJujuXDGDataHomeSuite.TearDownSuite(c) 79 } 80 81 type providerSuite struct { 82 baseProviderSuite 83 testMAASObject *gomaasapi.TestMAASObject 84 } 85 86 func spaceJSON(space gomaasapi.CreateSpace) *bytes.Buffer { 87 var out bytes.Buffer 88 err := json.NewEncoder(&out).Encode(space) 89 if err != nil { 90 panic(err) 91 } 92 return &out 93 } 94 95 const exampleAgentName = "dfb69555-0bc4-4d1f-85f2-4ee390974984" 96 97 func (s *providerSuite) SetUpSuite(c *gc.C) { 98 s.baseProviderSuite.SetUpSuite(c) 99 s.testMAASObject = gomaasapi.NewTestMAAS("1.0") 100 } 101 102 func (s *providerSuite) SetUpTest(c *gc.C) { 103 s.baseProviderSuite.SetUpTest(c) 104 mockCapabilities := func(client *gomaasapi.MAASObject) (set.Strings, error) { 105 return set.NewStrings("network-deployment-ubuntu"), nil 106 } 107 mockGetController := func(maasServer, apiKey string) (gomaasapi.Controller, error) { 108 return nil, gomaasapi.NewUnsupportedVersionError("oops") 109 } 110 s.PatchValue(&GetCapabilities, mockCapabilities) 111 s.PatchValue(&GetMAAS2Controller, mockGetController) 112 // Creating a space ensures that the spaces endpoint won't 404. 113 s.testMAASObject.TestServer.NewSpace(spaceJSON(gomaasapi.CreateSpace{Name: "space-0"})) 114 } 115 116 func (s *providerSuite) TearDownTest(c *gc.C) { 117 s.baseProviderSuite.TearDownTest(c) 118 s.testMAASObject.TestServer.Clear() 119 } 120 121 func (s *providerSuite) TearDownSuite(c *gc.C) { 122 s.baseProviderSuite.TearDownSuite(c) 123 s.testMAASObject.Close() 124 } 125 126 var maasEnvAttrs = coretesting.Attrs{ 127 "name": "test env", 128 "type": "maas", 129 "maas-oauth": "a:b:c", 130 "maas-agent-name": exampleAgentName, 131 } 132 133 // makeEnviron creates a functional maasEnviron for a test. 134 func (suite *providerSuite) makeEnviron() *maasEnviron { 135 testAttrs := coretesting.Attrs{} 136 for k, v := range maasEnvAttrs { 137 testAttrs[k] = v 138 } 139 testAttrs["maas-server"] = suite.testMAASObject.TestServer.URL 140 attrs := coretesting.FakeConfig().Merge(testAttrs) 141 cfg, err := config.New(config.NoDefaults, attrs) 142 if err != nil { 143 panic(err) 144 } 145 env, err := NewEnviron(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 AllocatableIPLow: net.ParseIP(fmt.Sprintf("192.168.%d.139", ipRange)).To4(), 186 AllocatableIPHigh: net.ParseIP(fmt.Sprintf("192.168.%d.255", ipRange)).To4(), 187 SpaceProviderId: network.Id(fmt.Sprintf("%d", spaceID)), 188 } 189 } 190 191 func createSubnet(ipRange, spaceAndNICID uint) gomaasapi.CreateSubnet { 192 space := fmt.Sprintf("space-%d", spaceAndNICID) 193 return createSubnetWithSpace(ipRange, spaceAndNICID, space) 194 } 195 196 func createSubnetWithSpace(ipRange, NICID uint, space string) gomaasapi.CreateSubnet { 197 var s gomaasapi.CreateSubnet 198 s.DNSServers = []string{"192.168.1.2"} 199 s.Name = fmt.Sprintf("maas-eth%d", NICID) 200 s.Space = space 201 s.GatewayIP = fmt.Sprintf("192.168.%v.1", ipRange) 202 s.CIDR = fmt.Sprintf("192.168.%v.0/24", ipRange) 203 return s 204 } 205 206 func (suite *providerSuite) addSubnet(c *gc.C, ipRange, spaceAndNICID uint, systemID string) uint { 207 space := fmt.Sprintf("space-%d", spaceAndNICID) 208 return suite.addSubnetWithSpace(c, ipRange, spaceAndNICID, space, systemID) 209 } 210 211 func (suite *providerSuite) addSubnetWithSpace(c *gc.C, ipRange, NICID uint, space string, systemID string) uint { 212 out := bytes.Buffer{} 213 err := json.NewEncoder(&out).Encode(createSubnetWithSpace(ipRange, NICID, space)) 214 c.Assert(err, jc.ErrorIsNil) 215 subnet := suite.testMAASObject.TestServer.NewSubnet(&out) 216 c.Assert(err, jc.ErrorIsNil) 217 218 other := gomaasapi.AddressRange{} 219 other.Start = fmt.Sprintf("192.168.%d.139", ipRange) 220 other.End = fmt.Sprintf("192.168.%d.149", ipRange) 221 other.Purpose = []string{"not-the-dynamic-range"} 222 suite.testMAASObject.TestServer.AddFixedAddressRange(subnet.ID, other) 223 224 ar := gomaasapi.AddressRange{} 225 ar.Start = fmt.Sprintf("192.168.%d.10", ipRange) 226 ar.End = fmt.Sprintf("192.168.%d.138", ipRange) 227 ar.Purpose = []string{"something", "dynamic-range"} 228 suite.testMAASObject.TestServer.AddFixedAddressRange(subnet.ID, ar) 229 if systemID != "" { 230 var nni gomaasapi.NodeNetworkInterface 231 nni.Name = subnet.Name 232 nni.Links = append(nni.Links, gomaasapi.NetworkLink{ 233 ID: uint(1), 234 Mode: "auto", 235 Subnet: subnet, 236 }) 237 suite.testMAASObject.TestServer.SetNodeNetworkLink(systemID, nni) 238 } 239 return subnet.ID 240 }