From 1bd9a1e8f46b56812cb87a3faad91ecc6e865212 Mon Sep 17 00:00:00 2001 From: Maurice Schreiber Date: Fri, 19 May 2017 14:46:44 -0400 Subject: [PATCH] Add ou to security service Allows to configure in which organizational unit the share ends up APIImpact Change-Id: I70fd4e0ea7898e85dff59a927b3cb086d5e408ac Needed-By: I77d87c8e6f98054f2f02bc4202c14314ff321964 Partial-Bug: #1696669 --- api-ref/source/parameters.yaml | 15 ++++ .../security-service-create-response.json | 1 + .../security-service-show-response.json | 1 + .../security-service-update-request.json | 1 + .../security-service-update-response.json | 1 + ...urity-services-list-detailed-response.json | 2 + ...vices-list-for-share-network-response.json | 2 + api-ref/source/security-services.inc | 8 ++ manila/api/openstack/api_version_request.py | 3 +- .../openstack/rest_api_version_history.rst | 4 + manila/api/views/security_service.py | 9 ++ ...0274d20c560f_add_ou_to_security_service.py | 38 ++++++++ manila/db/sqlalchemy/models.py | 1 + manila/share/manager.py | 1 + manila/tests/api/v2/test_security_services.py | 86 +++++++++++++++++++ manila/tests/db/sqlalchemy/test_api.py | 2 + manila/tests/share/test_manager.py | 1 + ...-to-security-service-06b69615bd417d40.yaml | 5 ++ 18 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 manila/db/migrations/alembic/versions/0274d20c560f_add_ou_to_security_service.py create mode 100644 manila/tests/api/v2/test_security_services.py create mode 100644 releasenotes/notes/bug-1696669-add-ou-to-security-service-06b69615bd417d40.yaml diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index 09a12237fb..012ce6840d 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -2375,6 +2375,21 @@ security_service_name: in: body required: true type: string +security_service_ou: + description: | + The security service ou. + in: body + required: true + type: string + min_version: 2.44 +security_service_ou_request: + description: | + The security service ou. An organizational unit + can be added to specify where the share ends up. + in: body + required: false + type: string + min_version: 2.44 security_service_password: description: | The user password, if you specify a ``user``. diff --git a/api-ref/source/samples/security-service-create-response.json b/api-ref/source/samples/security-service-create-response.json index e6c9f2197c..61f892bdab 100644 --- a/api-ref/source/samples/security-service-create-response.json +++ b/api-ref/source/samples/security-service-create-response.json @@ -2,6 +2,7 @@ "security_service": { "status": "new", "domain": null, + "ou": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ1", "created_at": "2015-09-07T12:19:10.695211", diff --git a/api-ref/source/samples/security-service-show-response.json b/api-ref/source/samples/security-service-show-response.json index 6391b0d75b..c85849cd9f 100644 --- a/api-ref/source/samples/security-service-show-response.json +++ b/api-ref/source/samples/security-service-show-response.json @@ -2,6 +2,7 @@ "security_service": { "status": "new", "domain": null, + "ou": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ1", "created_at": "2015-09-07T12:19:10.000000", diff --git a/api-ref/source/samples/security-service-update-request.json b/api-ref/source/samples/security-service-update-request.json index 4bf480308b..328e9383a3 100644 --- a/api-ref/source/samples/security-service-update-request.json +++ b/api-ref/source/samples/security-service-update-request.json @@ -1,6 +1,7 @@ { "security_service": { "domain": "my_domain", + "ou": "CN=Computers", "password": "***", "user": "new_user", "description": "Adding a description" diff --git a/api-ref/source/samples/security-service-update-response.json b/api-ref/source/samples/security-service-update-response.json index 7647800e96..e963542809 100644 --- a/api-ref/source/samples/security-service-update-response.json +++ b/api-ref/source/samples/security-service-update-response.json @@ -2,6 +2,7 @@ "security_service": { "status": "new", "domain": "my_domain", + "ou": "CN=Computers", "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ1", "created_at": "2015-09-07T12:19:10.000000", diff --git a/api-ref/source/samples/security-services-list-detailed-response.json b/api-ref/source/samples/security-services-list-detailed-response.json index a593bea0f6..956092b476 100644 --- a/api-ref/source/samples/security-services-list-detailed-response.json +++ b/api-ref/source/samples/security-services-list-detailed-response.json @@ -3,6 +3,7 @@ { "status": "new", "domain": null, + "ou": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ1", "created_at": "2015-09-07T12:19:10.000000", @@ -19,6 +20,7 @@ { "status": "new", "domain": null, + "ou": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ2", "created_at": "2015-09-07T12:25:03.000000", diff --git a/api-ref/source/samples/security-services-list-for-share-network-response.json b/api-ref/source/samples/security-services-list-for-share-network-response.json index 8abfabd804..5f42fe15c1 100644 --- a/api-ref/source/samples/security-services-list-for-share-network-response.json +++ b/api-ref/source/samples/security-services-list-for-share-network-response.json @@ -3,6 +3,7 @@ { "status": "new", "domain": null, + "ou": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ1", "created_at": "2015-09-07T12:19:10.000000", @@ -21,6 +22,7 @@ { "status": "new", "domain": null, + "ou": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ2", "created_at": "2015-09-07T12:25:03.000000", diff --git a/api-ref/source/security-services.inc b/api-ref/source/security-services.inc index dbe1973fb5..b974bab8d3 100644 --- a/api-ref/source/security-services.inc +++ b/api-ref/source/security-services.inc @@ -27,6 +27,8 @@ You can configure a security service with these options: - A domain. +- An ou, the organizational unit. (available starting with API version 2.44) + - A user or group name. - The password for the user, if you specify a user name. @@ -118,6 +120,7 @@ Response parameters - user: security_service_user - password: security_service_password - domain: security_service_domain + - ou: security_service_ou - server: security_service_server - updated_at: security_service_updated_at - created_at: security_service_created_at @@ -173,6 +176,7 @@ Response parameters - user: security_service_user - password: security_service_password - domain: security_service_domain + - ou: security_service_ou - server: security_service_server - updated_at: security_service_updated_at - created_at: security_service_created_at @@ -218,6 +222,7 @@ Request - user: security_service_user_request - password: security_service_password_request - domain: security_service_domain_request + - ou: security_service_ou_request - server: security_service_server_request Request example @@ -241,6 +246,7 @@ Response parameters - user: security_service_user - password: security_service_password - domain: security_service_domain + - ou: security_service_ou - server: security_service_server - updated_at: security_service_updated_at - created_at: security_service_created_at @@ -293,6 +299,7 @@ Request - user: security_service_user_request - password: security_service_password_request - domain: security_service_domain_request + - ou: security_service_ou_request - server: security_service_server_request Request example @@ -316,6 +323,7 @@ Response parameters - user: security_service_user - password: security_service_password - domain: security_service_domain + - ou: security_service_ou - server: security_service_server - updated_at: security_service_updated_at - created_at: security_service_created_at diff --git a/manila/api/openstack/api_version_request.py b/manila/api/openstack/api_version_request.py index bcf64d7b9f..2700c12d7b 100644 --- a/manila/api/openstack/api_version_request.py +++ b/manila/api/openstack/api_version_request.py @@ -114,13 +114,14 @@ REST_API_VERSION_HISTORY = """ * 2.41 - Added 'description' in share type create/list APIs. * 2.42 - Added ``with_count`` in share list API to get total count info. * 2.43 - Added filter search by extra spec for share type list. + * 2.44 - Added 'ou' field to 'security_service' object. """ # The minimum and maximum versions of the API supported # The default api version request is defined to be the # minimum version of the API supported. _MIN_API_VERSION = "2.0" -_MAX_API_VERSION = "2.43" +_MAX_API_VERSION = "2.44" DEFAULT_API_VERSION = _MIN_API_VERSION diff --git a/manila/api/openstack/rest_api_version_history.rst b/manila/api/openstack/rest_api_version_history.rst index 051b843b5d..63337ae326 100644 --- a/manila/api/openstack/rest_api_version_history.rst +++ b/manila/api/openstack/rest_api_version_history.rst @@ -238,3 +238,7 @@ user documentation. 2.43 ---- Added filter search by extra spec for share type list. + +2.44 +---- + Added 'ou' field to 'security_service' object. diff --git a/manila/api/views/security_service.py b/manila/api/views/security_service.py index 27dcbc96a9..62dd6a976f 100644 --- a/manila/api/views/security_service.py +++ b/manila/api/views/security_service.py @@ -21,6 +21,9 @@ class ViewBuilder(common.ViewBuilder): """Model a server API response as a python dictionary.""" _collection_name = 'security_services' + _detail_version_modifiers = [ + 'add_ou_to_security_service', + ] def summary_list(self, request, security_services): """Show a list of security services without many details.""" @@ -53,8 +56,14 @@ class ViewBuilder(common.ViewBuilder): 'domain', 'user', 'password', 'project_id') for key in keys: view['security_service'][key] = security_service.get(key) + self.update_versioned_resource_dict( + request, view['security_service'], security_service) return view + @common.ViewBuilder.versioned_method("2.44") + def add_ou_to_security_service(self, context, ss_dict, ss): + ss_dict['ou'] = ss.get('ou') + def _list_view(self, func, request, security_services): """Provide a view for a list of security services.""" security_services_list = [func(request, service)['security_service'] diff --git a/manila/db/migrations/alembic/versions/0274d20c560f_add_ou_to_security_service.py b/manila/db/migrations/alembic/versions/0274d20c560f_add_ou_to_security_service.py new file mode 100644 index 0000000000..4f1564299f --- /dev/null +++ b/manila/db/migrations/alembic/versions/0274d20c560f_add_ou_to_security_service.py @@ -0,0 +1,38 @@ +# Copyright 2018 SAP SE +# +# 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. + +"""Add ou to security service + +Revision ID: 0274d20c560f +Revises: 4a482571410f +Create Date: 2017-05-19 17:27:30.274440 + +""" + +# revision identifiers, used by Alembic. +revision = '0274d20c560f' +down_revision = '4a482571410f' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.add_column( + 'security_services', + sa.Column('ou', sa.String(255), nullable=True)) + + +def downgrade(): + op.drop_column('security_services', 'ou') diff --git a/manila/db/sqlalchemy/models.py b/manila/db/sqlalchemy/models.py index 6a07de1013..e1cea5a5d9 100644 --- a/manila/db/sqlalchemy/models.py +++ b/manila/db/sqlalchemy/models.py @@ -884,6 +884,7 @@ class SecurityService(BASE, ManilaBase): password = Column(String(255), nullable=True) name = Column(String(255), nullable=True) description = Column(String(255), nullable=True) + ou = Column(String(255), nullable=True) class ShareNetwork(BASE, ManilaBase): diff --git a/manila/share/manager.py b/manila/share/manager.py index e32d722256..ce1bf76689 100644 --- a/manila/share/manager.py +++ b/manila/share/manager.py @@ -3443,6 +3443,7 @@ class ShareManager(manager.SchedulerDependentManager): ss_type = security_service['type'] data = { 'name': security_service['name'], + 'ou': security_service['ou'], 'domain': security_service['domain'], 'server': security_service['server'], 'dns_ip': security_service['dns_ip'], diff --git a/manila/tests/api/v2/test_security_services.py b/manila/tests/api/v2/test_security_services.py new file mode 100644 index 0000000000..e1e2c7db4b --- /dev/null +++ b/manila/tests/api/v2/test_security_services.py @@ -0,0 +1,86 @@ +# Copyright 2018 SAP SE +# +# 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 datetime +import ddt +import mock + +from manila.api.v1 import security_service +from manila.common import constants +from manila import context +from manila import test +from manila.tests.api import fakes + + +def stub_security_service(self, version, id): + ss_dict = dict( + id=id, + name='security_service_%s' % str(id), + type=constants.SECURITY_SERVICES_ALLOWED_TYPES[0], + description='Fake Security Service Desc', + dns_ip='1.1.1.1', + server='fake-server', + domain='fake-domain', + user='fake-user', + password='fake-password', + status=constants.STATUS_NEW, + share_networks=[], + created_at=datetime.datetime(2017, 8, 24, 1, 1, 1, 1), + updated_at=datetime.datetime(2017, 8, 24, 1, 1, 1, 1), + project_id='fake-project' + ) + if self.is_microversion_ge(version, '2.44'): + ss_dict['ou'] = 'fake-ou' + + return ss_dict + + +@ddt.ddt +class SecurityServicesAPITest(test.TestCase): + @ddt.data( + ('2.0'), + ('2.43'), + ('2.44'), + ) + def test_index(self, version): + ss = [ + stub_security_service(self, version, 1), + stub_security_service(self, version, 2), + ] + ctxt = context.RequestContext('admin', 'fake', True) + request = fakes.HTTPRequest.blank('/security-services?all_tenants=1', + version=version) + request.headers['X-Openstack-Manila-Api-Version'] = version + request.environ['manila.context'] = ctxt + self.mock_object(security_service.db, 'security_service_get_all', + mock.Mock(return_value=ss)) + self.mock_object(security_service.db, + 'share_network_get_all_by_security_service', + mock.Mock(return_value=[])) + + ss_controller = security_service.SecurityServiceController() + + result = ss_controller.detail(request) + + self.assertIsInstance(result, dict) + self.assertEqual(['security_services'], list(result.keys())) + self.assertIsInstance(result['security_services'], list) + self.assertEqual(2, len(result['security_services'])) + self.assertIn(ss[0], result['security_services']) + + ss_keys = list(result['security_services'][0].keys()) + if self.is_microversion_ge(version, '2.44'): + self.assertIn('ou', ss_keys) + else: + self.assertNotIn('ou', ss_keys) diff --git a/manila/tests/db/sqlalchemy/test_api.py b/manila/tests/db/sqlalchemy/test_api.py index 4e3725a33b..73c8b1c14c 100644 --- a/manila/tests/db/sqlalchemy/test_api.py +++ b/manila/tests/db/sqlalchemy/test_api.py @@ -46,6 +46,7 @@ security_service_dict = { 'dns_ip': 'fake dns', 'server': 'fake ldap server', 'domain': 'fake ldap domain', + 'ou': 'fake ldap ou', 'user': 'fake user', 'password': 'fake password', 'name': 'whatever', @@ -2182,6 +2183,7 @@ class SecurityServiceDatabaseAPITestCase(BaseDatabaseAPITestCase): 'dns_ip': 'new dns', 'server': 'new ldap server', 'domain': 'new ldap domain', + 'ou': 'new ldap ou', 'user': 'new user', 'password': 'new password', 'name': 'new whatever', diff --git a/manila/tests/share/test_manager.py b/manila/tests/share/test_manager.py index 2ca7a6f725..80856b3800 100644 --- a/manila/tests/share/test_manager.py +++ b/manila/tests/share/test_manager.py @@ -2858,6 +2858,7 @@ class ShareManagerTestCase(test.TestCase): for ss_type in constants.SECURITY_SERVICES_ALLOWED_TYPES: network_info['security_services'].append({ 'name': 'fake_name' + ss_type, + 'ou': 'fake_ou' + ss_type, 'domain': 'fake_domain' + ss_type, 'server': 'fake_server' + ss_type, 'dns_ip': 'fake_dns_ip' + ss_type, diff --git a/releasenotes/notes/bug-1696669-add-ou-to-security-service-06b69615bd417d40.yaml b/releasenotes/notes/bug-1696669-add-ou-to-security-service-06b69615bd417d40.yaml new file mode 100644 index 0000000000..c31f10aa3f --- /dev/null +++ b/releasenotes/notes/bug-1696669-add-ou-to-security-service-06b69615bd417d40.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added 'ou' field to 'security_service' object to be able to configure in + which organizational unit the share ends up.