GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — plexxi-v2.2.1 ( 2317c4 )
by
unknown
05:42
created

PacksController   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 34
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 34
rs 10
wmc 3

3 Methods

Rating   Name   Duplication   Size   Complexity  
A get_one() 0 4 1
A get_all() 0 4 1
A __init__() 0 3 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 re
17
18
from collections import defaultdict
19
from collections import OrderedDict
20
21
import pecan
22
from pecan.rest import RestController
23
import six
24
25
import st2common
26
from st2common import log as logging
27
from st2common.bootstrap.triggersregistrar import TriggersRegistrar
28
from st2common.bootstrap.sensorsregistrar import SensorsRegistrar
29
from st2common.bootstrap.actionsregistrar import ActionsRegistrar
30
from st2common.bootstrap.aliasesregistrar import AliasesRegistrar
31
from st2common.bootstrap.policiesregistrar import PolicyRegistrar
32
import st2common.bootstrap.policiesregistrar as policies_registrar
33
import st2common.bootstrap.runnersregistrar as runners_registrar
34
from st2common.bootstrap.rulesregistrar import RulesRegistrar
35
import st2common.bootstrap.ruletypesregistrar as rule_types_registrar
36
from st2common.bootstrap.configsregistrar import ConfigsRegistrar
37
import st2common.content.utils as content_utils
38
from st2common.models.api.base import jsexpose
39
from st2api.controllers.resource import ResourceController
40
from st2api.controllers.v1.actionexecutions import ActionExecutionsControllerMixin
41
from st2common.models.api.action import LiveActionCreateAPI
42
from st2common.models.api.pack import PackAPI
43
from st2common.models.api.pack import PackInstallRequestAPI
44
from st2common.models.api.pack import PackRegisterRequestAPI
45
from st2common.models.api.pack import PackSearchRequestAPI
46
from st2common.models.api.pack import PackAsyncAPI
47
from st2common.exceptions.db import StackStormDBObjectNotFoundError
48
from st2common.persistence.pack import Pack
49
from st2common.rbac.types import PermissionType
50
from st2common.rbac.decorators import request_user_has_permission
51
from st2common.rbac.decorators import request_user_has_resource_db_permission
52
from st2common.services import packs as packs_service
53
54
http_client = six.moves.http_client
55
56
__all__ = [
57
    'PacksController',
58
    'BasePacksController',
59
    'ENTITIES'
60
]
61
62
LOG = logging.getLogger(__name__)
63
64
# Note: The order those are defined it's important so they are registered in the same order as
65
# they are in st2-register-content.
66
# We also need to use list of tuples to preserve the order.
67
ENTITIES = OrderedDict([
68
    ('trigger', (TriggersRegistrar, 'triggers')),
69
    ('sensor', (SensorsRegistrar, 'sensors')),
70
    ('action', (ActionsRegistrar, 'actions')),
71
    ('rule', (RulesRegistrar, 'rules')),
72
    ('alias', (AliasesRegistrar, 'aliases')),
73
    ('policy', (PolicyRegistrar, 'policies')),
74
    ('config', (ConfigsRegistrar, 'configs'))
75
])
76
77
78
class PackInstallController(ActionExecutionsControllerMixin, RestController):
79
80
    @request_user_has_permission(permission_type=PermissionType.PACK_INSTALL)
81
    @jsexpose(body_cls=PackInstallRequestAPI, status_code=http_client.ACCEPTED)
82
    def post(self, pack_install_request):
83
        parameters = {
84
            'packs': pack_install_request.packs,
85
        }
86
87
        if pack_install_request.force:
88
            parameters['force'] = True
89
90
        new_liveaction_api = LiveActionCreateAPI(action='packs.install',
91
                                                 parameters=parameters,
92
                                                 user=None)
93
94
        execution = self._handle_schedule_execution(liveaction_api=new_liveaction_api)
95
96
        return PackAsyncAPI(execution_id=execution.id)
97
98
99
class PackUninstallController(ActionExecutionsControllerMixin, RestController):
100
101
    @request_user_has_permission(permission_type=PermissionType.PACK_UNINSTALL)
102
    @jsexpose(body_cls=PackInstallRequestAPI, arg_types=[str], status_code=http_client.ACCEPTED)
103
    def post(self, pack_uninstall_request, ref_or_id=None):
104
        if ref_or_id:
105
            parameters = {
106
                'packs': [ref_or_id]
107
            }
108
        else:
109
            parameters = {
110
                'packs': pack_uninstall_request.packs
111
            }
112
113
        new_liveaction_api = LiveActionCreateAPI(action='packs.uninstall',
114
                                                 parameters=parameters,
115
                                                 user=None)
116
117
        execution = self._handle_schedule_execution(liveaction_api=new_liveaction_api)
118
119
        return PackAsyncAPI(execution_id=execution.id)
120
121
122
class PackRegisterController(RestController):
123
124
    @request_user_has_permission(permission_type=PermissionType.PACK_REGISTER)
125
    @jsexpose(body_cls=PackRegisterRequestAPI)
126
    def post(self, pack_register_request):
127
        if pack_register_request and hasattr(pack_register_request, 'types'):
128
            types = pack_register_request.types
129
        else:
130
            types = ['runner', 'action', 'trigger', 'sensor', 'rule', 'rule_type', 'alias',
131
                     'policy_type', 'policy', 'config']
132
133
        if pack_register_request and hasattr(pack_register_request, 'packs'):
134
            packs = list(set(pack_register_request.packs))
135
        else:
136
            packs = None
137
138
        result = defaultdict(int)
139
140
        # Register depended resources (actions depend on runners, rules depend on rule types, etc)
141
        if ('runner' in types or 'runners' in types) or ('action' in types or 'actions' in types):
142
            result['runners'] = runners_registrar.register_runners(experimental=True)
143
        if ('rule_type' in types or 'rule_types' in types) or \
144
           ('rule' in types or 'rules' in types):
145
            result['rule_types'] = rule_types_registrar.register_rule_types()
146
        if ('policy_type' in types or 'policy_types' in types) or \
147
           ('policy' in types or 'policies' in types):
148
            result['policy_types'] = policies_registrar.register_policy_types(st2common)
149
150
        use_pack_cache = False
151
152
        fail_on_failure = getattr(pack_register_request, 'fail_on_failure', True)
153
        for type, (Registrar, name) in six.iteritems(ENTITIES):
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in type.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
154
            if type in types or name in types:
155
                registrar = Registrar(use_pack_cache=use_pack_cache,
156
                                      fail_on_failure=fail_on_failure)
157
                if packs:
158
                    for pack in packs:
159
                        pack_path = content_utils.get_pack_base_path(pack)
160
161
                        try:
162
                            registered_count = registrar.register_from_pack(pack_dir=pack_path)
163
                            result[name] += registered_count
164
                        except ValueError as e:
165
                            # Throw more user-friendly exception if requsted pack doesn't exist
166
                            if re.match('Directory ".*?" doesn\'t exist', str(e)):
167
                                msg = 'Pack "%s" not found on disk: %s' % (pack, str(e))
168
                                raise ValueError(msg)
169
170
                            raise e
171
                else:
172
                    packs_base_paths = content_utils.get_packs_base_paths()
173
                    registered_count = registrar.register_from_packs(base_dirs=packs_base_paths)
174
                    result[name] += registered_count
175
176
        return result
177
178
179
class PackSearchController(RestController):
180
181
    @request_user_has_permission(permission_type=PermissionType.PACK_SEARCH)
182
    @jsexpose(body_cls=PackSearchRequestAPI)
183
    def post(self, pack_search_request):
184
        if hasattr(pack_search_request, 'query'):
185
            packs = packs_service.search_pack_index(pack_search_request.query,
186
                                                    case_sensitive=False)
187
            return [PackAPI(**pack) for pack in packs]
188
        else:
189
            pack = packs_service.get_pack_from_index(pack_search_request.pack)
190
            return PackAPI(**pack) if pack else None
191
192
193
class IndexHealthController(RestController):
194
195
    @request_user_has_permission(permission_type=PermissionType.PACK_VIEW_INDEX_HEALTH)
196
    @jsexpose()
197
    def get(self):
198
        """
199
        Check if all listed indexes are healthy: they should be reachable,
200
        return valid JSON objects, and yield more than one result.
201
        """
202
        _, status = packs_service.fetch_pack_index(allow_empty=True)
203
204
        health = {
205
            "indexes": {
206
                "count": len(status),
207
                "valid": 0,
208
                "invalid": 0,
209
                "errors": {},
210
                "status": status,
211
            },
212
            "packs": {
213
                "count": 0,
214
            },
215
        }
216
217
        for index in status:
218
            if index['error']:
219
                error_count = health['indexes']['errors'].get(index['error'], 0) + 1
220
                health['indexes']['invalid'] += 1
221
                health['indexes']['errors'][index['error']] = error_count
222
            else:
223
                health['indexes']['valid'] += 1
224
            health['packs']['count'] += index['packs']
225
226
        return health
227
228
229
class BasePacksController(ResourceController):
230
    model = PackAPI
231
    access = Pack
232
233
    def _get_one_by_ref_or_id(self, ref_or_id, exclude_fields=None):
234
        LOG.info('GET %s with ref_or_id=%s', pecan.request.path, ref_or_id)
235
236
        instance = self._get_by_ref_or_id(ref_or_id=ref_or_id, exclude_fields=exclude_fields)
237
238
        if not instance:
239
            msg = 'Unable to identify resource with ref_or_id "%s".' % (ref_or_id)
240
            pecan.abort(http_client.NOT_FOUND, msg)
241
            return
242
243
        from_model_kwargs = self._get_from_model_kwargs_for_request(request=pecan.request)
244
        result = self.model.from_model(instance, **from_model_kwargs)
245
        LOG.debug('GET %s with ref_or_id=%s, client_result=%s', pecan.request.path, ref_or_id,
246
                  result)
247
248
        return result
249
250
    def _get_by_ref_or_id(self, ref_or_id, exclude_fields=None):
251
        resource_db = self._get_by_id(resource_id=ref_or_id, exclude_fields=exclude_fields)
252
253
        if not resource_db:
254
            # Try ref
255
            resource_db = self._get_by_ref(ref=ref_or_id, exclude_fields=exclude_fields)
256
257
        if not resource_db:
258
            msg = 'Resource with a ref or id "%s" not found' % (ref_or_id)
259
            raise StackStormDBObjectNotFoundError(msg)
260
261
        return resource_db
262
263
    def _get_by_ref(self, ref, exclude_fields=None):
264
        """
265
        Note: In this case "ref" is pack name and not StackStorm's ResourceReference.
266
        """
267
        resource_db = self.access.query(ref=ref, exclude_fields=exclude_fields).first()
268
        return resource_db
269
270
271
class PacksIndexController(RestController):
272
    search = PackSearchController()
273
    health = IndexHealthController()
274
275
276
class PacksController(BasePacksController):
277
    from st2api.controllers.v1.packviews import PackViewsController
278
279
    model = PackAPI
280
    access = Pack
281
    supported_filters = {
282
        'name': 'name',
283
        'ref': 'ref'
284
    }
285
286
    query_options = {
287
        'sort': ['ref']
288
    }
289
290
    # Nested controllers
291
    install = PackInstallController()
292
    uninstall = PackUninstallController()
293
    register = PackRegisterController()
294
    views = PackViewsController()
295
    index = PacksIndexController()
296
297
    def __init__(self):
298
        super(PacksController, self).__init__()
299
        self.get_one_db_method = self._get_by_ref_or_id
300
301
    @request_user_has_permission(permission_type=PermissionType.PACK_LIST)
302
    @jsexpose()
303
    def get_all(self, **kwargs):
304
        return super(PacksController, self)._get_all(**kwargs)
305
306
    @request_user_has_resource_db_permission(permission_type=PermissionType.PACK_VIEW)
307
    @jsexpose(arg_types=[str])
308
    def get_one(self, ref_or_id):
309
        return self._get_one_by_ref_or_id(ref_or_id=ref_or_id)
310