diff options
Diffstat (limited to 'iotronic/api/controllers/v1/board.py')
-rw-r--r-- | iotronic/api/controllers/v1/board.py | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/iotronic/api/controllers/v1/board.py b/iotronic/api/controllers/v1/board.py index 6539c85..054e7a3 100644 --- a/iotronic/api/controllers/v1/board.py +++ b/iotronic/api/controllers/v1/board.py | |||
@@ -152,11 +152,50 @@ class InjectionCollection(collection.Collection): | |||
152 | return collection | 152 | return collection |
153 | 153 | ||
154 | 154 | ||
155 | class ExposedService(base.APIBase): | ||
156 | service = types.uuid_or_name | ||
157 | board_uuid = types.uuid_or_name | ||
158 | public_port = wsme.types.IntegerType() | ||
159 | |||
160 | def __init__(self, **kwargs): | ||
161 | self.fields = [] | ||
162 | fields = list(objects.ExposedService.fields) | ||
163 | fields.remove('board_uuid') | ||
164 | for k in fields: | ||
165 | # Skip fields we do not expose. | ||
166 | if not hasattr(self, k): | ||
167 | continue | ||
168 | self.fields.append(k) | ||
169 | setattr(self, k, kwargs.get(k, wtypes.Unset)) | ||
170 | setattr(self, 'service', kwargs.get('service_uuid', wtypes.Unset)) | ||
171 | |||
172 | |||
173 | class ExposedCollection(collection.Collection): | ||
174 | """API representation of a collection of injection.""" | ||
175 | |||
176 | exposed = [ExposedService] | ||
177 | |||
178 | def __init__(self, **kwargs): | ||
179 | self._type = 'exposed' | ||
180 | |||
181 | @staticmethod | ||
182 | def get_list(exposed, fields=None): | ||
183 | collection = ExposedCollection() | ||
184 | collection.exposed = [ExposedService(**n.as_dict()) | ||
185 | for n in exposed] | ||
186 | return collection | ||
187 | |||
188 | |||
155 | class PluginAction(base.APIBase): | 189 | class PluginAction(base.APIBase): |
156 | action = wsme.wsattr(wtypes.text) | 190 | action = wsme.wsattr(wtypes.text) |
157 | parameters = types.jsontype | 191 | parameters = types.jsontype |
158 | 192 | ||
159 | 193 | ||
194 | class ServiceAction(base.APIBase): | ||
195 | action = wsme.wsattr(wtypes.text) | ||
196 | parameters = types.jsontype | ||
197 | |||
198 | |||
160 | class BoardPluginsController(rest.RestController): | 199 | class BoardPluginsController(rest.RestController): |
161 | def __init__(self, board_ident): | 200 | def __init__(self, board_ident): |
162 | self.board_ident = board_ident | 201 | self.board_ident = board_ident |
@@ -282,11 +321,72 @@ class BoardPluginsController(rest.RestController): | |||
282 | rpc_board.uuid) | 321 | rpc_board.uuid) |
283 | 322 | ||
284 | 323 | ||
324 | class BoardServicesController(rest.RestController): | ||
325 | _custom_actions = { | ||
326 | 'action': ['POST'], | ||
327 | } | ||
328 | |||
329 | def __init__(self, board_ident): | ||
330 | self.board_ident = board_ident | ||
331 | |||
332 | def _get_services_on_board_collection(self, board_uuid, fields=None): | ||
333 | services = objects.ExposedService.list(pecan.request.context, | ||
334 | board_uuid) | ||
335 | |||
336 | return ExposedCollection.get_list(services, | ||
337 | fields=fields) | ||
338 | |||
339 | @expose.expose(ExposedCollection, | ||
340 | status_code=200) | ||
341 | def get_all(self): | ||
342 | """Retrieve a list of services of a board. | ||
343 | |||
344 | """ | ||
345 | rpc_board = api_utils.get_rpc_board(self.board_ident) | ||
346 | |||
347 | cdict = pecan.request.context.to_policy_values() | ||
348 | cdict['project_id'] = rpc_board.project | ||
349 | policy.authorize('iot:service_on_board:get', cdict, cdict) | ||
350 | |||
351 | return self._get_services_on_board_collection(rpc_board.uuid) | ||
352 | |||
353 | @expose.expose(wtypes.text, types.uuid_or_name, body=ServiceAction, | ||
354 | status_code=200) | ||
355 | def action(self, service_ident, ServiceAction): | ||
356 | |||
357 | if not ServiceAction.action: | ||
358 | raise exception.MissingParameterValue( | ||
359 | ("Action is not specified.")) | ||
360 | |||
361 | if not ServiceAction.parameters: | ||
362 | ServiceAction.parameters = {} | ||
363 | |||
364 | rpc_board = api_utils.get_rpc_board(self.board_ident) | ||
365 | rpc_service = api_utils.get_rpc_service(service_ident) | ||
366 | |||
367 | try: | ||
368 | cdict = pecan.request.context.to_policy_values() | ||
369 | cdict['owner'] = rpc_board.owner | ||
370 | policy.authorize('iot:service_action:post', cdict, cdict) | ||
371 | |||
372 | except exception: | ||
373 | return exception | ||
374 | |||
375 | rpc_board.check_if_online() | ||
376 | |||
377 | result = pecan.request.rpcapi.action_service(pecan.request.context, | ||
378 | rpc_service.uuid, | ||
379 | rpc_board.uuid, | ||
380 | ServiceAction.action) | ||
381 | return result | ||
382 | |||
383 | |||
285 | class BoardsController(rest.RestController): | 384 | class BoardsController(rest.RestController): |
286 | """REST controller for Boards.""" | 385 | """REST controller for Boards.""" |
287 | 386 | ||
288 | _subcontroller_map = { | 387 | _subcontroller_map = { |
289 | 'plugins': BoardPluginsController, | 388 | 'plugins': BoardPluginsController, |
389 | 'services': BoardServicesController, | ||
290 | } | 390 | } |
291 | 391 | ||
292 | invalid_sort_key_list = ['extra', 'location'] | 392 | invalid_sort_key_list = ['extra', 'location'] |