diff --git a/masakariclient/cliargs.py b/masakariclient/cliargs.py deleted file mode 100644 index 9cea2cb..0000000 --- a/masakariclient/cliargs.py +++ /dev/null @@ -1,171 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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 argparse - -from masakariclient.common.i18n import _ -from masakariclient.common import utils - - -def add_global_args(parser, version): - # GLOBAL ARGUMENTS - parser.add_argument( - '-h', '--help', action='store_true', - help=argparse.SUPPRESS) - - parser.add_argument( - '--masakari-api-version', action='version', version=version, - default=utils.env('MASAKARI_API_VERSION', default='1'), - help=_('Version number for Masakari API to use, Default to "1".')) - - parser.add_argument( - '-d', '--debug', - action='store_true', - default=False, - help=_('Print debugging output.')) - - -def add_global_identity_args(parser): - parser.add_argument( - '--os-auth-plugin', dest='auth_plugin', metavar='AUTH_PLUGIN', - default=utils.env('OS_AUTH_PLUGIN', default=None), - help=_('Authentication plugin, default to env[OS_AUTH_PLUGIN]')) - - parser.add_argument( - '--os-auth-url', dest='auth_url', metavar='AUTH_URL', - default=utils.env('OS_AUTH_URL'), - help=_('Defaults to env[OS_AUTH_URL]')) - - parser.add_argument( - '--os-project-id', dest='project_id', metavar='PROJECT_ID', - default=utils.env('OS_PROJECT_ID'), - help=_('Defaults to env[OS_PROJECT_ID].')) - - parser.add_argument( - '--os-project-name', dest='project_name', metavar='PROJECT_NAME', - default=utils.env('OS_PROJECT_NAME'), - help=_('Defaults to env[OS_PROJECT_NAME].')) - - parser.add_argument( - '--os-tenant-id', dest='tenant_id', metavar='TENANT_ID', - default=utils.env('OS_TENANT_ID'), - help=_('Defaults to env[OS_TENANT_ID].')) - - parser.add_argument( - '--os-tenant-name', dest='tenant_name', metavar='TENANT_NAME', - default=utils.env('OS_TENANT_NAME'), - help=_('Defaults to env[OS_TENANT_NAME].')) - - parser.add_argument( - '--os-domain-id', dest='domain_id', metavar='DOMAIN_ID', - default=utils.env('OS_DOMAIN_ID'), - help=_('Domain ID for scope of authorization, defaults to ' - 'env[OS_DOMAIN_ID].')) - - parser.add_argument( - '--os-domain-name', dest='domain_name', metavar='DOMAIN_NAME', - default=utils.env('OS_DOMAIN_NAME'), - help=_('Domain name for scope of authorization, defaults to ' - 'env[OS_DOMAIN_NAME].')) - - parser.add_argument( - '--os-project-domain-id', dest='project_domain_id', - metavar='PROJECT_DOMAIN_ID', - default=utils.env('OS_PROJECT_DOMAIN_ID'), - help=_('Project domain ID for scope of authorization, defaults to ' - 'env[OS_PROJECT_DOMAIN_ID].')) - - parser.add_argument( - '--os-project-domain-name', dest='project_domain_name', - metavar='PROJECT_DOMAIN_NAME', - default=utils.env('OS_PROJECT_DOMAIN_NAME'), - help=_('Project domain name for scope of authorization, defaults to ' - 'env[OS_PROJECT_DOMAIN_NAME].')) - - parser.add_argument( - '--os-user-domain-id', dest='user_domain_id', - metavar='USER_DOMAIN_ID', - default=utils.env('OS_USER_DOMAIN_ID'), - help=_('User domain ID for scope of authorization, defaults to ' - 'env[OS_USER_DOMAIN_ID].')) - - parser.add_argument( - '--os-user-domain-name', dest='user_domain_name', - metavar='USER_DOMAIN_NAME', - default=utils.env('OS_USER_DOMAIN_NAME'), - help=_('User domain name for scope of authorization, defaults to ' - 'env[OS_USER_DOMAIN_NAME].')) - - parser.add_argument( - '--os-username', dest='username', metavar='USERNAME', - default=utils.env('OS_USERNAME'), - help=_('Defaults to env[OS_USERNAME].')) - - parser.add_argument( - '--os-user-id', dest='user_id', metavar='USER_ID', - default=utils.env('OS_USER_ID'), - help=_('Defaults to env[OS_USER_ID].')) - - parser.add_argument( - '--os-password', dest='password', metavar='PASSWORD', - default=utils.env('OS_PASSWORD'), - help=_('Defaults to env[OS_PASSWORD]')) - - parser.add_argument( - '--os-trust-id', dest='trust_id', metavar='TRUST_ID', - default=utils.env('OS_TRUST_ID'), - help=_('Defaults to env[OS_TRUST_ID]')) - - verify_group = parser.add_mutually_exclusive_group() - - verify_group.add_argument( - '--os-cacert', dest='verify', metavar='CA_BUNDLE_FILE', - default=utils.env('OS_CACERT', default=True), - help=_('Path of CA TLS certificate(s) used to verify the remote ' - 'server\'s certificate. Without this option masakari looks ' - 'for the default system CA certificates.')) - - verify_group.add_argument( - '--verify', - action='store_true', - help=_('Verify server certificate (default)')) - - verify_group.add_argument( - '--insecure', dest='verify', action='store_false', - help=_('Explicitly allow masakariclient to perform "insecure SSL" ' - '(HTTPS) requests. The server\'s certificate will not be ' - 'verified against any certificate authorities. This ' - 'option should be used with caution.')) - - parser.add_argument( - '--os-token', dest='token', metavar='TOKEN', - default=utils.env('OS_TOKEN', default=None), - help=_('A string token to bootstrap the Keystone database, defaults ' - 'to env[OS_TOKEN]')) - - parser.add_argument( - '--os-access-info', dest='access_info', metavar='ACCESS_INFO', - default=utils.env('OS_ACCESS_INFO'), - help=_('Access info, defaults to env[OS_ACCESS_INFO]')) - - parser.add_argument( - '--os-interface', dest='interface', metavar='INTERFACE', - default=utils.env('OS_INTERFACE', default='internal'), - help=_('API Interface to use [public, internal, admin]' - ', defaults to env[OS_INTERFACE]')) - - parser.add_argument( - '--os-region-name', dest='region_name', metavar='REGION_NAME', - default=utils.env('OS_REGION_NAME'), - help=_('Region of the cloud to use, defaults to env[OS_REGION_NAME]')) diff --git a/masakariclient/client.py b/masakariclient/client.py deleted file mode 100644 index 586b2f8..0000000 --- a/masakariclient/client.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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. - -from masakariclient.common import utils - - -def Client(api_ver, *args, **kwargs): - """Import versioned client module. - - :param api_ver: API version required. - :param args: API args. - :param kwargs: the auth parameters for client. - """ - module = utils.import_versioned_module(api_ver, 'client') - cls = getattr(module, 'Client') - - return cls(*args, **kwargs) diff --git a/masakariclient/common/utils.py b/masakariclient/common/utils.py index 6b05b9a..a1fa3a6 100644 --- a/masakariclient/common/utils.py +++ b/masakariclient/common/utils.py @@ -12,20 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os -import prettytable -import textwrap - -from oslo_serialization import jsonutils -from oslo_utils import encodeutils -from oslo_utils import importutils from oslo_utils import uuidutils from masakariclient.common import exception as exc from masakariclient.common.i18n import _ -def format_parameters(params, parse_semicolon=True): +def _format_parameters(params, parse_semicolon=True): """Reformat parameters into dict of format expected by the API.""" if not params: return {} @@ -62,113 +55,6 @@ def remove_unspecified_items(attrs): return attrs -def import_versioned_module(version, submodule=None): - module = 'masakariclient.v%s' % version - if submodule: - module = '.'.join((module, submodule)) - return importutils.import_module(module) - - -def arg(*args, **kwargs): - """Decorator for CLI args.""" - - def _decorator(func): - if not hasattr(func, 'arguments'): - func.arguments = [] - - if (args, kwargs) not in func.arguments: - func.arguments.insert(0, (args, kwargs)) - - return func - - return _decorator - - -def env(*args, **kwargs): - """Returns the first environment variable set. - - If all are empty, defaults to '' or keyword arg `default`. - """ - for arg in args: - value = os.environ.get(arg) - if value: - return value - return kwargs.get('default', '') - - -def print_list(objs, fields, formatters={}, sortby_index=None): - """Print list data by PrettyTable.""" - - if sortby_index is None: - sortby = None - else: - sortby = fields[sortby_index] - mixed_case_fields = ['serverId'] - pt = prettytable.PrettyTable([f for f in fields], caching=False) - pt.align = 'l' - - for o in objs: - row = [] - for field in fields: - if field in formatters: - row.append(formatters[field](o)) - else: - if field in mixed_case_fields: - field_name = field.replace(' ', '_') - else: - field_name = field.lower().replace(' ', '_') - data = getattr(o, field_name, '') - if data is None: - data = '-' - # '\r' would break the table, so remove it. - data = str(data).replace("\r", "") - row.append(data) - pt.add_row(row) - - if sortby is not None: - result = encodeutils.safe_encode(pt.get_string(sortby=sortby)) - else: - result = encodeutils.safe_encode(pt.get_string()) - - result = result.decode() - - print(result) - - -def print_dict(d, dict_property="Property", dict_value="Value", wrap=0): - """Print dictionary data (eg. show) by PrettyTable.""" - - pt = prettytable.PrettyTable([dict_property, dict_value], caching=False) - pt.align = 'l' - for k, v in sorted(d.items()): - # convert dict to str to check length - if isinstance(v, (dict, list)): - v = jsonutils.dumps(v) - if wrap > 0: - v = textwrap.fill(str(v), wrap) - # if value has a newline, add in multiple rows - # e.g. fault with stacktrace - if v and isinstance(v, str) and (r'\n' in v or '\r' in v): - # '\r' would break the table, so remove it. - if '\r' in v: - v = v.replace('\r', '') - lines = v.strip().split(r'\n') - col1 = k - for line in lines: - pt.add_row([col1, line]) - col1 = '' - else: - if v is None: - v = '-' - pt.add_row([k, v]) - - result = encodeutils.safe_encode(pt.get_string()) - - result = result.decode() - - print(result) - - def format_sort_filter_params(parsed_args): queries = {} limit = parsed_args.limit @@ -196,7 +82,7 @@ def format_sort_filter_params(parsed_args): queries['sort_dir'] = sort_dirs if parsed_args.filters: - queries.update(format_parameters(parsed_args.filters)) + queries.update(_format_parameters(parsed_args.filters)) return queries diff --git a/masakariclient/shell.py b/masakariclient/shell.py deleted file mode 100644 index b450edd..0000000 --- a/masakariclient/shell.py +++ /dev/null @@ -1,206 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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 argparse -import logging -import sys - -from oslo_utils import encodeutils - -import masakariclient -from masakariclient import cliargs -from masakariclient import client as masakari_client -from masakariclient.common import exception as exc -from masakariclient.common.i18n import _ -from masakariclient.common import utils - -USER_AGENT = 'python-masakariclient' -LOG = logging.getLogger(__name__) - - -class MasakariShell(object): - def __init__(self): - pass - - def do_bash_completion(self, args): - """All of the commands and options to stdout.""" - commands = set() - options = set() - for sc_str, sc in self.subcommands.items(): - if sc_str == 'bash_completion' or sc_str == 'bash-completion': - continue - - commands.add(sc_str) - for option in list(sc._optionals._option_string_actions): - options.add(option) - - print(' '.join(commands | options)) - - def _add_bash_completion_subparser(self, subparsers): - subparser = subparsers.add_parser('bash_completion', - add_help=False, - formatter_class=HelpFormatter) - - subparser.set_defaults(func=self.do_bash_completion) - self.subcommands['bash_completion'] = subparser - - def _get_subcommand_parser(self, base_parser, version): - parser = base_parser - - self.subcommands = {} - subparsers = parser.add_subparsers(metavar='') - submodule = utils.import_versioned_module(version, 'shell') - self._find_actions(subparsers, submodule) - self._add_bash_completion_subparser(subparsers) - - return parser - - def _find_actions(self, subparsers, actions_module): - for attr in (a for a in dir(actions_module) if a.startswith('do_')): - command = attr[3:].replace('_', '-') - callback = getattr(actions_module, attr) - - desc = callback.__doc__ or '' - help = desc.strip().split('\n')[0] - arguments = getattr(callback, 'arguments', []) - - subparser = subparsers.add_parser(command, - help=help, - description=desc, - add_help=False, - formatter_class=HelpFormatter) - - subparser.add_argument('-h', '--help', - action='help', - help=argparse.SUPPRESS) - - for (args, kwargs) in arguments: - subparser.add_argument(*args, **kwargs) - subparser.set_defaults(func=callback) - - self.subcommands[command] = subparser - - def _setup_masakari_client(self, api_ver, args): - """Create masakari client using given args.""" - kwargs = { - 'auth_plugin': args.auth_plugin or 'password', - 'auth_url': args.auth_url, - 'project_name': args.project_name or args.tenant_name, - 'project_id': args.project_id or args.tenant_id, - 'domain_name': args.domain_name, - 'domain_id': args.domain_id, - 'project_domain_name': args.project_domain_name, - 'project_domain_id': args.project_domain_id, - 'user_domain_name': args.user_domain_name, - 'user_domain_id': args.user_domain_id, - 'username': args.username, - 'user_id': args.user_id, - 'password': args.password, - 'verify': args.verify, - 'token': args.token, - 'trust_id': args.trust_id, - 'interface': args.interface, - 'region_name': args.region_name, - } - - return masakari_client.Client(api_ver, user_agent=USER_AGENT, **kwargs) - - def _setup_logging(self, debug): - if debug: - log_level = logging.DEBUG - else: - log_level = logging.WARNING - log_format = "%(levelname)s (%(module)s) %(message)s" - logging.basicConfig(format=log_format, level=log_level) - logging.getLogger('iso8601').setLevel(logging.WARNING) - logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING) - - def main(self, argv): - - parser = argparse.ArgumentParser( - prog='masakari', - description="masakari shell", - epilog='Type "masakari help " for help on a specific ' - 'command.', - add_help=False, - ) - # add add arguments - cliargs.add_global_args(parser, masakariclient.__version__) - cliargs.add_global_identity_args(parser) - - # parse main arguments - (options, args) = parser.parse_known_args(argv) - - self._setup_logging(options.debug) - - base_parser = parser - api_ver = options.masakari_api_version - - # add subparser - subcommand_parser = self._get_subcommand_parser(base_parser, api_ver) - self.parser = subcommand_parser - - # --help/-h or no arguments - if not args and options.help or not argv: - self.do_help(options) - return 0 - - args = subcommand_parser.parse_args(argv) - - sc = self._setup_masakari_client(api_ver, args) - # call specified function - args.func(sc.service, args) - - @utils.arg('command', metavar='', nargs='?', - help=_('Display help for .')) - def do_help(self, args): - """Display help about this program or one of its subcommands.""" - if getattr(args, 'command', None): - if args.command in self.subcommands: - self.subcommands[args.command].print_help() - else: - raise exc.CommandError("'%s' is not a valid subcommand" % - args.command) - else: - self.parser.print_help() - - -class HelpFormatter(argparse.HelpFormatter): - def start_section(self, heading): - heading = '%s%s' % (heading[0].upper(), heading[1:]) - super(HelpFormatter, self).start_section(heading) - - -def main(args=None): - try: - print(_("Deprecated: masakari CLI is deprecated and will be removed " - "after Stein is released. Use openstack CLI instead."), - file=sys.stderr) - if args is None: - args = sys.argv[1:] - - MasakariShell().main(args) - except KeyboardInterrupt: - print(_("KeyboardInterrupt masakari client"), sys.stderr) - return 130 - except Exception as e: - if '--debug' in args or '-d' in args: - raise - else: - print(encodeutils.safe_encode(str(e), sys.stderr)) - return 1 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/masakariclient/tests/unit/test_cliargs.py b/masakariclient/tests/unit/test_cliargs.py deleted file mode 100644 index 559ab59..0000000 --- a/masakariclient/tests/unit/test_cliargs.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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 testtools -from unittest import mock - -from masakariclient import cliargs - - -class TestCliArgs(testtools.TestCase): - - def test_add_global_identity_args(self): - parser = mock.Mock() - cliargs.add_global_identity_args(parser) - expected = [ - '--os-auth-plugin', - '--os-auth-url', - '--os-project-id', - '--os-project-name', - '--os-tenant-id', - '--os-tenant-name', - '--os-domain-id', - '--os-domain-name', - '--os-project-domain-id', - '--os-project-domain-name', - '--os-user-domain-id', - '--os-user-domain-name', - '--os-username', - '--os-user-id', - '--os-password', - '--os-trust-id', - '--os-token', - '--os-access-info', - '--os-interface', - '--os-region-name' - ] - - options = [arg[0][0] for arg in parser.add_argument.call_args_list] - self.assertEqual(expected, options) - - parser.add_mutually_exclusive_group.assert_called_once_with() - group = parser.add_mutually_exclusive_group.return_value - - verify_opts = [arg[0][0] for arg in group.add_argument.call_args_list] - verify_args = [ - '--os-cacert', - '--verify', - '--insecure' - ] - self.assertEqual(verify_args, verify_opts) - - def test_add_global_args(self): - parser = mock.Mock() - cliargs.add_global_args(parser, '1') - expected = [ - '-h', - '--masakari-api-version', - '-d' - ] - - options = [arg[0][0] for arg in parser.add_argument.call_args_list] - self.assertEqual(expected, options) diff --git a/masakariclient/tests/unit/test_client.py b/masakariclient/tests/unit/test_client.py deleted file mode 100644 index 618a95e..0000000 --- a/masakariclient/tests/unit/test_client.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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. - -""" -test_masakariclient ----------------------------------- - -Tests for `masakariclient` module. -""" -from unittest import mock - -from masakariclient import client as mc -from masakariclient.common import utils -from masakariclient.tests import base - - -class FakeClient(object): - - def __init__(self, session): - super(FakeClient, self).__init__() - self.session = session - - -class TestMasakariclient(base.TestCase): - - @mock.patch.object(utils, 'import_versioned_module') - def test_client_init(self, mock_import): - the_module = mock.Mock() - the_module.Client = FakeClient - mock_import.return_value = the_module - session = mock.Mock() - - res = mc.Client('FAKE_VER', session) - - mock_import.assert_called_once_with('FAKE_VER', 'client') - self.assertIsInstance(res, FakeClient) diff --git a/masakariclient/tests/unit/test_shell.py b/masakariclient/tests/unit/test_shell.py deleted file mode 100644 index c9cfdfc..0000000 --- a/masakariclient/tests/unit/test_shell.py +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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. - -""" -test_shell ----------------------------------- - -Tests for `masakariclient` module. -""" -import io -import logging -from unittest import mock - -import sys -import testtools - -from masakariclient import shell -from masakariclient.tests import base - - -class FakeClient(object): - - def __init__(self): - super(FakeClient, self).__init__() - self.service = FakeService() - - -class FakeService(object): - - def __init__(self): - super(FakeService, self).__init__() - - def do_notification_list(self): - pass - - -class HelpFormatterTest(testtools.TestCase): - - def test_start_section(self): - formatter = shell.HelpFormatter('masakari') - res = formatter.start_section(('dummyheading', 'dummy', 'dummy')) - self.assertIsNone(res) - heading = formatter._current_section.heading - self.assertEqual("DUMMYHEADING('dummy', 'dummy')", heading) - - -class TestMasakariShell(base.TestCase): - def setUp(self): - super(TestMasakariShell, self).setUp() - - def _shell(self, func, *args, **kwargs): - orig_out = sys.stdout - sys.stdout = io.StringIO() - func(*args, **kwargs) - output = sys.stdout.getvalue() - sys.stdout.close() - sys.stdout = orig_out - - return output - - def test_do_bash_completion(self): - sh = shell.MasakariShell() - sc1 = mock.Mock() - sc2 = mock.Mock() - sc1._optionals._option_string_actions = ('A1', 'A2', 'C') - sc2._optionals._option_string_actions = ('B1', 'B2', 'C') - sh.subcommands = { - 'command-foo': sc1, - 'command-bar': sc2, - 'bash-completion': None, - 'bash_completion': None, - } - - output = self._shell(sh.do_bash_completion, None) - - output = output.split('\n')[0] - output_list = output.split(' ') - for option in ('A1', 'A2', 'C', 'B1', 'B2', - 'command-foo', 'command-bar'): - self.assertIn(option, output_list) - - @mock.patch.object(logging, 'basicConfig') - @mock.patch.object(logging, 'getLogger') - def test_setup_logging_debug_true(self, moc_getLogger, - moc_basicConfig): - sh = shell.MasakariShell() - sh._setup_logging(True) - - moc_basicConfig.assert_called_once_with( - format="%(levelname)s (%(module)s) %(message)s", - level=logging.DEBUG) - mock_calls = [ - mock.call('iso8601'), - mock.call().setLevel(logging.WARNING), - mock.call('urllib3.connectionpool'), - mock.call().setLevel(logging.WARNING), - ] - moc_getLogger.assert_has_calls(mock_calls) - - @mock.patch.object(logging, 'basicConfig') - @mock.patch.object(logging, 'getLogger') - def test_setup_logging_debug_false(self, - moc_getLogger, - moc_basicConfig): - sh = shell.MasakariShell() - sh._setup_logging(False) - - moc_basicConfig.assert_called_once_with( - format="%(levelname)s (%(module)s) %(message)s", - level=logging.WARNING) - mock_calls = [ - mock.call('iso8601'), - mock.call().setLevel(logging.WARNING), - mock.call('urllib3.connectionpool'), - mock.call().setLevel(logging.WARNING), - ] - moc_getLogger.assert_has_calls(mock_calls) diff --git a/masakariclient/tests/unit/v1/__init__.py b/masakariclient/tests/unit/v1/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/masakariclient/tests/unit/v1/fakes.py b/masakariclient/tests/unit/v1/fakes.py deleted file mode 100644 index 9885966..0000000 --- a/masakariclient/tests/unit/v1/fakes.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright(c) 2017 Nippon Telegraph and Telephone Corporation -# -# 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. - - -class FakeSegment(object): - def __init__(self, segment_values): - self.segment_values = segment_values - - def to_dict(self): - return self.segment_values - - -class FakeHost(object): - def __init__(self, host_values): - self.host_values = host_values - - def to_dict(self): - return self.host_values diff --git a/masakariclient/tests/unit/v1/test_client.py b/masakariclient/tests/unit/v1/test_client.py deleted file mode 100644 index e69d277..0000000 --- a/masakariclient/tests/unit/v1/test_client.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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. -""" -test_masakariclient ----------------------------------- - -Tests for `masakariclient` module. -""" -from unittest import mock - -from keystoneauth1.identity.generic import password as ks_password -from keystoneauth1 import session as ks_session -from openstack import connection - -from masakariclient.tests import base -import masakariclient.v1.client as mc - - -class FakeConnection(object): - - def __init__(self, prof=None, user_agent=None, **kwargs): - super(FakeConnection, self).__init__() - self.ha = None - - -class TestV1Client(base.TestCase): - - def setUp(self): - super(TestV1Client, self).setUp() - self.auth = mock.Mock() - self.session = mock.Mock() - self.conn = mock.Mock() - self.service = mock.Mock() - self.conn.instance_ha = self.service - - @mock.patch.object(connection, 'Connection') - @mock.patch.object(ks_session, 'Session') - @mock.patch.object(ks_password, 'Password') - def test_client_init(self, mock_password, mock_session, mock_connection): - - mock_password.return_value = self.auth - mock_session.return_value = self.session - mock_connection.return_value = self.conn - - fake_auth_url = 'fake_auth_url' - fake_username = 'fake_username' - fake_password = 'fake_password' - fake_user_domain_id = 'fake_user_domain_id' - fake_project_name = 'fake_project_name' - fake_project_domain_id = 'fake_project_domain_id' - fake_interface = 'fake_interface' - fake_region_name = 'fake_region_name' - - res = mc.Client(auth_url=fake_auth_url, - username=fake_username, - password=fake_password, - user_domain_id=fake_user_domain_id, - project_name=fake_project_name, - project_domain_id=fake_project_domain_id, - interface=fake_interface, - region_name=fake_region_name) - - self.assertEqual(self.conn.instance_ha, res.service) - mock_password.assert_called_once_with( - auth_url=fake_auth_url, - username=fake_username, - password=fake_password, - user_domain_id=fake_user_domain_id, - project_name=fake_project_name, - project_domain_id=fake_project_domain_id) - mock_session.assert_called_once_with(auth=self.auth) - mock_connection.assert_called_once_with( - session=self.session, interface=fake_interface, - region_name=fake_region_name, - ha_api_version=None) diff --git a/masakariclient/tests/unit/v1/test_shell.py b/masakariclient/tests/unit/v1/test_shell.py deleted file mode 100644 index 58b2258..0000000 --- a/masakariclient/tests/unit/v1/test_shell.py +++ /dev/null @@ -1,371 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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. -""" -test_masakariclient ----------------------------------- - -Tests for `masakariclient` module. -""" - -from unittest import mock - -import ddt -import io -import sys - -from openstack import exceptions as sdk_exc -from openstack.instance_ha.v1 import _proxy - -from masakariclient.common.i18n import _ -from masakariclient.common import utils -from masakariclient import shell -from masakariclient.tests import base -from masakariclient.tests.unit.v1 import fakes -import masakariclient.v1.shell as ms - - -@ddt.ddt -class TestV1Shell(base.TestCase): - - def setUp(self): - super(TestV1Shell, self).setUp() - self.notification_vals = { - 'notification_uuid': 'b3bf75d7-c2e9-4023-a10b-e5b464b9b539', - 'source_host_uuid': '68fa7386-983e-4497-b5c4-3780f774d302', - 'created_at': '2016-11-15T12:24:39.000000', - 'updated_at': None, - 'payload': {'event': 'STOPPED'}, - 'generated_time': '2016-10-10T10:00:00.000000', - 'type': 'VM', - 'id': '27'} - - self.segment_vals = { - 'uuid': '870da19d-37ec-41d2-a4b2-7be54b0d6ec9', - 'created_at': '2016-11-17T10:08:32.000000', - 'recovery_method': 'auto', - 'updated_at': '2016-11-17T10:09:56.000000', - 'name': 'testsegment05', - 'service_type': 'testsegment01_auto', - 'id': '14', - 'description': 'UPDATE Discription'} - - self.hosts_vals = { - 'reserved': False, - 'uuid': '0951e72c-49f5-46aa-8465-2d61ed3b46d9', - 'deleted': False, - 'on_maintenance': False, - 'created_at': '2016-11-29T11:10:51.000000', - 'control_attributes': 'control-attributesX', - 'updated_at': '2016-11-29T11:30:18.000000', - 'name': 'new_host-3', - 'failover_segment': { - 'uuid': '6b985a8a-f8c0-42e4-beaa-d2fcd8dabbb6', - 'deleted': False, - 'created_at': '2016-11-16T04:46:38.000000', - 'description': None, - 'recovery_method': 'auto', - 'updated_at': None, - 'service_type': 'testsegment01_auto', - 'deleted_at': None, - 'id': 3, - 'name': 'testsegment01'}, - 'deleted_at': None, - 'type': 'typeX', - 'id': 10, - 'failover_segment_id': '6b985a8a-f8c0-42e4-beaa-d2fcd8dabbb6'} - self.hosts_object = fakes.FakeHost(self.hosts_vals) - - def _run_command(self, cmd): - shell.main(cmd.split()) - - @mock.patch.object(utils, 'print_list') - def test_do_notification_list(self, mock_print_list): - service = mock.Mock() - service.notifications.return_value = self.notification_vals - args = mock.Mock() - columns = [ - 'notification_uuid', - 'generated_time', - 'status', - 'source_host_uuid', - 'type'] - - ms.do_notification_list(service, args) - - mock_print_list.assert_called_once_with( - self.notification_vals, - columns) - - @mock.patch.object(utils, 'print_list') - def test_do_segment_list(self, mock_print_list): - service = mock.Mock() - service.segments.return_value = self.segment_vals - args = mock.Mock() - columns = [ - 'uuid', - 'name', - 'description', - 'service_type', - 'recovery_method'] - - ms.do_segment_list(service, args) - - mock_print_list.assert_called_once_with( - self.segment_vals, - columns) - - @mock.patch.object(utils, 'print_dict') - @mock.patch.object(utils, 'get_uuid_by_name') - def test_do_segment_show(self, mock_get_uuid_by_name, mock_print_dict): - mock_get_uuid_by_name.return_value = self.segment_vals.get('uuid') - service = mock.Mock() - segment_object = fakes.FakeSegment(self.segment_vals) - service.get_segment.return_value = segment_object - args = mock.Mock() - - ms.do_segment_show(service, args) - mock_get_uuid_by_name.assert_called_once_with(service, args.id) - mock_print_dict.assert_called_once_with(self.segment_vals) - - @mock.patch.object(utils, 'print_dict') - @ddt.data({"recovery_method": "auto"}, - {"recovery_method": "reserved_host"}, - {"recovery_method": "auto_priority"}, - {"recovery_method": "rh_priority"}) - def test_do_segment_create_with_all_recovery_methods( - self, ddt_data, mock_print_dict): - service = mock.Mock() - args = mock.Mock() - self.segment_vals['recovery_method'] = ddt_data['recovery_method'] - segment_object = fakes.FakeSegment(self.segment_vals) - service.create_segment.return_value = segment_object - self._run_command( - "segment-create " - "--name 'test-segment'" - " --recovery-method %s " - "--service-type test_service" % ddt_data['recovery_method']) - ms.do_segment_create(service, args) - mock_print_dict.assert_called_once_with( - self.segment_vals) - - def test_do_segment_create_with_invalid_recovery_method(self): - cmd = ("segment-create --name 'test-segment' --recovery-method" - " invalid_recovery_method --service-type test_service") - self.assertRaises(SystemExit, self._run_command, cmd) - - @mock.patch.object(utils, 'print_dict') - @mock.patch.object(utils, 'remove_unspecified_items') - @mock.patch.object(utils, 'get_uuid_by_name') - @ddt.data({"recovery_method": "auto"}, - {"recovery_method": "reserved_host"}, - {"recovery_method": "auto_priority"}, - {"recovery_method": "rh_priority"}) - def test_do_segment_update(self, ddt_data, - mock_get_uuid_by_name, - mock_remove_unspecified_items, - mock_print_dict): - mock_get_uuid_by_name.return_value = self.segment_vals.get('uuid') - self.segment_vals['recovery_method'] = ddt_data['recovery_method'] - mock_remove_unspecified_items.return_value = self.segment_vals - service = mock.Mock() - segment_object = fakes.FakeSegment(self.segment_vals) - service.update_segment.return_value = segment_object - args = mock.Mock() - args.recovery_method = ddt_data['recovery_method'] - ms.do_segment_update(service, args) - mock_get_uuid_by_name.assert_called_once_with(service, args.id) - attrs = { - 'name': args.name, - 'description': args.description, - 'recovery_method': args.recovery_method, - 'service_type': args.service_type, - } - mock_remove_unspecified_items.assert_called_once_with(attrs) - mock_print_dict.assert_called_once_with(self.segment_vals) - - def test_do_segment_update_with_invalid_recovery_method(self): - cmd = ("segment-update --id bdba001e-c01b-490e-9405-fdf72d849b41 " - "--recovery-method invalid_recovery_method") - self.assertRaises(SystemExit, self._run_command, cmd) - - @mock.patch.object(utils, 'print_dict') - @mock.patch.object(utils, 'get_uuid_by_name') - def test_do_segment_delete(self, mock_get_uuid_by_name, mock_print_dict): - mock_get_uuid_by_name.return_value = self.segment_vals.get('uuid') - service = mock.Mock() - segment_object = fakes.FakeSegment(self.segment_vals) - service.delete_segment.return_value = segment_object - args = mock.Mock() - - ms.do_segment_delete(service, args) - mock_get_uuid_by_name.assert_called_once_with(service, args.id) - mock_print_dict.assert_called_once_with(self.segment_vals) - - @mock.patch.object(utils, 'get_uuid_by_name') - @mock.patch.object(_proxy.Proxy, 'delete_segment') - def test_do_segment_delete_with_non_existing_uuid( - self, mock_get_uuid_by_name, mock_delete_segment): - mock_get_uuid_by_name.return_value = self.segment_vals.get('uuid') - - expected_msg = _("No failover segment with " - "id (%s)") % mock_get_uuid_by_name - - def fake_delete_segment(self, mock_get_uuid_by_name, - ignore_missing=False): - if not ignore_missing: - raise sdk_exc.ResourceNotFound(expected_msg) - - mock_delete_segment.side_effect = fake_delete_segment - service = mock.Mock() - args = mock.Mock() - - original = sys.stdout - sys.stdout = io.StringIO() - ms.do_segment_delete(service, args) - output = sys.stdout.getvalue() - sys.stdout = original - self.assertIn(expected_msg, output) - - @mock.patch.object(utils, 'print_list') - @mock.patch.object(utils, 'get_uuid_by_name') - def test_do_host_list(self, mock_get_uuid_by_name, mock_print_list): - mock_get_uuid_by_name.return_value = self.segment_vals.get('uuid') - service = mock.Mock() - service.hosts.return_value = self.hosts_vals - args = mock.Mock() - columns = [ - 'uuid', - 'name', - 'type', - 'control_attributes', - 'reserved', - 'on_maintenance', - 'failover_segment_id'] - - ms.do_host_list(service, args) - - mock_get_uuid_by_name.assert_called_once_with(service, args.segment_id) - mock_print_list.assert_called_once_with( - self.hosts_vals, - columns) - - @mock.patch.object(utils, 'print_dict') - @mock.patch.object(utils, 'get_uuid_by_name') - def test_do_host_show(self, mock_get_uuid_by_name, mock_print_dict): - mock_get_uuid_by_name.side_effect = [self.segment_vals.get('uuid'), - self.hosts_vals.get('uuid')] - service = mock.Mock() - service.get_host.return_value = self.hosts_object - args = mock.Mock() - - ms.do_host_show(service, args) - mock_get_uuid_by_name.assert_any_call(service, args.segment_id) - mock_get_uuid_by_name.assert_any_call( - service, args.id, segment=self.segment_vals.get('uuid')) - mock_print_dict.assert_called_once_with(self.hosts_vals) - - @mock.patch.object(utils, 'print_dict') - @mock.patch.object(utils, 'remove_unspecified_items') - @mock.patch.object(utils, 'get_uuid_by_name') - def test_do_host_create(self, - mock_get_uuid_by_name, - mock_remove_unspecified_items, - mock_print_dict): - mock_get_uuid_by_name.return_value = self.hosts_vals.get('uuid') - mock_remove_unspecified_items.return_value = self.hosts_vals - service = mock.Mock() - service.create_host.return_value = self.hosts_object - args = mock.Mock() - - ms.do_host_create(service, args) - mock_get_uuid_by_name.assert_called_once_with(service, args.segment_id) - attrs = { - 'name': args.name, - 'type': args.type, - 'control_attributes': args.control_attributes, - 'reserved': args.reserved, - 'on_maintenance': args.on_maintenance, - } - mock_remove_unspecified_items.assert_called_once_with(attrs) - mock_print_dict.assert_called_once_with(self.hosts_vals) - - @mock.patch.object(utils, 'print_dict') - @mock.patch.object(utils, 'remove_unspecified_items') - @mock.patch.object(utils, 'get_uuid_by_name') - def test_do_host_update(self, - mock_get_uuid_by_name, - mock_remove_unspecified_items, - mock_print_dict): - mock_get_uuid_by_name.side_effect = [self.segment_vals.get('uuid'), - self.hosts_vals.get('uuid')] - mock_remove_unspecified_items.return_value = self.hosts_vals - service = mock.Mock() - service.update_host.return_value = self.hosts_object - args = mock.Mock() - - ms.do_host_update(service, args) - mock_get_uuid_by_name.assert_any_call(service, args.segment_id) - mock_get_uuid_by_name.assert_any_call( - service, args.id, segment=self.segment_vals.get('uuid')) - attrs = { - 'name': args.name, - 'type': args.type, - 'control_attributes': args.control_attributes, - 'reserved': args.reserved, - 'on_maintenance': args.on_maintenance, - } - mock_remove_unspecified_items.assert_called_once_with(attrs) - mock_print_dict.assert_called_once_with(self.hosts_vals) - - @mock.patch.object(utils, 'print_dict') - @mock.patch.object(utils, 'get_uuid_by_name') - def test_do_host_delete(self, mock_get_uuid_by_name, mock_print_dict): - mock_get_uuid_by_name.side_effect = [self.segment_vals.get('uuid'), - self.hosts_vals.get('uuid')] - service = mock.Mock() - service.delete_host.return_value = self.hosts_object - args = mock.Mock() - - ms.do_host_delete(service, args) - mock_get_uuid_by_name.assert_any_call(service, args.segment_id) - mock_get_uuid_by_name.assert_any_call( - service, args.id, segment=self.segment_vals.get('uuid')) - mock_print_dict.assert_called_once_with(self.hosts_vals) - - @mock.patch.object(utils, 'get_uuid_by_name') - @mock.patch.object(_proxy.Proxy, 'delete_host') - def test_do_host_delete_with_non_existing_uuid(self, - mock_get_uuid_by_name, - mock_delete_host): - mock_get_uuid_by_name.return_value = self.segment_vals.get('uuid') - host_id = self.hosts_vals.get('uuid') - expected_msg = _("Host '%(host_id)s' under failover_segment " "'" - "%(seg_id)s' ""could not be found") % { - 'host_id': host_id, 'seg_id': mock_get_uuid_by_name} - - def fake_delete_host( - host_id, mock_get_uuid_by_name, ignore_missing=False): - if not ignore_missing: - raise sdk_exc.ResourceNotFound(expected_msg) - - mock_delete_host.side_effect = fake_delete_host - service = mock.Mock() - args = mock.Mock() - - original = sys.stdout - sys.stdout = io.StringIO() - ms.do_host_delete(service, args) - output = sys.stdout.getvalue() - sys.stdout = original - self.assertIn(expected_msg, output) diff --git a/masakariclient/v1/__init__.py b/masakariclient/v1/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/masakariclient/v1/client.py b/masakariclient/v1/client.py deleted file mode 100644 index 3215b13..0000000 --- a/masakariclient/v1/client.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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. - -from keystoneauth1.identity.generic import password as ks_password -from keystoneauth1 import session as ks_session -from openstack import connection - - -class Client(object): - - def __init__(self, **kwargs): - session = kwargs.get('session') - if session is None: - auth = ks_password.Password( - auth_url=kwargs.get('auth_url'), - username=kwargs.get('username'), - password=kwargs.get('password'), - user_domain_id=kwargs.get('user_domain_id'), - project_name=kwargs.get('project_name'), - project_domain_id=kwargs.get('project_domain_id')) - - session = ks_session.Session(auth=auth) - - con = connection.Connection( - session=session, - interface=kwargs.get('interface'), - region_name=kwargs.get('region_name'), - ha_api_version=kwargs.get('api_version')) - self.service = con.instance_ha diff --git a/masakariclient/v1/shell.py b/masakariclient/v1/shell.py deleted file mode 100644 index 32bc959..0000000 --- a/masakariclient/v1/shell.py +++ /dev/null @@ -1,292 +0,0 @@ -# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation -# -# 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. - - -from oslo_serialization import jsonutils - -from masakariclient.common import utils - - -def do_notification_list(service, args): - """List notifications. - - :param service: service object. - :param args: API args. - """ - try: - notifications = service.notifications() - columns = [ - 'notification_uuid', 'generated_time', 'status', - 'source_host_uuid', 'type'] - utils.print_list(notifications, columns) - - except Exception as e: - print(e) - - -@utils.arg('--id', metavar='', required=True, - help='Notification to display (name or ID)') -def do_notification_show(service, args): - """Show a notification details.""" - try: - notification = service.get_notification(args.id) - utils.print_dict(notification.to_dict()) - - except Exception as e: - print(e) - - -@utils.arg('--type', metavar='', required=True, - choices=['COMPUTE_HOST', 'VM', 'PROCESS'], - help='Type of failure. The supported options are: ' - 'COMPUTE_HOST, VM, PROCESS.') -@utils.arg('--hostname', metavar='', required=True, - help='Hostname of notification.') -@utils.arg('--generated-time', metavar='', required=True, - help='Timestamp for notification. e.g. 2016-01-01T01:00:00.000') -@utils.arg('--payload', metavar='', required=True, - help='JSON string about failure event.') -def do_notification_create(service, args): - """Create a notification.""" - try: - payload = jsonutils.loads(args.payload) - attrs = { - 'type': args.type, - 'hostname': args.hostname, - 'generated_time': args.generated_time, - 'payload': payload, - } - notification = service.create_notification(**attrs) - utils.print_dict(notification.to_dict()) - - except Exception as e: - print(e) - - -def do_segment_list(service, args): - """List segments.""" - try: - segments = service.segments() - fields = [ - 'uuid', 'name', 'description', - 'service_type', 'recovery_method'] - utils.print_list(segments, fields) - except Exception as e: - print(e) - - -@utils.arg('--id', metavar='', required=True, - help='Segment to display (name or ID)') -def do_segment_show(service, args): - """Show a segment details.""" - try: - segment_id = utils.get_uuid_by_name(service, args.id) - segment = service.get_segment(segment_id) - utils.print_dict(segment.to_dict()) - except Exception as e: - print(e) - - -@utils.arg('--name', metavar='', required=True, - help='Name of segment.') -@utils.arg('--recovery-method', metavar='', required=True, - choices=['auto', 'reserved_host', 'auto_priority', 'rh_priority'], - help='Recovery method. ' - 'The supported options are: auto, reserved_host,' - ' auto_priority, rh_priority.') -@utils.arg('--service-type', metavar='', required=True, - help='Service type of segment.') -@utils.arg('--description', metavar='', required=False, - help='Description of segment.') -def do_segment_create(service, args): - """Create segment.""" - try: - attrs = { - 'name': args.name, - 'description': args.description, - 'recovery_method': args.recovery_method, - 'service_type': args.service_type, - } - segment = service.create_segment(**attrs) - utils.print_dict(segment.to_dict()) - except Exception as e: - print(e) - - -@utils.arg('--id', metavar='', - required=True, help='Name or ID of segment.') -@utils.arg('--name', metavar='', - required=False, help='Name of segment.') -@utils.arg('--recovery-method', metavar='', - choices=['auto', 'reserved_host', 'auto_priority', 'rh_priority'], - required=False, - help='Recovery method. ' - 'The supported options are: auto, reserved_host, ' - 'auto_priority, rh_priority.') -@utils.arg('--service-type', metavar='', - required=False, help='Service type of segment.') -@utils.arg('--description', metavar='', - required=False, help='Description of segment.') -def do_segment_update(service, args): - """Update a segment.""" - try: - segment_id = utils.get_uuid_by_name( - service, args.id) - attrs = { - 'name': args.name, - 'description': args.description, - 'recovery_method': args.recovery_method, - 'service_type': args.service_type, - } - attrs = utils.remove_unspecified_items(attrs) - segment = service.update_segment(segment_id, **attrs) - utils.print_dict(segment.to_dict()) - except Exception as e: - print(e) - - -@utils.arg('--id', metavar='', required=True, - help='Name or ID of the segment to delete.') -def do_segment_delete(service, args): - """Delete a segment.""" - try: - segment_id = utils.get_uuid_by_name( - service, args.id) - segment = service.delete_segment(segment_id, ignore_missing=False) - utils.print_dict(segment.to_dict()) - except Exception as e: - print(e) - - -@utils.arg('--segment-id', metavar='', required=True, - help='Segment to display (name or ID)') -def do_host_list(service, args): - """List hosts.""" - try: - segment_id = utils.get_uuid_by_name( - service, args.segment_id) - hosts = service.hosts(segment_id) - fields = [ - 'uuid', 'name', 'type', 'control_attributes', 'reserved', - 'on_maintenance', 'failover_segment_id'] - utils.print_list(hosts, fields) - except Exception as e: - print(e) - - -@utils.arg('--segment-id', metavar='', required=True, - help='Segment to display (name or ID)') -@utils.arg('--id', metavar='', required=True, - help='Host to display (name or ID)') -def do_host_show(service, args): - """Show a host details.""" - try: - segment_id = utils.get_uuid_by_name( - service, args.segment_id) - host_id = utils.get_uuid_by_name( - service, args.id, segment=segment_id) - host = service.get_host(host_id, segment_id=segment_id) - utils.print_dict(host.to_dict()) - except Exception as e: - print(e) - - -@utils.arg('--name', metavar='', required=True, - help='Name of host.') -@utils.arg('--type', metavar='', required=True, - help='Type of host.') -@utils.arg('--control-attributes', metavar='', - required=True, help='Control attributes of host.') -@utils.arg('--segment-id', metavar='', required=True, - help='Name or ID of segment.') -@utils.arg('--reserved', metavar='', required=False, - choices=['True', 'False'], - help='Host reservation. The supported options are: True, False.') -@utils.arg('--on-maintenance', metavar='', required=False, - choices=['True', 'False'], - help='Maintenance status of host. The supported options are: ' - 'True, False.') -def do_host_create(service, args): - """Create a host.""" - try: - segment_id = utils.get_uuid_by_name( - service, args.segment_id) - attrs = { - 'name': args.name, - 'type': args.type, - 'control_attributes': args.control_attributes, - 'reserved': args.reserved, - 'on_maintenance': args.on_maintenance, - } - utils.remove_unspecified_items(attrs) - host = service.create_host(segment_id, **attrs) - utils.print_dict(host.to_dict()) - except Exception as e: - print(e) - - -@utils.arg('--segment-id', metavar='', required=True, - help='Name or ID of segment.') -@utils.arg('--id', metavar='', required=True, - help='Name or ID of host.') -@utils.arg('--reserved', metavar='', required=False, - choices=['True', 'False'], - help='Host reservation. The supported options are: True, False.') -@utils.arg('--on-maintenance', metavar='', - required=False, choices=['True', 'False'], - help='Maintenance status of host. The supported options are: ' - 'True, False.') -@utils.arg('--name', metavar='', required=False, - help='Name of host.') -@utils.arg('--type', metavar='', required=False, - help='Type of host.') -@utils.arg('--control-attributes', metavar='', - required=False, help='Control attributes of host.') -def do_host_update(service, args): - """Update a host.""" - try: - segment_id = utils.get_uuid_by_name( - service, args.segment_id) - host_id = utils.get_uuid_by_name( - service, args.id, segment=segment_id) - attrs = { - 'name': args.name, - 'type': args.type, - 'control_attributes': args.control_attributes, - 'reserved': args.reserved, - 'on_maintenance': args.on_maintenance, - } - attrs = utils.remove_unspecified_items(attrs) - host = service.update_host(host_id, segment_id=segment_id, **attrs) - utils.print_dict(host.to_dict()) - except Exception as e: - print(e) - - -@utils.arg('--segment-id', metavar='', required=True, - help='Name or ID of segment.') -@utils.arg('--id', metavar='', required=True, - help='Name or ID of the host to delete.') -def do_host_delete(service, args): - """Delete a host.""" - try: - segment_id = utils.get_uuid_by_name( - service, args.segment_id) - host_id = utils.get_uuid_by_name( - service, args.id, segment=segment_id) - host = service.delete_host(host_id, segment_id=segment_id, - ignore_missing=False) - utils.print_dict(host.to_dict()) - except Exception as e: - print(e) diff --git a/releasenotes/notes/drop-the-legacy-client-1b25f27aa5525295.yaml b/releasenotes/notes/drop-the-legacy-client-1b25f27aa5525295.yaml new file mode 100644 index 0000000..83af215 --- /dev/null +++ b/releasenotes/notes/drop-the-legacy-client-1b25f27aa5525295.yaml @@ -0,0 +1,6 @@ +--- +upgrade: + - | + The legacy Masakari client (invoked by calling ``masakari`` as opposed to + ``openstack``) has been removed. It has been deprecated since + Stein. diff --git a/setup.cfg b/setup.cfg index ee3fb74..4ed2d32 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,9 +26,6 @@ packages = masakariclient [entry_points] -console_scripts = - masakari = masakariclient.shell:main - openstack.cli.extension = ha = masakariclient.plugin