diff options
-rw-r--r-- | iotronic/api/controllers/v1/board.py | 26 | ||||
-rw-r--r-- | iotronic/common/exception.py | 4 | ||||
-rw-r--r-- | iotronic/conductor/endpoints.py | 104 | ||||
-rw-r--r-- | iotronic/conductor/rpcapi.py | 13 | ||||
-rw-r--r-- | iotronic/db/api.py | 2 | ||||
-rw-r--r-- | iotronic/db/sqlalchemy/api.py | 6 | ||||
-rw-r--r-- | iotronic/objects/exposedservice.py | 20 |
7 files changed, 100 insertions, 75 deletions
diff --git a/iotronic/api/controllers/v1/board.py b/iotronic/api/controllers/v1/board.py index 054e7a3..d316be8 100644 --- a/iotronic/api/controllers/v1/board.py +++ b/iotronic/api/controllers/v1/board.py | |||
@@ -322,8 +322,10 @@ class BoardPluginsController(rest.RestController): | |||
322 | 322 | ||
323 | 323 | ||
324 | class BoardServicesController(rest.RestController): | 324 | class BoardServicesController(rest.RestController): |
325 | |||
325 | _custom_actions = { | 326 | _custom_actions = { |
326 | 'action': ['POST'], | 327 | 'action': ['POST'], |
328 | 'restore': ['GET'] | ||
327 | } | 329 | } |
328 | 330 | ||
329 | def __init__(self, board_ident): | 331 | def __init__(self, board_ident): |
@@ -358,9 +360,6 @@ class BoardServicesController(rest.RestController): | |||
358 | raise exception.MissingParameterValue( | 360 | raise exception.MissingParameterValue( |
359 | ("Action is not specified.")) | 361 | ("Action is not specified.")) |
360 | 362 | ||
361 | if not ServiceAction.parameters: | ||
362 | ServiceAction.parameters = {} | ||
363 | |||
364 | rpc_board = api_utils.get_rpc_board(self.board_ident) | 363 | rpc_board = api_utils.get_rpc_board(self.board_ident) |
365 | rpc_service = api_utils.get_rpc_service(service_ident) | 364 | rpc_service = api_utils.get_rpc_service(service_ident) |
366 | 365 | ||
@@ -380,6 +379,27 @@ class BoardServicesController(rest.RestController): | |||
380 | ServiceAction.action) | 379 | ServiceAction.action) |
381 | return result | 380 | return result |
382 | 381 | ||
382 | @expose.expose(ExposedCollection, | ||
383 | status_code=200) | ||
384 | def restore(self): | ||
385 | rpc_board = api_utils.get_rpc_board(self.board_ident) | ||
386 | |||
387 | try: | ||
388 | cdict = pecan.request.context.to_policy_values() | ||
389 | cdict['owner'] = rpc_board.owner | ||
390 | policy.authorize('iot:service_action:post', cdict, cdict) | ||
391 | |||
392 | except exception: | ||
393 | return exception | ||
394 | |||
395 | rpc_board.check_if_online() | ||
396 | |||
397 | pecan.request.rpcapi.restore_services_on_board( | ||
398 | pecan.request.context, | ||
399 | rpc_board.uuid) | ||
400 | |||
401 | return self._get_services_on_board_collection(rpc_board.uuid) | ||
402 | |||
383 | 403 | ||
384 | class BoardsController(rest.RestController): | 404 | class BoardsController(rest.RestController): |
385 | """REST controller for Boards.""" | 405 | """REST controller for Boards.""" |
diff --git a/iotronic/common/exception.py b/iotronic/common/exception.py index 76d24d2..8309149 100644 --- a/iotronic/common/exception.py +++ b/iotronic/common/exception.py | |||
@@ -609,3 +609,7 @@ class ServiceAlreadyExposed(Conflict): | |||
609 | 609 | ||
610 | class ExposedServiceNotFound(NotFound): | 610 | class ExposedServiceNotFound(NotFound): |
611 | message = _("ExposedService %(uuid)s could not be found.") | 611 | message = _("ExposedService %(uuid)s could not be found.") |
612 | |||
613 | |||
614 | class NoExposedServices(NotFound): | ||
615 | message = _("No exposed services on the board %(uuid)s.") | ||
diff --git a/iotronic/conductor/endpoints.py b/iotronic/conductor/endpoints.py index 5e10c49..14a4518 100644 --- a/iotronic/conductor/endpoints.py +++ b/iotronic/conductor/endpoints.py | |||
@@ -305,12 +305,12 @@ class ConductorEndpoint(object): | |||
305 | return serializer.serialize_entity(ctx, service) | 305 | return serializer.serialize_entity(ctx, service) |
306 | 306 | ||
307 | def action_service(self, ctx, service_uuid, board_uuid, action): | 307 | def action_service(self, ctx, service_uuid, board_uuid, action): |
308 | LOG.info('Enable service with id %s into the board %s', | ||
309 | service_uuid, board_uuid) | ||
310 | service = objects.Service.get(ctx, service_uuid) | 308 | service = objects.Service.get(ctx, service_uuid) |
311 | objects.service.is_valid_action(action) | 309 | objects.service.is_valid_action(action) |
312 | 310 | ||
313 | if action == "ServiceEnable": | 311 | if action == "ServiceEnable": |
312 | LOG.info('Enabling service with id %s into the board %s', | ||
313 | service_uuid, board_uuid) | ||
314 | try: | 314 | try: |
315 | objects.ExposedService.get(ctx, | 315 | objects.ExposedService.get(ctx, |
316 | board_uuid, | 316 | board_uuid, |
@@ -348,6 +348,8 @@ class ConductorEndpoint(object): | |||
348 | return res.message | 348 | return res.message |
349 | 349 | ||
350 | elif action == "ServiceDisable": | 350 | elif action == "ServiceDisable": |
351 | LOG.info('Disabling service with id %s into the board %s', | ||
352 | service_uuid, board_uuid) | ||
351 | exposed = objects.ExposedService.get(ctx, | 353 | exposed = objects.ExposedService.get(ctx, |
352 | board_uuid, | 354 | board_uuid, |
353 | service_uuid) | 355 | service_uuid) |
@@ -361,12 +363,11 @@ class ConductorEndpoint(object): | |||
361 | return result | 363 | return result |
362 | 364 | ||
363 | elif action == "ServiceRestore": | 365 | elif action == "ServiceRestore": |
364 | 366 | LOG.info('Restoring service with id %s into the board %s', | |
367 | service_uuid, board_uuid) | ||
365 | exposed = objects.ExposedService.get(ctx, board_uuid, | 368 | exposed = objects.ExposedService.get(ctx, board_uuid, |
366 | service_uuid) | 369 | service_uuid) |
367 | 370 | ||
368 | print(exposed) | ||
369 | |||
370 | res = self.execute_on_board(ctx, board_uuid, action, | 371 | res = self.execute_on_board(ctx, board_uuid, action, |
371 | (service.name, exposed.public_port, | 372 | (service.name, exposed.public_port, |
372 | service.port, exposed.pid)) | 373 | service.port, exposed.pid)) |
@@ -396,58 +397,41 @@ class ConductorEndpoint(object): | |||
396 | LOG.debug(res.message) | 397 | LOG.debug(res.message) |
397 | return res.message | 398 | return res.message |
398 | 399 | ||
399 | # try: | 400 | def restore_services_on_board(self, ctx, board_uuid): |
400 | # | 401 | LOG.info('Restoring the services into the board %s', |
401 | # | 402 | board_uuid) |
402 | # return exception.ServiceAlreadyExposed(uuid=service_uuid) | 403 | |
403 | # except: | 404 | exposed_list = objects.ExposedService.get_by_board_uuid(ctx, |
404 | # name=service.name | 405 | board_uuid) |
405 | # public_port=random_public_port() | 406 | |
406 | # port=service.port | 407 | # response = [] |
407 | # | 408 | for exposed in exposed_list: |
408 | # res = self.execute_on_board(ctx, board_uuid, action, | 409 | service = objects.Service.get_by_uuid(ctx, exposed.service_uuid) |
409 | # (name, public_port, port)) | 410 | res = self.execute_on_board(ctx, board_uuid, "ServiceRestore", |
410 | # | 411 | (service.name, exposed.public_port, |
411 | # if res.result == wm.SUCCESS: | 412 | service.port, exposed.pid)) |
412 | # pid = res.message[0] | 413 | |
413 | # | 414 | if res.result == wm.SUCCESS: |
414 | # exp_data = { | 415 | pid = res.message[0] |
415 | # 'board_uuid': board_uuid, | 416 | |
416 | # 'service_uuid': service_uuid, | 417 | exp_data = { |
417 | # 'public_port': public_port, | 418 | 'id': exposed.id, |
418 | # 'pid': pid, | 419 | 'board_uuid': exposed.board_uuid, |
419 | # } | 420 | 'service_uuid': exposed.service_uuid, |
420 | # exposed = objects.ExposedService(ctx, **exp_data) | 421 | 'public_port': exposed.public_port, |
421 | # exposed.create() | 422 | 'pid': pid, |
422 | # | 423 | } |
423 | # res.message = res.message[1] | 424 | |
424 | # elif res.result == wm.ERROR: | 425 | exposed = objects.ExposedService(ctx, **exp_data) |
425 | # LOG.error('Error in the execution of %s on %s: %s', | 426 | exposed.save() |
426 | # action, | 427 | |
427 | # board_uuid, res.message) | 428 | # response.append(exposed) |
428 | # raise exception.ErrorExecutionOnBoard(call=action, | 429 | elif res.result == wm.ERROR: |
429 | # board=board_uuid, | 430 | LOG.error('Error in restoring %s on %s: %s', |
430 | # error=res.message) | 431 | service.name, |
431 | # LOG.debug(res.message) | 432 | board_uuid, res.message) |
432 | # return res.message | 433 | raise exception.ErrorExecutionOnBoard(call="ServiceRestore", |
433 | # | 434 | board=board_uuid, |
434 | # | 435 | error=res.message) |
435 | # | 436 | |
436 | # | 437 | return 0 |
437 | # | ||
438 | # | ||
439 | # | ||
440 | # | ||
441 | # | ||
442 | # | ||
443 | # | ||
444 | # exposed = objects.ExposedService.get(ctx, board_uuid, | ||
445 | # service_uuid) | ||
446 | # | ||
447 | # res = self.execute_on_board(ctx, board_uuid, action, | ||
448 | # (service.name, exposed.pid)) | ||
449 | # | ||
450 | # result=manage_result(res,action,board_uuid) | ||
451 | # LOG.debug(res.message) | ||
452 | # exposed.destroy() | ||
453 | # return result | ||
diff --git a/iotronic/conductor/rpcapi.py b/iotronic/conductor/rpcapi.py index 223c993..6dfebfd 100644 --- a/iotronic/conductor/rpcapi.py +++ b/iotronic/conductor/rpcapi.py | |||
@@ -263,3 +263,16 @@ class ConductorAPI(object): | |||
263 | 263 | ||
264 | return cctxt.call(context, 'action_service', service_uuid=service_uuid, | 264 | return cctxt.call(context, 'action_service', service_uuid=service_uuid, |
265 | board_uuid=board_uuid, action=action) | 265 | board_uuid=board_uuid, action=action) |
266 | |||
267 | def restore_services_on_board(self, context, | ||
268 | board_uuid, topic=None): | ||
269 | """Restore all the services on a board. | ||
270 | |||
271 | :param context: request context. | ||
272 | :param board_uuid: board id or uuid. | ||
273 | |||
274 | """ | ||
275 | cctxt = self.client.prepare(topic=topic or self.topic, version='1.0') | ||
276 | |||
277 | return cctxt.call(context, 'restore_services_on_board', | ||
278 | board_uuid=board_uuid) | ||
diff --git a/iotronic/db/api.py b/iotronic/db/api.py index 82fafff..dfdf4d2 100644 --- a/iotronic/db/api.py +++ b/iotronic/db/api.py | |||
@@ -475,7 +475,7 @@ class Connection(object): | |||
475 | """ | 475 | """ |
476 | 476 | ||
477 | @abc.abstractmethod | 477 | @abc.abstractmethod |
478 | def get_exposed_service_by_board_uuid(self, board_uuid): | 478 | def get_exposed_services_by_board_uuid(self, board_uuid): |
479 | """get an exposed of a service using a board_uuid | 479 | """get an exposed of a service using a board_uuid |
480 | 480 | ||
481 | :param board_uuid: The id or uuid of a board. | 481 | :param board_uuid: The id or uuid of a board. |
diff --git a/iotronic/db/sqlalchemy/api.py b/iotronic/db/sqlalchemy/api.py index 275f674..76f9d80 100644 --- a/iotronic/db/sqlalchemy/api.py +++ b/iotronic/db/sqlalchemy/api.py | |||
@@ -764,14 +764,14 @@ class Connection(api.Connection): | |||
764 | 764 | ||
765 | # EXPOSED SERVICE api | 765 | # EXPOSED SERVICE api |
766 | 766 | ||
767 | def get_exposed_service_by_board_uuid(self, board_uuid): | 767 | def get_exposed_services_by_board_uuid(self, board_uuid): |
768 | query = model_query( | 768 | query = model_query( |
769 | models.ExposedService).filter_by( | 769 | models.ExposedService).filter_by( |
770 | board_uuid=board_uuid) | 770 | board_uuid=board_uuid) |
771 | try: | 771 | try: |
772 | return query.one() | 772 | return query.all() |
773 | except NoResultFound: | 773 | except NoResultFound: |
774 | raise exception.ExposedServiceNotFound() | 774 | raise exception.NoExposedServices(uuid=board_uuid) |
775 | 775 | ||
776 | def create_exposed_service(self, values): | 776 | def create_exposed_service(self, values): |
777 | # ensure defaults are present for new services | 777 | # ensure defaults are present for new services |
diff --git a/iotronic/objects/exposedservice.py b/iotronic/objects/exposedservice.py index 7e96cda..3396545 100644 --- a/iotronic/objects/exposedservice.py +++ b/iotronic/objects/exposedservice.py | |||
@@ -55,16 +55,20 @@ class ExposedService(base.IotronicObject): | |||
55 | 55 | ||
56 | @base.remotable_classmethod | 56 | @base.remotable_classmethod |
57 | def get_by_board_uuid(cls, context, board_uuid): | 57 | def get_by_board_uuid(cls, context, board_uuid): |
58 | """Find a exposed_service based on uuid and return a Board object. | 58 | """Return a list of ExposedService objects. |
59 | |||
60 | :param context: Security context. | ||
61 | :param limit: maximum number of resources to return in a single result. | ||
62 | :param marker: pagination marker for large data sets. | ||
63 | :param sort_key: column to sort results by. | ||
64 | :param sort_dir: direction to sort. "asc" or "desc". | ||
65 | :param filters: Filters to apply. | ||
66 | :returns: a list of :class:`ExposedService` object. | ||
59 | 67 | ||
60 | :param board_uuid: the uuid of a exposed_service. | ||
61 | :returns: a :class:`exposed_service` object. | ||
62 | """ | 68 | """ |
63 | db_exp_service = cls.dbapi.get_exposed_service_by_board_uuid( | 69 | db_exps = cls.dbapi.get_exposed_services_by_board_uuid(board_uuid) |
64 | board_uuid) | 70 | return [ExposedService._from_db_object(cls(context), obj) |
65 | exp_service = ExposedService._from_db_object(cls(context), | 71 | for obj in db_exps] |
66 | db_exp_service) | ||
67 | return exp_service | ||
68 | 72 | ||
69 | @base.remotable_classmethod | 73 | @base.remotable_classmethod |
70 | def get_by_service_uuid(cls, context, service_uuid): | 74 | def get_by_service_uuid(cls, context, service_uuid): |