diff --git a/heatclient/tests/unit/test_software_configs.py b/heatclient/tests/unit/test_software_configs.py index 936ed50b..5adcad61 100644 --- a/heatclient/tests/unit/test_software_configs.py +++ b/heatclient/tests/unit/test_software_configs.py @@ -47,6 +47,17 @@ class SoftwareConfigManagerTest(testtools.TestCase): super(SoftwareConfigManagerTest, self).setUp() self.manager = software_configs.SoftwareConfigManager(mock.MagicMock()) + def test_list(self): + config_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57' + self.manager.client.json_request.return_value = ( + {}, + {'software_configs': []}) + result = self.manager.list(limit=1, marker=config_id) + self.assertEqual([], result) + call_args = self.manager.client.get.call_args + self.assertEqual( + ('/software_configs?limit=1&marker=%s' % config_id,), *call_args) + @mock.patch.object(utils, 'get_response_body') def test_get(self, mock_body): config_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57' diff --git a/heatclient/v1/shell.py b/heatclient/v1/shell.py index a0d3a6c6..0c6e87b5 100644 --- a/heatclient/v1/shell.py +++ b/heatclient/v1/shell.py @@ -1216,6 +1216,22 @@ def do_config_create(hc, args): print(jsonutils.dumps(sc.to_dict(), indent=2)) +@utils.arg('-l', '--limit', metavar='', + help=_('Limit the number of configs returned.')) +@utils.arg('-m', '--marker', metavar='', + help=_('Return configs that appear after the given config ID.')) +def do_config_list(hc, args): + '''List software configs.''' + kwargs = {} + if args.limit: + kwargs['limit'] = args.limit + if args.marker: + kwargs['marker'] = args.marker + scs = hc.software_configs.list(**kwargs) + fields = ['id', 'name', 'group', 'creation_time'] + utils.print_list(scs, fields, sortby_index=None) + + @utils.arg('id', metavar='', help=_('ID of the config.')) @utils.arg('-c', '--config-only', default=False, action="store_true", diff --git a/heatclient/v1/software_configs.py b/heatclient/v1/software_configs.py index dd3264db..bc948283 100644 --- a/heatclient/v1/software_configs.py +++ b/heatclient/v1/software_configs.py @@ -10,6 +10,9 @@ # License for the specific language governing permissions and limitations # under the License. +import six +from six.moves.urllib import parse + from heatclient.common import utils from heatclient.openstack.common.apiclient import base @@ -28,6 +31,26 @@ class SoftwareConfig(base.Resource): class SoftwareConfigManager(base.BaseManager): resource_class = SoftwareConfig + def list(self, **kwargs): + """Get a list of software configs. + :rtype: list of :class:`SoftwareConfig` + """ + qparams = {} + + for opt, val in six.iteritems(kwargs): + if val: + qparams[opt] = val + + # Transform the dict to a sequence of two-element tuples in fixed + # order, then the encoded string will be consistent in Python 2&3. + if qparams: + new_qparams = sorted(qparams.items(), key=lambda x: x[0]) + query_string = "?%s" % parse.urlencode(new_qparams) + else: + query_string = "" + url = '/software_configs%s' % query_string + return self._list(url, "software_configs") + def get(self, config_id): """Get the details for a specific software config.