From 7a81c74103657f30a7b5af110dc220fd5172fc4e Mon Sep 17 00:00:00 2001 From: Tim Hinrichs Date: Thu, 16 Oct 2014 07:26:54 -0700 Subject: [PATCH] Added datasource schema openstack congress datasource schema list openstack congress datasource table schema list Change-Id: I8e94f145928f2b319722f81c0299545a17e818a8 --- NEWS | 5 ++ congressclient/common/utils.py | 12 ++++- congressclient/osc/v1/datasource.py | 58 +++++++++++++++++++++ congressclient/tests/v1/test_datasource.py | 60 ++++++++++++++++++++++ congressclient/v1/client.py | 12 +++++ setup.cfg | 2 + 6 files changed, 148 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ece5b19..e2fca71 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,11 @@ - python34 compatibility - New CLI command to simulate results of rule - openstack congress policy simulate Show the result of simulation. + - Add new CLI command to check the status of a datasource + - openstack congress datasource status list + - Add new CLI for viewing schemas + - openstack congress datasource table schema show Show schema for datasource table. + - openstack congress datasource schema show Show schema for datasource. 1.0.0 - 2014-09-29 diff --git a/congressclient/common/utils.py b/congressclient/common/utils.py index 85a6efc..e68e8f2 100644 --- a/congressclient/common/utils.py +++ b/congressclient/common/utils.py @@ -60,6 +60,17 @@ def import_class(import_str): return getattr(sys.modules[mod_str], class_str) +def format_long_dict_list(data): + """Return a formatted string. + + :param data: a list of dicts + :rtype: a string formatted to {a:b, c:d}, {e:f, g:h} + """ + newdata = [str({str(key): str(value) for key, value in d.iteritems()}) + for d in data] + return ',\n'.join(newdata) + '\n' + + def format_list(data): """Return a formatted strings @@ -80,7 +91,6 @@ def get_dict_properties(item, fields, mixed_case_fields=[], formatters={}): to format the values """ row = [] - for field in fields: if field in mixed_case_fields: field_name = field.replace(' ', '_') diff --git a/congressclient/osc/v1/datasource.py b/congressclient/osc/v1/datasource.py index ca33830..17c7077 100644 --- a/congressclient/osc/v1/datasource.py +++ b/congressclient/osc/v1/datasource.py @@ -93,6 +93,64 @@ class ListDatasourceStatus(lister.Lister): for s in data)) +class ShowDatasourceSchema(lister.Lister): + """Show schema for datasource.""" + + log = logging.getLogger(__name__ + '.ShowDatasourceSchema') + + def get_parser(self, prog_name): + parser = super(ShowDatasourceSchema, self).get_parser(prog_name) + parser.add_argument( + 'datasource_name', + metavar="", + help="Name of the datasource") + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + client = self.app.client_manager.congressclient + data = client.show_datasource_schema( + parsed_args.datasource_name) + formatters = {'columns': utils.format_long_dict_list} + newdata = [{'table': x['table_id'], + 'columns': x['columns']} + for x in data['tables']] + columns = ['table', 'columns'] + return (columns, + (utils.get_dict_properties(s, columns, + formatters=formatters) + for s in newdata)) + + +class ShowDatasourceTableSchema(lister.Lister): + """Show schema for datasource table.""" + + log = logging.getLogger(__name__ + '.ShowDatasourceTableSchema') + + def get_parser(self, prog_name): + parser = super(ShowDatasourceTableSchema, self).get_parser(prog_name) + parser.add_argument( + 'datasource_name', + metavar="", + help="Name of the datasource") + parser.add_argument( + 'table_name', + metavar="", + help="Name of the table") + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + client = self.app.client_manager.congressclient + data = client.show_datasource_table_schema( + parsed_args.datasource_name, + parsed_args.table_name) + columns = ['name', 'description'] + return (columns, + (utils.get_dict_properties(s, columns) + for s in data['columns'])) + + class ListDatasourceRows(lister.Lister): """List datasource rows.""" diff --git a/congressclient/tests/v1/test_datasource.py b/congressclient/tests/v1/test_datasource.py index ee6ea3c..3f3ee67 100644 --- a/congressclient/tests/v1/test_datasource.py +++ b/congressclient/tests/v1/test_datasource.py @@ -91,6 +91,66 @@ class TestListDatasourceStatus(common.TestCongressBase): self.assertEqual(['key', 'value'], result[0]) +class TestShowDatasourceSchema(common.TestCongressBase): + def test_show_datasource_schema(self): + datasource_name = 'neutron' + arglist = [ + datasource_name + ] + verifylist = [ + ('datasource_name', datasource_name) + ] + response = { + "tables": + [{'table_id': 'ports', + 'columns': [{"name": "name", "description": "None"}, + {"name": "status", "description": "None"}, + {"name": "id", "description": "None"}]}, + {'table_id': 'routers', + 'columns': [{"name": "name", "description": "None"}, + {"name": "floating_ip", "description": "None"}, + {"name": "id", "description": "None"}]}] + } + lister = mock.Mock(return_value=response) + self.app.client_manager.congressclient.show_datasource_schema = lister + cmd = datasource.ShowDatasourceSchema(self.app, self.namespace) + + parsed_args = self.check_parser(cmd, arglist, verifylist) + result = cmd.take_action(parsed_args) + + lister.assert_called_with(datasource_name) + self.assertEqual(['table', 'columns'], result[0]) + + +class TestShowDatasourceTableSchema(common.TestCongressBase): + def test_show_datasource_table_schema(self): + datasource_name = 'neutron' + table_name = 'ports' + arglist = [ + datasource_name, table_name + ] + verifylist = [ + ('datasource_name', datasource_name), + ('table_name', table_name) + ] + response = { + 'table_id': 'ports', + 'columns': [{"name": "name", "description": "None"}, + {"name": "status", "description": "None"}, + {"name": "id", "description": "None"}] + } + lister = mock.Mock(return_value=response) + client = self.app.client_manager.congressclient + client.show_datasource_table_schema = lister + cmd = datasource.ShowDatasourceTableSchema(self.app, self.namespace) + + parsed_args = self.check_parser(cmd, arglist, verifylist) + result = cmd.take_action(parsed_args) + + lister.assert_called_with(datasource_name, table_name) + self.assertEqual(['name', 'description'], result[0]) + + class TestListDatasourceRows(common.TestCongressBase): def test_list_datasource_row(self): diff --git a/congressclient/v1/client.py b/congressclient/v1/client.py index 40d06f6..b040cde 100644 --- a/congressclient/v1/client.py +++ b/congressclient/v1/client.py @@ -47,6 +47,8 @@ class Client(object): datasources = '/v1/data-sources' datasource_tables = '/v1/data-sources/%s/tables' datasource_status = '/v1/data-sources/%s/status' + datasource_schema = '/v1/data-sources/%s/schema' + datasource_table_schema = '/v1/data-sources/%s/tables/%s/spec' datasource_rows = '/v1/data-sources/%s/tables/%s/rows' def __init__(self, **kwargs): @@ -116,3 +118,13 @@ class Client(object): resp, body = self.httpclient.get(self.datasource_status % datasource_name) return body + + def show_datasource_schema(self, datasource_name): + resp, body = self.httpclient.get(self.datasource_schema % + datasource_name) + return body + + def show_datasource_table_schema(self, datasource_name, table_name): + resp, body = self.httpclient.get(self.datasource_table_schema % + (datasource_name, table_name)) + return body diff --git a/setup.cfg b/setup.cfg index 0bae00e..5f60dd9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,6 +40,8 @@ openstack.congressclient.v1 = congress_datasource_table_list = congressclient.osc.v1.datasource:ListDatasourceTables congress_datasource_row_list = congressclient.osc.v1.datasource:ListDatasourceRows congress_datasource_status_list = congressclient.osc.v1.datasource:ListDatasourceStatus + congress_datasource_schema_show = congressclient.osc.v1.datasource:ShowDatasourceSchema + congress_datasource_table_schema_show = congressclient.osc.v1.datasource:ShowDatasourceTableSchema [build_sphinx] source-dir = doc/source