Completed
Pull Request — master (#2842)
by Edward
05:16
created

PackSearchController.post()   A

Complexity

Conditions 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
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 pecan
17
from pecan.rest import RestController
18
import six
19
20
import st2common
21
from st2common import log as logging
22
from st2common.bootstrap.triggersregistrar import TriggersRegistrar
23
from st2common.bootstrap.sensorsregistrar import SensorsRegistrar
24
from st2common.bootstrap.actionsregistrar import ActionsRegistrar
25
from st2common.bootstrap.aliasesregistrar import AliasesRegistrar
26
from st2common.bootstrap.policiesregistrar import PolicyRegistrar
27
import st2common.bootstrap.policiesregistrar as policies_registrar
28
import st2common.bootstrap.runnersregistrar as runners_registrar
29
from st2common.bootstrap.rulesregistrar import RulesRegistrar
30
import st2common.bootstrap.ruletypesregistrar as rule_types_registrar
31
from st2common.bootstrap.configsregistrar import ConfigsRegistrar
32
import st2common.content.utils as content_utils
33
from st2common.models.api.base import jsexpose
34
from st2api.controllers.resource import ResourceController
35
from st2api.controllers.v1.actionexecutions import ActionExecutionsControllerMixin
36
from st2common.models.api.action import LiveActionCreateAPI
37
from st2common.models.api.pack import PackAPI
38
from st2common.models.api.pack import PackInitRequestAPI
39
from st2common.models.api.pack import PackInstallRequestAPI
40
from st2common.models.api.pack import PackRegisterRequestAPI
41
from st2common.models.api.pack import PackSearchRequestAPI
42
from st2common.models.api.pack import PackAsyncAPI
43
from st2common.persistence.pack import Pack
44
from st2common.rbac.types import PermissionType
45
from st2common.rbac.decorators import request_user_has_permission
46
from st2common.rbac.decorators import request_user_has_resource_db_permission
47
from st2common.services.packs import search_pack_index
48
49
http_client = six.moves.http_client
50
51
__all__ = [
52
    'PacksController',
53
    'BasePacksController'
54
]
55
56
LOG = logging.getLogger(__name__)
57
58
ENTITIES = {
59
    'action': (ActionsRegistrar, 'actions'),
60
    'trigger': (TriggersRegistrar, 'triggers'),
61
    'sensor': (SensorsRegistrar, 'sensors'),
62
    'rule': (RulesRegistrar, 'rules'),
63
    'alias': (AliasesRegistrar, 'aliases'),
64
    'policy': (PolicyRegistrar, 'policy'),
65
    'config': (ConfigsRegistrar, 'config')
66
}
67
68
69
class PackInitController(ActionExecutionsControllerMixin, RestController):
70
71
    @jsexpose(body_cls=PackInitRequestAPI, status_code=http_client.ACCEPTED)
72
    def post(self, args):
73
        parameters = vars(args)
74
75
        new_liveaction_api = LiveActionCreateAPI(action='packs.create',
76
                                                 parameters=parameters,
77
                                                 user=None)
78
79
        execution = self._handle_schedule_execution(liveaction_api=new_liveaction_api)
80
81
        return PackAsyncAPI(execution_id=execution.id)
82
83
84
class PackInstallController(ActionExecutionsControllerMixin, RestController):
85
86
    @jsexpose(body_cls=PackInstallRequestAPI, status_code=http_client.ACCEPTED)
87
    def post(self, pack_install_request):
88
        parameters = {
89
            'packs': pack_install_request.packs
90
        }
91
92
        new_liveaction_api = LiveActionCreateAPI(action='packs.install',
93
                                                 parameters=parameters,
94
                                                 user=None)
95
96
        execution = self._handle_schedule_execution(liveaction_api=new_liveaction_api)
97
98
        return PackAsyncAPI(execution_id=execution.id)
99
100
101
class PackUninstallController(ActionExecutionsControllerMixin, RestController):
102
103
    @jsexpose(body_cls=PackInstallRequestAPI, arg_types=[str], status_code=http_client.ACCEPTED)
104
    def post(self, pack_uninstall_request, ref_or_id=None):
105
        if ref_or_id:
106
            parameters = {
107
                'packs': [ref_or_id]
108
            }
109
        else:
110
            parameters = {
111
                'packs': pack_uninstall_request.packs
112
            }
113
114
        new_liveaction_api = LiveActionCreateAPI(action='packs.uninstall',
115
                                                 parameters=parameters,
116
                                                 user=None)
117
118
        execution = self._handle_schedule_execution(liveaction_api=new_liveaction_api)
119
120
        return PackAsyncAPI(execution_id=execution.id)
121
122
123
class PackRegisterController(RestController):
124
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
        use_pack_cache = True
134
        packs_base_paths = content_utils.get_packs_base_paths()
135
136
        result = {}
137
138
        if 'runner' in types or 'action' in types:
139
            result['runners'] = runners_registrar.register_runner_types(experimental=True)
140
        if 'rule_type' in types or 'rule' in types:
141
            result['rule_types'] = rule_types_registrar.register_rule_types()
142
        if 'policy_type' in types or 'policy' in types:
143
            result['policy_types'] = policies_registrar.register_policy_types(st2common)
144
145
        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...
146
            if type in types:
147
                registrar = Registrar(use_pack_cache=use_pack_cache,
148
                                      fail_on_failure=False)
149
                result[name] = registrar.register_from_packs(base_dirs=packs_base_paths)
150
151
        return result
152
153
154
class PackSearchController(RestController):
155
156
    @jsexpose(body_cls=PackSearchRequestAPI)
157
    def post(self, pack_search_request):
158
        if hasattr(pack_search_request, 'query'):
159
            return search_pack_index(query=pack_search_request.query)
160
        else:
161
            return search_pack_index(pack=pack_search_request.pack)
162
163
164
class BasePacksController(ResourceController):
165
    model = PackAPI
166
    access = Pack
167
168
    def _get_one_by_ref_or_id(self, ref_or_id, exclude_fields=None):
169
        LOG.info('GET %s with ref_or_id=%s', pecan.request.path, ref_or_id)
170
171
        instance = self._get_by_ref_or_id(ref_or_id=ref_or_id, exclude_fields=exclude_fields)
172
173
        if not instance:
174
            msg = 'Unable to identify resource with ref_or_id "%s".' % (ref_or_id)
175
            pecan.abort(http_client.NOT_FOUND, msg)
176
            return
177
178
        from_model_kwargs = self._get_from_model_kwargs_for_request(request=pecan.request)
179
        result = self.model.from_model(instance, **from_model_kwargs)
180
        LOG.debug('GET %s with ref_or_id=%s, client_result=%s', pecan.request.path, ref_or_id,
181
                  result)
182
183
        return result
184
185
    def _get_by_ref_or_id(self, ref_or_id, exclude_fields=None):
186
        resource_db = self._get_by_id(resource_id=ref_or_id, exclude_fields=exclude_fields)
187
188
        if not resource_db:
189
            # Try ref
190
            resource_db = self._get_by_ref(ref=ref_or_id, exclude_fields=exclude_fields)
191
192
        return resource_db
193
194
    def _get_by_ref(self, ref, exclude_fields=None):
195
        """
196
        Note: In this case "ref" is pack name and not StackStorm's ResourceReference.
197
        """
198
        resource_db = self.access.query(ref=ref, exclude_fields=exclude_fields).first()
199
        return resource_db
200
201
202
class PacksController(BasePacksController):
203
    from st2api.controllers.v1.packviews import PackViewsController
204
205
    model = PackAPI
206
    access = Pack
207
    supported_filters = {
208
        'name': 'name',
209
        'ref': 'ref'
210
    }
211
212
    query_options = {
213
        'sort': ['ref']
214
    }
215
216
    # Nested controllers
217
    init = PackInitController()
218
    install = PackInstallController()
219
    uninstall = PackUninstallController()
220
    register = PackRegisterController()
221
    search = PackSearchController()
222
    views = PackViewsController()
223
224
    @request_user_has_permission(permission_type=PermissionType.PACK_LIST)
225
    @jsexpose()
226
    def get_all(self, **kwargs):
227
        return super(PacksController, self)._get_all(**kwargs)
228
229
    @request_user_has_resource_db_permission(permission_type=PermissionType.PACK_VIEW)
230
    @jsexpose(arg_types=[str])
231
    def get_one(self, ref_or_id):
232
        return self._get_one_by_ref_or_id(ref_or_id=ref_or_id)
233