diff --git a/manila/share/drivers/netapp/dataontap/client/client_cmode.py b/manila/share/drivers/netapp/dataontap/client/client_cmode.py index 143568d2fb..d7e8fff9d9 100644 --- a/manila/share/drivers/netapp/dataontap/client/client_cmode.py +++ b/manila/share/drivers/netapp/dataontap/client/client_cmode.py @@ -1716,6 +1716,8 @@ class NetAppCmodeClient(client_base.NetAppBaseClient): if security_service['ou'] is not None: api_args['organizational-unit'] = security_service['ou'] + if security_service.get('default_ad_site'): + api_args['default-site'] = security_service['default_ad_site'] try: LOG.debug("Trying to setup CIFS server with data: %s", api_args) @@ -1757,12 +1759,32 @@ class NetAppCmodeClient(client_base.NetAppBaseClient): msg = _("Failed to modify existing CIFS server user-name. %s") raise exception.NetAppException(msg % e.message) + if 'default_ad_site' in differring_keys: + if new_security_service['default_ad_site'] is not None: + cifs_server = self._get_cifs_server_name(vserver_name) + api_args = { + 'admin-username': new_security_service['user'], + 'admin-password': new_security_service['password'], + 'force-account-overwrite': 'true', + 'cifs-server': cifs_server, + 'default-site': new_security_service['default_ad_site'] + } + try: + LOG.debug("Trying to modify CIFS server with data: %s", + api_args) + self.send_request('cifs-server-modify', api_args) + except netapp_api.NaApiError as e: + msg = _("Failed to modify CIFS server entry. %s") + raise exception.NetAppException(msg % e.message) + self.configure_cifs_options(new_security_service) + if 'server' in differring_keys: if current_security_service['server'] is not None: self.remove_preferred_dcs(current_security_service) if new_security_service['server'] is not None: self.set_preferred_dc(new_security_service) + self.configure_cifs_options(new_security_service) @na_utils.trace def create_kerberos_realm(self, security_service): @@ -2007,10 +2029,13 @@ class NetAppCmodeClient(client_base.NetAppBaseClient): @na_utils.trace def configure_cifs_options(self, security_service): - if not security_service['server']: - return + if security_service.get('server'): + api_args = {'mode': 'none'} + elif security_service.get('default_ad_site'): + api_args = {'mode': 'site'} + else: + api_args = {'mode': 'all'} - api_args = {'mode': 'none'} try: self.send_request( 'cifs-domain-server-discovery-mode-modify', diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py index 5ff9087c5d..25206dba63 100644 --- a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py +++ b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py @@ -2014,7 +2014,8 @@ class NetAppCmodeMultiSVMFileStorageLibrary( new_sec_service): different_keys = [] - valid_keys = ['dns_ip', 'server', 'domain', 'user', 'password', 'ou'] + valid_keys = ['dns_ip', 'server', 'domain', 'user', 'password', + 'ou', 'default_ad_site'] for key, value in current_sec_service.items(): if (current_sec_service[key] != new_sec_service[key] and key in valid_keys): @@ -2040,6 +2041,15 @@ class NetAppCmodeMultiSVMFileStorageLibrary( LOG.error(msg) return False + if ss_type == 'active_directory': + server = security_service.get('server') + default_ad_site = security_service.get('default_ad_site') + if server and default_ad_site: + msg = _("Active directory security service must not have " + "both 'server' and 'default_ad_site' parameters.") + LOG.error(msg) + return False + if not all([security_service[key] is not None for key in mandatory_params[ss_type]]): msg = _("The security service %s does not have all the " diff --git a/manila/tests/share/drivers/netapp/dataontap/client/fakes.py b/manila/tests/share/drivers/netapp/dataontap/client/fakes.py index b4bc264ecf..7ae4e902b3 100644 --- a/manila/tests/share/drivers/netapp/dataontap/client/fakes.py +++ b/manila/tests/share/drivers/netapp/dataontap/client/fakes.py @@ -479,6 +479,7 @@ CIFS_SECURITY_SERVICE = { 'domain': 'fake_domain', 'dns_ip': 'fake_dns_ip', 'server': 'fake_server', + 'default_ad_site': None, } CIFS_SECURITY_SERVICE_2 = { @@ -489,6 +490,29 @@ CIFS_SECURITY_SERVICE_2 = { 'domain': 'fake_domain_2', 'dns_ip': 'fake_dns_ip_2', 'server': 'fake_server_2', + 'default_ad_site': None, +} + +CIFS_SECURITY_SERVICE_3 = { + 'type': 'active_directory', + 'password': 'fake_password_3', + 'user': 'fake_user_3', + 'ou': 'fake_ou_3', + 'domain': 'fake_domain_3', + 'dns_ip': 'fake_dns_ip_3', + 'default_ad_site': 'fake_default_ad_site_3', + 'server': None, +} + +CIFS_SECURITY_SERVICE_4 = { + 'type': 'active_directory', + 'password': 'fake_password_4', + 'user': 'fake_user_4', + 'ou': 'fake_ou_4', + 'domain': 'fake_domain_4', + 'dns_ip': 'fake_dns_ip_4', + 'default_ad_site': 'fake_default_ad_site_4', + 'server': None, } LDAP_LINUX_SECURITY_SERVICE = { diff --git a/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py b/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py index 49c4162177..803fd30e84 100644 --- a/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py +++ b/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py @@ -2653,6 +2653,36 @@ class NetAppClientCmodeTestCase(test.TestCase): self.client.send_request.assert_has_calls([ mock.call('cifs-server-create', cifs_server_create_args)]) + def test_configure_active_directory_with_ad_site(self): + + self.mock_object(self.client, 'send_request') + self.mock_object(self.client, 'configure_dns') + self.mock_object(self.client, 'set_preferred_dc') + + self.client.configure_active_directory(fake.CIFS_SECURITY_SERVICE_3, + fake.VSERVER_NAME) + + cifs_server = (fake.VSERVER_NAME[0:8] + + '-' + + fake.VSERVER_NAME[-6:]).replace('_', '-').upper() + + cifs_server_create_args = { + 'admin-username': fake.CIFS_SECURITY_SERVICE_3['user'], + 'admin-password': fake.CIFS_SECURITY_SERVICE_3['password'], + 'force-account-overwrite': 'true', + 'cifs-server': cifs_server, + 'organizational-unit': fake.CIFS_SECURITY_SERVICE_3['ou'], + 'domain': fake.CIFS_SECURITY_SERVICE_3['domain'], + 'default-site': fake.CIFS_SECURITY_SERVICE_3['default_ad_site'], + } + + self.client.configure_dns.assert_called_with( + fake.CIFS_SECURITY_SERVICE_3) + self.client.set_preferred_dc.assert_called_with( + fake.CIFS_SECURITY_SERVICE_3) + self.client.send_request.assert_has_calls([ + mock.call('cifs-server-create', cifs_server_create_args)]) + def test_configure_active_directory_api_error(self): self.mock_object(self.client, 'send_request', self._mock_api_error()) @@ -7989,19 +8019,37 @@ class NetAppClientCmodeTestCase(test.TestCase): self.client.send_request.assert_called_once_with( 'volume-autosize-get', {'volume': fake.SHARE_NAME}) - def test_modify_active_directory_security_service(self): - curr_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE) - new_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_2) + @ddt.data('server_to_server', + 'server_to_default_ad_site', + 'default_ad_site_to_default_ad_site', + 'default_ad_site_to_server') + def test_modify_active_directory_security_service(self, + modify_ad_direction): + if modify_ad_direction == 'server_to_server': + curr_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE) + new_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_2) + if modify_ad_direction == 'server_to_default_ad_site': + curr_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE) + new_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_3) + if modify_ad_direction == 'default_ad_site_to_default_ad_site': + curr_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_3) + new_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_4) + if modify_ad_direction == 'default_ad_site_to_server': + curr_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_4) + new_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_2) + # we don't support domain change, but this validation isn't made in # within this method new_sec_service['domain'] = curr_sec_service['domain'] - api_responses = [fake.PASSED_RESPONSE, fake.PASSED_RESPONSE] + api_responses = [fake.PASSED_RESPONSE, fake.PASSED_RESPONSE, + fake.PASSED_RESPONSE] self.mock_object(self.client, 'send_request', mock.Mock(side_effect=api_responses)) self.mock_object(self.client, 'remove_preferred_dcs') self.mock_object(self.client, 'set_preferred_dc') - differing_keys = {'password', 'user', 'server'} + self.mock_object(self.client, 'configure_cifs_options') + differing_keys = {'password', 'user', 'server', 'default_ad_site'} self.client.modify_active_directory_security_service( fake.VSERVER_NAME, differing_keys, new_sec_service, @@ -8021,9 +8069,30 @@ class NetAppClientCmodeTestCase(test.TestCase): self.client.send_request.assert_has_calls([ mock.call('cifs-local-user-set-password', set_pass_api_args), mock.call('cifs-local-user-rename', user_rename_api_args)]) - self.client.remove_preferred_dcs.assert_called_once_with( - curr_sec_service) - self.client.set_preferred_dc.assert_called_once_with(new_sec_service) + + if modify_ad_direction in ('default_ad_site_to_default_ad_site', + 'server_to_default_ad_site'): + cifs_server_modify_args = { + 'admin-username': new_sec_service['user'], + 'admin-password': new_sec_service['password'], + 'force-account-overwrite': 'true', + 'cifs-server': cifs_server, + 'default-site': new_sec_service['default_ad_site'], + } + self.client.send_request.assert_has_calls([ + mock.call('cifs-server-modify', cifs_server_modify_args)]) + self.client.configure_cifs_options.assert_has_calls([ + mock.call(new_sec_service)]) + if modify_ad_direction in ('server_to_server', + 'server_to_default_ad_site'): + self.client.remove_preferred_dcs.assert_called_once_with( + curr_sec_service) + if modify_ad_direction in ('server_to_server', + 'default_ad_site_to_server'): + self.client.set_preferred_dc.assert_called_once_with( + new_sec_service) + self.client.configure_cifs_options.assert_has_calls([ + mock.call(new_sec_service)]) @ddt.data(True, False) def test_modify_active_directory_security_service_error( diff --git a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py index b27f2b5289..a13454c3e7 100644 --- a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py +++ b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py @@ -3598,6 +3598,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): def test__get_different_keys_for_equal_ss_type(self): curr_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE) new_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_2) + new_sec_service2 = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_3) expected_keys = ['password', 'user', 'ou', 'domain', 'dns_ip', 'server'] @@ -3607,6 +3608,13 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): self.assertEqual(expected_keys, result) + expected_keys = ['password', 'user', 'ou', + 'domain', 'dns_ip', 'server', 'default_ad_site'] + result = self.library._get_different_keys_for_equal_ss_type( + curr_sec_service, new_sec_service2) + + self.assertEqual(expected_keys, result) + @ddt.data( {'current': None, 'new': fake.CIFS_SECURITY_SERVICE, diff --git a/manila/tests/share/drivers/netapp/dataontap/fakes.py b/manila/tests/share/drivers/netapp/dataontap/fakes.py index ddca99a3d2..03d44026b7 100644 --- a/manila/tests/share/drivers/netapp/dataontap/fakes.py +++ b/manila/tests/share/drivers/netapp/dataontap/fakes.py @@ -1647,6 +1647,7 @@ CIFS_SECURITY_SERVICE = { 'domain': 'fake_domain', 'dns_ip': 'fake_dns_ip', 'server': 'fake_server', + 'default_ad_site': None, } CIFS_SECURITY_SERVICE_2 = { @@ -1658,7 +1659,21 @@ CIFS_SECURITY_SERVICE_2 = { 'domain': 'fake_domain_2', 'dns_ip': 'fake_dns_ip_2', 'server': 'fake_server_2', + 'default_ad_site': None, } + +CIFS_SECURITY_SERVICE_3 = { + 'id': 'fake_id_3', + 'type': 'active_directory', + 'password': 'fake_password_3', + 'user': 'fake_user_3', + 'ou': 'fake_ou_3', + 'domain': 'fake_domain_3', + 'dns_ip': 'fake_dns_ip_3', + 'default_ad_site': 'fake_default_ad_site', + 'server': None +} + LDAP_LINUX_SECURITY_SERVICE = { 'id': 'fake_id', 'type': 'ldap', diff --git a/releasenotes/notes/netapp-use-default-ad-site-security-service-55748f54c2390fad.yaml b/releasenotes/notes/netapp-use-default-ad-site-security-service-55748f54c2390fad.yaml new file mode 100644 index 0000000000..8c97ba2c77 --- /dev/null +++ b/releasenotes/notes/netapp-use-default-ad-site-security-service-55748f54c2390fad.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + For Netapp ONTAP driver, the 'default_ad_site' will restrict the Domain + controller's discovery mode to 'site' i.e. only Domain Controller's in + local site will be discovered.