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