github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/provider/maas/environ_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package maas_test 5 6 import ( 7 stdtesting "testing" 8 9 "github.com/juju/gomaasapi" 10 jc "github.com/juju/testing/checkers" 11 "github.com/juju/utils/set" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/environs/config" 15 envtesting "github.com/juju/juju/environs/testing" 16 "github.com/juju/juju/provider/maas" 17 coretesting "github.com/juju/juju/testing" 18 ) 19 20 type environSuite struct { 21 coretesting.BaseSuite 22 envtesting.ToolsFixture 23 testMAASObject *gomaasapi.TestMAASObject 24 restoreTimeouts func() 25 } 26 27 var _ = gc.Suite(&environSuite{}) 28 29 func TestMAAS(t *stdtesting.T) { 30 gc.TestingT(t) 31 } 32 33 // TDOO: jam 2013-12-06 This is copied from the providerSuite which is in a 34 // whitebox package maas. Either move that into a whitebox test so it can be 35 // shared, or into a 'testing' package so we can use it here. 36 func (s *environSuite) SetUpSuite(c *gc.C) { 37 s.restoreTimeouts = envtesting.PatchAttemptStrategies(maas.ShortAttempt) 38 s.BaseSuite.SetUpSuite(c) 39 TestMAASObject := gomaasapi.NewTestMAAS("1.0") 40 s.testMAASObject = TestMAASObject 41 } 42 43 func (s *environSuite) SetUpTest(c *gc.C) { 44 s.BaseSuite.SetUpTest(c) 45 s.ToolsFixture.SetUpTest(c) 46 47 mockCapabilities := func(client *gomaasapi.MAASObject) (set.Strings, error) { 48 return set.NewStrings("network-deployment-ubuntu"), nil 49 } 50 mockGetController := func(maasServer, apiKey string) (gomaasapi.Controller, error) { 51 return nil, gomaasapi.NewUnsupportedVersionError("oops") 52 } 53 s.PatchValue(&maas.GetCapabilities, mockCapabilities) 54 s.PatchValue(&maas.GetMAAS2Controller, mockGetController) 55 } 56 57 func (s *environSuite) TearDownTest(c *gc.C) { 58 s.testMAASObject.TestServer.Clear() 59 s.ToolsFixture.TearDownTest(c) 60 s.BaseSuite.TearDownTest(c) 61 } 62 63 func (s *environSuite) TearDownSuite(c *gc.C) { 64 s.testMAASObject.Close() 65 s.restoreTimeouts() 66 s.BaseSuite.TearDownSuite(c) 67 } 68 69 func getSimpleTestConfig(c *gc.C, extraAttrs coretesting.Attrs) *config.Config { 70 attrs := coretesting.FakeConfig() 71 attrs["type"] = "maas" 72 attrs["maas-server"] = "http://maas.testing.invalid" 73 attrs["maas-oauth"] = "a:b:c" 74 for k, v := range extraAttrs { 75 attrs[k] = v 76 } 77 cfg, err := config.New(config.NoDefaults, attrs) 78 c.Assert(err, jc.ErrorIsNil) 79 return cfg 80 } 81 82 func (*environSuite) TestSetConfigValidatesFirst(c *gc.C) { 83 // SetConfig() validates the config change and disallows, for example, 84 // changes in the environment name. 85 oldCfg := getSimpleTestConfig(c, coretesting.Attrs{"name": "old-name"}) 86 newCfg := getSimpleTestConfig(c, coretesting.Attrs{"name": "new-name"}) 87 env, err := maas.NewEnviron(oldCfg) 88 c.Assert(err, jc.ErrorIsNil) 89 90 // SetConfig() fails, even though both the old and the new config are 91 // individually valid. 92 err = env.SetConfig(newCfg) 93 c.Assert(err, gc.NotNil) 94 c.Check(err, gc.ErrorMatches, ".*cannot change name.*") 95 96 // The old config is still in place. The new config never took effect. 97 c.Check(env.Config().Name(), gc.Equals, "old-name") 98 } 99 100 func (*environSuite) TestSetConfigRefusesChangingAgentName(c *gc.C) { 101 oldCfg := getSimpleTestConfig(c, coretesting.Attrs{"maas-agent-name": "agent-one"}) 102 newCfgTwo := getSimpleTestConfig(c, coretesting.Attrs{"maas-agent-name": "agent-two"}) 103 env, err := maas.NewEnviron(oldCfg) 104 c.Assert(err, jc.ErrorIsNil) 105 106 // SetConfig() fails, even though both the old and the new config are 107 // individually valid. 108 err = env.SetConfig(newCfgTwo) 109 c.Assert(err, gc.NotNil) 110 c.Check(err, gc.ErrorMatches, ".*cannot change maas-agent-name.*") 111 112 // The old config is still in place. The new config never took effect. 113 c.Check(maas.MAASAgentName(env), gc.Equals, "agent-one") 114 115 // It also refuses to set it to the empty string: 116 err = env.SetConfig(getSimpleTestConfig(c, coretesting.Attrs{"maas-agent-name": ""})) 117 c.Check(err, gc.ErrorMatches, ".*cannot change maas-agent-name.*") 118 119 // And to nil 120 err = env.SetConfig(getSimpleTestConfig(c, nil)) 121 c.Check(err, gc.ErrorMatches, ".*cannot change maas-agent-name.*") 122 } 123 124 func (*environSuite) TestSetConfigAllowsEmptyFromNilAgentName(c *gc.C) { 125 // bug #1256179 is that when using an older version of Juju (<1.16.2) 126 // we didn't include maas-agent-name in the database, so it was 'nil' 127 // in the OldConfig. However, when setting an environment, we would set 128 // it to "" (because maasModelConfig.Validate ensures it is a 'valid' 129 // string). We can't create that from NewEnviron or newConfig because 130 // both of them Validate the contents. 'cmd/juju/model 131 // SetEnvironmentCommand' instead uses conn.State.ModelConfig() which 132 // just reads the content of the database into a map, so we just create 133 // the map ourselves. 134 135 // Even though we use 'nil' here, it actually stores it as "" because 136 // 1.16.2 already validates the value 137 baseCfg := getSimpleTestConfig(c, coretesting.Attrs{"maas-agent-name": ""}) 138 c.Check(baseCfg.UnknownAttrs()["maas-agent-name"], gc.Equals, "") 139 env, err := maas.NewEnviron(baseCfg) 140 c.Assert(err, jc.ErrorIsNil) 141 provider := env.Provider() 142 143 attrs := coretesting.FakeConfig() 144 // These are attrs we need to make it a valid Config, but would usually 145 // be set by other infrastructure 146 attrs["type"] = "maas" 147 nilCfg, err := config.New(config.NoDefaults, attrs) 148 c.Assert(err, jc.ErrorIsNil) 149 validatedConfig, err := provider.Validate(baseCfg, nilCfg) 150 c.Assert(err, jc.ErrorIsNil) 151 c.Check(validatedConfig.UnknownAttrs()["maas-agent-name"], gc.Equals, "") 152 // However, you can't set it to an actual value if you haven't been using a value 153 valueCfg := getSimpleTestConfig(c, coretesting.Attrs{"maas-agent-name": "agent-name"}) 154 _, err = provider.Validate(valueCfg, nilCfg) 155 c.Check(err, gc.ErrorMatches, ".*cannot change maas-agent-name.*") 156 } 157 158 func (*environSuite) TestDestroyWithEmptyAgentName(c *gc.C) { 159 // Related bug #1256179, comment as above. 160 baseCfg := getSimpleTestConfig(c, coretesting.Attrs{"maas-agent-name": ""}) 161 env, err := maas.NewEnviron(baseCfg) 162 c.Assert(err, jc.ErrorIsNil) 163 164 err = env.Destroy() 165 c.Assert(err, gc.ErrorMatches, "unsafe destruction") 166 } 167 168 func (*environSuite) TestSetConfigAllowsChangingNilAgentNameToEmptyString(c *gc.C) { 169 oldCfg := getSimpleTestConfig(c, nil) 170 newCfgTwo := getSimpleTestConfig(c, coretesting.Attrs{"maas-agent-name": ""}) 171 env, err := maas.NewEnviron(oldCfg) 172 c.Assert(err, jc.ErrorIsNil) 173 174 err = env.SetConfig(newCfgTwo) 175 c.Assert(err, jc.ErrorIsNil) 176 c.Check(maas.MAASAgentName(env), gc.Equals, "") 177 } 178 179 func (*environSuite) TestSetConfigUpdatesConfig(c *gc.C) { 180 origAttrs := coretesting.Attrs{ 181 "server-name": "http://maas2.testing.invalid", 182 "maas-oauth": "a:b:c", 183 "admin-secret": "secret", 184 } 185 cfg := getSimpleTestConfig(c, origAttrs) 186 env, err := maas.NewEnviron(cfg) 187 c.Check(err, jc.ErrorIsNil) 188 c.Check(env.Config().Name(), gc.Equals, "testenv") 189 190 anotherServer := "http://maas.testing.invalid" 191 anotherOauth := "c:d:e" 192 anotherSecret := "secret2" 193 newAttrs := coretesting.Attrs{ 194 "server-name": anotherServer, 195 "maas-oauth": anotherOauth, 196 "admin-secret": anotherSecret, 197 } 198 cfg2 := getSimpleTestConfig(c, newAttrs) 199 errSetConfig := env.SetConfig(cfg2) 200 c.Check(errSetConfig, gc.IsNil) 201 c.Check(env.Config().Name(), gc.Equals, "testenv") 202 authClient, _ := gomaasapi.NewAuthenticatedClient(anotherServer, anotherOauth, "1.0") 203 maasClient := gomaasapi.NewMAAS(*authClient) 204 MAASServer := maas.GetMAASClient(env) 205 c.Check(MAASServer, gc.DeepEquals, maasClient) 206 } 207 208 func (*environSuite) TestNewEnvironSetsConfig(c *gc.C) { 209 cfg := getSimpleTestConfig(c, nil) 210 211 env, err := maas.NewEnviron(cfg) 212 213 c.Check(err, jc.ErrorIsNil) 214 c.Check(env.Config().Name(), gc.Equals, "testenv") 215 } 216 217 var expectedCloudinitConfig = []string{ 218 "set -xe", 219 "mkdir -p '/var/lib/juju'\ncat > '/var/lib/juju/MAASmachine.txt' << 'EOF'\n'hostname: testing.invalid\n'\nEOF\nchmod 0755 '/var/lib/juju/MAASmachine.txt'", 220 } 221 222 func (*environSuite) TestNewCloudinitConfig(c *gc.C) { 223 cfg := getSimpleTestConfig(c, nil) 224 env, err := maas.NewEnviron(cfg) 225 c.Assert(err, jc.ErrorIsNil) 226 modifyNetworkScript := maas.RenderEtcNetworkInterfacesScript() 227 script := expectedCloudinitConfig 228 script = append(script, modifyNetworkScript) 229 cloudcfg, err := maas.NewCloudinitConfig(env, "testing.invalid", "quantal") 230 c.Assert(err, jc.ErrorIsNil) 231 c.Assert(cloudcfg.SystemUpdate(), jc.IsTrue) 232 c.Assert(cloudcfg.RunCmds(), jc.DeepEquals, script) 233 } 234 235 func (*environSuite) TestNewCloudinitConfigWithDisabledNetworkManagement(c *gc.C) { 236 attrs := coretesting.Attrs{ 237 "disable-network-management": true, 238 } 239 cfg := getSimpleTestConfig(c, attrs) 240 env, err := maas.NewEnviron(cfg) 241 c.Assert(err, jc.ErrorIsNil) 242 cloudcfg, err := maas.NewCloudinitConfig(env, "testing.invalid", "quantal") 243 c.Assert(err, jc.ErrorIsNil) 244 c.Assert(cloudcfg.SystemUpdate(), jc.IsTrue) 245 c.Assert(cloudcfg.RunCmds(), jc.DeepEquals, expectedCloudinitConfig) 246 }