Test Failed
Push — master ( e380d0...f5671d )
by W
02:58
created

st2common/st2common/models/api/inquiry.py (1 issue)

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 __future__ import absolute_import
17
import copy
18
import six
19
20
from st2common.constants.action import LIVEACTION_STATUSES
21
from st2common.models.api.base import BaseAPI
22
from st2common.models.api.action import RunnerTypeAPI, ActionAPI, LiveActionAPI
23
from st2common.models.db.execution import ActionExecutionDB
24
from st2common import log as logging
25
26
27
LOG = logging.getLogger(__name__)
28
29
REQUIRED_ATTR_SCHEMAS = {
30
    "action": copy.deepcopy(ActionAPI.schema),
31
    "runner": copy.deepcopy(RunnerTypeAPI.schema),
32
    "liveaction": copy.deepcopy(LiveActionAPI.schema),
33
}
34
35
for k, v in six.iteritems(REQUIRED_ATTR_SCHEMAS):
36
    v.update({"required": True})
37
38
39
class InquiryAPI(BaseAPI):
40
    """Model for working with Inquiries within the API controller
41
42
    Please see InquiryResponseAPI for a model more appropriate for API
43
    responses. This model contains fields that do not comply with the API
44
    spec.
45
    """
46
47
    # Inquiries don't have their own database model, since (right now) they are just
48
    # ActionExecutions with a "pending" status. The "from_model" function will serve
49
    # to transform the relevant fields to a new InquiryAPI instance
50
    model = ActionExecutionDB
51
52
    schema = {
53
        "title": "Inquiry",
54
        "description": "Record of an Inquiry",
55
        "type": "object",
56
        "properties": {
57
            "id": {
58
                "type": "string",
59
                "required": True
60
            },
61
            "route": {
62
                "type": "string",
63
                "default": "",
64
                "required": True
65
            },
66
            "ttl": {
67
                "type": "integer",
68
                "default": 1440,
69
                "required": True
70
            },
71
            "users": {
72
                "type": "array",
73
                "default": [],
74
                "required": True
75
            },
76
            "roles": {
77
                "type": "array",
78
                "default": [],
79
                "required": True
80
            },
81
            "schema": {
82
                "type": "object",
83
                "default": {
84
                    "title": "response_data",
85
                    "type": "object",
86
                    "properties": {
87
                        "continue": {
88
                            "type": "boolean",
89
                            "description": "Would you like to continue the workflow?",
90
                            "required": True
91
                        }
92
                    },
93
                },
94
                "required": True
95
            },
96
            "liveaction": REQUIRED_ATTR_SCHEMAS['liveaction'],
97
            "runner": REQUIRED_ATTR_SCHEMAS['runner'],
98
            "status": {
99
                "description": "The current status of the action execution.",
100
                "type": "string",
101
                "enum": LIVEACTION_STATUSES
102
            },
103
            "parent": {"type": "string"},
104
            "result": {
105
                "anyOf": [{"type": "array"},
106
                          {"type": "boolean"},
107
                          {"type": "integer"},
108
                          {"type": "number"},
109
                          {"type": "object"},
110
                          {"type": "string"}]
111
            }
112
        },
113
        "additionalProperties": False
114
    }
115
116
    @classmethod
117
    def from_model(cls, model, mask_secrets=False):
118
        doc = cls._from_model(model, mask_secrets=mask_secrets)
119
120
        newdoc = {
121
            "id": doc["id"],
122
            "runner": doc["runner"],
123
            "status": doc["status"],
124
            "liveaction": doc["liveaction"],
125
            "parent": doc.get("parent"),
126
            "result": doc['result']
127
        }
128
129
        for field in ["route", "ttl", "users", "roles", "schema"]:
130
            newdoc[field] = doc["result"].get(field)
131
132
        return cls(**newdoc)
133
134
135
class InquiryResponseAPI(BaseAPI):
136
    """A more pruned Inquiry model, containing only the fields needed for an API response
137
    """
138
139
    model = ActionExecutionDB
140
    schema = {
141
        "title": "Inquiry",
142
        "description": "Record of an Inquiry",
143
        "type": "object",
144
        "properties": {
145
            "id": {
146
                "type": "string",
147
                "required": True
148
            },
149
            "route": {
150
                "type": "string",
151
                "default": "",
152
                "required": True
153
            },
154
            "ttl": {
155
                "type": "integer",
156
                "default": 1440,
157
                "required": True
158
            },
159
            "users": {
160
                "type": "array",
161
                "default": [],
162
                "required": True
163
            },
164
            "roles": {
165
                "type": "array",
166
                "default": [],
167
                "required": True
168
            },
169
            "schema": {
170
                "type": "object",
171
                "default": {
172
                    "title": "response_data",
173
                    "type": "object",
174
                    "properties": {
175
                        "continue": {
176
                            "type": "boolean",
177
                            "description": "Would you like to continue the workflow?",
178
                            "required": True
179
                        }
180
                    },
181
                },
182
                "required": True
183
            }
184
        },
185
        "additionalProperties": False
186
    }
187
188
    @classmethod
189
    def from_model(cls, model, mask_secrets=False, skip_db=False):
0 ignored issues
show
Arguments number differs from overridden 'from_model' method
Loading history...
190
        """Create InquiryResponseAPI instance from model
191
192
        Allows skipping the BaseAPI._from_model function if you already
193
        have a properly formed dict and just need to prune it
194
195
        :param skip_db: Skip the parent class' _from_model function call
196
        :rtype: InquiryResponseAPI
197
        """
198
199
        if not skip_db:
200
            doc = cls._from_model(model, mask_secrets=mask_secrets)
201
        else:
202
            doc = model
203
204
        newdoc = {
205
            "id": doc["id"]
206
        }
207
        for field in ["route", "ttl", "users", "roles", "schema"]:
208
            newdoc[field] = doc["result"].get(field)
209
210
        return cls(**newdoc)
211
212
    @classmethod
213
    def from_inquiry_api(cls, inquiry_api, mask_secrets=False):
214
        """ Allows translation of InquiryAPI directly to InquiryResponseAPI
215
216
        This bypasses the DB modeling, since there's no DB model for Inquiries yet.
217
        """
218
219
        return cls(
220
            id=getattr(inquiry_api, 'id', None),
221
            route=getattr(inquiry_api, 'route', None),
222
            ttl=getattr(inquiry_api, 'ttl', None),
223
            users=getattr(inquiry_api, 'users', None),
224
            roles=getattr(inquiry_api, 'roles', None),
225
            schema=getattr(inquiry_api, 'schema', None)
226
        )
227