diff --git a/api-ref/source/v2-admin/admin-tenants.inc b/api-ref/source/v2-admin/admin-tenants.inc index 1f228a1674..d61b35668f 100644 --- a/api-ref/source/v2-admin/admin-tenants.inc +++ b/api-ref/source/v2-admin/admin-tenants.inc @@ -5,41 +5,6 @@ Tenants ======= -Show tenant details, by ID -========================== - -.. rest_method:: GET /v2.0/tenants/{tenantId} - -Shows details for a tenant, by ID. - -Normal response codes: 200,203 -Error response codes: 413,405,404,403,401,400,503 - -Request -------- - -.. rest_parameters:: parameters.yaml - - - tenantId: tenant_id_path - -Response Parameters -------------------- - -.. rest_parameters:: parameters.yaml - - - tenant: tenant - - enabled: tenant_enabled - - description: tenant_description - - name: tenant_name - - id: tenant_id - -Response Example ----------------- - -.. literalinclude:: samples/admin/tenant-show-response.json - :language: javascript - - List users on a tenant ====================== @@ -110,158 +75,3 @@ Response Example .. literalinclude:: samples/admin/roles-list-response.json :language: javascript - - -List tenants (admin endpoint) -============================= - -.. rest_method:: GET /v2.0/tenants - -Lists all tenants. - -Normal response codes: 200,203 -Error response codes: 413,405,404,403,401,400,503 - -Response Parameters -------------------- - -.. rest_parameters:: parameters.yaml - - - tenants: tenants - - tenant_links: tenant_links - - enabled: tenant_enabled - - description: tenant_description - - name: tenant_name - - id: tenant_id - -Response Example ----------------- - -.. literalinclude:: ../v2/samples/admin/tenants-list-response.json - :language: javascript - - -Show tenant details, by name -============================ - -.. rest_method:: GET /v2.0/tenants - -Shows details for a tenant, by name. - -Normal response codes: 200,203 -Error response codes: 413,405,404,403,401,400,503 - -Request -------- - -.. rest_parameters:: parameters.yaml - - - name: tenant_name_query - -Response Parameters -------------------- - -.. rest_parameters:: parameters.yaml - - - tenant: tenant - - enabled: tenant_enabled - - description: tenant_description - - name: tenant_name - - id: tenant_id - -Response Example ----------------- - -.. literalinclude:: samples/admin/tenant-show-response.json - :language: javascript - - -Delete tenant -============= - -.. rest_method:: DELETE /v2.0/tenants/{tenantId} - -Deletes a tenant. - -Normal response codes: 204 -Error response codes: 413,415,405,404,403,401,400,503,409 - -Request -------- - -.. rest_parameters:: parameters.yaml - - - tenantId: tenant_id_path - - -Update tenant -============= - -.. rest_method:: POST /v2.0/tenants/{tenantId} - -Updates a tenant. - -Normal response codes: 200 -Error response codes: 413,415,405,404,403,401,400,503,409 - -Request -------- - -.. rest_parameters:: parameters.yaml - - - tenantId: tenant_id_path - - tenant: tenant - - enabled: tenant_enabled - - description: tenant_description - - name: tenant_name - -Request Example ---------------- - -.. literalinclude:: samples/admin/tenant-update-request.json - :language: javascript - -Response Parameters -------------------- - -.. rest_parameters:: parameters.yaml - - - tenant: tenant - - enabled: tenant_enabled - - description: tenant_description - - name: tenant_name - - id: tenant_id - -Response Example ----------------- - -.. literalinclude:: samples/admin/tenant-show-response.json - :language: javascript - - -Create tenant -============= - -.. rest_method:: POST /v2.0/tenants - -Creates a tenant. - -Normal response codes: 201 -Error response codes: 413,415,405,404,403,401,400,503,409 - -Request Example ---------------- - -.. literalinclude:: samples/admin/tenantwithoutid-create-request.json - :language: javascript - -Response Parameters -------------------- - -.. rest_parameters:: parameters.yaml - - - tenant: tenant - - enabled: tenant_enabled - - description: tenant_description - - name: tenant_name - - id: tenant_id diff --git a/keystone/resource/controllers.py b/keystone/resource/controllers.py index 664b99ef4f..354c491eaf 100644 --- a/keystone/resource/controllers.py +++ b/keystone/resource/controllers.py @@ -15,8 +15,6 @@ """Workflow Logic the Resource service.""" -import uuid - from six.moves import http_client from keystone.common import controller @@ -32,93 +30,6 @@ from keystone.resource import schema CONF = keystone.conf.CONF -@dependency.requires('resource_api') -class Tenant(controller.V2Controller): - - @controller.v2_deprecated - def get_all_projects(self, request, **kw): - """Get a list of all tenants for an admin user.""" - self.assert_admin(request) - - name = request.params.get('name') - if name: - return self._get_project_by_name(name) - - try: - tenant_refs = self.resource_api.list_projects_in_domain( - CONF.identity.default_domain_id) - except exception.DomainNotFound: - # If the default domain doesn't exist then there are no V2 - # projects. - tenant_refs = [] - tenant_refs = [self.v3_to_v2_project(tenant_ref) - for tenant_ref in tenant_refs - if not tenant_ref.get('is_domain')] - params = { - 'limit': request.params.get('limit'), - 'marker': request.params.get('marker'), - } - return self.format_project_list(tenant_refs, **params) - - def _assert_not_is_domain_project(self, project_id, project_ref=None): - # Projects acting as a domain should not be visible via v2 - if not project_ref: - project_ref = self.resource_api.get_project(project_id) - if project_ref.get('is_domain'): - raise exception.ProjectNotFound(project_id) - - @controller.v2_deprecated - def get_project(self, request, tenant_id): - # TODO(termie): this stuff should probably be moved to middleware - self.assert_admin(request) - ref = self.resource_api.get_project(tenant_id) - self._assert_not_is_domain_project(tenant_id, ref) - return {'tenant': self.v3_to_v2_project(ref)} - - def _get_project_by_name(self, tenant_name): - # Projects acting as a domain should not be visible via v2 - ref = self.resource_api.get_project_by_name( - tenant_name, CONF.identity.default_domain_id) - self._assert_not_is_domain_project(ref['id'], ref) - return {'tenant': self.v3_to_v2_project(ref)} - - # CRUD Extension - @controller.v2_deprecated - def create_project(self, request, tenant): - tenant_ref = self._normalize_dict(tenant) - - validation.lazy_validate(schema.tenant_create, tenant) - self.assert_admin(request) - - self.resource_api.ensure_default_domain_exists() - - tenant_ref['id'] = tenant_ref.get('id', uuid.uuid4().hex) - tenant = self.resource_api.create_project( - tenant_ref['id'], - self._normalize_domain_id(request, tenant_ref), - initiator=request.audit_initiator) - return {'tenant': self.v3_to_v2_project(tenant)} - - @controller.v2_deprecated - def update_project(self, request, tenant_id, tenant): - validation.lazy_validate(schema.tenant_update, tenant) - self.assert_admin(request) - self._assert_not_is_domain_project(tenant_id) - - tenant_ref = self.resource_api.update_project( - tenant_id, tenant, initiator=request.audit_initiator) - return {'tenant': self.v3_to_v2_project(tenant_ref)} - - @controller.v2_deprecated - def delete_project(self, request, tenant_id): - self.assert_admin(request) - self._assert_not_is_domain_project(tenant_id) - self.resource_api.delete_project( - tenant_id, - initiator=request.audit_initiator - ) - - @dependency.requires('resource_api') class DomainV3(controller.V3Controller): collection_name = 'domains' diff --git a/keystone/resource/routers.py b/keystone/resource/routers.py index 7e8936bf30..d289b59da9 100644 --- a/keystone/resource/routers.py +++ b/keystone/resource/routers.py @@ -21,20 +21,6 @@ from keystone.common import wsgi from keystone.resource import controllers -class Admin(wsgi.ComposableRouter): - def add_routes(self, mapper): - # Tenant Operations - tenant_controller = controllers.Tenant() - mapper.connect('/tenants', - controller=tenant_controller, - action='get_all_projects', - conditions=dict(method=['GET'])) - mapper.connect('/tenants/{tenant_id}', - controller=tenant_controller, - action='get_project', - conditions=dict(method=['GET'])) - - class Routers(wsgi.RoutersBase): def append_v3_routers(self, mapper, routers): diff --git a/keystone/tests/unit/common/test_notifications.py b/keystone/tests/unit/common/test_notifications.py index 44e61f603f..d5d0764161 100644 --- a/keystone/tests/unit/common/test_notifications.py +++ b/keystone/tests/unit/common/test_notifications.py @@ -918,34 +918,6 @@ class V2Notifications(BaseNotificationTest): 'user', cadftaxonomy.SECURITY_ACCOUNT_USER) - def test_project(self): - token = self.get_scoped_token() - resp = self.admin_request( - method='POST', - path='/v2.0/tenants', - body={ - 'tenant': { - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex, - 'enabled': True - }, - }, - token=token, - ) - project_id = resp.result.get('tenant').get('id') - self._assert_initiator_data_is_set(CREATED_OPERATION, - 'project', - cadftaxonomy.SECURITY_PROJECT) - # test for delete project - self.admin_request( - method='DELETE', - path='/v2.0/tenants/%s' % project_id, - token=token, - ) - self._assert_initiator_data_is_set(DELETED_OPERATION, - 'project', - cadftaxonomy.SECURITY_PROJECT) - class TestEventCallbacks(test_v3.RestfulTestCase): diff --git a/keystone/tests/unit/resource/test_controllers.py b/keystone/tests/unit/resource/test_controllers.py deleted file mode 100644 index d835412fba..0000000000 --- a/keystone/tests/unit/resource/test_controllers.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2016 IBM Corp. -# -# 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. - -import uuid - - -import keystone.conf -from keystone import exception -from keystone.resource import controllers -from keystone.tests import unit -from keystone.tests.unit.ksfixtures import database - - -CONF = keystone.conf.CONF - - -class TenantTestCaseNoDefaultDomain(unit.TestCase): - - def setUp(self): - super(TenantTestCaseNoDefaultDomain, self).setUp() - self.useFixture(database.Database()) - self.load_backends() - self.tenant_controller = controllers.Tenant() - - def test_setup(self): - # Other tests in this class assume there's no default domain, so make - # sure the setUp worked as expected. - self.assertRaises( - exception.DomainNotFound, - self.resource_api.get_domain, CONF.identity.default_domain_id) - - def test_get_all_projects(self): - # When get_all_projects is done and there's no default domain, the - # result is an empty list. - req = self.make_request(is_admin=True) - res = self.tenant_controller.get_all_projects(req) - self.assertEqual([], res['tenants']) - - def test_create_project(self): - # When a project is created using the v2 controller and there's no - # default domain, it doesn't fail with can't find domain (a default - # domain is created) - tenant = {'name': uuid.uuid4().hex} - self.tenant_controller.create_project(self.make_request(is_admin=True), - tenant) - # If the above doesn't fail then this is successful. diff --git a/keystone/tests/unit/test_no_admin_token_auth.py b/keystone/tests/unit/test_no_admin_token_auth.py index 90e9608804..b3f4f62a56 100644 --- a/keystone/tests/unit/test_no_admin_token_auth.py +++ b/keystone/tests/unit/test_no_admin_token_auth.py @@ -55,7 +55,7 @@ class TestNoAdminTokenAuth(unit.TestCase): # Note(blk-u): Picked /v2.0/tenants because it's an operation that # requires is_admin in the context, any operation that requires # is_admin would work for this test. - REQ_PATH = '/v2.0/tenants' + REQ_PATH = '/v2.0/users' # If the following does not raise, then the test is successful. self.admin_app.get(REQ_PATH, headers={'X-Auth-Token': 'NotAdminToken'}, diff --git a/keystone/tests/unit/test_v2.py b/keystone/tests/unit/test_v2.py index 30c3fa6a77..d53a2ed07a 100644 --- a/keystone/tests/unit/test_v2.py +++ b/keystone/tests/unit/test_v2.py @@ -148,11 +148,6 @@ class CoreApiTests(object): expected_status=http_client.OK) self.assertValidAuthenticationResponse(r) - def test_get_tenants_for_token(self): - r = self.public_request(path='/v2.0/tenants', - token=self.get_scoped_token()) - self.assertValidTenantListResponse(r) - def test_validate_token(self): token = self.get_scoped_token() r = self.admin_request( @@ -245,24 +240,6 @@ class CoreApiTests(object): token=token) self.assertValidEndpointListResponse(r) - def test_get_tenant(self): - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/tenants/%(tenant_id)s' % { - 'tenant_id': self.tenant_bar['id'], - }, - token=token) - self.assertValidTenantResponse(r) - - def test_get_tenant_by_name(self): - token = self.get_scoped_token() - r = self.admin_request( - path='/v2.0/tenants?name=%(tenant_name)s' % { - 'tenant_name': self.tenant_bar['name'], - }, - token=token) - self.assertValidTenantResponse(r) - def test_get_user(self): token = self.get_scoped_token() r = self.admin_request( diff --git a/keystone/tests/unit/test_v2_controller.py b/keystone/tests/unit/test_v2_controller.py deleted file mode 100644 index fc47f5574d..0000000000 --- a/keystone/tests/unit/test_v2_controller.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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. - -import uuid - -from testtools import matchers - -from keystone.assignment import controllers as assignment_controllers -from keystone import exception -from keystone.resource import controllers as resource_controllers -from keystone.tests import unit -from keystone.tests.unit import default_fixtures -from keystone.tests.unit.ksfixtures import database - - -class TenantTestCase(unit.TestCase): - """Test for the V2 Tenant controller. - - These tests exercise :class:`keystone.assignment.controllers.Tenant`. - - """ - - def setUp(self): - super(TenantTestCase, self).setUp() - self.useFixture(database.Database()) - self.load_backends() - self.load_fixtures(default_fixtures) - self.tenant_controller = resource_controllers.Tenant() - self.assignment_tenant_controller = ( - assignment_controllers.TenantAssignment()) - - def test_list_projects_default_domain(self): - """Test that list projects only returns those in the default domain.""" - domain = unit.new_domain_ref() - self.resource_api.create_domain(domain['id'], domain) - project1 = unit.new_project_ref(domain_id=domain['id']) - self.resource_api.create_project(project1['id'], project1) - # Check the real total number of projects, we should have the: - # - tenants in the default fixtures - # - the project representing the default domain - # - the project representing the domain we created above - # - the project we created above - refs = self.resource_api.list_projects() - self.assertThat( - refs, matchers.HasLength(len(default_fixtures.TENANTS) + 3)) - - # Now list all projects using the v2 API - we should only get - # back those in the default features, since only those are in the - # default domain. - refs = self.tenant_controller.get_all_projects( - self.make_request(is_admin=True)) - self.assertEqual(len(default_fixtures.TENANTS), len(refs['tenants'])) - for tenant in default_fixtures.TENANTS: - tenant_copy = tenant.copy() - tenant_copy.pop('domain_id') - tenant_copy.pop('parent_id') - tenant_copy.pop('is_domain') - self.assertIn(tenant_copy, refs['tenants']) - - def _create_is_domain_project(self): - project = unit.new_project_ref(is_domain=True) - project_ref = self.resource_api.create_project(project['id'], project) - return self.tenant_controller.v3_to_v2_project(project_ref) - - def test_get_is_domain_project_not_found(self): - """Test that get project does not return is_domain projects.""" - project = self._create_is_domain_project() - - request = self.make_request(is_admin=True, - query_string='name=%s' % project['name']) - - self.assertRaises( - exception.ProjectNotFound, - self.tenant_controller.get_all_projects, - request) - - request = self.make_request(is_admin=True, - query_string='name=%s' % project['id']) - - self.assertRaises( - exception.ProjectNotFound, - self.tenant_controller.get_all_projects, - request) - - def test_create_is_domain_project_fails(self): - """Test that the creation of a project acting as a domain fails.""" - project = {'name': uuid.uuid4().hex, 'domain_id': 'default', - 'is_domain': True} - - self.assertRaises( - exception.ValidationError, - self.tenant_controller.create_project, - self.make_request(is_admin=True), - project) - - def test_create_project_passing_is_domain_false_fails(self): - """Test that passing is_domain=False is not allowed.""" - project = {'name': uuid.uuid4().hex, 'domain_id': 'default', - 'is_domain': False} - - self.assertRaises( - exception.ValidationError, - self.tenant_controller.create_project, - self.make_request(is_admin=True), - project) - - def test_update_is_domain_project_not_found(self): - """Test that update is_domain project is not allowed in v2.""" - project = self._create_is_domain_project() - - project['name'] = uuid.uuid4().hex - self.assertRaises( - exception.ProjectNotFound, - self.tenant_controller.update_project, - self.make_request(is_admin=True), - project['id'], - project) - - def test_delete_is_domain_project_not_found(self): - """Test that delete is_domain project is not allowed in v2.""" - project = self._create_is_domain_project() - - self.assertRaises( - exception.ProjectNotFound, - self.tenant_controller.delete_project, - self.make_request(is_admin=True), - project['id']) - - def test_list_is_domain_project_not_found(self): - """Test v2 get_all_projects having projects that act as a domain. - - In v2 no project with the is_domain flag enabled should be returned. - """ - project1 = self._create_is_domain_project() - project2 = self._create_is_domain_project() - - refs = self.tenant_controller.get_all_projects( - self.make_request(is_admin=True)) - projects = refs.get('tenants') - - self.assertNotIn(project1, projects) - self.assertNotIn(project2, projects) diff --git a/keystone/tests/unit/test_v3_auth.py b/keystone/tests/unit/test_v3_auth.py index b56fbcefef..4fe1f2ffe3 100644 --- a/keystone/tests/unit/test_v3_auth.py +++ b/keystone/tests/unit/test_v3_auth.py @@ -1708,9 +1708,9 @@ class TokenAPITests(object): '/auth/tokens', headers={'X-Subject-Token': v2_token}) # Attempting to use the deleted token on v2 should fail. - self.admin_request( - path='/v2.0/tenants', method='GET', token=v2_token, - expected_status=http_client.UNAUTHORIZED) + self._validate_token_v2( + v2_token, expected_status=http_client.NOT_FOUND + ) def test_rescoping_token(self): expires = self.v3_token_data['token']['expires_at'] diff --git a/keystone/v2_crud/admin_crud.py b/keystone/v2_crud/admin_crud.py index 90dcbbec41..9ecaa1ed18 100644 --- a/keystone/v2_crud/admin_crud.py +++ b/keystone/v2_crud/admin_crud.py @@ -16,7 +16,6 @@ from keystone import assignment from keystone.common import extension from keystone.common import wsgi from keystone import identity -from keystone import resource extension.register_admin_extension( @@ -46,27 +45,11 @@ class Router(wsgi.ComposableRouter): """ def add_routes(self, mapper): - tenant_controller = resource.controllers.Tenant() assignment_tenant_controller = ( assignment.controllers.TenantAssignment()) user_controller = identity.controllers.User() # Tenant Operations - mapper.connect( - '/tenants', - controller=tenant_controller, - action='create_project', - conditions=dict(method=['POST'])) - mapper.connect( - '/tenants/{tenant_id}', - controller=tenant_controller, - action='update_project', - conditions=dict(method=['PUT', 'POST'])) - mapper.connect( - '/tenants/{tenant_id}', - controller=tenant_controller, - action='delete_project', - conditions=dict(method=['DELETE'])) mapper.connect( '/tenants/{tenant_id}/users', controller=assignment_tenant_controller, diff --git a/keystone/version/service.py b/keystone/version/service.py index 4e70972ae4..6bd9d3658d 100644 --- a/keystone/version/service.py +++ b/keystone/version/service.py @@ -97,7 +97,6 @@ def admin_app_factory(global_conf, **local_conf): return wsgi.ComposingRouter(routes.Mapper(), [identity_routers.Admin(), token_routers.Router(), - resource_routers.Admin(), admin_crud.Router(), routers.VersionV2('admin'), routers.Extension()])