From 650fa9c34210808491ceeba3b3115c0365501a39 Mon Sep 17 00:00:00 2001 From: Kiran Pawar Date: Tue, 9 Aug 2022 17:03:50 +0000 Subject: [PATCH] Add defaultadsite to security service Allows to configure optional field 'defaultadsite' which if provided set domain controller discovery mode to 'site' APIImpact --- api-ref/source/parameters.yaml | 15 ++++++++ .../security-service-create-response.json | 1 + .../security-service-show-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 | 1 + manila/api/v1/security_service.py | 7 ++++ manila/api/views/security_service.py | 5 +++ ...9_add_defaultadsite_to_security_service.py | 36 +++++++++++++++++++ manila/db/sqlalchemy/models.py | 1 + .../netapp/dataontap/client/client_cmode.py | 11 +++--- manila/share/manager.py | 2 ++ manila/tests/api/v2/test_security_services.py | 8 +++++ manila/tests/db/sqlalchemy/test_api.py | 2 ++ manila/tests/share/test_manager.py | 2 ++ ...-to-security-service-e90854c1a69be581.yaml | 7 ++++ 17 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 manila/db/migrations/alembic/versions/636ecb8f3939_add_defaultadsite_to_security_service.py create mode 100644 releasenotes/notes/add-defaultadsite-to-security-service-e90854c1a69be581.yaml diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index 5c26308c38..460e15186b 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -2209,6 +2209,21 @@ scheduler_hints: required: false type: object min_version: 2.65 +security_service_defaultadsite: + description: | + The security service default AD site. + in: body + required: true + type: string + min_version: 2.65 +security_service_defaultadsite_request: + description: | + The security service default AD site. An organizational unit + can be added to specify where the share ends up. + in: body + required: false + type: string + min_version: 2.65 security_service_dns_ip: description: | The DNS IP address that is used inside the project network. diff --git a/api-ref/source/samples/security-service-create-response.json b/api-ref/source/samples/security-service-create-response.json index 61f892bdab..9faf403c7d 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, + "defaultadsite": null, "ou": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ1", diff --git a/api-ref/source/samples/security-service-show-response.json b/api-ref/source/samples/security-service-show-response.json index c85849cd9f..d536265685 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, + "defaultadsite": null, "ou": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ1", 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 956092b476..6b10225a1d 100644 --- a/api-ref/source/samples/security-services-list-detailed-response.json +++ b/api-ref/source/samples/security-services-list-detailed-response.json @@ -4,6 +4,7 @@ "status": "new", "domain": null, "ou": null, + "defaultadsite": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ1", "created_at": "2015-09-07T12:19:10.000000", @@ -21,6 +22,7 @@ "status": "new", "domain": null, "ou": null, + "defaultadsite": 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 5f42fe15c1..93ecac35cc 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 @@ -4,6 +4,7 @@ "status": "new", "domain": null, "ou": null, + "defaultadsite": null, "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "name": "SecServ1", "created_at": "2015-09-07T12:19:10.000000", @@ -23,6 +24,7 @@ "status": "new", "domain": null, "ou": null, + "defaultadsite": 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 659482b305..11d9acb42f 100644 --- a/api-ref/source/security-services.inc +++ b/api-ref/source/security-services.inc @@ -33,6 +33,8 @@ You can configure a security service with these options: - The password for the user, if you specify a user name. +- A default AD site, optional (available starting with API version 2.65) + A security service resource can also be given a user defined name and description. @@ -125,6 +127,7 @@ Response parameters - password: security_service_password - domain: security_service_domain - ou: security_service_ou + - defaultadsite: security_service_defaultadsite - server: security_service_server - updated_at: updated_at - created_at: created_at @@ -181,6 +184,7 @@ Response parameters - password: security_service_password - domain: security_service_domain - ou: security_service_ou + - defaultadsite: security_service_defaultadsite - server: security_service_server - updated_at: updated_at - created_at: created_at @@ -227,6 +231,7 @@ Request - password: security_service_password_request - domain: security_service_domain_request - ou: security_service_ou_request + - defaultadsite: security_service_defaultadsite_request - server: security_service_server_request Request example @@ -251,6 +256,7 @@ Response parameters - password: security_service_password - domain: security_service_domain - ou: security_service_ou + - defaultadsite: security_service_defaultadsite - server: security_service_server - updated_at: updated_at - created_at: created_at @@ -304,6 +310,7 @@ Request - password: security_service_password_request - domain: security_service_domain_request - ou: security_service_ou_request + - defaultadsite: security_service_defaultadsite_request - server: security_service_server_request Request example @@ -328,6 +335,7 @@ Response parameters - password: security_service_password - domain: security_service_domain - ou: security_service_ou + - defaultadsite: security_service_defaultadsite - server: security_service_server - updated_at: updated_at - created_at: created_at diff --git a/manila/api/openstack/api_version_request.py b/manila/api/openstack/api_version_request.py index 1d9cc5e911..0ef5acc0ef 100644 --- a/manila/api/openstack/api_version_request.py +++ b/manila/api/openstack/api_version_request.py @@ -172,6 +172,7 @@ 'update_security_service', 'update_security_service_check' and 'add_security_service_check'. * 2.65 - Added ability to set scheduler hints via the share create API. + Added default AD site option in security service. """ # The minimum and maximum versions of the API supported diff --git a/manila/api/v1/security_service.py b/manila/api/v1/security_service.py index 8e998d13b8..5808ca7220 100644 --- a/manila/api/v1/security_service.py +++ b/manila/api/v1/security_service.py @@ -209,6 +209,13 @@ def create(self, req, body): "service. Valid types are %(types)s") % {'type': security_srv_type, 'types': ','.join(allowed_types)})) + server = security_service_args.get('server') + defaultadsite = security_service_args.get('defaultadsite') + if server and defaultadsite: + raise exception.InvalidInput( + reason=(_("Can not create security service because both " + "server and default AD site is provided, Specify " + "either server or default AD site."))) security_service_args['project_id'] = context.project_id security_service = db.security_service_create( context, security_service_args) diff --git a/manila/api/views/security_service.py b/manila/api/views/security_service.py index 62dd6a976f..98c365a4bf 100644 --- a/manila/api/views/security_service.py +++ b/manila/api/views/security_service.py @@ -23,6 +23,7 @@ class ViewBuilder(common.ViewBuilder): _collection_name = 'security_services' _detail_version_modifiers = [ 'add_ou_to_security_service', + 'add_defaultadsite_to_security_service', ] def summary_list(self, request, security_services): @@ -64,6 +65,10 @@ def detail(self, request, security_service): def add_ou_to_security_service(self, context, ss_dict, ss): ss_dict['ou'] = ss.get('ou') + @common.ViewBuilder.versioned_method("2.65") + def add_defaultadsite_to_security_service(self, context, ss_dict, ss): + ss_dict['defaultadsite'] = ss.get('defaultadsite') + 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/636ecb8f3939_add_defaultadsite_to_security_service.py b/manila/db/migrations/alembic/versions/636ecb8f3939_add_defaultadsite_to_security_service.py new file mode 100644 index 0000000000..2fc101a8da --- /dev/null +++ b/manila/db/migrations/alembic/versions/636ecb8f3939_add_defaultadsite_to_security_service.py @@ -0,0 +1,36 @@ +# 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 defaultadsite to security service + +Revision ID: 636ecb8f3939 +Revises: fbdfabcba377 +Create Date: 2022-08-09 10:29:08.394103 + +""" + +# revision identifiers, used by Alembic. +revision = '636ecb8f3939' +down_revision = 'fbdfabcba377' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.add_column( + 'security_services', + sa.Column('defaultadsite', sa.String(255), nullable=True)) + + +def downgrade(): + op.drop_column('security_services', 'defaultadsite') diff --git a/manila/db/sqlalchemy/models.py b/manila/db/sqlalchemy/models.py index cd80cd1fef..87731a9ea4 100644 --- a/manila/db/sqlalchemy/models.py +++ b/manila/db/sqlalchemy/models.py @@ -938,6 +938,7 @@ class SecurityService(BASE, ManilaBase): name = Column(String(255), nullable=True) description = Column(String(255), nullable=True) ou = Column(String(255), nullable=True) + defaultadsite = Column(String(255), nullable=True) class ShareNetwork(BASE, ManilaBase): diff --git a/manila/share/drivers/netapp/dataontap/client/client_cmode.py b/manila/share/drivers/netapp/dataontap/client/client_cmode.py index e7bbd5f526..79ea4fd57a 100644 --- a/manila/share/drivers/netapp/dataontap/client/client_cmode.py +++ b/manila/share/drivers/netapp/dataontap/client/client_cmode.py @@ -1781,6 +1781,8 @@ def configure_active_directory(self, security_service, vserver_name): if security_service['ou'] is not None: api_args['organizational-unit'] = security_service['ou'] + if security_service.get('defaultadsite', None): + api_args['default-site'] = security_service['defaultadsite'] for attempt in range(6): try: @@ -2129,12 +2131,13 @@ def configure_cifs_options(self, security_service): # no raise to be non-blocking LOG.warning(msg, e.message) - if not security_service['server']: + if security_service.get('server', None): + api_args = {'mode': 'none'} + elif security_service.get('defaultadsite', None): + api_args = {'mode': 'site'} + else: return - api_args = { - 'mode': 'none' - } try: self.send_request( 'cifs-domain-server-discovery-mode-modify', diff --git a/manila/share/manager.py b/manila/share/manager.py index 7d4e7b7663..0d60669138 100644 --- a/manila/share/manager.py +++ b/manila/share/manager.py @@ -3299,6 +3299,7 @@ def manage_share_server(self, context, share_server_id, identifier, data = { 'name': security_service['name'], 'ou': security_service['ou'], + 'defaultadsite': security_service['defaultadsite'], 'domain': security_service['domain'], 'server': security_service['server'], 'dns_ip': security_service['dns_ip'], @@ -4206,6 +4207,7 @@ def _setup_server(self, context, share_server, metadata): data = { 'name': security_service['name'], 'ou': security_service['ou'], + 'defaultadsite': security_service['defaultadsite'], '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 index 060e1c5c6e..27a2c243bd 100644 --- a/manila/tests/api/v2/test_security_services.py +++ b/manila/tests/api/v2/test_security_services.py @@ -43,6 +43,8 @@ def stub_security_service(self, version, id): ) if self.is_microversion_ge(version, '2.44'): ss_dict['ou'] = 'fake-ou' + if self.is_microversion_ge(version, '2.65'): + ss_dict['defaultadsite'] = 'fake-defaultadsite' return ss_dict @@ -53,6 +55,7 @@ class SecurityServicesAPITest(test.TestCase): ('2.0'), ('2.43'), ('2.44'), + ('2.65'), ) def test_index(self, version): ss = [ @@ -85,3 +88,8 @@ def test_index(self, version): self.assertIn('ou', ss_keys) else: self.assertNotIn('ou', ss_keys) + + if self.is_microversion_ge(version, '2.65'): + self.assertIn('defaultadsite', ss_keys) + else: + self.assertNotIn('defaultadsite', ss_keys) diff --git a/manila/tests/db/sqlalchemy/test_api.py b/manila/tests/db/sqlalchemy/test_api.py index 9056744cd2..e691b46015 100644 --- a/manila/tests/db/sqlalchemy/test_api.py +++ b/manila/tests/db/sqlalchemy/test_api.py @@ -45,6 +45,7 @@ 'dns_ip': 'fake dns', 'server': 'fake ldap server', 'domain': 'fake ldap domain', + 'defaultadsite': 'fake ldap defaultadsite', 'ou': 'fake ldap ou', 'user': 'fake user', 'password': 'fake password', @@ -2948,6 +2949,7 @@ def test_update(self): 'dns_ip': 'new dns', 'server': 'new ldap server', 'domain': 'new ldap domain', + 'defaultadsite': 'new ldap defaultadsite', 'ou': 'new ldap ou', 'user': 'new user', 'password': 'new password', diff --git a/manila/tests/share/test_manager.py b/manila/tests/share/test_manager.py index a110bbbfd6..8ed5e20d2d 100644 --- a/manila/tests/share/test_manager.py +++ b/manila/tests/share/test_manager.py @@ -3517,6 +3517,7 @@ def test_setup_server(self): network_info['security_services'].append({ 'name': 'fake_name' + ss_type, 'ou': 'fake_ou' + ss_type, + 'defaultadsite': 'fake_defaultadsite' + ss_type, 'domain': 'fake_domain' + ss_type, 'server': 'fake_server' + ss_type, 'dns_ip': 'fake_dns_ip' + ss_type, @@ -6378,6 +6379,7 @@ def test_manage_share_server(self, admin_network_api, driver_return): ss_data_from_db = { 'name': ss_from_db['name'], 'ou': ss_from_db['ou'], + 'defaultadsite': ss_from_db['defaultadsite'], 'domain': ss_from_db['domain'], 'server': ss_from_db['server'], 'dns_ip': ss_from_db['dns_ip'], diff --git a/releasenotes/notes/add-defaultadsite-to-security-service-e90854c1a69be581.yaml b/releasenotes/notes/add-defaultadsite-to-security-service-e90854c1a69be581.yaml new file mode 100644 index 0000000000..d8d80e48d9 --- /dev/null +++ b/releasenotes/notes/add-defaultadsite-to-security-service-e90854c1a69be581.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Added 'defaultadsite' field to 'security_service' object to be able to + configure in default AD site. This option can not be used along-with + 'server' field of 'security_service' and restrict the discovery mode + to 'site' i.e. only Domain Controller's in local site will be discovered.