Adds CLI heat service-list
Adds 'service-list' to heat CLI for reporting the status of all running engines in given cloud environment "DocImpact" Implements: blueprint heat-manage-service-list Change-Id: Ief8b6e9bdd1a9b7428e0c8f58b65e9bff607c592
This commit is contained in:
parent
2d356098e5
commit
71b8aa1272
59
heatclient/tests/test_service.py
Normal file
59
heatclient/tests/test_service.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# Copyright 2012 OpenStack Foundation
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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 heatclient import exc
|
||||||
|
import testtools
|
||||||
|
|
||||||
|
|
||||||
|
from heatclient.v1 import services
|
||||||
|
|
||||||
|
|
||||||
|
class ManageServiceTest(testtools.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(ManageServiceTest, self).setUp()
|
||||||
|
|
||||||
|
def test_service_list(self):
|
||||||
|
class FakeResponse(object):
|
||||||
|
def json(self):
|
||||||
|
return {'services': []}
|
||||||
|
|
||||||
|
class FakeClient(object):
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
assert args[0] == ('/services')
|
||||||
|
return FakeResponse()
|
||||||
|
|
||||||
|
manager = services.ServiceManager(FakeClient())
|
||||||
|
self.assertEqual(manager.list(), [])
|
||||||
|
|
||||||
|
def test_service_list_403(self):
|
||||||
|
class FakeClient403(object):
|
||||||
|
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
assert args[0] == ('/services')
|
||||||
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
|
manager = services.ServiceManager(FakeClient403())
|
||||||
|
self.assertRaises(exc.HTTPForbidden,
|
||||||
|
manager.list)
|
||||||
|
|
||||||
|
def test_service_list_503(self):
|
||||||
|
class FakeClient503(object):
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
assert args[0] == ('/services')
|
||||||
|
raise exc.HTTPServiceUnavailable()
|
||||||
|
|
||||||
|
manager = services.ServiceManager(FakeClient503())
|
||||||
|
self.assertRaises(exc.HTTPServiceUnavailable,
|
||||||
|
manager.list)
|
@ -2958,3 +2958,87 @@ class MockShellTestStandaloneToken(MockShellTestUserPass):
|
|||||||
'OS_PASSWORD': 'password'
|
'OS_PASSWORD': 'password'
|
||||||
}
|
}
|
||||||
self.set_fake_env(fake_env)
|
self.set_fake_env(fake_env)
|
||||||
|
|
||||||
|
|
||||||
|
class ShellTestManageService(ShellBase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(ShellTestManageService, self).setUp()
|
||||||
|
self.set_fake_env(FAKE_ENV_KEYSTONE_V2)
|
||||||
|
|
||||||
|
def _set_fake_env(self):
|
||||||
|
'''Patch os.environ to avoid required auth info.'''
|
||||||
|
self.set_fake_env(FAKE_ENV_KEYSTONE_V2)
|
||||||
|
|
||||||
|
def _test_error_case(self, code, message):
|
||||||
|
self.register_keystone_auth_fixture()
|
||||||
|
|
||||||
|
resp_dict = {
|
||||||
|
'explanation': '',
|
||||||
|
'code': code,
|
||||||
|
'error': {
|
||||||
|
'message': message,
|
||||||
|
'type': '',
|
||||||
|
'traceback': '',
|
||||||
|
},
|
||||||
|
'title': 'test title'
|
||||||
|
}
|
||||||
|
resp_string = jsonutils.dumps(resp_dict)
|
||||||
|
resp = fakes.FakeHTTPResponse(
|
||||||
|
code,
|
||||||
|
'test reason',
|
||||||
|
{'content-type': 'application/json'},
|
||||||
|
resp_string)
|
||||||
|
(http.HTTPClient.json_request('GET', '/services').
|
||||||
|
AndRaise(exc.from_response(resp)))
|
||||||
|
|
||||||
|
exc.verbose = 1
|
||||||
|
|
||||||
|
self.m.ReplayAll()
|
||||||
|
e = self.assertRaises(exc.HTTPException,
|
||||||
|
self.shell, "service-list")
|
||||||
|
self.m.VerifyAll()
|
||||||
|
self.assertIn(message, str(e))
|
||||||
|
|
||||||
|
def test_service_list(self):
|
||||||
|
self.register_keystone_auth_fixture()
|
||||||
|
resp_dict = {
|
||||||
|
'services': [
|
||||||
|
{
|
||||||
|
"status": "up",
|
||||||
|
"binary": "heat-engine",
|
||||||
|
"engine_id": "9d9242c3-4b9e-45e1-9e74-7615fbf20e5d",
|
||||||
|
"hostname": "mrkanag",
|
||||||
|
"updated_at": "2015-02-03T05:57:59.000000",
|
||||||
|
"topic": "engine",
|
||||||
|
"host": "engine-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
resp_string = jsonutils.dumps(resp_dict)
|
||||||
|
headers = {}
|
||||||
|
http_resp = fakes.FakeHTTPResponse(200, 'OK', headers, resp_string)
|
||||||
|
response = (http_resp, resp_dict)
|
||||||
|
http.HTTPClient.json_request('GET', '/services').AndReturn(response)
|
||||||
|
|
||||||
|
self.m.ReplayAll()
|
||||||
|
services_text = self.shell('service-list')
|
||||||
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
required = [
|
||||||
|
'hostname', 'binary', 'engine_id', 'host',
|
||||||
|
'topic', 'updated_at', 'status'
|
||||||
|
]
|
||||||
|
for r in required:
|
||||||
|
self.assertRegexpMatches(services_text, r)
|
||||||
|
|
||||||
|
def test_service_list_503(self):
|
||||||
|
self._test_error_case(
|
||||||
|
message='All heat engines are down',
|
||||||
|
code=503)
|
||||||
|
|
||||||
|
def test_service_list_403(self):
|
||||||
|
self._test_error_case(
|
||||||
|
message=('You are not authorized to '
|
||||||
|
'complete this action'),
|
||||||
|
code=403)
|
||||||
|
@ -19,6 +19,7 @@ from heatclient.v1 import build_info
|
|||||||
from heatclient.v1 import events
|
from heatclient.v1 import events
|
||||||
from heatclient.v1 import resource_types
|
from heatclient.v1 import resource_types
|
||||||
from heatclient.v1 import resources
|
from heatclient.v1 import resources
|
||||||
|
from heatclient.v1 import services
|
||||||
from heatclient.v1 import software_configs
|
from heatclient.v1 import software_configs
|
||||||
from heatclient.v1 import software_deployments
|
from heatclient.v1 import software_deployments
|
||||||
from heatclient.v1 import stacks
|
from heatclient.v1 import stacks
|
||||||
@ -49,3 +50,4 @@ class Client(object):
|
|||||||
self.http_client)
|
self.http_client)
|
||||||
self.software_configs = software_configs.SoftwareConfigManager(
|
self.software_configs = software_configs.SoftwareConfigManager(
|
||||||
self.http_client)
|
self.http_client)
|
||||||
|
self.services = services.ServiceManager(self.http_client)
|
||||||
|
32
heatclient/v1/services.py
Normal file
32
heatclient/v1/services.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# 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 heatclient.openstack.common.apiclient import base
|
||||||
|
|
||||||
|
|
||||||
|
class Service(base.Resource):
|
||||||
|
def __repr__(self):
|
||||||
|
return "<Service %s>" % self._info
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceManager(base.BaseManager):
|
||||||
|
resource_class = Service
|
||||||
|
|
||||||
|
def list(self):
|
||||||
|
"""Get a list of services.
|
||||||
|
:rtype: list of :class:`Service`
|
||||||
|
"""
|
||||||
|
url = '/services'
|
||||||
|
return self._list(url, "services")
|
@ -1169,3 +1169,11 @@ def do_snapshot_list(hc, args):
|
|||||||
'creation_time': lambda x: x['creation_time'],
|
'creation_time': lambda x: x['creation_time'],
|
||||||
}
|
}
|
||||||
utils.print_list(snapshots["snapshots"], fields, formatters=formatters)
|
utils.print_list(snapshots["snapshots"], fields, formatters=formatters)
|
||||||
|
|
||||||
|
|
||||||
|
def do_service_list(hc, args=None):
|
||||||
|
'''List the Heat engines.'''
|
||||||
|
fields = ['hostname', 'binary', 'engine_id', 'host',
|
||||||
|
'topic', 'updated_at', 'status']
|
||||||
|
services = hc.services.list()
|
||||||
|
utils.print_list(services, fields, sortby_index=1)
|
||||||
|
Loading…
Reference in New Issue
Block a user