Change references of tenant to project
Refernces from tenant to project were made in several places, including DB, HTTP Headers, configuration items, json in responses and devstack integration. Additionally, a migration script using Alembic was included. Implements: blueprint tenant-to-project-ref Change-Id: I4b21182f555ccd412a4ca4e0ce753f07edcd07f8
This commit is contained in:
parent
9552fce675
commit
6b26ecaf75
|
@ -29,10 +29,10 @@ def ctx_from_headers(headers):
|
|||
|
||||
return context.ClimateContext(
|
||||
user_id=headers['X-User-Id'],
|
||||
tenant_id=headers['X-Tenant-Id'],
|
||||
project_id=headers['X-Project-Id'],
|
||||
auth_token=headers['X-Auth-Token'],
|
||||
service_catalog=service_catalog,
|
||||
user_name=headers['X-User-Name'],
|
||||
tenant_name=headers['X-Tenant-Name'],
|
||||
project_name=headers['X-Project-Name'],
|
||||
roles=map(unicode.strip, headers['X-Roles'].split(',')),
|
||||
)
|
||||
|
|
|
@ -36,7 +36,7 @@ CONF.import_opt('os_auth_port', 'climate.config')
|
|||
CONF.import_opt('os_auth_protocol', 'climate.config')
|
||||
CONF.import_opt('os_admin_username', 'climate.config')
|
||||
CONF.import_opt('os_admin_password', 'climate.config')
|
||||
CONF.import_opt('os_admin_tenant_name', 'climate.config')
|
||||
CONF.import_opt('os_admin_project_name', 'climate.config')
|
||||
CONF.import_opt('os_auth_version', 'climate.config')
|
||||
CONF.import_opt('log_exchange', 'climate.config')
|
||||
|
||||
|
@ -99,7 +99,7 @@ def make_app():
|
|||
auth_protocol=cfg.CONF.os_auth_protocol,
|
||||
admin_user=cfg.CONF.os_admin_username,
|
||||
admin_password=cfg.CONF.os_admin_password,
|
||||
admin_tenant_name=cfg.CONF.os_admin_tenant_name,
|
||||
admin_tenant_name=cfg.CONF.os_admin_project_name,
|
||||
auth_version=cfg.CONF.os_auth_version,
|
||||
)(app.wsgi_app)
|
||||
|
||||
|
|
|
@ -35,10 +35,10 @@ class API(object):
|
|||
"""List all existing leases."""
|
||||
ctx = context.current()
|
||||
if policy.enforce(ctx, 'admin', {}, do_raise=False):
|
||||
tenant_id = None
|
||||
project_id = None
|
||||
else:
|
||||
tenant_id = ctx.tenant_id
|
||||
return self.manager_rpcapi.list_leases(tenant_id=tenant_id)
|
||||
project_id = ctx.project_id
|
||||
return self.manager_rpcapi.list_leases(project_id=project_id)
|
||||
|
||||
@policy.authorize('leases', 'create')
|
||||
def create_lease(self, data):
|
||||
|
|
|
@ -44,7 +44,7 @@ class Lease(base._Base):
|
|||
user_id = types.UuidType()
|
||||
"The ID of the user who creates the lease"
|
||||
|
||||
tenant_id = types.UuidType()
|
||||
project_id = types.UuidType()
|
||||
"The ID of the project or tenant the lease belongs to"
|
||||
|
||||
trust_id = types.UuidType()
|
||||
|
@ -63,7 +63,7 @@ class Lease(base._Base):
|
|||
start_date=u'2014-01-01 01:23',
|
||||
end_date=u'2014-02-01 13:37',
|
||||
user_id=u'efd87807-12d2-4b38-9c70-5f5c2ac427ff',
|
||||
tenant_id=u'bd9431c1-8d69-4ad3-803a-8d4a6b89fd36',
|
||||
project_id=u'bd9431c1-8d69-4ad3-803a-8d4a6b89fd36',
|
||||
trust_id=u'35b17138-b364-4e6a-a131-8f3099c5be68',
|
||||
reservations=[{u'resource_id': u'1234',
|
||||
u'resource_type': u'virtual:instance'}],
|
||||
|
|
|
@ -43,14 +43,14 @@ os_opts = [
|
|||
cfg.StrOpt('os_admin_username',
|
||||
default='admin',
|
||||
help='This OpenStack user is used to verify provided tokens. '
|
||||
'The user must have admin role in <os_admin_tenant_name> '
|
||||
'tenant'),
|
||||
'The user must have admin role in <os_admin_project_name> '
|
||||
'project'),
|
||||
cfg.StrOpt('os_admin_password',
|
||||
default='climate',
|
||||
help='Password of the admin user'),
|
||||
cfg.StrOpt('os_admin_tenant_name',
|
||||
cfg.StrOpt('os_admin_project_name',
|
||||
default='admin',
|
||||
help='Name of tenant where the user is admin'),
|
||||
help='Name of project where the user is admin'),
|
||||
cfg.StrOpt('os_auth_version',
|
||||
default='v2.0',
|
||||
help='We use API v3 to allow trusts using.'),
|
||||
|
|
|
@ -81,11 +81,11 @@ class ClimateContext(BaseContext):
|
|||
|
||||
_elements = set([
|
||||
"user_id",
|
||||
"tenant_id",
|
||||
"project_id",
|
||||
"auth_token",
|
||||
"service_catalog",
|
||||
"user_name",
|
||||
"tenant_name",
|
||||
"project_name",
|
||||
"roles",
|
||||
"is_admin",
|
||||
])
|
||||
|
|
|
@ -156,9 +156,9 @@ def lease_get_all():
|
|||
|
||||
|
||||
@to_dict
|
||||
def lease_get_all_by_tenant(tenant_id):
|
||||
"""Return all leases in specific tenant."""
|
||||
return IMPL.lease_get_all_by_tenant(tenant_id)
|
||||
def lease_get_all_by_project(project_id):
|
||||
"""Return all leases in specific project."""
|
||||
return IMPL.lease_get_all_by_project(project_id)
|
||||
|
||||
|
||||
@to_dict
|
||||
|
@ -174,9 +174,9 @@ def lease_get(lease_id):
|
|||
|
||||
|
||||
@to_dict
|
||||
def lease_list(tenant_id=None):
|
||||
def lease_list(project_id=None):
|
||||
"""Return a list of all existing leases."""
|
||||
return IMPL.lease_list(tenant_id)
|
||||
return IMPL.lease_list(project_id)
|
||||
|
||||
|
||||
def lease_destroy(lease_id):
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
# Copyright 2014 OpenStack Foundation.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Change tenant to project
|
||||
|
||||
Revision ID: 2bcfe76b0474
|
||||
Revises: 0_1
|
||||
Create Date: 2014-03-19 18:08:50.825586
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '2bcfe76b0474'
|
||||
down_revision = '10e34bba18e8'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
engine = op.get_bind().engine
|
||||
if engine.name == 'sqlite':
|
||||
# Only for testing purposes with sqlite
|
||||
op.execute('CREATE TABLE tmp_leases as SELECT created_at, updated_at, '
|
||||
'id, name, user_id, tenant_id as project_id, start_date, '
|
||||
'end_date, trust_id FROM leases')
|
||||
op.execute('DROP TABLE leases')
|
||||
op.execute('ALTER TABLE tmp_leases RENAME TO leases')
|
||||
return
|
||||
|
||||
op.alter_column('leases', 'tenant_id', name='project_id',
|
||||
existing_type=sa.String(length=255))
|
||||
|
||||
|
||||
def downgrade():
|
||||
engine = op.get_bind().engine
|
||||
if engine.name == 'sqlite':
|
||||
# Only for testing purposes with sqlite
|
||||
op.execute('CREATE TABLE tmp_leases as SELECT created_at, updated_at, '
|
||||
'id, name, user_id, project_id as tenant_id, start_date, '
|
||||
'end_date, trust_id FROM leases')
|
||||
op.execute('DROP TABLE leases')
|
||||
op.execute('ALTER TABLE tmp_leases RENAME TO leases')
|
||||
return
|
||||
|
||||
op.alter_column('leases', 'project_id', name='tenant_id',
|
||||
existing_type=sa.String(length=255))
|
|
@ -48,7 +48,7 @@ def model_query(model, session=None):
|
|||
|
||||
:param model: base model to query
|
||||
:param project_only: if present and current context is user-type,
|
||||
then restrict query to match the tenant_id from current context.
|
||||
then restrict query to match the project_id from current context.
|
||||
"""
|
||||
session = session or get_session()
|
||||
|
||||
|
@ -207,7 +207,7 @@ def lease_get_all():
|
|||
return query.all()
|
||||
|
||||
|
||||
def lease_get_all_by_tenant(tenant_id):
|
||||
def lease_get_all_by_project(project_id):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
@ -215,10 +215,10 @@ def lease_get_all_by_user(user_id):
|
|||
raise NotImplementedError
|
||||
|
||||
|
||||
def lease_list(tenant_id=None):
|
||||
def lease_list(project_id=None):
|
||||
query = model_query(models.Lease, get_session())
|
||||
if tenant_id is not None:
|
||||
query = query.filter_by(tenant_id=tenant_id)
|
||||
if project_id is not None:
|
||||
query = query.filter_by(project_id=project_id)
|
||||
return query.all()
|
||||
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ class Lease(mb.ClimateBase):
|
|||
id = _id_column()
|
||||
name = sa.Column(sa.String(80), nullable=False)
|
||||
user_id = sa.Column(sa.String(255), nullable=True)
|
||||
tenant_id = sa.Column(sa.String(255), nullable=True)
|
||||
project_id = sa.Column(sa.String(255), nullable=True)
|
||||
start_date = sa.Column(sa.DateTime, nullable=False)
|
||||
end_date = sa.Column(sa.DateTime, nullable=False)
|
||||
trust_id = sa.Column(sa.String(36))
|
||||
|
|
|
@ -30,9 +30,9 @@ class ManagerRPCAPI(service.RPCClient):
|
|||
"""Get detailed info about some lease."""
|
||||
return self.call('get_lease', lease_id=lease_id)
|
||||
|
||||
def list_leases(self, tenant_id=None):
|
||||
def list_leases(self, project_id=None):
|
||||
"""List all leases."""
|
||||
return self.call('list_leases', tenant_id=tenant_id)
|
||||
return self.call('list_leases', project_id=project_id)
|
||||
|
||||
def create_lease(self, lease_values):
|
||||
"""Create lease with specified parameters."""
|
||||
|
|
|
@ -153,8 +153,8 @@ class ManagerService(service_utils.RPCServer):
|
|||
def get_lease(self, lease_id):
|
||||
return db_api.lease_get(lease_id)
|
||||
|
||||
def list_leases(self, tenant_id=None):
|
||||
return db_api.lease_list(tenant_id)
|
||||
def list_leases(self, project_id=None):
|
||||
return db_api.lease_list(project_id)
|
||||
|
||||
def create_lease(self, lease_values):
|
||||
"""Create a lease with reservations.
|
||||
|
@ -186,7 +186,7 @@ class ManagerService(service_utils.RPCServer):
|
|||
|
||||
ctx = context.current()
|
||||
lease_values['user_id'] = ctx.user_id
|
||||
lease_values['tenant_id'] = ctx.tenant_id
|
||||
lease_values['project_id'] = ctx.project_id
|
||||
lease_values['start_date'] = start_date
|
||||
lease_values['end_date'] = end_date
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@ admin_opts = [
|
|||
cfg.StrOpt('climate_password',
|
||||
default='climate_password',
|
||||
help='Password of the user for write operations'),
|
||||
cfg.StrOpt('climate_tenant_name',
|
||||
cfg.StrOpt('climate_project_name',
|
||||
default='admin',
|
||||
help='Tenant of the user for write operations'),
|
||||
help='Project of the user for write operations'),
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(admin_opts, group=RESOURCE_TYPE)
|
||||
|
|
|
@ -63,7 +63,7 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper):
|
|||
config = cfg.CONF[self.resource_type]
|
||||
self.username = config.climate_username
|
||||
self.api_key = config.climate_password
|
||||
self.project_id = config.climate_tenant_name
|
||||
self.project_id = config.climate_project_name
|
||||
|
||||
def create_reservation(self, values):
|
||||
"""Create reservation."""
|
||||
|
|
|
@ -32,7 +32,7 @@ class NovaInventory(nova.NovaClientWrapper):
|
|||
config = cfg.CONF[plugin.RESOURCE_TYPE]
|
||||
self.username = config.climate_username
|
||||
self.api_key = config.climate_password
|
||||
self.project_id = config.climate_tenant_name
|
||||
self.project_id = config.climate_project_name
|
||||
|
||||
def get_host_details(self, host):
|
||||
"""Get Nova capabilities of a single host
|
||||
|
|
|
@ -33,12 +33,12 @@ OPTS = [
|
|||
default='freepool',
|
||||
help='Name of the special aggregate where all hosts '
|
||||
'are candidate for physical host reservation'),
|
||||
cfg.StrOpt('tenant_id_key',
|
||||
default='climate:tenant',
|
||||
help='Aggregate metadata value for key matching tenant_id'),
|
||||
cfg.StrOpt('project_id_key',
|
||||
default='climate:project',
|
||||
help='Aggregate metadata value for key matching project_id'),
|
||||
cfg.StrOpt('climate_owner',
|
||||
default='climate:owner',
|
||||
help='Aggregate metadata key for knowing owner tenant_id'),
|
||||
help='Aggregate metadata key for knowing owner project_id'),
|
||||
cfg.StrOpt('climate_az_prefix',
|
||||
default='climate:',
|
||||
help='Prefix for Availability Zones created by Climate'),
|
||||
|
@ -59,7 +59,7 @@ class ReservationPool(nova.NovaClientWrapper):
|
|||
config = cfg.CONF[plugin.RESOURCE_TYPE]
|
||||
self.username = config.climate_username
|
||||
self.api_key = config.climate_password
|
||||
self.project_id = config.climate_tenant_name
|
||||
self.project_id = config.climate_project_name
|
||||
|
||||
def get_aggregate_from_name_or_id(self, aggregate_obj):
|
||||
"""Return an aggregate by name or an id."""
|
||||
|
@ -115,7 +115,7 @@ class ReservationPool(nova.NovaClientWrapper):
|
|||
'without Availability Zone' % name)
|
||||
agg = self.nova.aggregates.create(name, None)
|
||||
|
||||
meta = {self.config.climate_owner: self.ctx.tenant_id}
|
||||
meta = {self.config.climate_owner: self.ctx.project_id}
|
||||
self.nova.aggregates.set_metadata(agg, meta)
|
||||
|
||||
return agg
|
||||
|
@ -262,7 +262,7 @@ class ReservationPool(nova.NovaClientWrapper):
|
|||
def add_project(self, pool, project_id):
|
||||
"""Add a project to an aggregate."""
|
||||
|
||||
metadata = {project_id: self.config.tenant_id_key}
|
||||
metadata = {project_id: self.config.project_id_key}
|
||||
|
||||
agg = self.get_aggregate_from_name_or_id(pool)
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ def enforce(context, action, target, do_raise=True):
|
|||
``volume:attach_volume``
|
||||
:param target: dictionary representing the object of the action
|
||||
for object creation this should be a dictionary representing the
|
||||
location of the object e.g. ``{'tenant_id': context.tenant_id}``
|
||||
location of the object e.g. ``{'project_id': context.project_id}``
|
||||
:param do_raise: if True (the default), raises PolicyNotAuthorized;
|
||||
if False, returns False
|
||||
|
||||
|
@ -98,7 +98,7 @@ def authorize(extension, action=None, api='climate', ctx=None,
|
|||
@functools.wraps(func)
|
||||
def wrapped(self, *args, **kwargs):
|
||||
cur_ctx = ctx or context.current()
|
||||
tgt = target or {'tenant_id': cur_ctx.tenant_id,
|
||||
tgt = target or {'project_id': cur_ctx.project_id,
|
||||
'user_id': cur_ctx.user_id}
|
||||
if action is None:
|
||||
act = '%s:%s' % (api, extension)
|
||||
|
|
|
@ -40,15 +40,15 @@ class APITest(tests.TestCase):
|
|||
def fake_ctx_from_headers(headers):
|
||||
if not headers:
|
||||
return context.ClimateContext(
|
||||
user_id='fake', tenant_id='fake', roles=['member'])
|
||||
user_id='fake', project_id='fake', roles=['member'])
|
||||
roles = headers.get('X-Roles', six.text_type('member')).split(',')
|
||||
return context.ClimateContext(
|
||||
user_id=headers.get('X-User-Id', 'fake'),
|
||||
tenant_id=headers.get('X-Tenant-Id', 'fake'),
|
||||
project_id=headers.get('X-Project-Id', 'fake'),
|
||||
auth_token=headers.get('X-Auth-Token', None),
|
||||
service_catalog=None,
|
||||
user_name=headers.get('X-User-Name', 'fake'),
|
||||
tenant_name=headers.get('X-Tenant-Name', 'fake'),
|
||||
project_name=headers.get('X-Project-Name', 'fake'),
|
||||
roles=roles,
|
||||
)
|
||||
|
||||
|
|
|
@ -26,10 +26,10 @@ class ContextTestCase(tests.TestCase):
|
|||
super(ContextTestCase, self).setUp()
|
||||
|
||||
self.fake_headers = {u'X-User-Id': u'1',
|
||||
u'X-Tenant-Id': u'1',
|
||||
u'X-Project-Id': u'1',
|
||||
u'X-Auth-Token': u'111-111-111',
|
||||
u'X-User-Name': u'user_name',
|
||||
u'X-Tenant-Name': u'tenant_name',
|
||||
u'X-Project-Name': u'project_name',
|
||||
u'X-Roles': u'user_name0, user_name1'}
|
||||
|
||||
def test_ctx_from_headers(self):
|
||||
|
@ -40,11 +40,11 @@ class ContextTestCase(tests.TestCase):
|
|||
self.context.assert_called_once_with(user_id=u'1',
|
||||
roles=[u'user_name0',
|
||||
u'user_name1'],
|
||||
tenant_name=u'tenant_name',
|
||||
project_name=u'project_name',
|
||||
auth_token=u'111-111-111',
|
||||
service_catalog={
|
||||
u'nova': u'catalog'},
|
||||
tenant_id=u'1',
|
||||
project_id=u'1',
|
||||
user_name=u'user_name')
|
||||
|
||||
def test_ctx_from_headers_no_catalog(self):
|
||||
|
|
|
@ -32,8 +32,8 @@ def fake_lease(**kw):
|
|||
u'trust_id': kw.get('trust_id',
|
||||
u'35b17138-b364-4e6a-a131-8f3099c5be68'),
|
||||
u'user_id': kw.get('user_id', u'efd87807-12d2-4b38-9c70-5f5c2ac427ff'),
|
||||
u'tenant_id': kw.get('tenant_id',
|
||||
u'bd9431c1-8d69-4ad3-803a-8d4a6b89fd36'),
|
||||
u'project_id': kw.get('project_id',
|
||||
u'bd9431c1-8d69-4ad3-803a-8d4a6b89fd36'),
|
||||
u'reservations': kw.get('reservations', [
|
||||
{
|
||||
u'resource_id': u'1234',
|
||||
|
@ -48,7 +48,7 @@ def fake_lease_request_body(exclude=[], **kw):
|
|||
exclude.append('id')
|
||||
exclude.append('trust_id')
|
||||
exclude.append('user_id')
|
||||
exclude.append('tenant_id')
|
||||
exclude.append('project_id')
|
||||
lease_body = fake_lease(**kw)
|
||||
return dict((key, lease_body[key])
|
||||
for key in lease_body if key not in exclude)
|
||||
|
|
|
@ -115,3 +115,7 @@ class TestMigrations(migration.BaseWalkMigrationTestCase,
|
|||
|
||||
def _check_10e34bba18e8(self, engine, data):
|
||||
self.assertColumnExists(engine, 'computehosts', 'service_name')
|
||||
|
||||
def _check_2bcfe76b0474(self, engine, data):
|
||||
self.assertColumnExists(engine, 'leases', 'project_id')
|
||||
self.assertColumnNotExists(engine, 'leases', 'tenant_id')
|
||||
|
|
|
@ -79,7 +79,7 @@ def _get_fake_virt_lease_values(id=_get_fake_lease_uuid(),
|
|||
return {'id': id,
|
||||
'name': name,
|
||||
'user_id': _get_fake_random_uuid(),
|
||||
'tenant_id': _get_fake_random_uuid(),
|
||||
'project_id': _get_fake_random_uuid(),
|
||||
'start_date': start_date,
|
||||
'end_date': end_date,
|
||||
'trust': 'trust',
|
||||
|
@ -98,7 +98,7 @@ def _get_fake_phys_lease_values(id=_get_fake_lease_uuid(),
|
|||
return {'id': id,
|
||||
'name': name,
|
||||
'user_id': 'fake',
|
||||
'tenant_id': 'fake',
|
||||
'project_id': 'fake',
|
||||
'start_date': start_date,
|
||||
'end_date': end_date,
|
||||
'trust': 'trust',
|
||||
|
|
|
@ -17,7 +17,7 @@ policy_data = """
|
|||
{
|
||||
|
||||
"admin": "is_admin:True or role:admin or role:masterofuniverse",
|
||||
"admin_or_owner": "rule:admin or tenant_id:%(tenant_id)s",
|
||||
"admin_or_owner": "rule:admin or project_id:%(project_id)s",
|
||||
"default": "!",
|
||||
|
||||
"admin_api": "rule:admin",
|
||||
|
|
|
@ -36,7 +36,7 @@ class RPCAPITestCase(tests.TestCase):
|
|||
|
||||
def test_list_leases(self):
|
||||
self.manager.list_leases('fake')
|
||||
self.call.assert_called_once_with('list_leases', tenant_id='fake')
|
||||
self.call.assert_called_once_with('list_leases', project_id='fake')
|
||||
|
||||
def test_create_lease(self):
|
||||
self.manager.create_lease(self.fake_values)
|
||||
|
|
|
@ -40,13 +40,13 @@ class ReservationPoolTestCase(tests.TestCase):
|
|||
def setUp(self):
|
||||
super(ReservationPoolTestCase, self).setUp()
|
||||
self.pool_name = 'pool-name-xxx'
|
||||
self.tenant_id = 'tenant-uuid'
|
||||
self.project_id = 'project-uuid'
|
||||
self.fake_aggregate = AggregateFake(i=123,
|
||||
name='fooname',
|
||||
hosts=['host1', 'host2'])
|
||||
conf = cfg.CONF[host_plugin.RESOURCE_TYPE]
|
||||
self.freepool_name = conf.aggregate_freepool_name
|
||||
self.tenant_id_key = conf.tenant_id_key
|
||||
self.project_id_key = conf.project_id_key
|
||||
self.climate_owner = conf.climate_owner
|
||||
self.climate_az_prefix = conf.climate_az_prefix
|
||||
|
||||
|
@ -54,7 +54,7 @@ class ReservationPoolTestCase(tests.TestCase):
|
|||
name=self.freepool_name,
|
||||
hosts=['host3'])
|
||||
|
||||
self.set_context(context.ClimateContext(tenant_id=self.tenant_id))
|
||||
self.set_context(context.ClimateContext(project_id=self.project_id))
|
||||
|
||||
self.nova_client = nova_client
|
||||
self.nova = self.patch(self.nova_client, 'Client').return_value
|
||||
|
@ -115,7 +115,7 @@ class ReservationPoolTestCase(tests.TestCase):
|
|||
self.nova.aggregates.create\
|
||||
.assert_called_once_with(self.pool_name, az_name)
|
||||
|
||||
meta = {self.climate_owner: self.tenant_id}
|
||||
meta = {self.climate_owner: self.project_id}
|
||||
self.nova.aggregates.set_metadata\
|
||||
.assert_called_once_with(self.fake_aggregate, meta)
|
||||
|
||||
|
@ -311,7 +311,7 @@ class ReservationPoolTestCase(tests.TestCase):
|
|||
self.pool.add_project('pool', 'projectX')
|
||||
self.nova.aggregates.set_metadata\
|
||||
.assert_called_once_with(self.fake_aggregate.id,
|
||||
{'projectX': self.tenant_id_key})
|
||||
{'projectX': self.project_id_key})
|
||||
|
||||
def test_remove_project(self):
|
||||
self._patch_get_aggregate_from_name_or_id()
|
||||
|
|
|
@ -97,8 +97,8 @@ class TestClimateContext(tests.TestCase):
|
|||
self.assertEqual(ctx.is_admin, True)
|
||||
|
||||
def test_elevated(self):
|
||||
with context.ClimateContext(user_id="user", tenant_id="tenant"):
|
||||
with context.ClimateContext(user_id="user", project_id="project"):
|
||||
ctx = context.ClimateContext.elevated()
|
||||
self.assertEqual(ctx.user_id, "user")
|
||||
self.assertEqual(ctx.tenant_id, "tenant")
|
||||
self.assertEqual(ctx.project_id, "project")
|
||||
self.assertEqual(ctx.is_admin, True)
|
||||
|
|
|
@ -36,14 +36,15 @@ class DefaultPolicyTestCase(tests.TestCase):
|
|||
"example:exist": "!",
|
||||
"example:allowed": "@",
|
||||
"example:my_file": "role:admin or \
|
||||
tenant_id:%(tenant_id)s"
|
||||
project_id:%(project_id)s"
|
||||
}
|
||||
"""
|
||||
|
||||
self.default_rule = None
|
||||
policy.reset()
|
||||
self.read_cached_file.return_value = (True, self.rules)
|
||||
self.context = context.ClimateContext(user_id='fake', tenant_id='fake',
|
||||
self.context = context.ClimateContext(user_id='fake',
|
||||
project_id='fake',
|
||||
roles=['member'])
|
||||
|
||||
def _set_rules(self, default_rule):
|
||||
|
@ -69,8 +70,8 @@ class DefaultPolicyTestCase(tests.TestCase):
|
|||
self.assertEqual(result, True)
|
||||
|
||||
def test_templatized_enforcement(self):
|
||||
target_mine = {'tenant_id': 'fake'}
|
||||
target_not_mine = {'tenant_id': 'another'}
|
||||
target_mine = {'project_id': 'fake'}
|
||||
target_not_mine = {'project_id': 'another'}
|
||||
action = "example:my_file"
|
||||
policy.enforce(self.context, action, target_mine)
|
||||
self.assertRaises(exceptions.PolicyNotAuthorized, policy.enforce,
|
||||
|
@ -82,14 +83,15 @@ class ClimatePolicyTestCase(tests.TestCase):
|
|||
def setUp(self):
|
||||
super(ClimatePolicyTestCase, self).setUp()
|
||||
|
||||
self.context = context.ClimateContext(user_id='fake', tenant_id='fake',
|
||||
self.context = context.ClimateContext(user_id='fake',
|
||||
project_id='fake',
|
||||
roles=['member'])
|
||||
|
||||
def test_standardpolicy(self):
|
||||
target_good = {'user_id': self.context.user_id,
|
||||
'tenant_id': self.context.tenant_id}
|
||||
'project_id': self.context.project_id}
|
||||
target_wrong = {'user_id': self.context.user_id,
|
||||
'tenant_id': 'bad_tenant'}
|
||||
'project_id': 'bad_project'}
|
||||
action = "climate:leases"
|
||||
self.assertEqual(True, policy.enforce(self.context, action,
|
||||
target_good))
|
||||
|
@ -98,14 +100,14 @@ class ClimatePolicyTestCase(tests.TestCase):
|
|||
|
||||
def test_adminpolicy(self):
|
||||
target = {'user_id': self.context.user_id,
|
||||
'tenant_id': self.context.tenant_id}
|
||||
'project_id': self.context.project_id}
|
||||
action = "climate:oshosts"
|
||||
self.assertRaises(exceptions.PolicyNotAuthorized, policy.enforce,
|
||||
self.context, action, target)
|
||||
|
||||
def test_elevatedpolicy(self):
|
||||
target = {'user_id': self.context.user_id,
|
||||
'tenant_id': self.context.tenant_id}
|
||||
'project_id': self.context.project_id}
|
||||
action = "climate:oshosts"
|
||||
self.assertRaises(exceptions.PolicyNotAuthorized, policy.enforce,
|
||||
self.context, action, target)
|
||||
|
|
|
@ -39,7 +39,7 @@ class TestCKClient(tests.TestCase):
|
|||
self.username = 'fake_user'
|
||||
self.token = 'fake_token'
|
||||
self.password = 'fake_pass'
|
||||
self.tenant_name = 'fake_tenant'
|
||||
self.tenant_name = 'fake_project'
|
||||
self.auth_url = 'fake_url'
|
||||
self.trust_id = 'fake_trust'
|
||||
|
||||
|
@ -79,12 +79,13 @@ class TestCKClient(tests.TestCase):
|
|||
|
||||
self.keystone.ClimateKeystoneClient()
|
||||
|
||||
self.client.assert_called_once_with(version='3',
|
||||
username=self.ctx().user_name,
|
||||
token=self.ctx().auth_token,
|
||||
tenant_name=self.ctx().tenant_name,
|
||||
auth_url='http://fake.com/',
|
||||
endpoint='http://fake.com/')
|
||||
self.client.assert_called_once_with(
|
||||
version='3',
|
||||
username=self.ctx().user_name,
|
||||
token=self.ctx().auth_token,
|
||||
tenant_name=self.ctx().project_name,
|
||||
auth_url='http://fake.com/',
|
||||
endpoint='http://fake.com/')
|
||||
|
||||
def test_getattr(self):
|
||||
#TODO(n.s.): Will be done as soon as pypi package will be updated
|
||||
|
|
|
@ -37,7 +37,7 @@ class TestCNClient(tests.TestCase):
|
|||
self.version = '2'
|
||||
self.username = 'fake_user'
|
||||
self.api_key = self.ctx().auth_token
|
||||
self.project_id = self.ctx().tenant_id
|
||||
self.project_id = self.ctx().project_id
|
||||
self.auth_url = 'fake_auth'
|
||||
self.mgmt_url = 'fake_mgmt'
|
||||
|
||||
|
@ -68,7 +68,7 @@ class TestCNClient(tests.TestCase):
|
|||
self.client.assert_called_once_with(version=self.version,
|
||||
username=self.ctx().user_name,
|
||||
api_key=None,
|
||||
project_id=self.ctx().tenant_id,
|
||||
project_id=self.ctx().project_id,
|
||||
auth_url='http://fake.com/')
|
||||
|
||||
def test_getattr(self):
|
||||
|
|
|
@ -54,8 +54,8 @@ class TestTrusts(tests.TestCase):
|
|||
fake_ctx_dict = {'_BaseContext__values': {
|
||||
'auth_token': self.client().auth_token,
|
||||
'service_catalog': fake_item,
|
||||
'tenant_id': self.client().tenant_id,
|
||||
'tenant_name': 'admin',
|
||||
'project_id': self.client().tenant_id,
|
||||
'project_name': 'admin',
|
||||
'user_name': 'admin',
|
||||
}}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class ClimateKeystoneClient(object):
|
|||
kwargs.setdefault('version', cfg.CONF.keystone_client_version)
|
||||
if ctx is not None:
|
||||
kwargs.setdefault('username', ctx.user_name)
|
||||
kwargs.setdefault('tenant_name', ctx.tenant_name)
|
||||
kwargs.setdefault('tenant_name', ctx.project_name)
|
||||
if not kwargs.get('auth_url'):
|
||||
kwargs['auth_url'] = base.url_for(
|
||||
ctx.service_catalog, CONF.identity_service)
|
||||
|
|
|
@ -80,7 +80,7 @@ class ClimateNovaClient(object):
|
|||
if ctx is not None:
|
||||
kwargs.setdefault('username', ctx.user_name)
|
||||
kwargs.setdefault('api_key', None)
|
||||
kwargs.setdefault('project_id', ctx.tenant_id)
|
||||
kwargs.setdefault('project_id', ctx.project_id)
|
||||
kwargs.setdefault('auth_url', base.url_for(
|
||||
ctx.service_catalog, CONF.identity_service))
|
||||
|
||||
|
|
|
@ -28,14 +28,14 @@ def create_trust():
|
|||
trustee_id = keystone.ClimateKeystoneClient(
|
||||
username=CONF.os_admin_username,
|
||||
password=CONF.os_admin_password,
|
||||
tenant_name=CONF.os_admin_tenant_name).user_id
|
||||
tenant_name=CONF.os_admin_project_name).user_id
|
||||
|
||||
ctx = context.current()
|
||||
trust = client.trusts.create(trustor_user=ctx.user_id,
|
||||
trustee_user=trustee_id,
|
||||
impersonation=False,
|
||||
role_names=ctx.roles,
|
||||
project=ctx.tenant_id)
|
||||
project=ctx.project_id)
|
||||
return trust
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ def create_ctx_from_trust(trust_id):
|
|||
"""Return context built from given trust."""
|
||||
ctx = context.ClimateContext(
|
||||
user_name=CONF.os_admin_username,
|
||||
tenant_name=CONF.os_admin_tenant_name,
|
||||
project_name=CONF.os_admin_project_name,
|
||||
)
|
||||
auth_url = "%s://%s:%s/v3" % (CONF.os_auth_protocol,
|
||||
CONF.os_auth_host,
|
||||
|
@ -67,5 +67,5 @@ def create_ctx_from_trust(trust_id):
|
|||
ctx,
|
||||
auth_token=client.auth_token,
|
||||
service_catalog=client.service_catalog.catalog['catalog'],
|
||||
tenant_id=client.tenant_id,
|
||||
project_id=client.tenant_id,
|
||||
)
|
||||
|
|
|
@ -83,11 +83,11 @@ function configure_climate() {
|
|||
iniset $CLIMATE_CONF_FILE DEFAULT os_auth_port $KEYSTONE_SERVICE_PORT
|
||||
iniset $CLIMATE_CONF_FILE DEFAULT os_admin_password $SERVICE_PASSWORD
|
||||
iniset $CLIMATE_CONF_FILE DEFAULT os_admin_username climate
|
||||
iniset $CLIMATE_CONF_FILE DEFAULT os_admin_tenant_name $SERVICE_TENANT_NAME
|
||||
iniset $CLIMATE_CONF_FILE DEFAULT os_admin_project_name $SERVICE_TENANT_NAME
|
||||
|
||||
iniset $CLIMATE_CONF_FILE physical:host climate_username $CLIMATE_USER_NAME
|
||||
iniset $CLIMATE_CONF_FILE physical:host climate_password $SERVICE_PASSWORD
|
||||
iniset $CLIMATE_CONF_FILE physical:host climate_tenant_name $SERVICE_TENANT_NAME
|
||||
iniset $CLIMATE_CONF_FILE physical:host climate_project_name $SERVICE_TENANT_NAME
|
||||
iniset $CLIMATE_CONF_FILE physical:host aggregate_freepool_name $CLIMATE_FREEPOOL_NAME
|
||||
|
||||
iniset $CLIMATE_CONF_FILE DEFAULT host $HOST_IP
|
||||
|
|
|
@ -4,7 +4,7 @@ Introduction
|
|||
Idea of creating Climate originated with two different use cases:
|
||||
|
||||
* Compute host reservation (when user with admin privileges can reserve
|
||||
hardware resources that are dedicated to the sole use of a tenant)
|
||||
hardware resources that are dedicated to the sole use of a project)
|
||||
* Virtual machine (instance) reservation (when user may ask reservation service
|
||||
to provide him working VM not necessary now, but also in the future)
|
||||
|
||||
|
@ -79,7 +79,7 @@ Lease types (concepts)
|
|||
cannot be fulfilled immediately. Best-effort mechanism starts something like
|
||||
scavenger hunt trying to find resources for reservations. For compute hosts
|
||||
reservation that makes much sense, because in case there are instances
|
||||
belonging to other tenant on eligible hosts, and without them there will be
|
||||
belonging to other project on eligible hosts, and without them there will be
|
||||
possible to reserve these hosts, Climate may start instances migration.
|
||||
This operation can be timely and fairly complex and so different strategies
|
||||
may be applied depending on heuristic factors such as the number, type and
|
||||
|
|
|
@ -114,7 +114,7 @@ are mentioned.
|
|||
}
|
||||
],
|
||||
"start_date": "1234",
|
||||
"tenant_id": "tenant_id",
|
||||
"project_id": "project_id",
|
||||
"trust_id": "trust_id",
|
||||
"updated_at": null,
|
||||
"user_id": "user_id"
|
||||
|
@ -198,7 +198,7 @@ are mentioned.
|
|||
}
|
||||
],
|
||||
"start_date": "1234",
|
||||
"tenant_id": "tenant_id",
|
||||
"project_id": "project_id",
|
||||
"trust_id": "trust_id",
|
||||
"updated_at": null,
|
||||
"user_id": "user_id"
|
||||
|
@ -266,7 +266,7 @@ are mentioned.
|
|||
}
|
||||
],
|
||||
"start_date": "1234",
|
||||
"tenant_id": "tenant_id",
|
||||
"project_id": "project_id",
|
||||
"trust_id": "trust_id",
|
||||
"updated_at": null,
|
||||
"user_id": "user_id"
|
||||
|
@ -341,7 +341,7 @@ are mentioned.
|
|||
}
|
||||
],
|
||||
"start_date": "1234",
|
||||
"tenant_id": "tenant_id",
|
||||
"project_id": "project_id",
|
||||
"trust_id": "trust_id",
|
||||
"updated_at": null,
|
||||
"user_id": "user_id"
|
||||
|
|
|
@ -94,7 +94,7 @@ file using the following example:
|
|||
os_auth_protocol=<http, for example>
|
||||
os_admin_username=<username>
|
||||
os_admin_password=<password>
|
||||
os_admin_tenant_name=<tenant_name>
|
||||
os_admin_project_name=<project_name>
|
||||
|
||||
[manager]
|
||||
plugins=basic.vm.plugin,physical.host.plugin
|
||||
|
@ -108,7 +108,7 @@ file using the following example:
|
|||
on_end=on_end
|
||||
climate_username=<username>
|
||||
climate_password=<password>
|
||||
climate_tenant_name=<tenant_name>
|
||||
climate_project_name=<project_name>
|
||||
|
||||
..
|
||||
|
||||
|
|
|
@ -220,15 +220,15 @@
|
|||
#os_auth_port=35357
|
||||
|
||||
# This OpenStack user is used to verify provided tokens. The
|
||||
# user must have admin role in <os_admin_tenant_name> tenant
|
||||
# user must have admin role in <os_admin_project_name> project
|
||||
# (string value)
|
||||
#os_admin_username=admin
|
||||
|
||||
# Password of the admin user (string value)
|
||||
#os_admin_password=climate
|
||||
|
||||
# Name of tenant where the user is admin (string value)
|
||||
#os_admin_tenant_name=admin
|
||||
# Name of project where the user is admin (string value)
|
||||
#os_admin_project_name=admin
|
||||
|
||||
# We use API v3 to allow trusts using. (string value)
|
||||
#os_auth_version=v2.0
|
||||
|
@ -556,24 +556,30 @@
|
|||
# Options defined in keystoneclient.middleware.auth_token
|
||||
#
|
||||
|
||||
# Prefix to prepend at the beginning of the path (string
|
||||
# value)
|
||||
# Prefix to prepend at the beginning of the path. Deprecated,
|
||||
# use identity_uri. (string value)
|
||||
#auth_admin_prefix=
|
||||
|
||||
# Host providing the admin Identity API endpoint (string
|
||||
# value)
|
||||
# Host providing the admin Identity API endpoint. Deprecated,
|
||||
# use identity_uri. (string value)
|
||||
#auth_host=127.0.0.1
|
||||
|
||||
# Port of the admin Identity API endpoint (integer value)
|
||||
# Port of the admin Identity API endpoint. Deprecated, use
|
||||
# identity_uri. (integer value)
|
||||
#auth_port=35357
|
||||
|
||||
# Protocol of the admin Identity API endpoint(http or https)
|
||||
# (string value)
|
||||
# Protocol of the admin Identity API endpoint (http or https).
|
||||
# Deprecated, use identity_uri. (string value)
|
||||
#auth_protocol=https
|
||||
|
||||
# Complete public Identity API endpoint (string value)
|
||||
#auth_uri=<None>
|
||||
|
||||
# Complete admin Identity API endpoint. This should specify
|
||||
# the unversioned root endpoint eg. https://localhost:35357/
|
||||
# (string value)
|
||||
#identity_uri=<None>
|
||||
|
||||
# API version of the admin Identity API endpoint (string
|
||||
# value)
|
||||
#auth_version=<None>
|
||||
|
@ -722,8 +728,8 @@
|
|||
# Password of the user for write operations (string value)
|
||||
#climate_password=climate_password
|
||||
|
||||
# Tenant of the user for write operations (string value)
|
||||
#climate_tenant_name=admin
|
||||
# Project of the user for write operations (string value)
|
||||
#climate_project_name=admin
|
||||
|
||||
|
||||
#
|
||||
|
@ -743,11 +749,11 @@
|
|||
# for physical host reservation (string value)
|
||||
#aggregate_freepool_name=freepool
|
||||
|
||||
# Aggregate metadata value for key matching tenant_id (string
|
||||
# Aggregate metadata value for key matching project_id (string
|
||||
# value)
|
||||
#tenant_id_key=climate:tenant
|
||||
#project_id_key=climate:project
|
||||
|
||||
# Aggregate metadata key for knowing owner tenant_id (string
|
||||
# Aggregate metadata key for knowing owner project_id (string
|
||||
# value)
|
||||
#climate_owner=climate:owner
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"admin": "is_admin:True or role:admin or role:masterofuniverse",
|
||||
|
||||
"admin_or_owner": "rule:admin or tenant_id:%(tenant_id)s",
|
||||
"admin_or_owner": "rule:admin or project_id:%(project_id)s",
|
||||
|
||||
"default": "!",
|
||||
"admin_api": "rule:admin",
|
||||
|
|
Loading…
Reference in New Issue