Completed
Push — master ( bb5487...4fc1d0 )
by Manas
13:01 queued 05:18
created

st2client.commands.KeyValuePairBranch   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 26
Duplicated Lines 0 %
Metric Value
wmc 1
dl 0
loc 26
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
B __init__() 0 24 1
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
import os
17
import json
18
import logging
19
from os.path import join as pjoin
20
21
from st2client.commands import resource
22
from st2client.commands.noop import NoopCommand
23
from st2client.commands.resource import add_auth_token_to_kwargs_from_cli
24
from st2client.formatters import table
25
from st2client.models.keyvalue import KeyValuePair
26
from st2client.utils.date import format_isodate
27
28
LOG = logging.getLogger(__name__)
29
30
31
class KeyValuePairBranch(resource.ResourceBranch):
32
33
    def __init__(self, description, app, subparsers, parent_parser=None):
34
        super(KeyValuePairBranch, self).__init__(
35
            KeyValuePair, description, app, subparsers,
36
            parent_parser=parent_parser,
37
            commands={
38
                'list': KeyValuePairListCommand,
39
                'get': KeyValuePairGetCommand,
40
                'delete': KeyValuePairDeleteCommand,
41
                'create': NoopCommand,
42
                'update': NoopCommand
43
            })
44
45
        # Registers extended commands
46
        self.commands['set'] = KeyValuePairSetCommand(self.resource, self.app,
47
                                                      self.subparsers)
48
        self.commands['load'] = KeyValuePairLoadCommand(
49
            self.resource, self.app, self.subparsers)
50
        self.commands['delete_by_prefix'] = KeyValuePairDeleteByPrefixCommand(
51
            self.resource, self.app, self.subparsers)
52
53
        # Remove unsupported commands
54
        # TODO: Refactor parent class and make it nicer
55
        del self.commands['create']
56
        del self.commands['update']
57
58
59
class KeyValuePairListCommand(resource.ResourceListCommand):
60
    display_attributes = ['name', 'value', 'expire_timestamp']
61
    attribute_transform_functions = {
62
        'expire_timestamp': format_isodate,
63
    }
64
65
    def __init__(self, *args, **kwargs):
66
        super(KeyValuePairListCommand, self).__init__(*args, **kwargs)
67
68
        # Filter options
69
        self.parser.add_argument('--prefix', help=('Only return values which name starts with the '
70
                                                   ' provided prefix.'))
71
72
    def run_and_print(self, args, **kwargs):
73
        if args.prefix:
74
            kwargs['prefix'] = args.prefix
75
76
        instances = self.run(args, **kwargs)
77
        self.print_output(reversed(instances), table.MultiColumnTable,
78
                          attributes=args.attr, widths=args.width,
79
                          json=args.json,
80
                          attribute_transform_functions=self.attribute_transform_functions)
81
82
83
class KeyValuePairGetCommand(resource.ResourceGetCommand):
84
    pk_argument_name = 'name'
85
    display_attributes = ['name', 'value', 'expire_timestamp']
86
87
88
class KeyValuePairSetCommand(resource.ResourceCommand):
89
    display_attributes = ['name', 'value', 'expire_timestamp']
90
91
    def __init__(self, resource, *args, **kwargs):
0 ignored issues
show
Comprehensibility Bug introduced by
resource is re-defining a name which is already available in the outer-scope (previously defined on line 21).

It is generally a bad practice to shadow variables from the outer-scope. In most cases, this is done unintentionally and might lead to unexpected behavior:

param = 5

class Foo:
    def __init__(self, param):   # "param" would be flagged here
        self.param = param
Loading history...
92
        super(KeyValuePairSetCommand, self).__init__(
93
            resource, 'set',
94
            'Set an existing %s.' % resource.get_display_name().lower(),
95
            *args, **kwargs
96
        )
97
98
        self.parser.add_argument('name',
99
                                 metavar='name',
100
                                 help='Name of the key value pair.')
101
        self.parser.add_argument('value', help='Value paired with the key.')
102
        self.parser.add_argument('-l', '--ttl', dest='ttl', type=int, default=None,
103
                                 help='TTL (in seconds) for this value.')
104
105
    @add_auth_token_to_kwargs_from_cli
106
    def run(self, args, **kwargs):
107
        instance = KeyValuePair()
108
        instance.id = args.name  # TODO: refactor and get rid of id
109
        instance.name = args.name
110
        instance.value = args.value
111
112
        if args.ttl:
113
            instance.ttl = args.ttl
114
115
        return self.manager.update(instance, **kwargs)
116
117
    def run_and_print(self, args, **kwargs):
118
        instance = self.run(args, **kwargs)
119
        self.print_output(instance, table.PropertyValueTable,
120
                          attributes=self.display_attributes, json=args.json)
121
122
123
class KeyValuePairDeleteCommand(resource.ResourceDeleteCommand):
124
    pk_argument_name = 'name'
125
126
    @add_auth_token_to_kwargs_from_cli
127
    def run(self, args, **kwargs):
128
        resource_id = getattr(args, self.pk_argument_name, None)
129
        instance = self.get_resource(resource_id, **kwargs)
130
131
        if not instance:
132
            raise resource.ResourceNotFoundError('KeyValuePair with id "%s" not found', resource_id)
133
134
        instance.id = resource_id  # TODO: refactor and get rid of id
135
        self.manager.delete(instance, **kwargs)
136
137
138
class KeyValuePairDeleteByPrefixCommand(resource.ResourceCommand):
139
    """
140
    Commands which delete all the key value pairs which match the provided
141
    prefix.
142
    """
143
    def __init__(self, resource, *args, **kwargs):
0 ignored issues
show
Comprehensibility Bug introduced by
resource is re-defining a name which is already available in the outer-scope (previously defined on line 21).

It is generally a bad practice to shadow variables from the outer-scope. In most cases, this is done unintentionally and might lead to unexpected behavior:

param = 5

class Foo:
    def __init__(self, param):   # "param" would be flagged here
        self.param = param
Loading history...
144
        super(KeyValuePairDeleteByPrefixCommand, self).__init__(resource, 'delete_by_prefix',
145
            'Delete KeyValue pairs which match the provided prefix', *args, **kwargs)
146
147
        self.parser.add_argument('-p', '--prefix', required=True,
148
                                 help='Name prefix (e.g. twitter.TwitterSensor:)')
149
150
    @add_auth_token_to_kwargs_from_cli
151
    def run(self, args, **kwargs):
152
        prefix = args.prefix
153
        key_pairs = self.manager.get_all(prefix=prefix)
154
155
        to_delete = []
156
        for key_pair in key_pairs:
157
            key_pair.id = key_pair.name
158
            to_delete.append(key_pair)
159
160
        deleted = []
161
        for key_pair in to_delete:
162
            self.manager.delete(instance=key_pair, **kwargs)
163
            deleted.append(key_pair)
164
165
        return deleted
166
167
    def run_and_print(self, args, **kwargs):
168
        # TODO: Need to use args, instead of kwargs (args=) because of bad API
169
        # FIX ME
170
        deleted = self.run(args, **kwargs)
171
        key_ids = [key_pair.id for key_pair in deleted]
172
173
        print('Deleted %s keys' % (len(deleted)))
174
        print('Deleted key ids: %s' % (', '.join(key_ids)))
175
176
177
class KeyValuePairLoadCommand(resource.ResourceCommand):
178
    pk_argument_name = 'name'
179
    display_attributes = ['name', 'value']
180
181
    def __init__(self, resource, *args, **kwargs):
0 ignored issues
show
Comprehensibility Bug introduced by
resource is re-defining a name which is already available in the outer-scope (previously defined on line 21).

It is generally a bad practice to shadow variables from the outer-scope. In most cases, this is done unintentionally and might lead to unexpected behavior:

param = 5

class Foo:
    def __init__(self, param):   # "param" would be flagged here
        self.param = param
Loading history...
182
        help_text = ('Load a list of %s from file.' %
183
                     resource.get_plural_display_name().lower())
184
        super(KeyValuePairLoadCommand, self).__init__(resource, 'load',
185
            help_text, *args, **kwargs)
186
187
        self.parser.add_argument(
188
            'file', help=('JSON file containing the %s to create.'
189
                          % resource.get_plural_display_name().lower()))
190
191
    @add_auth_token_to_kwargs_from_cli
192
    def run(self, args, **kwargs):
193
        file_path = os.path.normpath(pjoin(os.getcwd(), args.file))
194
195
        if not os.path.exists(args.file):
196
            raise ValueError('File "%s" doesn\'t exist' % (file_path))
197
198
        if not os.path.isfile(args.file):
199
            raise ValueError('"%s" is not a file' % (file_path))
200
201
        with open(file_path, 'r') as f:
202
            kvps = json.loads(f.read())
203
204
        instances = []
205
        for item in kvps:
206
            name = item['name']
207
            value = item['value']
208
209
            instance = KeyValuePair()
210
            instance.id = name  # TODO: refactor and get rid of id
211
            instance.name = name
212
            instance.value = value
213
214
            self.manager.update(instance, **kwargs)
215
            instances.append(instance)
216
        return instances
217
218
    def run_and_print(self, args, **kwargs):
219
        instances = self.run(args, **kwargs)
220
        self.print_output(instances, table.MultiColumnTable,
221
                          attributes=['id', 'name', 'value'], json=args.json)
222