1
// Copyright 2013 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
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"
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"
34
const maas2VersionResponse = `{"version": "unknown", "subversion": "", "capabilities": ["networks-management", "static-ipaddresses", "ipv6-deployment-ubuntu", "devices-management", "storage-deployment-ubuntu", "network-deployment-ubuntu"]}`
36
type baseProviderSuite struct {
37
coretesting.FakeJujuXDGDataHomeSuite
38
envtesting.ToolsFixture
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")
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()
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() })
68
func (s *baseProviderSuite) TearDownTest(c *gc.C) {
69
s.ToolsFixture.TearDownTest(c)
70
s.FakeJujuXDGDataHomeSuite.TearDownTest(c)
73
func (s *baseProviderSuite) TearDownSuite(c *gc.C) {
74
s.FakeJujuXDGDataHomeSuite.TearDownSuite(c)
77
type providerSuite struct {
79
testMAASObject *gomaasapi.TestMAASObject
82
func spaceJSON(space gomaasapi.CreateSpace) *bytes.Buffer {
84
err := json.NewEncoder(&out).Encode(space)
91
func (s *providerSuite) SetUpSuite(c *gc.C) {
92
s.baseProviderSuite.SetUpSuite(c)
93
s.testMAASObject = gomaasapi.NewTestMAAS("1.0")
96
func (s *providerSuite) SetUpTest(c *gc.C) {
97
s.baseProviderSuite.SetUpTest(c)
98
mockCapabilities := func(client *gomaasapi.MAASObject) (set.Strings, error) {
99
return set.NewStrings("network-deployment-ubuntu"), nil
101
mockGetController := func(maasServer, apiKey string) (gomaasapi.Controller, error) {
102
return nil, gomaasapi.NewUnsupportedVersionError("oops")
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"}))
110
func (s *providerSuite) TearDownTest(c *gc.C) {
111
s.baseProviderSuite.TearDownTest(c)
112
s.testMAASObject.TestServer.Clear()
115
func (s *providerSuite) TearDownSuite(c *gc.C) {
116
s.baseProviderSuite.TearDownSuite(c)
117
s.testMAASObject.Close()
120
var maasEnvAttrs = coretesting.Attrs{
125
// makeEnviron creates a functional maasEnviron for a test.
126
func (suite *providerSuite) makeEnviron() *maasEnviron {
127
cred := cloud.NewCredential(cloud.OAuth1AuthType, map[string]string{
128
"maas-oauth": "a:b:c",
130
cloud := environs.CloudSpec{
133
Endpoint: suite.testMAASObject.TestServer.URL,
136
attrs := coretesting.FakeConfig().Merge(maasEnvAttrs)
137
suite.controllerUUID = coretesting.FakeControllerConfig().ControllerUUID()
138
cfg, err := config.New(config.NoDefaults, attrs)
142
env, err := NewEnviron(cloud, cfg)
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)
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"
161
return &maas1Instance{&node, nil, statusGetter}
164
func (suite *providerSuite) getNetwork(name string, id int, vlanTag int) *gomaasapi.MAASObject {
169
vlan = fmt.Sprintf("%d", vlanTag)
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)
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
SpaceProviderId: network.Id(fmt.Sprintf("%d", spaceID)),
186
func createSubnet(ipRange, spaceAndNICID uint) gomaasapi.CreateSubnet {
187
space := fmt.Sprintf("space-%d", spaceAndNICID)
188
return createSubnetWithSpace(ipRange, spaceAndNICID, space)
191
func createSubnetWithSpace(ipRange, NICID uint, space string) gomaasapi.CreateSubnet {
192
var s gomaasapi.CreateSubnet
193
s.DNSServers = []string{"192.168.1.2"}
194
s.Name = fmt.Sprintf("maas-eth%d", NICID)
196
s.GatewayIP = fmt.Sprintf("192.168.%v.1", ipRange)
197
s.CIDR = fmt.Sprintf("192.168.%v.0/24", ipRange)
201
func (suite *providerSuite) addSubnet(c *gc.C, ipRange, spaceAndNICID uint, systemID string) uint {
202
space := fmt.Sprintf("space-%d", spaceAndNICID)
203
return suite.addSubnetWithSpace(c, ipRange, spaceAndNICID, space, systemID)
206
func (suite *providerSuite) addSubnetWithSpace(c *gc.C, ipRange, NICID uint, space string, systemID string) uint {
207
out := bytes.Buffer{}
208
err := json.NewEncoder(&out).Encode(createSubnetWithSpace(ipRange, NICID, space))
209
c.Assert(err, jc.ErrorIsNil)
210
subnet := suite.testMAASObject.TestServer.NewSubnet(&out)
211
c.Assert(err, jc.ErrorIsNil)
213
other := gomaasapi.AddressRange{}
214
other.Start = fmt.Sprintf("192.168.%d.139", ipRange)
215
other.End = fmt.Sprintf("192.168.%d.149", ipRange)
216
other.Purpose = []string{"not-the-dynamic-range"}
217
suite.testMAASObject.TestServer.AddFixedAddressRange(subnet.ID, other)
219
ar := gomaasapi.AddressRange{}
220
ar.Start = fmt.Sprintf("192.168.%d.10", ipRange)
221
ar.End = fmt.Sprintf("192.168.%d.138", ipRange)
222
ar.Purpose = []string{"something", "dynamic-range"}
223
suite.testMAASObject.TestServer.AddFixedAddressRange(subnet.ID, ar)
225
var nni gomaasapi.NodeNetworkInterface
226
nni.Name = subnet.Name
227
nni.Links = append(nni.Links, gomaasapi.NetworkLink{
232
suite.testMAASObject.TestServer.SetNodeNetworkLink(systemID, nni)