From f5a57732a95e130689f6c5a16794e42266b206b0 Mon Sep 17 00:00:00 2001 From: Lingxian Kong Date: Mon, 16 Dec 2019 11:34:53 +1300 Subject: [PATCH] Support log actions in osc plugin - openstack database log show - openstack database log set [OPTIONS] Change-Id: I86f414a53e6f6416f96e0040635bb010aa49cf41 --- ...instance-log-actions-794fced41f9c11ea.yaml | 9 ++ setup.cfg | 3 +- troveclient/osc/v1/database_instances.py | 29 ------ troveclient/osc/v1/database_logs.py | 93 +++++++++++++++++++ .../tests/osc/v1/test_database_instances.py | 17 ---- .../tests/osc/v1/test_database_logs.py | 55 +++++++++++ troveclient/v1/instances.py | 23 +---- troveclient/v1/shell.py | 18 ++-- 8 files changed, 174 insertions(+), 73 deletions(-) create mode 100644 releasenotes/notes/ussuri-01-instance-log-actions-794fced41f9c11ea.yaml diff --git a/releasenotes/notes/ussuri-01-instance-log-actions-794fced41f9c11ea.yaml b/releasenotes/notes/ussuri-01-instance-log-actions-794fced41f9c11ea.yaml new file mode 100644 index 00000000..9ba2b279 --- /dev/null +++ b/releasenotes/notes/ussuri-01-instance-log-actions-794fced41f9c11ea.yaml @@ -0,0 +1,9 @@ +--- +features: + - | + Support following instance log actions: + + .. code-block:: console + + openstack database log show + openstack database log set [OPTIONS] diff --git a/setup.cfg b/setup.cfg index 743e2a0b..57c55bc5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -79,9 +79,10 @@ openstack.database.v1 = database_instance_upgrade = troveclient.osc.v1.database_instances:UpgradeDatabaseInstance database_limit_list = troveclient.osc.v1.database_limits:ListDatabaseLimits database_log_list = troveclient.osc.v1.database_logs:ListDatabaseLogs + database_log_set = troveclient.osc.v1.database_logs:SetDatabaseInstanceLog + database_log_show = troveclient.osc.v1.database_logs:ShowDatabaseInstanceLog database_quota_show = troveclient.osc.v1.database_quota:ShowDatabaseQuota database_quota_update = troveclient.osc.v1.database_quota:UpdateDatabaseQuota - database_log_enable = troveclient.osc.v1.database_instances:EnableDatabaseInstanceLog database_root_disable = troveclient.osc.v1.database_root:DisableDatabaseRoot database_root_enable = troveclient.osc.v1.database_root:EnableDatabaseRoot database_root_show = troveclient.osc.v1.database_root:ShowDatabaseRoot diff --git a/troveclient/osc/v1/database_instances.py b/troveclient/osc/v1/database_instances.py index 54140f87..5962341f 100644 --- a/troveclient/osc/v1/database_instances.py +++ b/troveclient/osc/v1/database_instances.py @@ -492,35 +492,6 @@ class UpgradeDatabaseInstance(command.Command): db_instances.upgrade(instance, parsed_args.datastore_version) -class EnableDatabaseInstanceLog(command.ShowOne): - - _description = _("Instructs Trove guest to start collecting log details.") - - def get_parser(self, prog_name): - parser = super(EnableDatabaseInstanceLog, self).get_parser(prog_name) - parser.add_argument( - 'instance', - metavar='', - type=str, - help=_('Id or Name of the instance.') - ) - parser.add_argument( - 'log_name', - metavar='', - type=str, - help=_('Name of log to publish.') - ) - return parser - - def take_action(self, parsed_args): - db_instances = self.app.client_manager.database.instances - instance = osc_utils.find_resource(db_instances, - parsed_args.instance) - log_info = db_instances.log_enable(instance, parsed_args.log_name) - result = log_info._info - return zip(*sorted(six.iteritems(result))) - - class ResizeDatabaseInstanceVolume(command.Command): _description = _("Resizes the volume size of an instance.") diff --git a/troveclient/osc/v1/database_logs.py b/troveclient/osc/v1/database_logs.py index aaba81e0..eb342c34 100644 --- a/troveclient/osc/v1/database_logs.py +++ b/troveclient/osc/v1/database_logs.py @@ -14,6 +14,7 @@ from osc_lib.command import command from osc_lib import utils as osc_utils +import six from troveclient.i18n import _ @@ -41,3 +42,95 @@ class ListDatabaseLogs(command.Lister): logs = [osc_utils.get_item_properties(l, self.columns) for l in log_list] return self.columns, logs + + +class SetDatabaseInstanceLog(command.ShowOne): + _description = _("Instructs Trove guest to operate logs.") + + def get_parser(self, prog_name): + parser = super(SetDatabaseInstanceLog, self).get_parser(prog_name) + + parser.add_argument( + 'instance', + metavar='', + type=str, + help=_('Id or Name of the instance.') + ) + parser.add_argument( + 'log_name', + metavar='', + type=str, + help=_('Name of log to operate.') + ) + parser.add_argument( + '--enable', + action='store_true', + help="Whether or not to enable log collection.", + ) + parser.add_argument( + '--disable', + action='store_true', + help="Whether or not to disable log collection.", + ) + parser.add_argument( + '--publish', + action='store_true', + help="Whether or not to publish log files to the backend storage " + "for logs(Swift by default).", + ) + parser.add_argument( + '--discard', + action='store_true', + help="Whether or not to discard the existing logs before publish.", + ) + + return parser + + def take_action(self, parsed_args): + db_instances = self.app.client_manager.database.instances + instance = osc_utils.find_resource(db_instances, + parsed_args.instance) + + log_info = db_instances.log_action( + instance, parsed_args.log_name, + enable=parsed_args.enable, + disable=parsed_args.disable, + discard=parsed_args.discard, + publish=parsed_args.publish + ) + result = log_info._info + + return zip(*sorted(six.iteritems(result))) + + +class ShowDatabaseInstanceLog(command.ShowOne): + _description = _("Show information of given log name for the database " + "instance.") + + def get_parser(self, prog_name): + parser = super(ShowDatabaseInstanceLog, self).get_parser(prog_name) + + parser.add_argument( + 'instance', + metavar='', + type=str, + help=_('Id or Name of the instance.') + ) + parser.add_argument( + 'log_name', + metavar='', + type=str, + help=_('Name of log to operate.') + ) + + return parser + + def take_action(self, parsed_args): + db_instances = self.app.client_manager.database.instances + instance = osc_utils.find_resource(db_instances, + parsed_args.instance) + + log_info = db_instances.log_show(instance, parsed_args.log_name) + result = log_info._info + + return zip(*sorted(six.iteritems(result))) diff --git a/troveclient/tests/osc/v1/test_database_instances.py b/troveclient/tests/osc/v1/test_database_instances.py index f91a453c..e6214121 100644 --- a/troveclient/tests/osc/v1/test_database_instances.py +++ b/troveclient/tests/osc/v1/test_database_instances.py @@ -320,23 +320,6 @@ class TestDatabaseInstanceForceDelete(TestInstances): parsed_args) -class TestDatabaseInstanceEnableLog(TestInstances): - - def setUp(self): - super(TestDatabaseInstanceEnableLog, self).setUp() - self.cmd = database_instances.EnableDatabaseInstanceLog(self.app, - None) - - @mock.patch.object(utils, 'find_resource') - def test_instance_enable_log(self, mock_find): - args = ['instance1', 'log_name'] - mock_find.side_effect = ['instance1'] - parsed_args = self.check_parser(self.cmd, args, []) - self.cmd.take_action(parsed_args) - self.instance_client.log_enable.assert_called_with('instance1', - 'log_name') - - class TestDatabaseInstancePromoteToReplicaSource(TestInstances): def setUp(self): diff --git a/troveclient/tests/osc/v1/test_database_logs.py b/troveclient/tests/osc/v1/test_database_logs.py index 1654380d..9def9e88 100644 --- a/troveclient/tests/osc/v1/test_database_logs.py +++ b/troveclient/tests/osc/v1/test_database_logs.py @@ -47,3 +47,58 @@ class TestLogList(TestLogs): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) self.assertEqual(self.values, data) + + +class TestShowDatabaseInstanceLog(TestLogs): + + def setUp(self): + super(TestShowDatabaseInstanceLog, self).setUp() + self.cmd = database_logs.ShowDatabaseInstanceLog(self.app, None) + self.columns = ( + 'container', + 'metafile', + 'name', + 'pending', + 'prefix', + 'published', + 'status', + 'type', + ) + + @mock.patch.object(utils, 'find_resource') + def test_show_instance_log(self, mock_find): + mock_find.return_value = 'fake_instance_id' + data = self.fake_logs.get_logs()[0] + self.instance_client.log_show.return_value = data + + args = ['instance', 'logname'] + parsed_args = self.check_parser(self.cmd, args, []) + columns, values = self.cmd.take_action(parsed_args) + + self.assertEqual(self.columns, columns) + self.assertItemsEqual(data.to_dict().values(), values) + + +class TestSetDatabaseInstanceLog(TestLogs): + def setUp(self): + super(TestSetDatabaseInstanceLog, self).setUp() + self.cmd = database_logs.SetDatabaseInstanceLog(self.app, None) + + @mock.patch.object(utils, 'find_resource') + def test_set_instance_log(self, mock_find): + mock_find.return_value = 'fake_instance_id' + data = self.fake_logs.get_logs()[0] + data.status = 'Ready' + self.instance_client.log_action.return_value = data + + args = ['instance1', 'log_name', '--enable'] + parsed_args = self.check_parser(self.cmd, args, []) + self.cmd.take_action(parsed_args) + + self.instance_client.log_action.assert_called_once_with( + 'fake_instance_id', 'log_name', + enable=True, + disable=False, + discard=False, + publish=False + ) diff --git a/troveclient/v1/instances.py b/troveclient/v1/instances.py index b6555936..a122bc3b 100644 --- a/troveclient/v1/instances.py +++ b/troveclient/v1/instances.py @@ -382,24 +382,10 @@ class Instances(base.ManagerWithFind): return [DatastoreLog(self, log, loaded=True) for log in body['logs']] def log_show(self, instance, log_name): - return self._log_action(instance, log_name) + return self.log_action(instance, log_name) - def log_enable(self, instance, log_name): - return self._log_action(instance, log_name, enable=True) - - def log_disable(self, instance, log_name, discard=None): - return self._log_action(instance, log_name, - disable=True, discard=discard) - - def log_publish(self, instance, log_name, disable=None, discard=None): - return self._log_action(instance, log_name, disable=disable, - publish=True, discard=discard) - - def log_discard(self, instance, log_name): - return self._log_action(instance, log_name, discard=True) - - def _log_action(self, instance, log_name, enable=None, disable=None, - publish=None, discard=None): + def log_action(self, instance, log_name, enable=None, disable=None, + publish=None, discard=None): """Perform action on guest log. :param instance: The :class:`Instance` (or its ID) of the database @@ -420,6 +406,7 @@ class Instances(base.ManagerWithFind): body.update({'publish': int(publish)}) if discard: body.update({'discard': int(discard)}) + url = "/instances/%s/log" % base.getid(instance) resp, body = self.api.client.post(url, body=body) common.check_for_exceptions(resp, body, url) @@ -427,7 +414,7 @@ class Instances(base.ManagerWithFind): def _get_container_info(self, instance, log_name, publish): try: - log_info = self._log_action(instance, log_name, publish=publish) + log_info = self.log_action(instance, log_name, publish=publish) container = log_info.container prefix = log_info.prefix metadata_file = log_info.metafile diff --git a/troveclient/v1/shell.py b/troveclient/v1/shell.py index 1dddb352..bb6f2f6e 100644 --- a/troveclient/v1/shell.py +++ b/troveclient/v1/shell.py @@ -2214,7 +2214,8 @@ def do_log_enable(cs, args): """Instructs Trove guest to start collecting log details.""" try: instance = _find_instance(cs, args.instance) - log_info = cs.instances.log_enable(instance, args.log_name) + log_info = cs.instances.log_action(instance, args.log_name, + enable=True) _print_object(log_info) except exceptions.GuestLogNotFoundError: print(NO_LOG_FOUND_ERROR % {'log_name': args.log_name, @@ -2227,15 +2228,15 @@ def do_log_enable(cs, args): @utils.arg('instance', metavar='', help=_('Id or Name of the instance.')) @utils.arg('log_name', metavar='', help=_('Name of log to publish.')) -@utils.arg('--discard', action='store_true', default=False, - help=_('Discard published contents of specified log.')) +@utils.arg('--disable', action='store_true', default=False, + help=_('Disable the collection of the specified log.')) @utils.service_type('database') def do_log_disable(cs, args): """Instructs Trove guest to stop collecting log details.""" try: instance = _find_instance(cs, args.instance) - log_info = cs.instances.log_disable(instance, args.log_name, - discard=args.discard) + log_info = cs.instances.log_action(instance, args.log_name, + disable=args.discard) _print_object(log_info) except exceptions.GuestLogNotFoundError: print(NO_LOG_FOUND_ERROR % {'log_name': args.log_name, @@ -2257,8 +2258,8 @@ def do_log_publish(cs, args): """Instructs Trove guest to publish latest log entries on instance.""" try: instance = _find_instance(cs, args.instance) - log_info = cs.instances.log_publish( - instance, args.log_name, disable=args.disable, + log_info = cs.instances.log_action( + instance, args.log_name, publish=True, disable=args.disable, discard=args.discard) _print_object(log_info) except exceptions.GuestLogNotFoundError: @@ -2277,7 +2278,8 @@ def do_log_discard(cs, args): """Instructs Trove guest to discard the container of the published log.""" try: instance = _find_instance(cs, args.instance) - log_info = cs.instances.log_discard(instance, args.log_name) + log_info = cs.instances.log_action(instance, args.log_name, + discard=True) _print_object(log_info) except exceptions.GuestLogNotFoundError: print(NO_LOG_FOUND_ERROR % {'log_name': args.log_name,