1# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#    http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import functools
16
17from openstack.cloud import _utils
18from openstack.config import loader
19from openstack import connection
20from openstack import exceptions
21
22__all__ = ['OpenStackInventory']
23
24
25class OpenStackInventory:
26
27    # Put this here so the capability can be detected with hasattr on the class
28    extra_config = None
29
30    def __init__(
31            self, config_files=None, refresh=False, private=False,
32            config_key=None, config_defaults=None, cloud=None,
33            use_direct_get=False):
34        if config_files is None:
35            config_files = []
36        config = loader.OpenStackConfig(
37            config_files=loader.CONFIG_FILES + config_files)
38        self.extra_config = config.get_extra_config(
39            config_key, config_defaults)
40
41        if cloud is None:
42            self.clouds = [
43                connection.Connection(config=cloud_region)
44                for cloud_region in config.get_all()
45            ]
46        else:
47            self.clouds = [
48                connection.Connection(config=config.get_one(cloud))
49            ]
50
51        if private:
52            for cloud in self.clouds:
53                cloud.private = True
54
55        # Handle manual invalidation of entire persistent cache
56        if refresh:
57            for cloud in self.clouds:
58                cloud._cache.invalidate()
59
60    def list_hosts(self, expand=True, fail_on_cloud_config=True,
61                   all_projects=False):
62        hostvars = []
63
64        for cloud in self.clouds:
65            try:
66                # Cycle on servers
67                for server in cloud.list_servers(detailed=expand,
68                                                 all_projects=all_projects):
69                    hostvars.append(server)
70            except exceptions.OpenStackCloudException:
71                # Don't fail on one particular cloud as others may work
72                if fail_on_cloud_config:
73                    raise
74
75        return hostvars
76
77    def search_hosts(self, name_or_id=None, filters=None, expand=True):
78        hosts = self.list_hosts(expand=expand)
79        return _utils._filter_list(hosts, name_or_id, filters)
80
81    def get_host(self, name_or_id, filters=None, expand=True):
82        if expand:
83            func = self.search_hosts
84        else:
85            func = functools.partial(self.search_hosts, expand=False)
86        return _utils._get_entity(self, func, name_or_id, filters)
87