Merge "Add defaultadsite to security service"

This commit is contained in:
Zuul 2023-05-25 16:09:24 +00:00 committed by Gerrit Code Review
commit 3e9d75421d
10 changed files with 346 additions and 29 deletions

View File

@ -87,6 +87,15 @@ class CreateShareSecurityService(command.ShowOne):
default=None, default=None,
help=_("Security service description.") help=_("Security service description.")
) )
parser.add_argument(
'--default-ad-site',
metavar='<default_ad_site>',
dest='default_ad_site',
default=None,
help=_("Default AD site. Available only for "
"microversion >= 2.76. Can be provided in the "
"place of '--server' but not along with it.")
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -104,12 +113,27 @@ class CreateShareSecurityService(command.ShowOne):
if share_client.api_version >= api_versions.APIVersion("2.44"): if share_client.api_version >= api_versions.APIVersion("2.44"):
kwargs['ou'] = parsed_args.ou kwargs['ou'] = parsed_args.ou
elif parsed_args.ou: elif parsed_args.ou:
raise exceptions.CommandError( raise exceptions.CommandError(
"Defining a security service Organizational Unit is " "Defining a security service Organizational Unit is "
"available only for microversion >= 2.44") "available only for microversion >= 2.44")
if share_client.api_version >= api_versions.APIVersion("2.76"):
kwargs['default_ad_site'] = parsed_args.default_ad_site
elif parsed_args.default_ad_site:
raise exceptions.CommandError(
"Defining a security service Default AD site is "
"available only for microversion >= 2.76")
if parsed_args.type == 'active_directory':
server = parsed_args.server
default_ad_site = parsed_args.default_ad_site
if server and default_ad_site:
raise exceptions.CommandError(
"Cannot create security service because both "
"server and 'default_ad_site' were provided. "
"Specify either server or 'default_ad_site'.")
security_service = share_client.security_services.create( security_service = share_client.security_services.create(
parsed_args.type, **kwargs) parsed_args.type, **kwargs)
@ -243,6 +267,14 @@ class SetShareSecurityService(command.Command):
default=None, default=None,
help=_("Set security service description.") help=_("Set security service description.")
) )
parser.add_argument(
'--default-ad-site',
metavar='<default_ad_site>',
dest='default_ad_site',
default=None,
help=_("Default AD site. "
"Available only for microversion >= 2.76.")
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -264,11 +296,26 @@ class SetShareSecurityService(command.Command):
if share_client.api_version >= api_versions.APIVersion("2.44"): if share_client.api_version >= api_versions.APIVersion("2.44"):
kwargs['ou'] = parsed_args.ou kwargs['ou'] = parsed_args.ou
elif parsed_args.ou: elif parsed_args.ou:
raise exceptions.CommandError(_( raise exceptions.CommandError(_(
"Setting a security service Organizational Unit is " "Setting a security service Organizational Unit is "
"available only for microversion >= 2.44")) "available only for microversion >= 2.44"))
if share_client.api_version >= api_versions.APIVersion("2.76"):
kwargs['default_ad_site'] = parsed_args.default_ad_site
elif parsed_args.default_ad_site:
raise exceptions.CommandError(
"Defining a security service Default AD site is "
"available only for microversion >= 2.76")
if security_service.type == 'active_directory':
server = parsed_args.server
default_ad_site = parsed_args.default_ad_site
if server and default_ad_site:
raise exceptions.CommandError(
"Cannot set security service because both "
"server and 'default_ad_site' were provided. "
"Specify either server or 'default_ad_site'.")
try: try:
security_service.update(**kwargs) security_service.update(**kwargs)
except Exception as e: except Exception as e:
@ -328,6 +375,13 @@ class UnsetShareSecurityService(command.Command):
action='store_true', action='store_true',
help=_("Unset security service description.") help=_("Unset security service description.")
) )
parser.add_argument(
'--default-ad-site',
dest='default_ad_site',
action='store_true',
help=_("Default AD site. "
"Available only for microversion >= 2.76.")
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -354,6 +408,16 @@ class UnsetShareSecurityService(command.Command):
raise exceptions.CommandError(_( raise exceptions.CommandError(_(
"Unsetting a security service Organizational Unit is " "Unsetting a security service Organizational Unit is "
"available only for microversion >= 2.44")) "available only for microversion >= 2.44"))
if (parsed_args.default_ad_site and
share_client.api_version >= api_versions.APIVersion("2.76")):
# the SDK unsets a value if it is an empty string
kwargs['default_ad_site'] = ''
elif parsed_args.default_ad_site:
raise exceptions.CommandError(_(
"Unsetting a security service Default AD site is "
"available only for microversion >= 2.76"))
try: try:
security_service.update(**kwargs) security_service.update(**kwargs)
except Exception as e: except Exception as e:
@ -418,6 +482,14 @@ class ListShareSecurityService(command.Lister):
"(Organizational Unit). " "(Organizational Unit). "
"Available only for microversion >= 2.44.") "Available only for microversion >= 2.44.")
) )
parser.add_argument(
'--default-ad-site',
metavar='<default_ad_site>',
dest='default_ad_site',
default=None,
help=_("Filter results by security service default_ad_site. "
"Available only for microversion >= 2.76.")
)
parser.add_argument( parser.add_argument(
'--server', '--server',
metavar='<server>', metavar='<server>',
@ -485,6 +557,14 @@ class ListShareSecurityService(command.Lister):
"Filtering results by security service Organizational Unit is " "Filtering results by security service Organizational Unit is "
"available only for microversion >= 2.44")) "available only for microversion >= 2.44"))
if (parsed_args.default_ad_site and
share_client.api_version >= api_versions.APIVersion("2.76")):
search_opts['default_ad_site'] = parsed_args.default_ad_site
elif parsed_args.default_ad_site:
raise exceptions.CommandError(_(
"Filtering results by security service Default AD site is "
"available only for microversion >= 2.76"))
if parsed_args.share_network: if parsed_args.share_network:
search_opts['share_network_id'] = oscutils.find_resource( search_opts['share_network_id'] = oscutils.find_resource(
share_client.share_networks, share_client.share_networks,

View File

@ -413,8 +413,9 @@ class BaseTestCase(base.ClientTestBase):
@classmethod @classmethod
def create_security_service(cls, type='ldap', name=None, description=None, def create_security_service(cls, type='ldap', name=None, description=None,
dns_ip=None, ou=None, server=None, domain=None, dns_ip=None, ou=None, server=None, domain=None,
user=None, password=None, client=None, user=None, password=None, default_ad_site=None,
cleanup_in_class=False, microversion=None): client=None, cleanup_in_class=False,
microversion=None):
if client is None: if client is None:
client = cls.get_admin_client() client = cls.get_admin_client()
data = { data = {
@ -428,6 +429,7 @@ class BaseTestCase(base.ClientTestBase):
'dns_ip': dns_ip, 'dns_ip': dns_ip,
'ou': ou, 'ou': ou,
'microversion': microversion, 'microversion': microversion,
'default_ad_site': default_ad_site,
} }
ss = client.create_security_service(**data) ss = client.create_security_service(**data)
resource = { resource = {

View File

@ -1589,7 +1589,8 @@ class ManilaCLIClient(base.CLIClient):
def create_security_service(self, type='ldap', name=None, description=None, def create_security_service(self, type='ldap', name=None, description=None,
dns_ip=None, ou=None, server=None, domain=None, dns_ip=None, ou=None, server=None, domain=None,
user=None, password=None, microversion=None): user=None, password=None, default_ad_site=None,
microversion=None):
"""Creates security service. """Creates security service.
:param type: security service type (ldap, kerberos or active_directory) :param type: security service type (ldap, kerberos or active_directory)
@ -1601,6 +1602,7 @@ class ManilaCLIClient(base.CLIClient):
:param domain: security service domain. :param domain: security service domain.
:param user: user of the new security service. :param user: user of the new security service.
:param password: password used by user. :param password: password used by user.
:param default_ad_site: default AD site
""" """
cmd = 'security-service-create %s ' % type cmd = 'security-service-create %s ' % type
@ -1612,7 +1614,8 @@ class ManilaCLIClient(base.CLIClient):
server=server, server=server,
domain=domain, domain=domain,
user=user, user=user,
password=password) password=password,
default_ad_site=default_ad_site)
ss_raw = self.manila(cmd, microversion=microversion) ss_raw = self.manila(cmd, microversion=microversion)
security_service = output_parser.details(ss_raw) security_service = output_parser.details(ss_raw)
@ -1622,7 +1625,8 @@ class ManilaCLIClient(base.CLIClient):
def update_security_service(self, security_service, name=None, def update_security_service(self, security_service, name=None,
description=None, dns_ip=None, ou=None, description=None, dns_ip=None, ou=None,
server=None, domain=None, user=None, server=None, domain=None, user=None,
password=None, microversion=None): password=None, default_ad_site=None,
microversion=None):
cmd = 'security-service-update %s ' % security_service cmd = 'security-service-update %s ' % security_service
cmd += self. _combine_security_service_data( cmd += self. _combine_security_service_data(
name=name, name=name,
@ -1632,13 +1636,15 @@ class ManilaCLIClient(base.CLIClient):
server=server, server=server,
domain=domain, domain=domain,
user=user, user=user,
password=password) password=password,
default_ad_site=default_ad_site)
return output_parser.details( return output_parser.details(
self.manila(cmd, microversion=microversion)) self.manila(cmd, microversion=microversion))
def _combine_security_service_data(self, name=None, description=None, def _combine_security_service_data(self, name=None, description=None,
dns_ip=None, ou=None, server=None, dns_ip=None, ou=None, server=None,
domain=None, user=None, password=None): domain=None, user=None, password=None,
default_ad_site=None):
data = '' data = ''
if name is not None: if name is not None:
data += '--name %s ' % name data += '--name %s ' % name
@ -1656,6 +1662,8 @@ class ManilaCLIClient(base.CLIClient):
data += '--user %s ' % user data += '--user %s ' % user
if password is not None: if password is not None:
data += '--password %s ' % password data += '--password %s ' % password
if default_ad_site is not None:
data += '--default-ad-site %s ' % default_ad_site
return data return data
@not_found_wrapper @not_found_wrapper

View File

@ -32,6 +32,7 @@ class SecurityServiceReadWriteTest(base.BaseTestCase):
self.domain = 'fake_domain' self.domain = 'fake_domain'
self.dns_ip = '1.2.3.4' self.dns_ip = '1.2.3.4'
self.ou = 'fake_ou' self.ou = 'fake_ou'
self.default_ad_site = 'fake_default_ad_site'
@ddt.data( @ddt.data(
{'name': 'test_name'}, {'name': 'test_name'},
@ -39,6 +40,7 @@ class SecurityServiceReadWriteTest(base.BaseTestCase):
{'user': 'test_username'}, {'user': 'test_username'},
{'password': 'test_password'}, {'password': 'test_password'},
{'server': 'test_server'}, {'server': 'test_server'},
{'default_ad_site': 'test_default_ad_site'},
{'domain': 'test_domain'}, {'domain': 'test_domain'},
{'dns_ip': 'test_dns_ip'}, {'dns_ip': 'test_dns_ip'},
{'ou': 'test_ou'}, {'ou': 'test_ou'},
@ -47,6 +49,7 @@ class SecurityServiceReadWriteTest(base.BaseTestCase):
{'user': '""'}, {'user': '""'},
{'password': '""'}, {'password': '""'},
{'server': '""'}, {'server': '""'},
{'default_ad_site': '""'},
{'domain': '""'}, {'domain': '""'},
{'dns_ip': '""'}, {'dns_ip': '""'},
{'ou': '""'}, {'ou': '""'},
@ -63,6 +66,10 @@ class SecurityServiceReadWriteTest(base.BaseTestCase):
'ou': self.ou, 'ou': self.ou,
} }
if 'default_ad_site' in ss_data:
expected_data.pop('server')
expected_data['default_ad_site'] = self.default_ad_site
ss = self.create_security_service(**expected_data) ss = self.create_security_service(**expected_data)
update = self.admin_client.update_security_service(ss['id'], **ss_data) update = self.admin_client.update_security_service(ss['id'], **ss_data)
expected_data.update(ss_data) expected_data.update(ss_data)

View File

@ -979,6 +979,7 @@ class FakeShareSecurityService(object):
"password": 'password', "password": 'password',
"project_id": uuid.uuid4().hex, "project_id": uuid.uuid4().hex,
"server": 'fake_hostname', "server": 'fake_hostname',
"default_ad_site": 'fake_default_ad_site',
"status": 'new', "status": 'new',
"type": 'ldap', "type": 'ldap',
"updated_at": datetime.datetime.now().isoformat(), "updated_at": datetime.datetime.now().isoformat(),

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
import ddt
from osc_lib import exceptions from osc_lib import exceptions
from osc_lib import utils as oscutils from osc_lib import utils as oscutils
@ -36,6 +37,7 @@ class TestShareSecurityService(manila_fakes.TestShare):
) )
@ddt.ddt
class TestShareSecurityServiceCreate(TestShareSecurityService): class TestShareSecurityServiceCreate(TestShareSecurityService):
def setUp(self): def setUp(self):
@ -67,7 +69,8 @@ class TestShareSecurityServiceCreate(TestShareSecurityService):
'--user', self.security_service.user, '--user', self.security_service.user,
'--password', self.security_service.password, '--password', self.security_service.password,
'--name', self.security_service.name, '--name', self.security_service.name,
'--description', self.security_service.description '--description', self.security_service.description,
'--default-ad-site', self.security_service.default_ad_site
] ]
verifylist = [ verifylist = [
('type', self.security_service.type), ('type', self.security_service.type),
@ -78,7 +81,8 @@ class TestShareSecurityServiceCreate(TestShareSecurityService):
('user', self.security_service.user), ('user', self.security_service.user),
('password', self.security_service.password), ('password', self.security_service.password),
('name', self.security_service.name), ('name', self.security_service.name),
('description', self.security_service.description) ('description', self.security_service.description),
('default_ad_site', self.security_service.default_ad_site)
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -93,26 +97,37 @@ class TestShareSecurityServiceCreate(TestShareSecurityService):
password=self.security_service.password, password=self.security_service.password,
name=self.security_service.name, name=self.security_service.name,
description=self.security_service.description, description=self.security_service.description,
ou=self.security_service.ou ou=self.security_service.ou,
default_ad_site=self.security_service.default_ad_site
) )
self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_share_security_service_create_api_version_exception(self): @ddt.data('2.43', '2.75')
def test_share_security_service_create_api_version_exception(self,
version):
self.app.client_manager.share.api_version = api_versions.APIVersion( self.app.client_manager.share.api_version = api_versions.APIVersion(
'2.43' version
) )
arglist = [ arglist = [
self.security_service.type, self.security_service.type,
'--ou', self.security_service.ou,
] ]
verifylist = [ verifylist = [
('type', self.security_service.type), ('type', self.security_service.type),
('ou', self.security_service.ou),
] ]
if api_versions.APIVersion(version) <= api_versions.APIVersion("2.43"):
arglist.extend(['--ou', self.security_service.ou])
verifylist.append(('ou', self.security_service.ou))
if api_versions.APIVersion(version) <= api_versions.APIVersion("2.75"):
arglist.extend(['--default-ad-site',
self.security_service.default_ad_site])
verifylist.append(('default_ad_site',
self.security_service.default_ad_site))
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises( self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args)
@ -215,6 +230,7 @@ class TestShareSecurityServiceShow(TestShareSecurityService):
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
@ddt.ddt
class TestShareSecurityServiceSet(TestShareSecurityService): class TestShareSecurityServiceSet(TestShareSecurityService):
def setUp(self): def setUp(self):
@ -243,7 +259,8 @@ class TestShareSecurityServiceSet(TestShareSecurityService):
'--user', self.security_service.user, '--user', self.security_service.user,
'--password', self.security_service.password, '--password', self.security_service.password,
'--name', self.security_service.name, '--name', self.security_service.name,
'--description', self.security_service.description '--description', self.security_service.description,
'--default-ad-site', self.security_service.default_ad_site
] ]
verifylist = [ verifylist = [
('security_service', self.security_service.id), ('security_service', self.security_service.id),
@ -254,7 +271,8 @@ class TestShareSecurityServiceSet(TestShareSecurityService):
('user', self.security_service.user), ('user', self.security_service.user),
('password', self.security_service.password), ('password', self.security_service.password),
('name', self.security_service.name), ('name', self.security_service.name),
('description', self.security_service.description) ('description', self.security_service.description),
('default_ad_site', self.security_service.default_ad_site)
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -268,7 +286,8 @@ class TestShareSecurityServiceSet(TestShareSecurityService):
password=self.security_service.password, password=self.security_service.password,
name=self.security_service.name, name=self.security_service.name,
description=self.security_service.description, description=self.security_service.description,
ou=self.security_service.ou ou=self.security_service.ou,
default_ad_site=self.security_service.default_ad_site,
) )
self.assertIsNone(result) self.assertIsNone(result)
@ -289,25 +308,35 @@ class TestShareSecurityServiceSet(TestShareSecurityService):
self.assertRaises( self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args)
def test_share_security_service_set_api_version_exception(self): @ddt.data('2.43', '2.75')
def test_share_security_service_set_api_version_exception(self, version):
self.app.client_manager.share.api_version = api_versions.APIVersion( self.app.client_manager.share.api_version = api_versions.APIVersion(
'2.43' version
) )
arglist = [ arglist = [
self.security_service.id, self.security_service.id,
'--ou', self.security_service.ou,
] ]
verifylist = [ verifylist = [
('security_service', self.security_service.id), ('security_service', self.security_service.id),
('ou', self.security_service.ou),
] ]
if api_versions.APIVersion(version) <= api_versions.APIVersion("2.43"):
arglist.extend(['--ou', self.security_service.ou])
verifylist.append(('ou', self.security_service.ou))
if api_versions.APIVersion(version) <= api_versions.APIVersion("2.75"):
arglist.extend(['--default-ad-site',
self.security_service.default_ad_site])
verifylist.append(('default_ad_site',
self.security_service.default_ad_site))
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises( self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args)
@ddt.ddt
class TestShareSecurityServiceUnset(TestShareSecurityService): class TestShareSecurityServiceUnset(TestShareSecurityService):
def setUp(self): def setUp(self):
@ -337,6 +366,7 @@ class TestShareSecurityServiceUnset(TestShareSecurityService):
'--password', '--password',
'--name', '--name',
'--description', '--description',
'--default-ad-site',
] ]
verifylist = [ verifylist = [
('security_service', self.security_service.id), ('security_service', self.security_service.id),
@ -347,7 +377,8 @@ class TestShareSecurityServiceUnset(TestShareSecurityService):
('user', True), ('user', True),
('password', True), ('password', True),
('name', True), ('name', True),
('description', True) ('description', True),
('default_ad_site', True)
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -361,7 +392,8 @@ class TestShareSecurityServiceUnset(TestShareSecurityService):
password='', password='',
name='', name='',
description='', description='',
ou='' ou='',
default_ad_site=''
) )
self.assertIsNone(result) self.assertIsNone(result)
@ -382,20 +414,28 @@ class TestShareSecurityServiceUnset(TestShareSecurityService):
self.assertRaises( self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args)
def test_share_security_service_unset_api_version_exception(self): @ddt.data('2.43', '2.75')
def test_share_security_service_unset_api_version_exception(self,
version):
self.app.client_manager.share.api_version = api_versions.APIVersion( self.app.client_manager.share.api_version = api_versions.APIVersion(
'2.43' version
) )
arglist = [ arglist = [
self.security_service.id, self.security_service.id,
'--ou',
] ]
verifylist = [ verifylist = [
('security_service', self.security_service.id), ('security_service', self.security_service.id),
('ou', True),
] ]
if api_versions.APIVersion(version) <= api_versions.APIVersion("2.43"):
arglist.extend(['--ou'])
verifylist.append(('ou', True))
if api_versions.APIVersion(version) <= api_versions.APIVersion("2.75"):
arglist.extend(['--default-ad-site']),
verifylist.append(('default_ad_site', True))
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises( self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args)
@ -460,6 +500,7 @@ class TestShareSecurityServiceList(TestShareSecurityService):
'--ou', self.services_list[0].ou, '--ou', self.services_list[0].ou,
'--server', self.services_list[0].server, '--server', self.services_list[0].server,
'--domain', self.services_list[0].domain, '--domain', self.services_list[0].domain,
'--default-ad-site', self.services_list[0].default_ad_site,
'--limit', '1', '--limit', '1',
] ]
verifylist = [ verifylist = [
@ -472,6 +513,7 @@ class TestShareSecurityServiceList(TestShareSecurityService):
('ou', self.services_list[0].ou), ('ou', self.services_list[0].ou),
('server', self.services_list[0].server), ('server', self.services_list[0].server),
('domain', self.services_list[0].domain), ('domain', self.services_list[0].domain),
('default_ad_site', self.services_list[0].default_ad_site),
('limit', 1), ('limit', 1),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -488,6 +530,7 @@ class TestShareSecurityServiceList(TestShareSecurityService):
'dns_ip': self.services_list[0].dns_ip, 'dns_ip': self.services_list[0].dns_ip,
'server': self.services_list[0].server, 'server': self.services_list[0].server,
'domain': self.services_list[0].domain, 'domain': self.services_list[0].domain,
'default_ad_site': self.services_list[0].default_ad_site,
'offset': None, 'offset': None,
'limit': 1, 'limit': 1,
'ou': self.services_list[0].ou, 'ou': self.services_list[0].ou,
@ -513,6 +556,21 @@ class TestShareSecurityServiceList(TestShareSecurityService):
self.assertRaises( self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args) exceptions.CommandError, self.cmd.take_action, parsed_args)
def test_share_security_service_list_ad_site_api_version_exception(self):
self.app.client_manager.share.api_version = api_versions.APIVersion(
'2.75'
)
arglist = [
'--default-ad-site', self.services_list[0].default_ad_site,
]
verifylist = [
('default_ad_site', self.services_list[0].default_ad_site),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args)
def test_share_security_service_list_detail_all_projects(self): def test_share_security_service_list_detail_all_projects(self):
arglist = [ arglist = [
'--all-projects', '--all-projects',

View File

@ -15,12 +15,15 @@
from unittest import mock from unittest import mock
import ddt
from manilaclient import exceptions from manilaclient import exceptions
from manilaclient.tests.unit import utils from manilaclient.tests.unit import utils
from manilaclient.tests.unit.v2 import fakes from manilaclient.tests.unit.v2 import fakes
from manilaclient.v2 import security_services from manilaclient.v2 import security_services
@ddt.ddt
class SecurityServiceTest(utils.TestCase): class SecurityServiceTest(utils.TestCase):
class _FakeSecurityService(object): class _FakeSecurityService(object):
@ -54,6 +57,31 @@ class SecurityServiceTest(utils.TestCase):
self.assertEqual(result['body'][security_services.RESOURCE_NAME], self.assertEqual(result['body'][security_services.RESOURCE_NAME],
values) values)
@ddt.data({'server': 'fake.ad.server'},
{'default_ad_site': 'fake.ad.default_ad_site'})
def test_create_all_fields_active_directory(self, option):
values = {
'type': 'active_directory',
'dns_ip': 'fake dns ip',
'ou': 'fake ou',
'domain': 'fake.ad.domain',
'user': 'fake user',
'password': 'fake password',
'name': 'fake name',
'description': 'fake description',
}
values.update(option)
with mock.patch.object(self.manager, '_create', fakes.fake_create):
result = self.manager.create(**values)
self.assertEqual(result['url'], security_services.RESOURCES_PATH)
self.assertEqual(result['resp_key'],
security_services.RESOURCE_NAME)
self.assertIn(security_services.RESOURCE_NAME, result['body'])
self.assertEqual(result['body'][security_services.RESOURCE_NAME],
values)
def test_create_some_fields(self): def test_create_some_fields(self):
values = { values = {
'type': 'ldap', 'type': 'ldap',

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from manilaclient import api_versions
from manilaclient import base from manilaclient import base
from manilaclient import exceptions from manilaclient import exceptions
@ -41,6 +42,7 @@ class SecurityServiceManager(base.ManagerWithFind):
resource_class = SecurityService resource_class = SecurityService
@api_versions.wraps("1.0", "2.75")
def create(self, type, dns_ip=None, ou=None, server=None, domain=None, def create(self, type, dns_ip=None, ou=None, server=None, domain=None,
user=None, password=None, name=None, user=None, password=None, name=None,
description=None): description=None):
@ -58,6 +60,42 @@ class SecurityServiceManager(base.ManagerWithFind):
:param description: security service description :param description: security service description
:rtype: :class:`SecurityService` :rtype: :class:`SecurityService`
""" """
return self._create_security_service(type, dns_ip=dns_ip, ou=ou,
server=server, domain=domain,
user=user, password=password,
name=name,
description=description)
@api_versions.wraps("2.76") # noqa
def create(self, type, dns_ip=None, ou=None, server=None, # noqa
domain=None, user=None, password=None, name=None,
description=None, default_ad_site=None):
"""Create security service for NAS.
:param type: security service type - 'ldap', 'kerberos' or
'active_directory'
:param dns_ip: dns ip address used inside tenant's network
:param ou: security service organizational unit
:param server: security service server ip address or hostname
:param domain: security service domain
:param user: security identifier used by tenant
:param password: password used by user
:param name: security service name
:param description: security service description
:param default_ad_site: default AD-Site
:rtype: :class:`SecurityService`
"""
return self._create_security_service(type, dns_ip=dns_ip, ou=ou,
server=server, domain=domain,
user=user, password=password,
name=name,
description=description,
default_ad_site=default_ad_site)
def _create_security_service(self, type, dns_ip=None, ou=None,
server=None, domain=None, user=None,
password=None, name=None,
description=None, default_ad_site=None):
values = {'type': type} values = {'type': type}
if dns_ip: if dns_ip:
values['dns_ip'] = dns_ip values['dns_ip'] = dns_ip
@ -75,6 +113,8 @@ class SecurityServiceManager(base.ManagerWithFind):
values['name'] = name values['name'] = name
if description: if description:
values['description'] = description values['description'] = description
if default_ad_site:
values['default_ad_site'] = default_ad_site
body = {RESOURCE_NAME: values} body = {RESOURCE_NAME: values}
@ -91,6 +131,7 @@ class SecurityServiceManager(base.ManagerWithFind):
RESOURCE_NAME, RESOURCE_NAME,
) )
@api_versions.wraps("1.0", "2.75")
def update(self, security_service, dns_ip=None, ou=None, server=None, def update(self, security_service, dns_ip=None, ou=None, server=None,
domain=None, password=None, user=None, name=None, domain=None, password=None, user=None, name=None,
description=None): description=None):
@ -107,7 +148,41 @@ class SecurityServiceManager(base.ManagerWithFind):
:param description: security service description :param description: security service description
:rtype: :class:`SecurityService` :rtype: :class:`SecurityService`
""" """
return self._update_security_service(security_service, dns_ip=dns_ip,
ou=ou, server=server,
domain=domain, password=password,
user=user, name=name,
description=description)
@api_versions.wraps("2.76") # noqa
def update(self, security_service, dns_ip=None, ou=None, # noqa
server=None, domain=None, password=None, user=None,
name=None, description=None, default_ad_site=None):
"""Updates a security service.
:param security_service: security service to update.
:param dns_ip: dns ip address used inside tenant's network
:param ou: security service organizational unit
:param server: security service server ip address or hostname
:param domain: security service domain
:param user: security identifier used by tenant
:param password: password used by user
:param name: security service name
:param description: security service description
:param default_ad_site: default AD-Site
:rtype: :class:`SecurityService`
"""
return self._update_security_service(security_service, dns_ip=dns_ip,
ou=ou, server=server,
domain=domain, password=password,
user=user, name=name,
description=description,
default_ad_site=default_ad_site)
def _update_security_service(self, security_service, dns_ip=None, ou=None,
server=None, domain=None, password=None,
user=None, name=None, description=None,
default_ad_site=None):
values = {} values = {}
if dns_ip is not None: if dns_ip is not None:
values['dns_ip'] = dns_ip values['dns_ip'] = dns_ip
@ -125,6 +200,8 @@ class SecurityServiceManager(base.ManagerWithFind):
values['name'] = name values['name'] = name
if description is not None: if description is not None:
values['description'] = description values['description'] = description
if default_ad_site is not None:
values['default_ad_site'] = default_ad_site
for k, v in values.items(): for k, v in values.items():
if v == '': if v == '':

View File

@ -4189,6 +4189,13 @@ def do_share_network_delete(cs, args):
metavar='<name>', metavar='<name>',
default=None, default=None,
help="Security service name.") help="Security service name.")
@cliutils.arg(
'--default-ad-site',
metavar='<default_ad_site>',
dest='default_ad_site',
default=None,
help="Default AD site. Available only for microversion >= 2.76. Can "
"be provided in the place of '--server' but not along with it.")
@cliutils.arg( @cliutils.arg(
'--description', '--description',
metavar='<description>', metavar='<description>',
@ -4214,6 +4221,21 @@ def do_security_service_create(cs, args):
"Security service Organizational Unit (ou) option " "Security service Organizational Unit (ou) option "
"is only available with manila API version >= 2.44") "is only available with manila API version >= 2.44")
if cs.api_version.matches(api_versions.APIVersion("2.76"),
api_versions.APIVersion()):
values['default_ad_site'] = args.default_ad_site
elif args.default_ad_site:
raise exceptions.CommandError(
"Default AD site option is only available with "
"manila API version >= 2.76")
if args.type == 'active_directory':
if args.server and args.default_ad_site:
raise exceptions.CommandError(
"Cannot create security service because both "
"server and 'default_ad_site' were provided. "
"Specify either server or 'default_ad_site'.")
security_service = cs.security_services.create(args.type, **values) security_service = cs.security_services.create(args.type, **values)
info = security_service._info.copy() info = security_service._info.copy()
cliutils.print_dict(info) cliutils.print_dict(info)
@ -4259,6 +4281,12 @@ def do_security_service_create(cs, args):
metavar='<name>', metavar='<name>',
default=None, default=None,
help="Security service name.") help="Security service name.")
@cliutils.arg(
'--default-ad-site',
metavar='<default_ad_site>',
dest='default_ad_site',
default=None,
help="Default AD site. Available only for microversion >= 2.76.")
@cliutils.arg( @cliutils.arg(
'--description', '--description',
metavar='<description>', metavar='<description>',
@ -4284,6 +4312,14 @@ def do_security_service_update(cs, args):
"Security service Organizational Unit (ou) option " "Security service Organizational Unit (ou) option "
"is only available with manila API version >= 2.44") "is only available with manila API version >= 2.44")
if cs.api_version.matches(api_versions.APIVersion("2.76"),
api_versions.APIVersion()):
values['default_ad_site'] = args.default_ad_site
elif args.default_ad_site:
raise exceptions.CommandError(
"Default AD site option is only available with "
"manila API version >= 2.76")
security_service = _find_security_service( security_service = _find_security_service(
cs, args.security_service).update(**values) cs, args.security_service).update(**values)
cliutils.print_dict(security_service._info) cliutils.print_dict(security_service._info)
@ -4379,6 +4415,12 @@ def do_security_service_show(cs, args):
metavar="<limit>", metavar="<limit>",
default=None, default=None,
help='Number of security services to return per request.') help='Number of security services to return per request.')
@cliutils.arg(
'--default-ad-site',
metavar='<default_ad_site>',
dest='default_ad_site',
default=None,
help="Default AD site. Available only for microversion >= 2.76.")
@cliutils.arg( @cliutils.arg(
'--columns', '--columns',
metavar='<columns>', metavar='<columns>',
@ -4414,6 +4456,14 @@ def do_security_service_list(cs, args):
"Security service Organizational Unit (ou) option " "Security service Organizational Unit (ou) option "
"is only available with manila API version >= 2.44") "is only available with manila API version >= 2.44")
if cs.api_version.matches(api_versions.APIVersion("2.76"),
api_versions.APIVersion()):
search_opts['default_ad_site'] = args.default_ad_site
elif args.ou:
raise exceptions.CommandError(
"Security service Default AD site option "
"is only available with manila API version >= 2.76")
if args.share_network: if args.share_network:
search_opts['share_network_id'] = _find_share_network( search_opts['share_network_id'] = _find_share_network(
cs, args.share_network).id cs, args.share_network).id

View File

@ -0,0 +1,6 @@
---
features:
- |
Users are now able to set a default active directory site while creating
security services by specifying 'default_ad_site'. Refer `Launchpad bug
#1988146 <https://bugs.launchpad.net/python-manilaclient/+bug/1988146>`_