cfg.StrOpt('heat_metadata_server_url',
default="",
help='URL of the Heat metadata server'),
+cfg.StrOpt('heat_stack_user_role',
+ default="heat_stack_user",
+ help='Keystone role for heat template-defined users'),
]
db_opts = [
cfg.StrOpt('sql_connection',
import eventlet
from heat.common import exception
+from heat.openstack.common import cfg
from heat.engine.resources import Resource
from heat.openstack.common import log as logging
enabled=True)
self.instance_id_set(user.id)
+ # We add the new user to a special keystone role
+ # This role is designed to allow easier differentiation of the
+ # heat-generated "stack users" which will generally have credentials
+ # deployed on an instance (hence are implicitly untrusted)
+ roles = self.keystone().roles.list()
+ stack_user_role = [r.id for r in roles
+ if r.name == cfg.CONF.heat_stack_user_role]
+ if len(stack_user_role) == 1:
+ role_id = stack_user_role[0]
+ logger.debug("Adding user %s to role %s" % (user.id, role_id))
+ self.keystone().roles.add_user_role(user.id, role_id, tenant_id)
+ else:
+ logger.error("Failed to add user %s to role %s, check role exists!"
+ % (self.physical_resource_name(),
+ cfg.CONF.heat_stack_user_role))
+
def handle_update(self):
return self.UPDATE_REPLACE
from nose.plugins.attrib import attr
from heat.common import exception
+from heat.common import config
from heat.engine import parser
from heat.engine import user
from heat.tests.v1_1 import fakes
from keystoneclient.v2_0 import users
+from keystoneclient.v2_0 import roles
from keystoneclient.v2_0 import ec2
+from heat.openstack.common import cfg
@attr(tag=['unit', 'resource'])
self.m = mox.Mox()
self.fc = fakes.FakeClient()
self.fc.users = users.UserManager(None)
+ self.fc.roles = roles.RoleManager(None)
self.fc.ec2 = ec2.CredentialsManager(None)
self.m.StubOutWithMock(user.User, 'keystone')
self.m.StubOutWithMock(user.AccessKey, 'keystone')
self.m.StubOutWithMock(self.fc.users, 'get')
self.m.StubOutWithMock(self.fc.users, 'delete')
self.m.StubOutWithMock(self.fc.users, 'list')
+ self.m.StubOutWithMock(self.fc.roles, 'list')
+ self.m.StubOutWithMock(self.fc.roles, 'add_user_role')
self.m.StubOutWithMock(self.fc.ec2, 'create')
self.m.StubOutWithMock(self.fc.ec2, 'get')
self.m.StubOutWithMock(self.fc.ec2, 'delete')
self.m.StubOutWithMock(eventlet, 'sleep')
+ config.register_engine_opts()
+ cfg.CONF.set_default('heat_stack_user_role', 'stack_user_role')
def tearDown(self):
self.m.UnsetStubs()
enabled=True,
tenant_id='test_tenant').AndReturn(fake_user)
+ fake_role = roles.Role(self.fc.roles, {'id': '123',
+ 'name': 'stack_user_role'})
+ user.User.keystone().AndReturn(self.fc)
+ self.fc.roles.list().AndReturn([fake_role])
+
+ user.User.keystone().AndReturn(self.fc)
+ self.fc.roles.add_user_role('1', '123', 'test_tenant').AndReturn(None)
+
# delete script
user.User.keystone().AndReturn(self.fc)
self.fc.users.get(user.DummyId('1')).AndRaise(Exception('not found'))