From aba2875905e26c99f5bd926ae7572f84a3776602 Mon Sep 17 00:00:00 2001 From: Jiao Pengju Date: Wed, 25 Oct 2017 18:09:54 +0800 Subject: [PATCH] Add commands for service management API Change-Id: I3e9a62327653ea1dc9b5807f50f250c739c1566d Implements: blueprint karbor-service-management --- karborclient/tests/unit/v1/test_services.py | 104 ++++++++++++++++++++ karborclient/v1/client.py | 2 + karborclient/v1/services.py | 64 ++++++++++++ karborclient/v1/shell.py | 42 ++++++++ 4 files changed, 212 insertions(+) create mode 100644 karborclient/tests/unit/v1/test_services.py create mode 100644 karborclient/v1/services.py diff --git a/karborclient/tests/unit/v1/test_services.py b/karborclient/tests/unit/v1/test_services.py new file mode 100644 index 0000000..ae16879 --- /dev/null +++ b/karborclient/tests/unit/v1/test_services.py @@ -0,0 +1,104 @@ +# 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 mock + +from karborclient.tests.unit import base +from karborclient.tests.unit.v1 import fakes + +cs = fakes.FakeClient() +mock_request_return = ({}, {'service': {}}) + + +class ServicesTest(base.TestCaseShell): + + @mock.patch('karborclient.common.http.HTTPClient.json_request') + def test_list_services(self, mock_request): + mock_request.return_value = mock_request_return + cs.services.list() + mock_request.assert_called_with( + 'GET', + '/os-services', + headers={} + ) + + @mock.patch('karborclient.common.http.HTTPClient.json_request') + def test_list_services_with_host(self, mock_request): + mock_request.return_value = mock_request_return + cs.services.list(host='fake_host') + mock_request.assert_called_with( + 'GET', + '/os-services?host=fake_host', + headers={} + ) + + @mock.patch('karborclient.common.http.HTTPClient.json_request') + def test_list_services_with_binary(self, mock_request): + mock_request.return_value = mock_request_return + cs.services.list(binary='fake_binary') + mock_request.assert_called_with( + 'GET', + '/os-services?binary=fake_binary', + headers={} + ) + + @mock.patch('karborclient.common.http.HTTPClient.json_request') + def test_list_services_with_host_and_binary(self, mock_request): + mock_request.return_value = mock_request_return + cs.services.list(host='fake_host', binary='fake_binary') + mock_request.assert_called_with( + 'GET', + '/os-services?binary=fake_binary&host=fake_host', + headers={} + ) + + @mock.patch('karborclient.common.http.HTTPClient.json_request') + def test_enable_service(self, mock_request): + mock_request.return_value = mock_request_return + body = { + 'status': 'enabled' + } + cs.services.enable('1') + mock_request.assert_called_with( + 'PUT', + '/os-services/1', + data=body, + headers={} + ) + + @mock.patch('karborclient.common.http.HTTPClient.json_request') + def test_disable_service(self, mock_request): + mock_request.return_value = mock_request_return + body = { + 'status': 'disabled' + } + cs.services.disable('1') + mock_request.assert_called_with( + 'PUT', + '/os-services/1', + data=body, + headers={} + ) + + @mock.patch('karborclient.common.http.HTTPClient.json_request') + def test_disable_service_with_reason(self, mock_request): + mock_request.return_value = mock_request_return + body = { + 'status': 'disabled', + 'disabled_reason': 'fake_reason' + } + cs.services.disable_log_reason('1', 'fake_reason') + mock_request.assert_called_with( + 'PUT', + '/os-services/1', + data=body, + headers={} + ) diff --git a/karborclient/v1/client.py b/karborclient/v1/client.py index 0be29e5..54394dc 100644 --- a/karborclient/v1/client.py +++ b/karborclient/v1/client.py @@ -20,6 +20,7 @@ from karborclient.v1 import protectables from karborclient.v1 import providers from karborclient.v1 import restores from karborclient.v1 import scheduled_operations +from karborclient.v1 import services from karborclient.v1 import triggers from karborclient.v1 import verifications @@ -48,3 +49,4 @@ class Client(object): operation_logs.OperationLogManager(self.http_client) self.verifications = verifications.VerificationManager( self.http_client) + self.services = services.ServiceManager(self.http_client) diff --git a/karborclient/v1/services.py b/karborclient/v1/services.py new file mode 100644 index 0000000..7763b44 --- /dev/null +++ b/karborclient/v1/services.py @@ -0,0 +1,64 @@ +# 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 karborclient.common import base + + +class Service(base.Resource): + def __repr__(self): + return "" % self._info + + +class ServiceManager(base.ManagerWithFind): + resource_class = Service + + def enable(self, service_id): + """Enable the service specified by the service ID + + :param service_id: The ID of the service to enable. + """ + body = { + 'status': 'enabled' + } + return self._update('/os-services/%s' % service_id, body, "service") + + def disable(self, service_id): + """Disable the service specified by the service ID. + + :param service_id: The ID of the service to disable. + """ + body = { + 'status': 'disabled' + } + return self._update('/os-services/%s' % service_id, body, "service") + + def disable_log_reason(self, service_id, reason): + """Disable the service with a reason. + + :param service_id: The ID of the service to disable. + :param reason: The reason for disabling a service. + """ + body = { + 'status': 'disabled', + 'disabled_reason': reason + } + return self._update("/os-services/%s" % service_id, body, "service") + + def list(self, host=None, binary=None): + """Lists all services.""" + search_opts = { + 'host': host, + 'binary': binary + } + resource_type = "os-services" + url = self._build_list_url(resource_type, search_opts=search_opts) + return self._list(url, 'services') diff --git a/karborclient/v1/shell.py b/karborclient/v1/shell.py index 5a009e5..c0a2aa4 100644 --- a/karborclient/v1/shell.py +++ b/karborclient/v1/shell.py @@ -1245,3 +1245,45 @@ def do_operationlog_show(cs, args): """Shows operation_log details.""" operation_log = cs.operation_logs.get(args.operation_log) utils.print_dict(operation_log.to_dict()) + + +@utils.arg('--host', + metavar='', + default=None, + help='Name of host.') +@utils.arg('--binary', + metavar='', + default=None, + help='Service binary.') +def do_service_list(cs, args): + """Show a list of all running services. Filter by host & binary.""" + result = cs.services.list(host=args.host, binary=args.binary) + columns = ["Id", "Binary", "Host", "Status", "State", + "Updated_at", "Disabled Reason"] + utils.print_list(result, columns) + + +@utils.arg('service_id', + metavar='', + help='ID of the service.') +def do_service_enable(cs, args): + """Enable the service.""" + result = cs.services.enable(args.service_id) + utils.print_list([result], ["Id", "Binary", "Host", "Status", "State", + "Updated_at", "Disabled Reason"]) + + +@utils.arg('service_id', + metavar='', + help='ID of the service.') +@utils.arg('--reason', + metavar='', + help='Reason for disabling the service.') +def do_service_disable(cs, args): + """Disable the service""" + if args.reason: + result = cs.services.disable_log_reason(args.service_id, args.reason) + else: + result = cs.services.disable(args.service_id) + utils.print_list([result], ["Id", "Binary", "Host", "Status", "State", + "Updated_at", "Disabled Reason"])