New Board Action.

'DevicePing', 'DeviceReboot', 'DeviceRestartLR', 'DeviceNetConfig',
'DeviceEcho', 'DeviceUpgradeLR' can be sent to the board.

Change-Id: I3faef69d5a205332ed3ce81301cfa620f862adcf
This commit is contained in:
Fabio Verboso 2019-04-29 14:50:38 +02:00
parent 73765913f8
commit 76fb5ffc64
6 changed files with 78 additions and 0 deletions

View File

@ -260,6 +260,11 @@ class Network(base.APIBase):
security_groups = types.jsontype
class BoardAction(base.APIBase):
action = wsme.wsattr(wtypes.text)
parameters = types.jsontype
class BoardPluginsController(rest.RestController):
def __init__(self, board_ident):
self.board_ident = board_ident
@ -719,6 +724,7 @@ class BoardsController(rest.RestController):
_custom_actions = {
'detail': ['GET'],
'action': ['POST'],
}
@pecan.expose()
@ -937,3 +943,24 @@ class BoardsController(rest.RestController):
return self._get_boards_collection(status, marker,
limit, sort_key, sort_dir,
project=project, fields=fields)
@expose.expose(wtypes.text, types.uuid_or_name, body=BoardAction,
status_code=200)
def action(self, board_ident, BoardAction):
"""Action on a board.
:param board_ident: UUID or logical name of a board.
"""
context = pecan.request.context
cdict = context.to_policy_values()
policy.authorize('iot:board_action:post', cdict, cdict)
if not BoardAction.parameters:
BoardAction.parameters = {}
rpc_board = api_utils.get_rpc_board(board_ident)
return pecan.request.rpcapi.action_board(pecan.request.context,
rpc_board.uuid,
BoardAction.action,
BoardAction.parameters)

View File

@ -142,6 +142,10 @@ class BoardAlreadyExists(Conflict):
message = _("A board with UUID %(uuid)s already exists.")
class InvalidBoardAction(Invalid):
message = _("Invalid Action %(action)s for the board.")
class BoardInvalidStatus(Conflict):
message = _(
"A board with UUID %(uuid)s has a not valid state: %(status)s.")

View File

@ -85,6 +85,9 @@ board_policies = [
'rule:is_admin or rule:is_admin_iot_project '
'or rule:is_manager_iot_project',
description='Update Board records'),
policy.RuleDefault('iot:board_action:post',
'rule:admin_or_owner',
description='Action on Board records'),
]

View File

@ -241,6 +241,27 @@ class ConductorEndpoint(object):
return res
def action_board(self, ctx, board_uuid, action, params):
LOG.info('Calling action %s, into the board %s with params %s',
action, board_uuid, params)
board = objects.Board.get(ctx, board_uuid)
if not board.is_online():
raise exception.BoardNotConnected(board=board.uuid)
objects.board.is_valid_action(action)
try:
result = self.execute_on_board(ctx, board_uuid, action,
(params))
except exception:
return exception
result = manage_result(result, action, board_uuid)
LOG.debug(result)
return result
def destroy_plugin(self, ctx, plugin_id):
LOG.info('Destroying plugin with id %s',
plugin_id)

View File

@ -128,6 +128,20 @@ class ConductorAPI(object):
wamp_rpc_call=wamp_rpc_call,
wamp_rpc_args=wamp_rpc_args)
def action_board(self, context, board_uuid, action, params, topic=None):
"""Action on a board
:param context: request context.
:param board_uuid: board id or uuid.
' :param action: action.
ì :param paramas: parameters of the action
ì :param long_running: boolean if a response need to be waited.
"""
cctxt = self.client.prepare(topic=topic or self.topic, version='1.0')
return cctxt.call(context, 'action_board', board_uuid=board_uuid,
action=action, params=params)
def create_plugin(self, context, plugin_obj, topic=None):
"""Add a plugin on the cloud

View File

@ -22,6 +22,15 @@ from iotronic.db import api as db_api
from iotronic.objects import base
from iotronic.objects import utils as obj_utils
ACTIONS = ['DevicePing', 'DeviceReboot', 'DeviceRestartLR',
'DeviceNetConfig', 'DeviceEcho', 'DeviceUpgradeLR']
def is_valid_action(action):
if action not in ACTIONS:
raise exception.InvalidBoardAction(action=action)
return True
class Board(base.IotronicObject):
# Version 1.0: Initial version