Passed
Push — develop ( 71cfc9...483b2a )
by Plexxi
07:06 queued 03:42
created

UserKeyValueLookup.__getattr__()   A

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 2
rs 10
1
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
from st2common.constants.keyvalue import SYSTEM_SCOPE, USER_SCOPE, ALLOWED_SCOPES
17
from st2common.exceptions.keyvalue import InvalidScopeException, InvalidUserException
18
from st2common.models.system.keyvalue import UserKeyReference
19
from st2common.persistence.keyvalue import KeyValuePair
20
21
22
class KeyValueLookup(object):
23
24
    def __init__(self, key_prefix='', cache=None, scope=SYSTEM_SCOPE):
25
        self._key_prefix = key_prefix
26
        if cache is None:
27
            cache = {}
28
        self._value_cache = cache
29
        self._scope = scope
30
31
    def __str__(self):
32
        return self._value_cache[self._key_prefix]
33
34
    def __getitem__(self, key):
35
        return self._get(key)
36
37
    def __getattr__(self, name):
38
        return self._get(name)
39
40
    def _get(self, name):
41
        # get the value for this key and save in value_cache
42
        key = '%s.%s' % (self._key_prefix, name) if self._key_prefix else name
43
        value = self._get_kv(key)
44
        self._value_cache[key] = value
45
        # return a KeyValueLookup as response since the lookup may not be complete e.g. if
46
        # the lookup is for 'key_base.key_value' it is likely that the calling code, e.g. Jinja,
47
        # will expect to do a dictionary style lookup for key_base and key_value as subsequent
48
        # calls. Saving the value in cache avoids extra DB calls.
49
        return KeyValueLookup(key_prefix=key, cache=self._value_cache, scope=self._scope)
50
51
    def _get_kv(self, key):
52
        scope = self._scope
53
        kvp = KeyValuePair.get_by_scope_and_name(scope=scope, name=key)
54
        return kvp.value if kvp else ''
55
56
57
class UserKeyValueLookup(object):
58
59
    def __init__(self, user, key_prefix='', cache=None, scope=USER_SCOPE):
60
        self._key_prefix = key_prefix
61
        if cache is None:
62
            cache = {}
63
        self._value_cache = cache
64
        self._user = user
65
        self._scope = scope
66
67
    def __str__(self):
68
        return self._value_cache[self._key_prefix]
69
70
    def __getitem__(self, key):
71
        return self._get(key)
72
73
    def __getattr__(self, name):
74
        return self._get(name)
75
76
    def _get(self, name):
77
        # get the value for this key and save in value_cache
78
        if not self._key_prefix:
79
            key = UserKeyReference(name=name, user=self._user).ref
80
        else:
81
            key = '%s.%s' % (self._key_prefix, name)
82
        value = self._get_kv(key)
83
        self._value_cache[key] = value
84
        # return a KeyValueLookup as response since the lookup may not be complete e.g. if
85
        # the lookup is for 'key_base.key_value' it is likely that the calling code, e.g. Jinja,
86
        # will expect to do a dictionary style lookup for key_base and key_value as subsequent
87
        # calls. Saving the value in cache avoids extra DB calls.
88
        return UserKeyValueLookup(user=self._user, key_prefix=key, cache=self._value_cache)
89
90
    def _get_kv(self, key):
91
        scope = self._scope
92
        kvp = KeyValuePair.get_by_scope_and_name(scope=scope, name=key)
93
        return kvp.value if kvp else ''
94
95
96
def get_key_reference(scope, name, user=None):
97
    """
98
    Given a key name and user this method returns a new name (string ref)
99
    to address the key value pair in the context of that user.
100
101
    :param user: User to whom key belongs.
102
    :type name: ``str``
103
104
    :param name: Original name of the key.
105
    :type name: ``str``
106
107
    :rtype: ``str``
108
    """
109
    if scope == SYSTEM_SCOPE:
110
        return name
111
    elif scope == USER_SCOPE:
112
        if not user:
113
            raise InvalidUserException('A valid user must be specified for user key ref.')
114
        return UserKeyReference(name=name, user=user).ref
115
    else:
116
        raise InvalidScopeException('Scope "%s" is not valid. Allowed scopes are %s.' %
117
                                    (scope, ALLOWED_SCOPES))
118