github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/apiserver/environmentmanager/environmentmanager_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package environmentmanager_test 5 6 import ( 7 "github.com/juju/loggo" 8 "github.com/juju/names" 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/apiserver/common" 13 "github.com/juju/juju/apiserver/environmentmanager" 14 "github.com/juju/juju/apiserver/params" 15 apiservertesting "github.com/juju/juju/apiserver/testing" 16 "github.com/juju/juju/environs" 17 "github.com/juju/juju/environs/config" 18 jujutesting "github.com/juju/juju/juju/testing" 19 // Register the providers for the field check test 20 _ "github.com/juju/juju/provider/azure" 21 _ "github.com/juju/juju/provider/ec2" 22 _ "github.com/juju/juju/provider/joyent" 23 _ "github.com/juju/juju/provider/local" 24 _ "github.com/juju/juju/provider/maas" 25 _ "github.com/juju/juju/provider/openstack" 26 "github.com/juju/juju/state" 27 coretesting "github.com/juju/juju/testing" 28 "github.com/juju/juju/version" 29 ) 30 31 type envManagerSuite struct { 32 jujutesting.JujuConnSuite 33 34 envmanager *environmentmanager.EnvironmentManagerAPI 35 resources *common.Resources 36 authoriser apiservertesting.FakeAuthorizer 37 } 38 39 var _ = gc.Suite(&envManagerSuite{}) 40 41 func (s *envManagerSuite) SetUpTest(c *gc.C) { 42 s.JujuConnSuite.SetUpTest(c) 43 s.resources = common.NewResources() 44 s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() }) 45 46 s.authoriser = apiservertesting.FakeAuthorizer{ 47 Tag: s.AdminUserTag(c), 48 } 49 50 loggo.GetLogger("juju.apiserver.environmentmanager").SetLogLevel(loggo.TRACE) 51 } 52 53 func (s *envManagerSuite) TestNewAPIAcceptsClient(c *gc.C) { 54 anAuthoriser := s.authoriser 55 anAuthoriser.Tag = names.NewUserTag("external@remote") 56 endPoint, err := environmentmanager.NewEnvironmentManagerAPI(s.State, s.resources, anAuthoriser) 57 c.Assert(err, jc.ErrorIsNil) 58 c.Assert(endPoint, gc.NotNil) 59 } 60 61 func (s *envManagerSuite) TestNewAPIRefusesNonClient(c *gc.C) { 62 anAuthoriser := s.authoriser 63 anAuthoriser.Tag = names.NewUnitTag("mysql/0") 64 endPoint, err := environmentmanager.NewEnvironmentManagerAPI(s.State, s.resources, anAuthoriser) 65 c.Assert(endPoint, gc.IsNil) 66 c.Assert(err, gc.ErrorMatches, "permission denied") 67 } 68 69 func (s *envManagerSuite) createArgs(c *gc.C, owner names.UserTag) params.EnvironmentCreateArgs { 70 return params.EnvironmentCreateArgs{ 71 OwnerTag: owner.String(), 72 Account: make(map[string]interface{}), 73 Config: map[string]interface{}{ 74 "name": "test-env", 75 "authorized-keys": "ssh-key", 76 // And to make it a valid dummy config 77 "state-server": false, 78 }, 79 } 80 } 81 82 func (s *envManagerSuite) createArgsForVersion(c *gc.C, owner names.UserTag, ver interface{}) params.EnvironmentCreateArgs { 83 params := s.createArgs(c, owner) 84 params.Config["agent-version"] = ver 85 return params 86 } 87 88 func (s *envManagerSuite) setAPIUser(c *gc.C, user names.UserTag) { 89 s.authoriser.Tag = user 90 envmanager, err := environmentmanager.NewEnvironmentManagerAPI(s.State, s.resources, s.authoriser) 91 c.Assert(err, jc.ErrorIsNil) 92 s.envmanager = envmanager 93 } 94 95 func (s *envManagerSuite) TestUserCanCreateEnvironment(c *gc.C) { 96 owner := names.NewUserTag("external@remote") 97 s.setAPIUser(c, owner) 98 env, err := s.envmanager.CreateEnvironment(s.createArgs(c, owner)) 99 c.Assert(err, jc.ErrorIsNil) 100 c.Assert(env.OwnerTag, gc.Equals, owner.String()) 101 c.Assert(env.Name, gc.Equals, "test-env") 102 } 103 104 func (s *envManagerSuite) TestAdminCanCreateEnvironmentForSomeoneElse(c *gc.C) { 105 s.setAPIUser(c, s.AdminUserTag(c)) 106 owner := names.NewUserTag("external@remote") 107 env, err := s.envmanager.CreateEnvironment(s.createArgs(c, owner)) 108 c.Assert(err, jc.ErrorIsNil) 109 c.Assert(env.OwnerTag, gc.Equals, owner.String()) 110 c.Assert(env.Name, gc.Equals, "test-env") 111 } 112 113 func (s *envManagerSuite) TestNonAdminCannotCreateEnvironmentForSomeoneElse(c *gc.C) { 114 s.setAPIUser(c, names.NewUserTag("non-admin@remote")) 115 owner := names.NewUserTag("external@remote") 116 _, err := s.envmanager.CreateEnvironment(s.createArgs(c, owner)) 117 c.Assert(err, gc.ErrorMatches, "permission denied") 118 } 119 120 func (s *envManagerSuite) TestRestrictedProviderFields(c *gc.C) { 121 s.setAPIUser(c, names.NewUserTag("non-admin@remote")) 122 for i, test := range []struct { 123 provider string 124 expected []string 125 }{ 126 { 127 provider: "azure", 128 expected: []string{ 129 "type", "ca-cert", "state-port", "api-port", "syslog-port", "rsyslog-ca-cert", "rsyslog-ca-key", 130 "location"}, 131 }, { 132 provider: "dummy", 133 expected: []string{ 134 "type", "ca-cert", "state-port", "api-port", "syslog-port", "rsyslog-ca-cert", "rsyslog-ca-key"}, 135 }, { 136 provider: "joyent", 137 expected: []string{ 138 "type", "ca-cert", "state-port", "api-port", "syslog-port", "rsyslog-ca-cert", "rsyslog-ca-key"}, 139 }, { 140 provider: "local", 141 expected: []string{ 142 "type", "ca-cert", "state-port", "api-port", "syslog-port", "rsyslog-ca-cert", "rsyslog-ca-key", 143 "container", "network-bridge", "root-dir"}, 144 }, { 145 provider: "maas", 146 expected: []string{ 147 "type", "ca-cert", "state-port", "api-port", "syslog-port", "rsyslog-ca-cert", "rsyslog-ca-key", 148 "maas-server"}, 149 }, { 150 provider: "openstack", 151 expected: []string{ 152 "type", "ca-cert", "state-port", "api-port", "syslog-port", "rsyslog-ca-cert", "rsyslog-ca-key", 153 "region", "auth-url", "auth-mode"}, 154 }, { 155 provider: "ec2", 156 expected: []string{ 157 "type", "ca-cert", "state-port", "api-port", "syslog-port", "rsyslog-ca-cert", "rsyslog-ca-key", 158 "region"}, 159 }, 160 } { 161 c.Logf("%d: %s provider", i, test.provider) 162 fields, err := environmentmanager.RestrictedProviderFields(s.envmanager, test.provider) 163 c.Check(err, jc.ErrorIsNil) 164 c.Check(fields, jc.SameContents, test.expected) 165 } 166 } 167 168 func (s *envManagerSuite) TestConfigSkeleton(c *gc.C) { 169 s.setAPIUser(c, names.NewUserTag("non-admin@remote")) 170 171 _, err := s.envmanager.ConfigSkeleton( 172 params.EnvironmentSkeletonConfigArgs{Provider: "ec2"}) 173 c.Check(err, gc.ErrorMatches, `provider value "ec2" not valid`) 174 _, err = s.envmanager.ConfigSkeleton( 175 params.EnvironmentSkeletonConfigArgs{Region: "the sun"}) 176 c.Check(err, gc.ErrorMatches, `region value "the sun" not valid`) 177 178 skeleton, err := s.envmanager.ConfigSkeleton(params.EnvironmentSkeletonConfigArgs{}) 179 c.Assert(err, jc.ErrorIsNil) 180 181 // The apiPort changes every test run as the dummy provider 182 // looks for a random open port. 183 apiPort := s.Environ.Config().APIPort() 184 185 c.Assert(skeleton.Config, jc.DeepEquals, params.EnvironConfig{ 186 "type": "dummy", 187 "ca-cert": coretesting.CACert, 188 "state-port": 1234, 189 "api-port": apiPort, 190 "syslog-port": 2345, 191 }) 192 } 193 194 func (s *envManagerSuite) TestCreateEnvironmentValidatesConfig(c *gc.C) { 195 admin := s.AdminUserTag(c) 196 s.setAPIUser(c, admin) 197 args := s.createArgs(c, admin) 198 delete(args.Config, "state-server") 199 _, err := s.envmanager.CreateEnvironment(args) 200 c.Assert(err, gc.ErrorMatches, "provider validation failed: state-server: expected bool, got nothing") 201 } 202 203 func (s *envManagerSuite) TestCreateEnvironmentBadConfig(c *gc.C) { 204 owner := names.NewUserTag("external@remote") 205 s.setAPIUser(c, owner) 206 for i, test := range []struct { 207 key string 208 value interface{} 209 errMatch string 210 }{ 211 { 212 key: "uuid", 213 value: "anything", 214 errMatch: `uuid is generated, you cannot specify one`, 215 }, { 216 key: "type", 217 value: "fake", 218 errMatch: `specified type "fake" does not match apiserver "dummy"`, 219 }, { 220 key: "ca-cert", 221 value: coretesting.OtherCACert, 222 errMatch: `(?s)specified ca-cert ".*" does not match apiserver ".*"`, 223 }, { 224 key: "state-port", 225 value: 9876, 226 errMatch: `specified state-port "9876" does not match apiserver "1234"`, 227 }, { 228 // The api-port is dynamic, but always in user-space, so > 1024. 229 key: "api-port", 230 value: 123, 231 errMatch: `specified api-port "123" does not match apiserver ".*"`, 232 }, { 233 key: "syslog-port", 234 value: 1234, 235 errMatch: `specified syslog-port "1234" does not match apiserver "2345"`, 236 }, { 237 key: "rsyslog-ca-cert", 238 value: "some-cert", 239 errMatch: `specified rsyslog-ca-cert "some-cert" does not match apiserver ".*"`, 240 }, { 241 key: "rsyslog-ca-key", 242 value: "some-key", 243 errMatch: `specified rsyslog-ca-key "some-key" does not match apiserver ".*"`, 244 }, 245 } { 246 c.Logf("%d: %s", i, test.key) 247 args := s.createArgs(c, owner) 248 args.Config[test.key] = test.value 249 _, err := s.envmanager.CreateEnvironment(args) 250 c.Assert(err, gc.ErrorMatches, test.errMatch) 251 252 } 253 } 254 255 func (s *envManagerSuite) TestCreateEnvironmentSameAgentVersion(c *gc.C) { 256 admin := s.AdminUserTag(c) 257 s.setAPIUser(c, admin) 258 args := s.createArgsForVersion(c, admin, version.Current.Number.String()) 259 _, err := s.envmanager.CreateEnvironment(args) 260 c.Assert(err, jc.ErrorIsNil) 261 } 262 263 func (s *envManagerSuite) TestCreateEnvironmentBadAgentVersion(c *gc.C) { 264 admin := s.AdminUserTag(c) 265 s.setAPIUser(c, admin) 266 267 bigger := version.Current.Number 268 bigger.Minor += 1 269 270 smaller := version.Current.Number 271 smaller.Minor -= 1 272 273 for i, test := range []struct { 274 value interface{} 275 errMatch string 276 }{ 277 { 278 value: 42, 279 errMatch: `creating config from values failed: agent-version: expected string, got int\(42\)`, 280 }, { 281 value: "not a number", 282 errMatch: `creating config from values failed: invalid agent version in environment configuration: "not a number"`, 283 }, { 284 value: bigger.String(), 285 errMatch: "agent-version cannot be greater than the server: .*", 286 }, { 287 value: smaller.String(), 288 errMatch: "no tools found for version .*", 289 }, 290 } { 291 c.Logf("test %d", i) 292 args := s.createArgsForVersion(c, admin, test.value) 293 _, err := s.envmanager.CreateEnvironment(args) 294 c.Check(err, gc.ErrorMatches, test.errMatch) 295 } 296 } 297 298 func (s *envManagerSuite) TestListEnvironmentsForSelf(c *gc.C) { 299 user := names.NewUserTag("external@remote") 300 s.setAPIUser(c, user) 301 result, err := s.envmanager.ListEnvironments(params.Entity{user.String()}) 302 c.Assert(err, jc.ErrorIsNil) 303 c.Assert(result.Environments, gc.HasLen, 0) 304 } 305 306 func (s *envManagerSuite) checkEnvironmentMatches(c *gc.C, env params.Environment, expected *state.Environment) { 307 c.Check(env.Name, gc.Equals, expected.Name()) 308 c.Check(env.UUID, gc.Equals, expected.UUID()) 309 c.Check(env.OwnerTag, gc.Equals, expected.Owner().String()) 310 } 311 312 func (s *envManagerSuite) TestListEnvironmentsAdminSelf(c *gc.C) { 313 user := s.AdminUserTag(c) 314 s.setAPIUser(c, user) 315 result, err := s.envmanager.ListEnvironments(params.Entity{user.String()}) 316 c.Assert(err, jc.ErrorIsNil) 317 c.Assert(result.Environments, gc.HasLen, 1) 318 expected, err := s.State.Environment() 319 c.Assert(err, jc.ErrorIsNil) 320 s.checkEnvironmentMatches(c, result.Environments[0], expected) 321 } 322 323 func (s *envManagerSuite) TestListEnvironmentsAdminListsOther(c *gc.C) { 324 user := s.AdminUserTag(c) 325 s.setAPIUser(c, user) 326 other := names.NewUserTag("external@remote") 327 result, err := s.envmanager.ListEnvironments(params.Entity{other.String()}) 328 c.Assert(err, jc.ErrorIsNil) 329 c.Assert(result.Environments, gc.HasLen, 0) 330 } 331 332 func (s *envManagerSuite) TestListEnvironmentsDenied(c *gc.C) { 333 user := names.NewUserTag("external@remote") 334 s.setAPIUser(c, user) 335 other := names.NewUserTag("other@remote") 336 _, err := s.envmanager.ListEnvironments(params.Entity{other.String()}) 337 c.Assert(err, gc.ErrorMatches, "permission denied") 338 } 339 340 type fakeProvider struct { 341 environs.EnvironProvider 342 } 343 344 func (*fakeProvider) Validate(cfg, old *config.Config) (*config.Config, error) { 345 return cfg, nil 346 } 347 348 func init() { 349 environs.RegisterProvider("fake", &fakeProvider{}) 350 }