diff --git a/cinderclient/tests/v1/fakes.py b/cinderclient/tests/v1/fakes.py index 3df0d95da..6586b8a3d 100644 --- a/cinderclient/tests/v1/fakes.py +++ b/cinderclient/tests/v1/fakes.py @@ -708,6 +708,11 @@ class FakeHTTPClient(base_client.HTTPClient): return (200, {}, {'host': body['host'], 'binary': body['binary'], 'status': 'disabled'}) + def put_os_services_disable_log_reason(self, body, **kw): + return (200, {}, {'host': body['host'], 'binary': body['binary'], + 'status': 'disabled', + 'disabled_reason': body['disabled_reason']}) + def get_os_availability_zone(self, **kw): return (200, {}, { "availabilityZoneInfo": [ diff --git a/cinderclient/tests/v1/test_services.py b/cinderclient/tests/v1/test_services.py index de8993505..0824924e5 100644 --- a/cinderclient/tests/v1/test_services.py +++ b/cinderclient/tests/v1/test_services.py @@ -64,3 +64,12 @@ class ServicesTest(utils.TestCase): cs.assert_called('PUT', '/os-services/disable', values) self.assertTrue(isinstance(s, services.Service)) self.assertEqual(s.status, 'disabled') + + def test_services_disable_log_reason(self): + s = cs.services.disable_log_reason( + 'host1', 'cinder-volume', 'disable bad host') + values = {"host": "host1", 'binary': 'cinder-volume', + "disabled_reason": "disable bad host"} + cs.assert_called('PUT', '/os-services/disable-log-reason', values) + self.assertTrue(isinstance(s, services.Service)) + self.assertEqual(s.status, 'disabled') diff --git a/cinderclient/tests/v1/test_shell.py b/cinderclient/tests/v1/test_shell.py index ddb669f35..4b3ca983f 100644 --- a/cinderclient/tests/v1/test_shell.py +++ b/cinderclient/tests/v1/test_shell.py @@ -347,6 +347,13 @@ class ShellTest(utils.TestCase): self.assert_called('PUT', '/os-services/disable', {"binary": "cinder-volume", "host": "host"}) + def test_services_disable_with_reason(self): + cmd = 'service-disable host cinder-volume --reason no_reason' + self.run_command(cmd) + body = {'host': 'host', 'binary': 'cinder-volume', + 'disabled_reason': 'no_reason'} + self.assert_called('PUT', '/os-services/disable-log-reason', body) + def test_service_enable(self): self.run_command('service-enable host cinder-volume') self.assert_called('PUT', '/os-services/enable', diff --git a/cinderclient/tests/v2/fakes.py b/cinderclient/tests/v2/fakes.py index f44814b0a..a3e1dd243 100644 --- a/cinderclient/tests/v2/fakes.py +++ b/cinderclient/tests/v2/fakes.py @@ -741,6 +741,11 @@ class FakeHTTPClient(base_client.HTTPClient): return (200, {}, {'host': body['host'], 'binary': body['binary'], 'status': 'disabled'}) + def put_os_services_disable_log_reason(self, body, **kw): + return (200, {}, {'host': body['host'], 'binary': body['binary'], + 'status': 'disabled', + 'disabled_reason': body['disabled_reason']}) + def get_os_availability_zone(self, **kw): return (200, {}, { "availabilityZoneInfo": [ diff --git a/cinderclient/tests/v2/test_services.py b/cinderclient/tests/v2/test_services.py index 07a238983..e088df4f7 100644 --- a/cinderclient/tests/v2/test_services.py +++ b/cinderclient/tests/v2/test_services.py @@ -64,3 +64,12 @@ class ServicesTest(utils.TestCase): cs.assert_called('PUT', '/os-services/disable', values) self.assertTrue(isinstance(s, services.Service)) self.assertEqual(s.status, 'disabled') + + def test_services_disable_log_reason(self): + s = cs.services.disable_log_reason( + 'host1', 'cinder-volume', 'disable bad host') + values = {"host": "host1", 'binary': 'cinder-volume', + "disabled_reason": "disable bad host"} + cs.assert_called('PUT', '/os-services/disable-log-reason', values) + self.assertTrue(isinstance(s, services.Service)) + self.assertEqual(s.status, 'disabled') diff --git a/cinderclient/tests/v2/test_shell.py b/cinderclient/tests/v2/test_shell.py index 90ef8cf3b..a194b7620 100644 --- a/cinderclient/tests/v2/test_shell.py +++ b/cinderclient/tests/v2/test_shell.py @@ -335,6 +335,13 @@ class ShellTest(utils.TestCase): self.assert_called('PUT', '/os-services/disable', {"binary": "cinder-volume", "host": "host"}) + def test_services_disable_with_reason(self): + cmd = 'service-disable host cinder-volume --reason no_reason' + self.run_command(cmd) + body = {'host': 'host', 'binary': 'cinder-volume', + 'disabled_reason': 'no_reason'} + self.assert_called('PUT', '/os-services/disable-log-reason', body) + def test_service_enable(self): self.run_command('service-enable host cinder-volume') self.assert_called('PUT', '/os-services/enable', diff --git a/cinderclient/v1/services.py b/cinderclient/v1/services.py index b7875d76d..3bc4b3b43 100644 --- a/cinderclient/v1/services.py +++ b/cinderclient/v1/services.py @@ -56,3 +56,9 @@ class ServiceManager(base.ManagerWithFind): body = {"host": host, "binary": binary} result = self._update("/os-services/disable", body) return self.resource_class(self, result) + + def disable_log_reason(self, host, binary, reason): + """Disable the service with reason.""" + body = {"host": host, "binary": binary, "disabled_reason": reason} + result = self._update("/os-services/disable-log-reason", body) + return self.resource_class(self, result) diff --git a/cinderclient/v1/shell.py b/cinderclient/v1/shell.py index 0f10168e5..984868519 100644 --- a/cinderclient/v1/shell.py +++ b/cinderclient/v1/shell.py @@ -986,6 +986,10 @@ def do_service_list(cs, args): """List all the services. Filter by host & service binary.""" result = cs.services.list(host=args.host, binary=args.binary) columns = ["Binary", "Host", "Zone", "Status", "State", "Updated_at"] + # NOTE(jay-lau-513): we check if the response has disabled_reason + # so as not to add the column when the extended ext is not enabled. + if result and hasattr(result[0], 'disabled_reason'): + columns.append("Disabled Reason") utils.print_list(result, columns) @@ -1001,11 +1005,18 @@ def do_service_enable(cs, args): @utils.arg('host', metavar='', help='Name of host.') @utils.arg('binary', metavar='', help='Service binary.') +@utils.arg('--reason', metavar='', + help='Reason for disabling service.') @utils.service_type('volume') def do_service_disable(cs, args): """Disable the service.""" - result = cs.services.disable(args.host, args.binary) columns = ["Host", "Binary", "Status"] + if args.reason: + columns.append('Disabled Reason') + result = cs.services.disable_log_reason(args.host, args.binary, + args.reason) + else: + result = cs.services.disable(args.host, args.binary) utils.print_list([result], columns) diff --git a/cinderclient/v2/services.py b/cinderclient/v2/services.py index b7875d76d..3bc4b3b43 100644 --- a/cinderclient/v2/services.py +++ b/cinderclient/v2/services.py @@ -56,3 +56,9 @@ class ServiceManager(base.ManagerWithFind): body = {"host": host, "binary": binary} result = self._update("/os-services/disable", body) return self.resource_class(self, result) + + def disable_log_reason(self, host, binary, reason): + """Disable the service with reason.""" + body = {"host": host, "binary": binary, "disabled_reason": reason} + result = self._update("/os-services/disable-log-reason", body) + return self.resource_class(self, result) diff --git a/cinderclient/v2/shell.py b/cinderclient/v2/shell.py index 9abd212f2..cfd03d226 100644 --- a/cinderclient/v2/shell.py +++ b/cinderclient/v2/shell.py @@ -1118,6 +1118,10 @@ def do_service_list(cs, args): """List all the services. Filter by host & service binary.""" result = cs.services.list(host=args.host, binary=args.binary) columns = ["Binary", "Host", "Zone", "Status", "State", "Updated_at"] + # NOTE(jay-lau-513): we check if the response has disabled_reason + # so as not to add the column when the extended ext is not enabled. + if result and hasattr(result[0], 'disabled_reason'): + columns.append("Disabled Reason") utils.print_list(result, columns) @@ -1133,11 +1137,18 @@ def do_service_enable(cs, args): @utils.arg('host', metavar='', help='Name of host.') @utils.arg('binary', metavar='', help='Service binary.') +@utils.arg('--reason', metavar='', + help='Reason for disabling service.') @utils.service_type('volumev2') def do_service_disable(cs, args): """Disable the service.""" - result = cs.services.disable(args.host, args.binary) columns = ["Host", "Binary", "Status"] + if args.reason: + columns.append('Disabled Reason') + result = cs.services.disable_log_reason(args.host, args.binary, + args.reason) + else: + result = cs.services.disable(args.host, args.binary) utils.print_list([result], columns)