File: utils.py

package info (click to toggle)
python-freezerclient 6.0.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 672 kB
  • sloc: python: 4,550; makefile: 25; sh: 2
file content (183 lines) | stat: -rw-r--r-- 5,174 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# (c) Copyright 2014-2016 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import logging
import os

from oslo_serialization import jsonutils as json
from oslo_utils import importutils

logging = logging.getLogger(__name__)


class Namespace(dict):
    """A dict subclass that exposes its items as attributes.

    Warning: Namespace instances do not have direct access to the
    dict methods.

    """

    def __init__(self, obj={}):
        super(Namespace, self).__init__(obj)

    def __dir__(self):
        return tuple(self)

    def __repr__(self):
        return "%s(%s)" % (type(self).__name__,
                           super(Namespace, self).__repr__())

    def __getattribute__(self, name):
        try:
            return self[name]
        except KeyError:
            # Return None in case the value doesn't exists
            # this is not an issue for the apiclient because it skips
            # None values
            return None

    def __setattr__(self, name, value):
        self[name] = value

    def __delattr__(self, name):
        del self[name]

    @classmethod
    def from_object(cls, obj, names=None):
        if names is None:
            names = dir(obj)
        ns = {name: getattr(obj, name) for name in names}
        return cls(ns)

    @classmethod
    def from_mapping(cls, ns, names=None):
        if names:
            ns = {name: ns[name] for name in names}
        return cls(ns)

    @classmethod
    def from_sequence(cls, seq, names=None):
        if names:
            seq = {name: val for name, val in seq if name in names}
        return cls(seq)

    @staticmethod
    def hasattr(ns, name):
        try:
            object.__getattribute__(ns, name)
        except AttributeError:
            return False
        return True

    @staticmethod
    def getattr(ns, name):
        return object.__getattribute__(ns, name)

    @staticmethod
    def setattr(ns, name, value):
        return object.__setattr__(ns, name, value)

    @staticmethod
    def delattr(ns, name):
        return object.__delattr__(ns, name)


class CachedProperty(object):
    def __init__(self, func):
        self.__doc__ = getattr(func, '__doc__')
        self.func = func

    def __get__(self, obj, cls):
        if obj is None:
            return self
        value = obj.__dict__[self.func.__name__] = self.func(obj)
        return value


def doc_from_json_file(path_to_file):
    """Build a json from a file in the file system
    :param path_to_file: path to file
    :return: in memory file in json format
    """
    with open(path_to_file, 'rb') as fd:
        try:
            return json.load(fd)
        except Exception as err:
            logging.error(err)
            raise Exception('Unable to load conf file. {0}'.format(err))


def create_headers_for_request(token):
    """Create a header dict to be passed to the api.

    :param token: token string coming from the api
    :return: a dict containing all the headers for a request
    """
    return {
        'X-Auth-Token': token,
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }


def prepare_search(search_term):
    """Return a search term that the api can use to query the db
    :param search_term: string
    :return: search dict
    """
    if search_term:
        return {"match": [{"_all": search_term}, ], }
    return {}


def check_api_version(api_version=None):
    """Check freezer version API to use
    1: not multi-tenant, useful for infrastructure
    2: multi-tenant, useful for backup as a service
    :return: str
    """
    if not api_version:
        freezer_api_version = os.environ.get('OS_BACKUP_API_VERSION', '2')
    else:
        freezer_api_version = api_version

    if freezer_api_version == '1':
        return '1'
    elif freezer_api_version == '2':
        return '2'
    else:
        raise Exception('Freezer API version not supported')


def get_client_class(api_version=None):
    """Return Client Class.
    Try to use provided api_version to import client class or
    Guess the api_version form env.
    Returns freezerclient.v{x}.client.Client
    :return: class
    """
    freezer_api_version = check_api_version(api_version)
    api_string = 'freezerclient.v{0}.client.Client'.format(freezer_api_version)
    return importutils.import_class(api_string)


def get_client_instance(opts={}, api_version=None):
    """Get Freezerclient Instance.
    We will the provided auth dict to instantiate a client instance
    Returns freezerclient.v{x}.client.Client Object
    :return: Object
    """
    return get_client_class(api_version)(**opts)