Add module-instance-count command
Added a --count_only flag to the call for module instances to return a summary of the applied instances based on the MD5 of the module (this is most useful for live_update modules, to see which ones haven't been updated). Added a new module-instance-count command. This was done to facilitate getting the summary, since it returns a different result set. It basically calls the same python interface as module-instances, but adds the --count_only flag. Also added some missing tests. Change-Id: Iea661166bf3a4f3520a590da5954aedcd0036243 Partial-Bug: #1554900 Depends-On: I4caf4a57226dd711575cde766076fa25d16792e2
This commit is contained in:
parent
d273969fa3
commit
714c6e781c
6
releasenotes/notes/add_mod_inst_count-ce532a2187b.yaml
Normal file
6
releasenotes/notes/add_mod_inst_count-ce532a2187b.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
fixes:
|
||||
- Add module-instance-count support to list
|
||||
a count of all instances having a specific
|
||||
module applied. Bug 1554900
|
||||
|
@ -178,6 +178,17 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
"region": "regionOne",
|
||||
"datastore": {"version": "5.6", "type": "mysql"}}]})
|
||||
|
||||
def get_instance_counts(self, **kw):
|
||||
return (200, {}, {"instances": [
|
||||
{
|
||||
"module_id": "4321",
|
||||
"module_name": "mod1",
|
||||
"min_date": "2015-05-02T11:06:16",
|
||||
"max_date": "2015-05-02T11:06:19",
|
||||
"module_md5": "9db783b92a9355f70c41806659fcb77d",
|
||||
"current": True,
|
||||
"count": 1}]})
|
||||
|
||||
def get_instances_1234(self, **kw):
|
||||
r = {'instance': self.get_instances()[2]['instances'][0]}
|
||||
return (200, {}, r)
|
||||
@ -479,6 +490,8 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
return (200, {}, {"modules": [{"module": {}}]})
|
||||
|
||||
def get_modules_4321_instances(self, **kw):
|
||||
if kw.get('count_only', False):
|
||||
return self.get_instance_counts()
|
||||
return self.get_instances()
|
||||
|
||||
def get_instances_modules(self, **kw):
|
||||
|
@ -233,6 +233,56 @@ class InstancesTest(testtools.TestCase):
|
||||
resp.status_code = 500
|
||||
self.assertRaises(Exception, self.instances.edit, 'instance1')
|
||||
|
||||
def test_module_apply(self):
|
||||
resp = mock.Mock()
|
||||
resp.status_code = 200
|
||||
body = {'modules': []}
|
||||
self.instances.api.client.post = mock.Mock(return_value=(resp, body))
|
||||
self.instances.module_apply(self.instance_with_id, "mod_id")
|
||||
resp.status_code = 500
|
||||
self.assertRaises(Exception, self.instances.module_apply,
|
||||
'instance1', 'mod1')
|
||||
|
||||
def test_module_remove(self):
|
||||
resp = mock.Mock()
|
||||
resp.status_code = 200
|
||||
body = {'modules': []}
|
||||
self.instances.api.client.delete = mock.Mock(return_value=(resp, body))
|
||||
self.instances.module_remove(self.instance_with_id, "mod_id")
|
||||
resp.status_code = 500
|
||||
self.assertRaises(Exception, self.instances.module_remove,
|
||||
'instance1', 'mod1')
|
||||
|
||||
def test_module_query(self):
|
||||
resp = mock.Mock()
|
||||
resp.status_code = 200
|
||||
body = {'modules': []}
|
||||
self.instances.api.client.get = mock.Mock(return_value=(resp, body))
|
||||
self.instances.module_query(self.instance_with_id)
|
||||
resp.status_code = 500
|
||||
self.assertRaises(Exception, self.instances.module_query,
|
||||
'instance1')
|
||||
|
||||
def test_module_retrieve(self):
|
||||
resp = mock.Mock()
|
||||
resp.status_code = 200
|
||||
body = {'modules': []}
|
||||
self.instances.api.client.get = mock.Mock(return_value=(resp, body))
|
||||
self.instances.module_retrieve(self.instance_with_id)
|
||||
resp.status_code = 500
|
||||
self.assertRaises(Exception, self.instances.module_retrieve,
|
||||
'instance1')
|
||||
|
||||
def test_module_list_instance(self):
|
||||
resp = mock.Mock()
|
||||
resp.status_code = 200
|
||||
body = {'modules': []}
|
||||
self.instances.api.client.get = mock.Mock(return_value=(resp, body))
|
||||
self.instances.modules(self.instance_with_id)
|
||||
resp.status_code = 500
|
||||
self.assertRaises(Exception, self.instances.modules,
|
||||
'instance1')
|
||||
|
||||
def test_upgrade(self):
|
||||
resp = mock.Mock()
|
||||
resp.status_code = 200
|
||||
|
@ -123,3 +123,25 @@ class TestModules(testtools.TestCase):
|
||||
self.modules.delete(self.module)
|
||||
resp.status_code = 500
|
||||
self.assertRaises(Exception, self.modules.delete, self.module_name)
|
||||
|
||||
def _test_instances(self, expected_query=None):
|
||||
page_mock = mock.Mock()
|
||||
self.modules._paginated = page_mock
|
||||
limit = "test-limit"
|
||||
marker = "test-marker"
|
||||
if not expected_query:
|
||||
expected_query = {}
|
||||
self.modules.instances(self.module_name, limit, marker,
|
||||
**expected_query)
|
||||
page_mock.assert_called_with("/modules/mod_1/instances",
|
||||
"instances", limit, marker,
|
||||
query_strings=expected_query)
|
||||
|
||||
def test_instance_count(self):
|
||||
expected_query = {'include_clustered': True,
|
||||
'count_only': True}
|
||||
self._test_instances(expected_query)
|
||||
|
||||
def test_instances(self):
|
||||
expected_query = {'include_clustered': True}
|
||||
self._test_instances(expected_query)
|
||||
|
@ -722,6 +722,21 @@ class ShellTest(utils.TestCase):
|
||||
self.assert_called_anytime(
|
||||
'GET', '/modules/4321/instances?include_clustered=True')
|
||||
|
||||
def test_module_instance_count(self):
|
||||
with mock.patch.object(troveclient.v1.modules.Module, '__repr__',
|
||||
mock.Mock(return_value='4321')):
|
||||
self.run_command('module-instance-count 4321')
|
||||
self.assert_called(
|
||||
'GET', '/modules/4321/instances?count_only=True')
|
||||
|
||||
def test_module_instance_count_clustered(self):
|
||||
with mock.patch.object(troveclient.v1.modules.Module, '__repr__',
|
||||
mock.Mock(return_value='4321')):
|
||||
self.run_command('module-instance-count 4321 --include_clustered')
|
||||
self.assert_called(
|
||||
'GET', '/modules/4321/instances?count_only=True&'
|
||||
'include_clustered=True')
|
||||
|
||||
def test_cluster_modules(self):
|
||||
self.run_command('cluster-modules cls-1234')
|
||||
self.assert_called_anytime('GET', '/clusters/cls-1234')
|
||||
|
@ -157,11 +157,13 @@ class Modules(base.ManagerWithFind):
|
||||
common.check_for_exceptions(resp, body, url)
|
||||
|
||||
def instances(self, module, limit=None, marker=None,
|
||||
include_clustered=False):
|
||||
include_clustered=False, count_only=False):
|
||||
"""Get a list of all instances this module has been applied to."""
|
||||
url = "/modules/%s/instances" % base.getid(module)
|
||||
query_strings = {}
|
||||
if include_clustered:
|
||||
query_strings['include_clustered'] = include_clustered
|
||||
if count_only:
|
||||
query_strings['count_only'] = count_only
|
||||
return self._paginated(url, "instances", limit, marker,
|
||||
query_strings=query_strings)
|
||||
|
@ -260,7 +260,7 @@ def do_list(cs, args):
|
||||
_print_instances(instances)
|
||||
|
||||
|
||||
def _print_instances(instances):
|
||||
def _print_instances(instances, is_admin=False):
|
||||
for instance in instances:
|
||||
setattr(instance, 'flavor_id', instance.flavor['id'])
|
||||
if hasattr(instance, 'volume'):
|
||||
@ -272,9 +272,12 @@ def _print_instances(instances):
|
||||
setattr(instance, 'datastore_version',
|
||||
instance.datastore['version'])
|
||||
setattr(instance, 'datastore', instance.datastore['type'])
|
||||
utils.print_list(instances, ['id', 'name', 'datastore',
|
||||
fields = ['id', 'name', 'datastore',
|
||||
'datastore_version', 'status',
|
||||
'flavor_id', 'size', 'region'])
|
||||
'flavor_id', 'size', 'region']
|
||||
if is_admin:
|
||||
fields.append('tenant_id')
|
||||
utils.print_list(instances, fields)
|
||||
|
||||
|
||||
@utils.arg('--limit', metavar='<limit>', type=int, default=None,
|
||||
@ -1964,7 +1967,27 @@ def do_module_instances(cs, args):
|
||||
while not args.limit and items.next:
|
||||
items = cs.modules.instances(module, marker=items.next)
|
||||
instance_list += items
|
||||
_print_instances(instance_list)
|
||||
_print_instances(instance_list, utils.is_admin(cs))
|
||||
|
||||
|
||||
@utils.arg('module', metavar='<module>', type=str,
|
||||
help=_('ID or name of the module.'))
|
||||
@utils.arg('--include_clustered', action="store_true", default=False,
|
||||
help=_("Include instances that are part of a cluster "
|
||||
"(default %(default)s)."))
|
||||
@utils.service_type('database')
|
||||
def do_module_instance_count(cs, args):
|
||||
"""Lists a count of the instances for each module md5."""
|
||||
module = _find_module(cs, args.module)
|
||||
count_list = cs.modules.instances(
|
||||
module, include_clustered=args.include_clustered,
|
||||
count_only=True)
|
||||
field_list = ['module_name', 'min_updated_date', 'max_updated_date',
|
||||
'module_md5', 'current', 'instance_count']
|
||||
utils.print_list(count_list, field_list,
|
||||
labels={'module_md5': 'Module MD5',
|
||||
'instance_count': 'Count',
|
||||
'module_id': 'Module ID'})
|
||||
|
||||
|
||||
@utils.arg('cluster', metavar='<cluster>',
|
||||
|
Loading…
Reference in New Issue
Block a user