diff --git a/shade/cmd/inventory.py b/shade/cmd/inventory.py index 47d38979c..26d615299 100755 --- a/shade/cmd/inventory.py +++ b/shade/cmd/inventory.py @@ -39,6 +39,8 @@ def parse_args(): group.add_argument('--host', help='List details about the specific host') parser.add_argument('--private', action='store_true', default=False, help='Use private IPs for interface_ip') + parser.add_argument('--cloud', default=None, + help='Return data for one cloud only') parser.add_argument('--yaml', action='store_true', default=False, help='Output data in nicely readable yaml') parser.add_argument('--debug', action='store_true', default=False, @@ -51,7 +53,8 @@ def main(): try: shade.simple_logging(debug=args.debug) inventory = shade.inventory.OpenStackInventory( - refresh=args.refresh, private=args.private) + refresh=args.refresh, private=args.private, + cloud=args.cloud) if args.list: output = inventory.list_hosts() elif args.host: diff --git a/shade/inventory.py b/shade/inventory.py index 98065971c..42863f070 100644 --- a/shade/inventory.py +++ b/shade/inventory.py @@ -28,7 +28,7 @@ class OpenStackInventory(object): def __init__( self, config_files=None, refresh=False, private=False, - config_key=None, config_defaults=None): + config_key=None, config_defaults=None, cloud=None): if config_files is None: config_files = [] config = os_client_config.config.OpenStackConfig( @@ -36,10 +36,19 @@ class OpenStackInventory(object): self.extra_config = config.get_extra_config( config_key, config_defaults) - self.clouds = [ - shade.OpenStackCloud(cloud_config=cloud_config) - for cloud_config in config.get_all_clouds() - ] + if cloud is None: + self.clouds = [ + shade.OpenStackCloud(cloud_config=cloud_config) + for cloud_config in config.get_all_clouds() + ] + else: + try: + self.clouds = [ + shade.OpenStackCloud( + cloud_config=config.get_one_cloud(cloud)) + ] + except os_client_config.exceptions.OpenStackConfigException as e: + raise shade.OpenStackCloudException(e) if private: for cloud in self.clouds: diff --git a/shade/tests/unit/test_inventory.py b/shade/tests/unit/test_inventory.py index 88a2d12e2..205d6721a 100644 --- a/shade/tests/unit/test_inventory.py +++ b/shade/tests/unit/test_inventory.py @@ -16,7 +16,10 @@ import mock import os_client_config +from os_client_config import exceptions as occ_exc + from shade import _utils +from shade import exc from shade import inventory from shade import meta from shade.tests import fakes @@ -42,6 +45,38 @@ class TestInventory(base.TestCase): self.assertEqual(1, len(inv.clouds)) self.assertTrue(mock_config.return_value.get_all_clouds.called) + @mock.patch("os_client_config.config.OpenStackConfig") + @mock.patch("shade.OpenStackCloud") + def test__init_one_cloud(self, mock_cloud, mock_config): + mock_config.return_value.get_one_cloud.return_value = [{}] + + inv = inventory.OpenStackInventory(cloud='supercloud') + + mock_config.assert_called_once_with( + config_files=os_client_config.config.CONFIG_FILES + ) + self.assertIsInstance(inv.clouds, list) + self.assertEqual(1, len(inv.clouds)) + self.assertFalse(mock_config.return_value.get_all_clouds.called) + mock_config.return_value.get_one_cloud.assert_called_once_with( + 'supercloud') + + @mock.patch("os_client_config.config.OpenStackConfig") + @mock.patch("shade.OpenStackCloud") + def test__raise_exception_on_no_cloud(self, mock_cloud, mock_config): + """ + Test that when os-client-config can't find a named cloud, a + shade exception is emitted. + """ + mock_config.return_value.get_one_cloud.side_effect = ( + occ_exc.OpenStackConfigException() + ) + self.assertRaises(exc.OpenStackCloudException, + inventory.OpenStackInventory, + cloud='supercloud') + mock_config.return_value.get_one_cloud.assert_called_once_with( + 'supercloud') + @mock.patch("os_client_config.config.OpenStackConfig") @mock.patch("shade.OpenStackCloud") def test_list_hosts(self, mock_cloud, mock_config):