Upgraded to Iotronic 0.5.0 functions and requirements.
Change-Id: I69cea568c3a9bd38377dc6a3f3dbc6494fd9d59b
This commit is contained in:
parent
60acb5cfbb
commit
fdbd0e0af9
|
@ -1,17 +1,18 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# from collections import OrderedDict
|
||||
# import threading
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from iotronicclient import client as iotronic_client
|
||||
# from django.conf import settings
|
||||
|
@ -71,6 +72,44 @@ def board_delete(request, board_id):
|
|||
iotronicclient(request).board.delete(board_id)
|
||||
|
||||
|
||||
# DEVICE MANAGEMENT
|
||||
def device_list(request, status=None, detail=None, project=None):
|
||||
"""List devices."""
|
||||
return iotronicclient(request).board.list(status, detail, project)
|
||||
|
||||
|
||||
def device_get(request, device_id, fields):
|
||||
"""Get device info."""
|
||||
return iotronicclient(request).board.get(device_id, fields)
|
||||
|
||||
|
||||
def device_create(request, code, mobile, location, type, name):
|
||||
"""Create device."""
|
||||
params = {"code": code,
|
||||
"mobile": mobile,
|
||||
"location": location,
|
||||
"type": type,
|
||||
"name": name}
|
||||
iotronicclient(request).board.create(**params)
|
||||
|
||||
|
||||
def device_update(request, device_id, patch):
|
||||
"""Update device."""
|
||||
iotronicclient(request).board.update(device_id, patch)
|
||||
|
||||
|
||||
def device_delete(request, device_id):
|
||||
"""Delete device."""
|
||||
iotronicclient(request).board.delete(device_id)
|
||||
|
||||
|
||||
def device_action(request, device_id, action, parameters):
|
||||
"""Action on device."""
|
||||
return iotronicclient(request).board.board_action(device_id,
|
||||
action,
|
||||
parameters)
|
||||
|
||||
|
||||
# PLUGIN MANAGEMENT (Cloud Side)
|
||||
def plugin_list(request, detail=None, project=None, with_public=False,
|
||||
all_plugins=False):
|
||||
|
@ -107,22 +146,22 @@ def plugin_delete(request, plugin_id):
|
|||
|
||||
|
||||
# PLUGIN MANAGEMENT (Board Side)
|
||||
def plugin_inject(request, board_id, plugin_id, onboot):
|
||||
"""Inject plugin on board(s)."""
|
||||
return iotronicclient(request).plugin_injection.plugin_inject(board_id,
|
||||
def plugin_inject(request, device_id, plugin_id, onboot):
|
||||
"""Inject plugin on device."""
|
||||
return iotronicclient(request).plugin_injection.plugin_inject(device_id,
|
||||
plugin_id,
|
||||
onboot)
|
||||
|
||||
|
||||
def plugin_action(request, board_id, plugin_id, action, params={}):
|
||||
"""Start/Stop/Call actions on board(s)."""
|
||||
def plugin_action(request, device_id, plugin_id, action, params={}):
|
||||
"""Start/Stop/Call actions on device."""
|
||||
return iotronicclient(request).plugin_injection.plugin_action(
|
||||
board_id, plugin_id, action, params)
|
||||
device_id, plugin_id, action, params)
|
||||
|
||||
|
||||
def plugin_remove(request, board_id, plugin_id):
|
||||
"""Remove plugin from board."""
|
||||
iotronicclient(request).plugin_injection.plugin_remove(board_id,
|
||||
def plugin_remove(request, device_id, plugin_id):
|
||||
"""Remove plugin from device."""
|
||||
iotronicclient(request).plugin_injection.plugin_remove(device_id,
|
||||
plugin_id)
|
||||
|
||||
|
||||
|
@ -142,6 +181,27 @@ def plugins_on_board(request, board_id):
|
|||
return detailed_plugins
|
||||
|
||||
|
||||
def plugins_on_device(request, device_id):
|
||||
"""Plugins on device."""
|
||||
plugins = iotronicclient(request).plugin_injection.plugins_on_board(
|
||||
device_id)
|
||||
|
||||
detailed_plugins = []
|
||||
fields = {"name", "public", "callable"}
|
||||
# fields = {"name"}
|
||||
for plugin in plugins:
|
||||
details = iotronicclient(request).plugin.get(plugin.plugin, fields)
|
||||
details._info[u"uuid"] = plugin.plugin
|
||||
"""
|
||||
detailed_plugins.append({"name": details._info["name"],
|
||||
"public": details._info["public"],
|
||||
"callable": details._info["callable"],
|
||||
"uuid": plugin.plugin})
|
||||
"""
|
||||
detailed_plugins.append(details)
|
||||
return detailed_plugins
|
||||
|
||||
|
||||
# SERVICE MANAGEMENT
|
||||
def service_list(request, detail=None):
|
||||
"""List services."""
|
||||
|
@ -197,34 +257,60 @@ def services_on_board(request, board_id, detail=False):
|
|||
return services
|
||||
|
||||
|
||||
def service_action(request, board_id, service_id, action):
|
||||
def services_on_device(request, device_id, detail=False):
|
||||
"""List services on device."""
|
||||
services = iotronicclient(request).exposed_service.services_on_board(
|
||||
device_id)
|
||||
|
||||
if detail:
|
||||
detailed_services = []
|
||||
fields = {"name", "port", "protocol"}
|
||||
|
||||
for service in services:
|
||||
details = iotronicclient(request).service.get(
|
||||
service._info["service"], fields)
|
||||
|
||||
detailed_services.append({"uuid": service._info["service"],
|
||||
"name": details._info["name"],
|
||||
"public_port":
|
||||
service._info["public_port"],
|
||||
"port": details._info["port"],
|
||||
"protocol": details._info["protocol"]})
|
||||
|
||||
return detailed_services
|
||||
|
||||
else:
|
||||
return services
|
||||
|
||||
|
||||
def service_action(request, device_id, service_id, action):
|
||||
"""Action on service."""
|
||||
return iotronicclient(request).exposed_service.service_action(board_id,
|
||||
return iotronicclient(request).exposed_service.service_action(device_id,
|
||||
service_id,
|
||||
action)
|
||||
|
||||
|
||||
def restore_services(request, board_id):
|
||||
def restore_services(request, device_id):
|
||||
"""Restore services."""
|
||||
return iotronicclient(request).exposed_service.restore_services(board_id)
|
||||
return iotronicclient(request).exposed_service.restore_services(device_id)
|
||||
|
||||
|
||||
# PORTS MANAGEMENT
|
||||
def port_list(request, board_id):
|
||||
"""Get ports attached to a board."""
|
||||
def port_list(request, device_id):
|
||||
"""Get ports attached to a device."""
|
||||
return iotronicclient(request).port.list()
|
||||
|
||||
|
||||
def attach_port(request, board_id, network_id, subnet_id):
|
||||
"""Attach port to a subnet for a board."""
|
||||
return iotronicclient(request).portonboard.attach_port(board_id,
|
||||
def attach_port(request, device_id, network_id, subnet_id):
|
||||
"""Attach port to a subnet for a device."""
|
||||
return iotronicclient(request).portonboard.attach_port(device_id,
|
||||
network_id,
|
||||
subnet_id)
|
||||
|
||||
|
||||
def detach_port(request, board_id, port_id):
|
||||
"""Detach port from the board."""
|
||||
iotronicclient(request).portonboard.detach_port(board_id, port_id)
|
||||
def detach_port(request, device_id, port_id):
|
||||
"""Detach port from the device."""
|
||||
iotronicclient(request).portonboard.detach_port(device_id, port_id)
|
||||
|
||||
|
||||
# FLEETS MANAGEMENT
|
||||
|
@ -256,8 +342,8 @@ def fleet_update(request, fleet_id, patch):
|
|||
iotronicclient(request).fleet.update(fleet_id, patch)
|
||||
|
||||
|
||||
def fleet_get_boards(request, fleet_id):
|
||||
"""Get fleet boards."""
|
||||
def fleet_get_devices(request, fleet_id):
|
||||
"""Get fleet devices."""
|
||||
return iotronicclient(request).fleet.boards_in_fleet(fleet=fleet_id)
|
||||
|
||||
|
||||
|
@ -272,14 +358,14 @@ def webservice_enabled_list(request):
|
|||
return iotronicclient(request).enabledwebservice.list()
|
||||
|
||||
|
||||
def webservice_get_enabled_info(request, board_id, detail=None):
|
||||
def webservice_get_enabled_info(request, device_id, detail=None):
|
||||
"""Get the information of the enabled webservices."""
|
||||
ws_info = []
|
||||
|
||||
ws_enabled = iotronicclient(request).enabledwebservice.list()
|
||||
|
||||
for ws in ws_enabled:
|
||||
if ws.board_uuid == board_id:
|
||||
if ws.board_uuid == device_id:
|
||||
ws_info = ws
|
||||
break
|
||||
|
||||
|
@ -302,35 +388,51 @@ def webservices_on_board(request, board_id, fields=None):
|
|||
return detailed_webservices
|
||||
|
||||
|
||||
def webservices_on_device(request, device_id, fields=None):
|
||||
"""Get web services on device list."""
|
||||
webservices = iotronicclient(request).webserviceonboard.list(device_id,
|
||||
fields)
|
||||
|
||||
detailed_webservices = []
|
||||
# fields = {"name", "port", "uuid"}
|
||||
|
||||
for ws in webservices:
|
||||
detailed_webservices.append({"name": ws._info["name"],
|
||||
"port": ws._info["port"],
|
||||
"uuid": ws._info["uuid"]})
|
||||
|
||||
return detailed_webservices
|
||||
|
||||
|
||||
def webservice_get(request, webservice_id, fields):
|
||||
"""Get web service info."""
|
||||
return iotronicclient(request).webservice.get(webservice_id, fields)
|
||||
|
||||
|
||||
def webservice_expose(request, board_id, name, port, secure):
|
||||
def webservice_expose(request, device, name, port, secure):
|
||||
"""Expose a web service."""
|
||||
return iotronicclient(request).webserviceonboard.expose(board_id,
|
||||
return iotronicclient(request).webserviceonboard.expose(device,
|
||||
name,
|
||||
port,
|
||||
secure)
|
||||
|
||||
|
||||
def webservice_unexpose(request, webservice_id):
|
||||
"""Unexpose a web service from a board."""
|
||||
"""Unexpose a web service from a device."""
|
||||
return iotronicclient(request).webservice.delete(webservice_id)
|
||||
|
||||
|
||||
def webservice_enable(request, board, dns, zone, email):
|
||||
def webservice_enable(request, dev, dns, zone, email):
|
||||
"""Enable web service."""
|
||||
return iotronicclient(request).webserviceonboard.enable_webservice(board,
|
||||
return iotronicclient(request).webserviceonboard.enable_webservice(dev,
|
||||
dns,
|
||||
zone,
|
||||
email)
|
||||
|
||||
|
||||
def webservice_disable(request, board):
|
||||
def webservice_disable(request, dev):
|
||||
"""Disable web service."""
|
||||
return iotronicclient(request).webserviceonboard.disable_webservice(board)
|
||||
return iotronicclient(request).webserviceonboard.disable_webservice(dev)
|
||||
|
||||
|
||||
def boards_no_webservice(request):
|
||||
|
@ -347,8 +449,9 @@ def boards_no_webservice(request):
|
|||
for i in range(len(board_ws_list)):
|
||||
if board.uuid == board_ws_list[i].board_uuid:
|
||||
break
|
||||
elif ((board.uuid != board_ws_list[i].board_uuid) and
|
||||
(i==len(board_ws_list)-1)):
|
||||
elif (
|
||||
(board.uuid != board_ws_list[i].board_uuid) and (i == len(board_ws_list)-1)
|
||||
):
|
||||
boards_no_ws_enabled.append((board.uuid, _(board.name)))
|
||||
|
||||
# LOG.debug('COMPLEMENTARY %s', boards_no_ws_enabled)
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
# Copyright 2015, Rackspace, US, Inc.
|
||||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
# The slug of the dashboard to be added to HORIZON['dashboards']. Required.
|
||||
DASHBOARD = 'iot'
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# The slug of the panel group to be added to HORIZON_CONFIG. Required.
|
||||
PANEL_GROUP = 'iot_devices'
|
||||
# The display name of the PANEL_GROUP. Required.
|
||||
PANEL_GROUP_NAME = _('Devices')
|
||||
# The slug of the dashboard the PANEL_GROUP associated with. Required.
|
||||
PANEL_GROUP_DASHBOARD = 'iot'
|
|
@ -0,0 +1,28 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'devices'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'iot'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
# PANEL_GROUP = 'iot'
|
||||
PANEL_GROUP = 'iot_devices'
|
||||
# If set, it will update the default panel of the PANEL_DASHBOARD.
|
||||
DEFAULT_PANEL = ''
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'iotronic_ui.iot.devices.panel.Devices'
|
|
@ -0,0 +1,23 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'fleets'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'iot'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'iot_devices'
|
||||
# If set, it will update the default panel of the PANEL_DASHBOARD.
|
||||
DEFAULT_PANEL = ''
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'iotronic_ui.iot.fleets.panel.Fleets'
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# The slug of the panel group to be added to HORIZON_CONFIG. Required.
|
||||
PANEL_GROUP = 'iot_plugins'
|
||||
# The display name of the PANEL_GROUP. Required.
|
||||
PANEL_GROUP_NAME = _('Plugins')
|
||||
# The slug of the dashboard the PANEL_GROUP associated with. Required.
|
||||
PANEL_GROUP_DASHBOARD = 'iot'
|
|
@ -0,0 +1,23 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'plugins_devices'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'iot'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'iot_plugins'
|
||||
# If set, it will update the default panel of the PANEL_DASHBOARD.
|
||||
DEFAULT_PANEL = ''
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'iotronic_ui.iot.plugins_devices.panel.PluginsDevices'
|
|
@ -0,0 +1,23 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'plugins'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'iot'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'iot_plugins'
|
||||
# If set, it will update the default panel of the PANEL_DASHBOARD.
|
||||
DEFAULT_PANEL = ''
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'iotronic_ui.iot.plugins.panel.Plugins'
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# The slug of the panel group to be added to HORIZON_CONFIG. Required.
|
||||
PANEL_GROUP = 'iot_services'
|
||||
# The display name of the PANEL_GROUP. Required.
|
||||
PANEL_GROUP_NAME = _('Services')
|
||||
# The slug of the dashboard the PANEL_GROUP associated with. Required.
|
||||
PANEL_GROUP_DASHBOARD = 'iot'
|
|
@ -0,0 +1,23 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'services_devices'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'iot'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'iot_services'
|
||||
# If set, it will update the default panel of the PANEL_DASHBOARD.
|
||||
DEFAULT_PANEL = ''
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'iotronic_ui.iot.services_devices.panel.ServicesDevices'
|
|
@ -0,0 +1,23 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'services'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'iot'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'iot_services'
|
||||
# If set, it will update the default panel of the PANEL_DASHBOARD.
|
||||
DEFAULT_PANEL = ''
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'iotronic_ui.iot.services.panel.Services'
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# The slug of the panel group to be added to HORIZON_CONFIG. Required.
|
||||
PANEL_GROUP = 'iot_webservices'
|
||||
# The display name of the PANEL_GROUP. Required.
|
||||
PANEL_GROUP_NAME = _('Web Services')
|
||||
# The slug of the dashboard the PANEL_GROUP associated with. Required.
|
||||
PANEL_GROUP_DASHBOARD = 'iot'
|
|
@ -0,0 +1,23 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'webservices_devices'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'iot'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'iot_webservices'
|
||||
# If set, it will update the default panel of the PANEL_DASHBOARD.
|
||||
DEFAULT_PANEL = ''
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'iotronic_ui.iot.webservices_devices.panel.WebServicesDevices'
|
|
@ -0,0 +1,23 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'webservices'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'iot'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'iot_webservices'
|
||||
# If set, it will update the default panel of the PANEL_DASHBOARD.
|
||||
DEFAULT_PANEL = ''
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'iotronic_ui.iot.webservices.panel.Webservices'
|
|
@ -82,7 +82,6 @@ class CreateBoardForm(forms.SelfHandlingForm):
|
|||
class UpdateBoardForm(forms.SelfHandlingForm):
|
||||
uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
|
||||
name = forms.CharField(label=_("Board Name"))
|
||||
|
||||
fleet_list = forms.ChoiceField(
|
||||
label=_("Fleets List"),
|
||||
widget=forms.Select(
|
||||
|
|
|
@ -80,7 +80,7 @@ class IndexView(tables.DataTableView):
|
|||
# ------------------------------------------------------------
|
||||
filter_ws = []
|
||||
for service in board_services:
|
||||
if ((service["name"] != "webservice") and
|
||||
if ((service["name"] != "webservice") and
|
||||
(service["name"] != "webservice_ssl")):
|
||||
filter_ws.append(service)
|
||||
|
||||
|
@ -90,7 +90,7 @@ class IndexView(tables.DataTableView):
|
|||
# board.__dict__.update(dict(services=board_services))
|
||||
board._info.update(dict(services=board_services))
|
||||
|
||||
if board.fleet != None:
|
||||
if board.fleet != None:
|
||||
fleet_info = api.iotronic.fleet_get(self.request,
|
||||
board.fleet,
|
||||
None)
|
||||
|
@ -295,7 +295,7 @@ class DisableServiceView(forms.ModalFormView):
|
|||
for board_service in board_services:
|
||||
if ((board_service["uuid"] == cloud_service._info["uuid"]) and
|
||||
((board_service["name"] != "webservice") and
|
||||
(board_service["name"] != "webservice_ssl"))):
|
||||
(board_service["name"] != "webservice_ssl"))):
|
||||
service_list.append((cloud_service._info["uuid"],
|
||||
_(cloud_service._info["name"])))
|
||||
# ------------------------------------------------------------
|
||||
|
|
|
@ -18,11 +18,13 @@ import horizon
|
|||
class Iot(horizon.Dashboard):
|
||||
name = _("IoT")
|
||||
slug = "iot"
|
||||
panels = ('boards', 'plugins', 'services',
|
||||
'webservices', 'fleets') # Add your panels here.
|
||||
# Commented because with group definition this will break the
|
||||
# configuration
|
||||
# panels = ('boards', 'plugins', 'services',
|
||||
# 'webservices', 'fleets', 'devices') # Add your panels here.
|
||||
|
||||
# Specify the slug of the dashboard's default panel.
|
||||
default_panel = 'boards'
|
||||
default_panel = 'devices'
|
||||
|
||||
|
||||
horizon.register(Iot)
|
||||
|
|
|
@ -0,0 +1,654 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import json
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
|
||||
from openstack_dashboard.api import iotronic
|
||||
# from iotronic_ui.api import iotronic
|
||||
from openstack_dashboard import policy
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CreateDeviceForm(forms.SelfHandlingForm):
|
||||
name = forms.CharField(label=_("Device Name"))
|
||||
code = forms.CharField(
|
||||
label=_("Registration Code"),
|
||||
help_text=_("Registration code")
|
||||
)
|
||||
|
||||
# MODIFY ---> options: yun, server
|
||||
type = forms.ChoiceField(
|
||||
label=_("Type"),
|
||||
# choices=[('gateway', _('Gateway')), ('server', _('Server'))],
|
||||
choices=[
|
||||
('raspberry', _('Arancino')),
|
||||
('yun', _('Arduino YUN')),
|
||||
('generic', _('Generic')),
|
||||
('raspberry', _('Raspberry')),
|
||||
('server', _('Server'))
|
||||
],
|
||||
widget=forms.Select(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-type'},
|
||||
)
|
||||
)
|
||||
|
||||
mobile = forms.BooleanField(label=_("Mobile"), required=False)
|
||||
|
||||
latitude = forms.FloatField(label=_("Latitude"))
|
||||
longitude = forms.FloatField(label=_("Longitude"))
|
||||
altitude = forms.FloatField(label=_("Altitude"))
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
|
||||
# Float
|
||||
# data["location"] = [{"latitude": data["latitude"],
|
||||
# "longitude": data["longitude"],
|
||||
# "altitude": data["altitude"]}]
|
||||
# String
|
||||
data["location"] = [{"latitude": str(data["latitude"]),
|
||||
"longitude": str(data["longitude"]),
|
||||
"altitude": str(data["altitude"])}]
|
||||
# LOG.debug('DATA: %s', data)
|
||||
iotronic.device_create(request, data["code"],
|
||||
data["mobile"], data["location"],
|
||||
data["type"], data["name"])
|
||||
|
||||
messages.success(request, _("Device created successfully."))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(request, _('Unable to create device.'))
|
||||
|
||||
|
||||
class UpdateDeviceForm(forms.SelfHandlingForm):
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
name = forms.CharField(label=_("Device Name"))
|
||||
|
||||
fleet_list = forms.ChoiceField(
|
||||
label=_("Fleets List"),
|
||||
widget=forms.Select(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-fleet'}),
|
||||
help_text=_("Select fleet in this pool "),
|
||||
required=False
|
||||
)
|
||||
|
||||
mobile = forms.BooleanField(label=_("Mobile"), required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(UpdateDeviceForm, self).__init__(*args, **kwargs)
|
||||
|
||||
# Populate fleets
|
||||
fleets = iotronic.fleet_list(self.request, None)
|
||||
fleets.sort(key=lambda b: b.name)
|
||||
|
||||
fleet_list = []
|
||||
fleet_list.append((None, _("-")))
|
||||
for fleet in fleets:
|
||||
fleet_list.append((fleet.uuid, _(fleet.name)))
|
||||
|
||||
# LOG.debug("FLEETS: %s", fleet_list)
|
||||
self.fields["fleet_list"].choices = fleet_list
|
||||
self.fields["fleet_list"].initial = kwargs["initial"]["fleet_id"]
|
||||
|
||||
# Admin
|
||||
if policy.check((("iot", "iot:update_boards"),), self.request):
|
||||
# LOG.debug("ADMIN")
|
||||
pass
|
||||
|
||||
# Manager or Admin of the iot project
|
||||
elif (policy.check((("iot", "iot_manager"),), self.request) or
|
||||
policy.check((("iot", "iot_admin"),), self.request)):
|
||||
# LOG.debug("NO-edit IOT ADMIN")
|
||||
pass
|
||||
|
||||
# Other users
|
||||
else:
|
||||
if self.request.user.id != kwargs["initial"]["owner"]:
|
||||
# LOG.debug("IMMUTABLE FIELDS")
|
||||
self.fields["name"].widget.attrs = {'readonly': 'readonly'}
|
||||
self.fields["mobile"].widget.attrs = {'disabled': 'disabled'}
|
||||
self.fields["fleet_list"].widget.attrs = {'disabled':
|
||||
'disabled'}
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
try:
|
||||
if data["fleet_list"] == '':
|
||||
data["fleet_list"] = None
|
||||
|
||||
iotronic.device_update(request, data["uuid"],
|
||||
{"name": data["name"],
|
||||
"fleet": data["fleet_list"],
|
||||
"mobile": data["mobile"]})
|
||||
messages.success(request, _("Device updated successfully."))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(request, _('Unable to update device.'))
|
||||
|
||||
|
||||
class AttachPortForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
networks_list = forms.ChoiceField(
|
||||
label=_("Networks List"),
|
||||
help_text=_("Select network:subnet from the list")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(AttachPortForm, self).__init__(*args, **kwargs)
|
||||
|
||||
net_choices = kwargs["initial"]["networks_list"]
|
||||
self.fields["networks_list"].choices = net_choices
|
||||
|
||||
def handle(self, request, data):
|
||||
array = data["networks_list"].split(':')
|
||||
LOG.debug(array)
|
||||
network_id = array[0]
|
||||
subnet_id = array[1]
|
||||
|
||||
try:
|
||||
attach = iotronic.attach_port(request, data["uuid"],
|
||||
network_id, subnet_id)
|
||||
|
||||
# LOG.debug("ATTACH: %s", attach)
|
||||
ip = attach._info["ip"]
|
||||
|
||||
message_text = "Attached port to ip " + str(ip) + \
|
||||
" on device " + str(data["name"]) + \
|
||||
" completed successfully"
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to attach port on device " + \
|
||||
str(data["name"])
|
||||
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class DetachPortForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
port_list = forms.MultipleChoiceField(
|
||||
label=_("Ports List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-detacj-ports'}),
|
||||
help_text=_("Select one or more of the following attached ports")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(DetachPortForm, self).__init__(*args, **kwargs)
|
||||
self.fields["port_list"].choices = kwargs["initial"]["ports"]
|
||||
|
||||
def handle(self, request, data):
|
||||
# LOG.debug("DATA: %s %s", data, len(data["port_list"]))
|
||||
|
||||
counter = 0
|
||||
|
||||
for port in data["port_list"]:
|
||||
try:
|
||||
iotronic.detach_port(request, data["uuid"], port)
|
||||
|
||||
message_text = "Detach port " + str(port) + \
|
||||
" from device " + str(data["name"]) + \
|
||||
" completed successfully"
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["port_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to detach port " + str(port) + \
|
||||
" from device " + str(data["name"])
|
||||
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class ActionDeviceForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
# action_list = forms.MultipleChoiceField(
|
||||
action_list = forms.ChoiceField(
|
||||
label=_("Actions List"),
|
||||
# widget=forms.SelectMultiple(
|
||||
widget=forms.Select(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-action-device'}),
|
||||
help_text=_("Select action in this pool ")
|
||||
)
|
||||
|
||||
parameters = forms.CharField(
|
||||
label=_("Parameters"),
|
||||
required=False,
|
||||
widget=forms.Textarea(
|
||||
attrs={'class': 'switchable',
|
||||
'data-slug': 'slug-actiondevice-json'}),
|
||||
help_text=_("Action parameters")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(ActionDeviceForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
self.fields["action_list"].choices = kwargs["initial"]["action_list"]
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
if not data["parameters"]:
|
||||
data["parameters"] = {}
|
||||
else:
|
||||
data["parameters"] = json.loads(data["parameters"])
|
||||
|
||||
try:
|
||||
action = iotronic.device_action(request,
|
||||
data["uuid"],
|
||||
data["action_list"],
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call action " \
|
||||
+ str(data["action_list"]) + " on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class PackageActionDeviceForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
manager_list = forms.ChoiceField(
|
||||
label=_("Manager"),
|
||||
widget=forms.Select(
|
||||
attrs={'class': 'switchable',
|
||||
'data-slug': 'slug-packageaction-manager'}),
|
||||
help_text=_("Select a manager in this pool ")
|
||||
)
|
||||
|
||||
command_list = forms.ChoiceField(
|
||||
label=_("Command"),
|
||||
widget=forms.Select(
|
||||
attrs={'class': 'switchable',
|
||||
'data-slug': 'slug-packageaction-command'}),
|
||||
help_text=_("Select a command in this pool ")
|
||||
)
|
||||
|
||||
packages = forms.CharField(
|
||||
label=_("Package"),
|
||||
# required=False,
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
'class': 'switchable',
|
||||
'rows': 2,
|
||||
'data-slug': 'slug-package'
|
||||
}
|
||||
),
|
||||
help_text=_("Package name")
|
||||
)
|
||||
|
||||
options = forms.CharField(
|
||||
label=_("Options"),
|
||||
required=False,
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
'class': 'switchable',
|
||||
'rows': 2,
|
||||
'data-slug': 'slug-options-json'
|
||||
}
|
||||
),
|
||||
help_text=_("Package options")
|
||||
)
|
||||
|
||||
version = forms.CharField(
|
||||
label=_("Version"),
|
||||
required=False,
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
'class': 'switchable',
|
||||
'rows': 1,
|
||||
'data-slug': 'slug-version-json'
|
||||
}
|
||||
),
|
||||
help_text=_("Package version")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(PackageActionDeviceForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
self.fields["manager_list"].choices = kwargs["initial"]["manager_list"]
|
||||
self.fields["command_list"].choices = kwargs["initial"]["command_list"]
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
if not data["options"]:
|
||||
data["options"] = ""
|
||||
if not data["version"]:
|
||||
data["version"] = ""
|
||||
|
||||
data["parameters"] = {"manager": data["manager_list"],
|
||||
"command": data["command_list"],
|
||||
"package": data["packages"],
|
||||
"options": data["options"],
|
||||
"version": data["version"]}
|
||||
|
||||
try:
|
||||
action = iotronic.device_action(request,
|
||||
data["uuid"],
|
||||
"DevicePkgOperation",
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call package action " \
|
||||
+ "DevicePkgOperation on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class MountActionDeviceForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
# mount_action_list = forms.MultipleChoiceField(
|
||||
mount_action_list = forms.ChoiceField(
|
||||
label=_("Mount actions List"),
|
||||
# widget=forms.SelectMultiple(
|
||||
widget=forms.Select(
|
||||
attrs={'class': 'switchable',
|
||||
'data-slug': 'slug-mountaction-device'}),
|
||||
help_text=_("Select action in this pool ")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(MountActionDeviceForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
mount_actions = kwargs["initial"]["mount_action_list"]
|
||||
self.fields["mount_action_list"].choices = mount_actions
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
data["parameters"] = {"mnt_cmd": data["mount_action_list"]}
|
||||
|
||||
try:
|
||||
action = iotronic.device_action(request,
|
||||
data["uuid"],
|
||||
"DeviceMountFs",
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call action " \
|
||||
+ str(data["mount_action_list"]) + " on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class UpgradeLRForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
delay = forms.IntegerField(
|
||||
label=_("Delay"),
|
||||
required=False,
|
||||
help_text=_("Delay in seconds")
|
||||
)
|
||||
|
||||
version = forms.CharField(
|
||||
label=_("Version"),
|
||||
required=False,
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
'class': 'switchable',
|
||||
'rows': 1,
|
||||
'data-slug': 'slug-version-json'
|
||||
}
|
||||
),
|
||||
help_text=_("Package version")
|
||||
)
|
||||
|
||||
update_conf = forms.BooleanField(
|
||||
label=_("Update Configuration"),
|
||||
required=False
|
||||
)
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
if not data["delay"]:
|
||||
data["delay"] = 3
|
||||
if not data["version"]:
|
||||
data["version"] = ""
|
||||
|
||||
data["parameters"] = {"delay": data["delay"],
|
||||
"version": data["version"],
|
||||
"update_conf": data["update_conf"]}
|
||||
|
||||
try:
|
||||
action = iotronic.device_action(request,
|
||||
data["uuid"],
|
||||
"DeviceUpgradeLR",
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call DeviceUpgradeLR on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class RestartLRForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
delay = forms.IntegerField(
|
||||
label=_("Delay"),
|
||||
required=False,
|
||||
help_text=_("Delay in seconds")
|
||||
)
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
if not data["delay"]:
|
||||
data["delay"] = 3
|
||||
|
||||
data["parameters"] = {"delay": data["delay"]}
|
||||
|
||||
try:
|
||||
action = iotronic.device_action(request,
|
||||
data["uuid"],
|
||||
"DeviceRestartLR",
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call DeviceRestartLR on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class RebootForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
delay = forms.IntegerField(
|
||||
label=_("Delay"),
|
||||
required=False,
|
||||
help_text=_("Delay in seconds")
|
||||
)
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
if not data["delay"]:
|
||||
data["delay"] = 3
|
||||
|
||||
data["parameters"] = {"delay": data["delay"]}
|
||||
|
||||
try:
|
||||
action = iotronic.device_action(request,
|
||||
data["uuid"],
|
||||
"DeviceReboot",
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call DeviceReboot on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class NetConfForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
data["parameters"] = {}
|
||||
|
||||
try:
|
||||
action = iotronic.device_action(request,
|
||||
data["uuid"],
|
||||
"DeviceNetConfig",
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call DeviceNetConfig on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class PingForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
data["parameters"] = {}
|
||||
|
||||
try:
|
||||
action = iotronic.device_action(request,
|
||||
data["uuid"],
|
||||
"DevicePing",
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call DevicePing on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
|
@ -0,0 +1,27 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import horizon
|
||||
from iotronic_ui.iot import dashboard
|
||||
|
||||
|
||||
class Devices(horizon.Panel):
|
||||
name = _("Manager")
|
||||
slug = "devices"
|
||||
|
||||
|
||||
dashboard.Iot.register(Devices)
|
|
@ -0,0 +1,220 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
from django import template
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ungettext_lazy
|
||||
|
||||
from horizon import tables
|
||||
|
||||
from openstack_dashboard import api
|
||||
# from iotronic_ui import api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CreateDeviceLink(tables.LinkAction):
|
||||
name = "create"
|
||||
verbose_name = _("Create Device")
|
||||
url = "horizon:iot:devices:create"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
# policy_rules = (("iot", "iot:create_device"),)
|
||||
|
||||
|
||||
class EditDeviceLink(tables.LinkAction):
|
||||
name = "edit"
|
||||
verbose_name = _("Edit")
|
||||
url = "horizon:iot:devices:update"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "pencil"
|
||||
# policy_rules = (("iot", "iot:update_device"),)
|
||||
|
||||
|
||||
class AttachPortLink(tables.LinkAction):
|
||||
name = "attachport"
|
||||
verbose_name = _("Attach Port")
|
||||
url = "horizon:iot:devices:attachport"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class DetachPortLink(tables.LinkAction):
|
||||
name = "detachport"
|
||||
verbose_name = _("Detach Port")
|
||||
url = "horizon:iot:devices:detachport"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class ActionLink(tables.LinkAction):
|
||||
name = "action"
|
||||
verbose_name = _("Action")
|
||||
url = "horizon:iot:devices:action"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class PackageActionLink(tables.LinkAction):
|
||||
name = "packageaction"
|
||||
verbose_name = _("Package Action")
|
||||
url = "horizon:iot:devices:packageaction"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class UpgradeLRLink(tables.LinkAction):
|
||||
name = "upgradelr"
|
||||
verbose_name = _("Upgrade LR")
|
||||
url = "horizon:iot:devices:upgradelr"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class RestartLRLink(tables.LinkAction):
|
||||
name = "restartlr"
|
||||
verbose_name = _("Restart LR")
|
||||
url = "horizon:iot:devices:restartlr"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class RebootLink(tables.LinkAction):
|
||||
name = "reboot"
|
||||
verbose_name = _("Reboot")
|
||||
url = "horizon:iot:devices:reboot"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class NetConfLink(tables.LinkAction):
|
||||
name = "netconf"
|
||||
verbose_name = _("Connections")
|
||||
url = "horizon:iot:devices:netconf"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class PingLink(tables.LinkAction):
|
||||
name = "ping"
|
||||
verbose_name = _("Ping")
|
||||
url = "horizon:iot:devices:ping"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class RestoreServices(tables.BatchAction):
|
||||
name = "restoreservices"
|
||||
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
return u"Restore ALL Services"
|
||||
|
||||
@staticmethod
|
||||
def action_past(count):
|
||||
return u"Restored ALL Services"
|
||||
|
||||
def allowed(self, request, device=None):
|
||||
return True
|
||||
|
||||
def action(self, request, device_id):
|
||||
api.iotronic.restore_services(request, device_id)
|
||||
|
||||
|
||||
class DeleteDevicesAction(tables.DeleteAction):
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
return ungettext_lazy(
|
||||
u"Delete Device",
|
||||
u"Delete Devices",
|
||||
count
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def action_past(count):
|
||||
return ungettext_lazy(
|
||||
u"Deleted Device",
|
||||
u"Deleted Devices",
|
||||
count
|
||||
)
|
||||
# policy_rules = (("iot", "iot:delete_device"),)
|
||||
|
||||
"""
|
||||
def allowed(self, request, role):
|
||||
return api.keystone.keystone_can_edit_role()
|
||||
"""
|
||||
|
||||
def delete(self, request, device_id):
|
||||
api.iotronic.board_delete(request, device_id)
|
||||
|
||||
|
||||
class DeviceFilterAction(tables.FilterAction):
|
||||
|
||||
# If uncommented it will appear the select menu list of fields
|
||||
# and filter button
|
||||
"""
|
||||
filter_type = "server"
|
||||
filter_choices = (("name", _("Device Name ="), True),
|
||||
("type", _("Type ="), True),
|
||||
("status", _("Status ="), True))
|
||||
"""
|
||||
|
||||
def filter(self, table, devices, filter_string):
|
||||
"""Naive case-insensitive search."""
|
||||
q = filter_string.lower()
|
||||
return [device for device in devices
|
||||
if q in device.name.lower()]
|
||||
|
||||
|
||||
def show_services(device_info):
|
||||
template_name = 'iot/devices/_cell_services.html'
|
||||
context = device_info._info
|
||||
# LOG.debug("CONTEXT: %s", context)
|
||||
return template.loader.render_to_string(template_name,
|
||||
context)
|
||||
|
||||
|
||||
class DevicesTable(tables.DataTable):
|
||||
name = tables.WrappingColumn('name', link="horizon:iot:devices:detail",
|
||||
verbose_name=_('Device Name'))
|
||||
type = tables.Column('type', verbose_name=_('Type'))
|
||||
# mobile = tables.Column('mobile', verbose_name=_('Mobile'))
|
||||
lr_version = tables.Column('lr_version', verbose_name=_('LR version'))
|
||||
# fleet = tables.Column('fleet', verbose_name=_('Fleet ID'))
|
||||
fleet_name = tables.Column('fleet_name', verbose_name=_('Fleet Name'))
|
||||
# code = tables.Column('code', verbose_name=_('Code'))
|
||||
status = tables.Column('status', verbose_name=_('Status'))
|
||||
uuid = tables.Column('uuid', verbose_name=_('Device ID'))
|
||||
# location = tables.Column('location', verbose_name=_('Geo'))
|
||||
services = tables.Column(show_services, verbose_name=_('SSH Access'))
|
||||
# extra = tables.Column('extra', verbose_name=_('Extra'))
|
||||
|
||||
# Overriding get_object_id method because in IoT service the "id" is
|
||||
# identified by the field UUID
|
||||
def get_object_id(self, datum):
|
||||
return datum.uuid
|
||||
|
||||
class Meta(object):
|
||||
name = "devices"
|
||||
verbose_name = _("devices")
|
||||
row_actions = (EditDeviceLink, AttachPortLink, DetachPortLink,
|
||||
PackageActionLink, UpgradeLRLink, RestartLRLink,
|
||||
RebootLink, NetConfLink, PingLink,
|
||||
ActionLink, RestoreServices, DeleteDevicesAction)
|
||||
table_actions = (DeviceFilterAction, CreateDeviceLink,
|
||||
DeleteDevicesAction)
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
# from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import tabs
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OverviewTab(tabs.Tab):
|
||||
name = _("Overview")
|
||||
slug = "overview"
|
||||
template_name = ("iot/devices/_detail_overview.html")
|
||||
|
||||
def get_context_data(self, request):
|
||||
|
||||
coordinates = self.tab_group.kwargs['device'].__dict__['location'][0]
|
||||
ports = self.tab_group.kwargs['device']._info['ports']
|
||||
services = self.tab_group.kwargs['device']._info['services']
|
||||
webservices = self.tab_group.kwargs['device']._info['webservices']
|
||||
plugins = self.tab_group.kwargs['device']._info['plugins']
|
||||
|
||||
return {"device": self.tab_group.kwargs['device'],
|
||||
"coordinates": coordinates,
|
||||
"services": services,
|
||||
"webservices": webservices,
|
||||
"ports": ports,
|
||||
"plugins": plugins,
|
||||
"is_superuser": request.user.is_superuser}
|
||||
|
||||
|
||||
class DeviceDetailTabs(tabs.TabGroup):
|
||||
slug = "device_details"
|
||||
# tabs = (OverviewTab, LogTab, ConsoleTab, AuditTab)
|
||||
tabs = (OverviewTab,)
|
||||
sticky = True
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Call action on device." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{% load i18n %}
|
||||
{% if services %}
|
||||
{% for service in services %}
|
||||
{% if service.name == "ssh" %}
|
||||
<dd>ssh -p {{ service.public_port}} root@{{ service.wstun_ip }}</dd>
|
||||
{% elif service.name == "nodered" %}
|
||||
<dd>https://nodered.bla.bla.eu</dd>
|
||||
{% elif service.name == "http" %}
|
||||
<dd>https://{{ service.wstun_ip }}:{{ service.public_port }}</dd>
|
||||
{% else %}
|
||||
<dd>{{ service.name }} [{{ service.protocol }}] {{ service.port }} --> {{ service.public_port }}</dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Add a new device." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
{% load i18n sizeformat %}
|
||||
|
||||
<div class="detail">
|
||||
|
||||
<h4>{% trans "Info" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ device.name }}</dd>
|
||||
<dt>{% trans "Status" %}</dt>
|
||||
<dd>{{ device.status }}</dd>
|
||||
<dt>{% trans "Type" %}</dt>
|
||||
<dd>{{ device.type }}</dd>
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ device.uuid }}</dd>
|
||||
<dt>{% trans "LR version" %}</dt>
|
||||
<dd>{{ device.lr_version }}</dd>
|
||||
<dt>{% trans "WAMP Agent" %}</dt>
|
||||
<dd>{{ device.agent }}</dd>
|
||||
<dt>{% trans "Code" %}</dt>
|
||||
<dd>{{ device.code }}</dd>
|
||||
<dt>{% trans "Creation data" %}</dt>
|
||||
<dd>{{ device.created_at }}</dd>
|
||||
<dt>{% trans "Location" %}</dt>
|
||||
<dd>Latitude: {{ coordinates.latitude }}</dd>
|
||||
<dd>Longitude: {{ coordinates.longitude }}</dd>
|
||||
<dd>Altitude: {{ coordinates.altitude }}</dd>
|
||||
<dt>{% trans "Connectivity" %}</dt>
|
||||
{% if device.connectivity.mac %}
|
||||
<dd>MAC: {{ device.connectivity.mac }}</dd>
|
||||
<dd>Interface: {{ device.connectivity.iface }}</dd>
|
||||
<dd>Local IP: {{ device.connectivity.local_ip }}</dd>
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Mobile" %}</dt>
|
||||
<dd>{{ device.mobile }}</dd>
|
||||
<dt>{% trans "Extra" %}</dt>
|
||||
<dd>{{ device.extra }}</dd>
|
||||
<dt>{% trans "Fleet Name" %}</dt>
|
||||
<dd>{{ device.fleet_name }}</dd>
|
||||
<dt>{% trans "Fleet ID" %}</dt>
|
||||
<dd>{{ device.fleet }}</dd>
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Ports" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if ports %}
|
||||
{% for port in ports %}
|
||||
<dt>{{ port.VIF_name }}</dt>
|
||||
<dd>{{ port.ip }}</dd>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if services %}
|
||||
{% for service in services %}
|
||||
<!--
|
||||
<dt>{{ service.name }} [{{ service.protocol }}] {{ service.port }}</dt>
|
||||
<dd>{{ service.public_port }}</dd>
|
||||
-->
|
||||
<!--
|
||||
<dt>{{ service.name }}</dt>
|
||||
<dd>[{{ service.protocol }}] L: {{ service.port }}; P: {{ service.public_port }}</dd>
|
||||
-->
|
||||
<dt>{{ service.name }}</dt>
|
||||
{% if service.name == "ssh" %}
|
||||
<dd>ssh -p {{ service.public_port}} root@{{ service.wstun_ip }}</dd>
|
||||
{% elif service.name == "nodered" %}
|
||||
<dd><a href="http://{{ service.wstun_ip }}:{{ service.public_port }}" target="_blank">http://{{ service.wstun_ip }}:{{ service.public_port }}</a></dd>
|
||||
{% else %}
|
||||
<dd>{{ service.name }} [{{ service.protocol }}] {{ service.port }} --> {{ service.public_port }}</dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Web Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if webservices %}
|
||||
{% for ws in webservices %}
|
||||
<dt>{{ ws.name }} [{{ ws.port }}]</dt>
|
||||
<dd>{{ ws.uuid }}</dd>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Plugins" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if plugins %}
|
||||
{% for plugin in plugins %}
|
||||
<dt>{{ plugin.name }}</dt>
|
||||
<dd>{{ plugin.id }}</dd>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!--<div id="mapdiv" style="min-height:300px; margin-bottom: 10px;" data-coordinates='[{"latitude": "{{ coordinates.latitude }}", "longitude": "{{ coordinates.longitude }}", "altitude": "{{ coordinates.altitude }}"}]'>-->
|
||||
<!--
|
||||
<div id="mapdiv" style="min-height:300px; margin-bottom: 10px;">
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
/*
|
||||
coordinates = JSON.parse(document.getElementById("mapdiv").getAttribute("data-coordinates"));
|
||||
lat = coordinates[0]["latitude"];
|
||||
lon = coordinates[0]["longitude"];
|
||||
alt = coordinates[0]["altitude"];
|
||||
*/
|
||||
var lat = "{{ coordinates.latitude }}";
|
||||
var lon = "{{ coordinates.longitude }}";
|
||||
var alt = "{{ coordinates.altitude }}";
|
||||
var label = "{{ board.name }}";
|
||||
var status = "{{ board.status }}";
|
||||
var updated = "{{ board.updated_at }}";
|
||||
|
||||
var array_coord = {"coordinates" : [{"lat": lat, "lon": lon, "alt": alt, "updated": updated, "label": label, "status": status}]}
|
||||
|
||||
render_map("mapdiv", array_coord);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
-->
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Show device connections." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Call package action on device." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Send ping command." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Reboot the device." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Restart LR on device." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Edit the device's details." %}</p>
|
||||
{% endblock %}
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Upgrade LR on device." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Action on Device" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/devices/_action.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Insert Device" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/devices/_create.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Devices" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Show connections" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/devices/_netconf.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Package action on Device" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/devices/_packageaction.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Ping" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/devices/_ping.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Reboot the device" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/devices/_reboot.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Restart LR" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/devices/_restartlr.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Update Device" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/devices/_update.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Upgrade LR" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/devices/_upgradelr.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,19 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from horizon.test import helpers as test
|
||||
|
||||
|
||||
class DevicesTests(test.TestCase):
|
||||
# Unit tests for devices.
|
||||
def test_me(self):
|
||||
self.assertTrue(1 + 1 == 2)
|
|
@ -0,0 +1,47 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from iotronic_ui.iot.devices import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^create/$', views.CreateView.as_view(), name='create'),
|
||||
url(r'^(?P<device_id>[^/]+)/update/$', views.UpdateView.as_view(),
|
||||
name='update'),
|
||||
url(r'^(?P<device_id>[^/]+)/detail/$', views.DeviceDetailView.as_view(),
|
||||
name='detail'),
|
||||
url(r'^(?P<device_id>[^/]+)/attachport/$',
|
||||
views.AttachPortView.as_view(), name='attachport'),
|
||||
url(r'^(?P<device_id>[^/]+)/detachport/$',
|
||||
views.DetachPortView.as_view(), name='detachport'),
|
||||
url(r'^(?P<device_id>[^/]+)/netconf/$',
|
||||
views.NetConfView.as_view(), name='netconf'),
|
||||
url(r'^(?P<device_id>[^/]+)/ping/$',
|
||||
views.PingView.as_view(), name='ping'),
|
||||
url(r'^(?P<device_id>[^/]+)/action/$',
|
||||
views.ActionView.as_view(), name='action'),
|
||||
url(r'^(?P<device_id>[^/]+)/packageaction/$',
|
||||
views.PackageActionView.as_view(), name='packageaction'),
|
||||
url(r'^(?P<device_id>[^/]+)/upgradelr/$',
|
||||
views.UpgradeLRView.as_view(), name='upgradelr'),
|
||||
url(r'^(?P<device_id>[^/]+)/restartlr/$',
|
||||
views.RestartLRView.as_view(), name='restartlr'),
|
||||
url(r'^(?P<device_id>[^/]+)/reboot/$',
|
||||
views.RebootView.as_view(), name='reboot'),
|
||||
]
|
|
@ -0,0 +1,647 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
# from horizon import messages
|
||||
from horizon import tables
|
||||
from horizon import tabs
|
||||
from horizon.utils import memoized
|
||||
|
||||
from openstack_dashboard import api
|
||||
# from iotronic_ui.api import iotronic
|
||||
from openstack_dashboard import policy
|
||||
|
||||
from iotronic_ui.iot.devices import forms as project_forms
|
||||
from iotronic_ui.iot.devices import tables as project_tables
|
||||
from iotronic_ui.iot.devices import tabs as project_tabs
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IndexView(tables.DataTableView):
|
||||
table_class = project_tables.DevicesTable
|
||||
template_name = 'iot/devices/index.html'
|
||||
page_title = _("Devices")
|
||||
|
||||
def get_data(self):
|
||||
devices = []
|
||||
|
||||
# Admin
|
||||
if policy.check((("iot", "iot:list_all_boards"),), self.request):
|
||||
try:
|
||||
devices = api.iotronic.device_list(self.request, None, None)
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve devices list.'))
|
||||
|
||||
# Admin_iot_project
|
||||
elif policy.check((("iot", "iot:list_project_boards"),), self.request):
|
||||
try:
|
||||
devices = api.iotronic.device_list(self.request, None, None)
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve user devices list.'))
|
||||
|
||||
# Other users
|
||||
else:
|
||||
try:
|
||||
devices = api.iotronic.device_list(self.request, None, None)
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve user devices list.'))
|
||||
|
||||
for device in devices:
|
||||
device_services = api.iotronic.services_on_device(self.request,
|
||||
device.uuid,
|
||||
True)
|
||||
|
||||
# x = api.iotronic.device_get(self.request, device.uuid, None)
|
||||
# LOG.debug('DEVICE: %s', x)
|
||||
# TO BE REMOVED
|
||||
# ------------------------------------------------------------
|
||||
filter_ws = []
|
||||
for service in device_services:
|
||||
# We are filtering the services that starts with "webservice"
|
||||
"""
|
||||
if ((service["name"] != "webservice") and
|
||||
(service["name"] != "webservice_ssl")):
|
||||
filter_ws.append(service)
|
||||
"""
|
||||
# We want to show only the "ssh" service
|
||||
if (service["name"] == "ssh"):
|
||||
service["wstun_ip"] = device.wstun_ip
|
||||
filter_ws.append(service)
|
||||
|
||||
device_services = filter_ws
|
||||
# ------------------------------------------------------------
|
||||
|
||||
# device.__dict__.update(dict(services=device_services))
|
||||
device._info.update(dict(services=device_services))
|
||||
|
||||
if device.fleet != None:
|
||||
fleet_info = api.iotronic.fleet_get(self.request,
|
||||
device.fleet,
|
||||
None)
|
||||
|
||||
device.fleet_name = fleet_info.name
|
||||
else:
|
||||
device.fleet_name = None
|
||||
|
||||
devices.sort(key=lambda b: b.name)
|
||||
# LOG.debug('DEVICES: %s', devices)
|
||||
return devices
|
||||
|
||||
|
||||
class CreateView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/create.html'
|
||||
modal_header = _("Create Device")
|
||||
form_id = "create_device_form"
|
||||
form_class = project_forms.CreateDeviceForm
|
||||
submit_label = _("Create Device")
|
||||
submit_url = reverse_lazy("horizon:iot:devices:create")
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Create Device")
|
||||
|
||||
|
||||
class UpdateView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/update.html'
|
||||
modal_header = _("Update Device")
|
||||
form_id = "update_device_form"
|
||||
form_class = project_forms.UpdateDeviceForm
|
||||
submit_label = _("Update Device")
|
||||
submit_url = "horizon:iot:devices:update"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Update Device")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UpdateView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
location = device.location[0]
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'mobile': device.mobile,
|
||||
'owner': device.owner,
|
||||
'fleet_id': device.fleet,
|
||||
'latitude': location["latitude"],
|
||||
'longitude': location["longitude"],
|
||||
'altitude': location["altitude"]}
|
||||
|
||||
|
||||
class AttachPortView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/attachport.html'
|
||||
modal_header = _("Attach")
|
||||
form_id = "attach_deviceport_form"
|
||||
form_class = project_forms.AttachPortForm
|
||||
submit_label = _("Attach")
|
||||
# submit_url = reverse_lazy("horizon:iot:devices:attachport")
|
||||
submit_url = "horizon:iot:devices:attachport"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Attach port")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(AttachPortView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
# Populate networks
|
||||
networks = api.neutron.network_list(self.request)
|
||||
net_choices = []
|
||||
|
||||
networks.sort(key=lambda b: b.name)
|
||||
for net in networks:
|
||||
for subnet in net["subnets"]:
|
||||
net_choices.append((net["id"] + ':' + subnet["id"],
|
||||
_(net["name"] + ':' + subnet["name"])))
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'networks_list': net_choices}
|
||||
|
||||
|
||||
class DetachPortView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/detachport.html'
|
||||
modal_header = _("Detach")
|
||||
form_id = "detach_deviceport_form"
|
||||
form_class = project_forms.DetachPortForm
|
||||
submit_label = _("Detach")
|
||||
# submit_url = reverse_lazy("horizon:iot:devices:detachport")
|
||||
submit_url = "horizon:iot:devices:detachport"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Detach port")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DetachPortView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
ports = api.iotronic.port_list(self.request, device.uuid)
|
||||
|
||||
# TO BE REMOVED (change it once the port_list per device is
|
||||
# completed and tested !
|
||||
# ################################################################
|
||||
# LOG.debug("PORTS: %s", ports)
|
||||
|
||||
ports.sort(key=lambda b: b.name)
|
||||
filtered_ports = []
|
||||
for port in ports:
|
||||
if port._info["board_uuid"] == device.uuid:
|
||||
filtered_ports.append((port._info["uuid"],
|
||||
_(port._info["ip"])))
|
||||
|
||||
ports = filtered_ports
|
||||
# ################################################################
|
||||
|
||||
# Populate device ports
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'ports': ports}
|
||||
|
||||
|
||||
class ActionView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/action.html'
|
||||
modal_header = _("Action on Device")
|
||||
form_id = "action_device_form"
|
||||
form_class = project_forms.ActionDeviceForm
|
||||
submit_label = _("Action")
|
||||
# submit_url = reverse_lazy("horizon:iot:devices:action")
|
||||
submit_url = "horizon:iot:devices:action"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Action on Device")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(ActionView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
# Populate actions (TO BE REPLACED with an action list api)
|
||||
actions = ["DeviceNetConfig", "DevicePing", "DeviceEcho",
|
||||
"DeviceUpgradeLR", "DevicePkgOperation",
|
||||
"DeviceRestartLR", "DeviceReboot"]
|
||||
actions.sort()
|
||||
|
||||
action_list = []
|
||||
for action in actions:
|
||||
name = action.replace("Device", "")
|
||||
action_list.append((action, _(name)))
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'action_list': action_list}
|
||||
|
||||
|
||||
class PackageActionView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/packageaction.html'
|
||||
modal_header = _("Action on packages on Device")
|
||||
form_id = "package_action_device_form"
|
||||
form_class = project_forms.PackageActionDeviceForm
|
||||
submit_label = _("Package Action")
|
||||
# submit_url = reverse_lazy("horizon:iot:devices:packageaction")
|
||||
submit_url = "horizon:iot:devices:packageaction"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Action on packages on Device")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(PackageActionView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
managers = ["apt", "npm", "pip", "pip3"]
|
||||
commands = ["install", "remove", "uninstall"]
|
||||
managers.sort()
|
||||
commands.sort()
|
||||
|
||||
manager_list = []
|
||||
command_list = []
|
||||
|
||||
for manager in managers:
|
||||
manager_list.append((manager, _(manager)))
|
||||
for command in commands:
|
||||
command_list.append((command, _(command)))
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'manager_list': manager_list,
|
||||
'command_list': command_list}
|
||||
|
||||
|
||||
class UpgradeLRView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/upgradelr.html'
|
||||
modal_header = _("Upgrade LR on Device")
|
||||
form_id = "upgrade_lr_form"
|
||||
form_class = project_forms.UpgradeLRForm
|
||||
submit_label = _("Upgrade")
|
||||
# submit_url = reverse_lazy("horizon:iot:devices:upgradelr")
|
||||
submit_url = "horizon:iot:devices:upgradelr"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Upgrade LR")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UpgradeLRView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name}
|
||||
|
||||
|
||||
class RestartLRView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/restartlr.html'
|
||||
modal_header = _("Restart LR on Device")
|
||||
form_id = "restart_lr_form"
|
||||
form_class = project_forms.RestartLRForm
|
||||
submit_label = _("Restart")
|
||||
# submit_url = reverse_lazy("horizon:iot:devices:restartlr")
|
||||
submit_url = "horizon:iot:devices:restartlr"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Restart LR")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(RestartLRView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name}
|
||||
|
||||
|
||||
class RebootView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/reboot.html'
|
||||
modal_header = _("Reboot the Device")
|
||||
form_id = "reboot_form"
|
||||
form_class = project_forms.RebootForm
|
||||
submit_label = _("Reboot")
|
||||
# submit_url = reverse_lazy("horizon:iot:devices:reboot")
|
||||
submit_url = "horizon:iot:devices:reboot"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Reboot Device")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(RebootView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name}
|
||||
|
||||
|
||||
class NetConfView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/netconf.html'
|
||||
modal_header = _("Device connections")
|
||||
form_id = "netconf_form"
|
||||
form_class = project_forms.NetConfForm
|
||||
submit_label = _("Show")
|
||||
# submit_url = reverse_lazy("horizon:iot:devices:netconf")
|
||||
submit_url = "horizon:iot:devices:netconf"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Device connections")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(NetConfView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name}
|
||||
|
||||
|
||||
class PingView(forms.ModalFormView):
|
||||
template_name = 'iot/devices/ping.html'
|
||||
modal_header = _("Ping")
|
||||
form_id = "ping_form"
|
||||
form_class = project_forms.PingForm
|
||||
submit_label = _("Submit")
|
||||
# submit_url = reverse_lazy("horizon:iot:devices:ping")
|
||||
submit_url = "horizon:iot:devices:ping"
|
||||
success_url = reverse_lazy('horizon:iot:devices:index')
|
||||
page_title = _("Ping")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(PingView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name}
|
||||
|
||||
|
||||
class DetailView(tabs.TabView):
|
||||
tab_group_class = project_tabs.DeviceDetailTabs
|
||||
template_name = 'horizon/common/_detail.html'
|
||||
page_title = "{{ device.name|default:device.uuid }}"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
device = self.get_data()
|
||||
context["device"] = device
|
||||
context["url"] = reverse(self.redirect_url)
|
||||
context["actions"] = self._get_actions(device)
|
||||
|
||||
return context
|
||||
|
||||
def _get_actions(self, device):
|
||||
table = project_tables.BoardsTable(self.request)
|
||||
return table.render_row_actions(device)
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_data(self):
|
||||
|
||||
device = []
|
||||
|
||||
device_id = self.kwargs['device_id']
|
||||
try:
|
||||
|
||||
device_ports = []
|
||||
|
||||
device = api.iotronic.device_get(self.request, device_id, None)
|
||||
|
||||
# FIX this problem with the new APIs
|
||||
# (remove the "if" clause with a better approach)
|
||||
# #################################################################
|
||||
ports = api.iotronic.port_list(self.request, device_id)
|
||||
|
||||
for port in ports:
|
||||
if port._info["board_uuid"] == device_id:
|
||||
device_ports.append(port._info)
|
||||
device._info.update(dict(ports=device_ports))
|
||||
# #################################################################
|
||||
|
||||
device_services = api.iotronic.services_on_device(self.request,
|
||||
device_id, True)
|
||||
|
||||
# We have to add the wstun_ip to the service
|
||||
for service in device_services:
|
||||
service["wstun_ip"] = device.wstun_ip
|
||||
|
||||
device._info.update(dict(services=device_services))
|
||||
|
||||
device_plugins = api.iotronic.plugins_on_device(self.request,
|
||||
device_id)
|
||||
device._info.update(dict(plugins=device_plugins))
|
||||
|
||||
device_webservices = api.iotronic.webservices_on_device(self.request,
|
||||
device_id)
|
||||
|
||||
# LOG.debug('DEVICE %s, WEB SERVICES: %s', device_id, device_webservices)
|
||||
device._info.update(dict(webservices=device_webservices))
|
||||
|
||||
# Adding fleet name
|
||||
if device.fleet != None:
|
||||
fleet_info = api.iotronic.fleet_get(self.request,
|
||||
device.fleet,
|
||||
None)
|
||||
|
||||
device.fleet_name = fleet_info.name
|
||||
else:
|
||||
device.fleet_name = None
|
||||
|
||||
# Adding LR web service description
|
||||
lr_ws = api.iotronic.webservice_get_enabled_info(self.request,
|
||||
device_id)
|
||||
device._info.update(dict(lr_webservice=lr_ws))
|
||||
|
||||
# LOG.debug("DEVICE: %s\n\n%s", device, device._info)
|
||||
|
||||
except Exception:
|
||||
msg = ('Unable to retrieve device %s information') % {'name':
|
||||
device.name}
|
||||
exceptions.handle(self.request, msg, ignore=True)
|
||||
return device
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
device = self.get_data()
|
||||
return self.tab_group_class(request, device=device, **kwargs)
|
||||
|
||||
|
||||
class DeviceDetailView(DetailView):
|
||||
redirect_url = 'horizon:iot:devices:index'
|
||||
|
||||
def _get_actions(self, device):
|
||||
table = project_tables.DevicesTable(self.request)
|
||||
return table.render_row_actions(device)
|
|
@ -35,8 +35,10 @@ class CreateFleetForm(forms.SelfHandlingForm):
|
|||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
iotronic.fleet_create(request, data["name"],
|
||||
data["description"])
|
||||
iotronic.fleet_create(
|
||||
request, data["name"],
|
||||
data["description"]
|
||||
)
|
||||
|
||||
messages.success(request, _("Fleet " + str(data["name"]) +
|
||||
" created successfully."))
|
||||
|
@ -79,9 +81,13 @@ class UpdateFleetForm(forms.SelfHandlingForm):
|
|||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
iotronic.fleet_update(request, data["uuid"],
|
||||
{"name": data["name"],
|
||||
"description": data["description"]})
|
||||
iotronic.fleet_update(
|
||||
request, data["uuid"],
|
||||
{
|
||||
"name": data["name"],
|
||||
"description": data["description"]
|
||||
}
|
||||
)
|
||||
|
||||
messages.success(request, _("Fleet updated successfully."))
|
||||
return True
|
||||
|
|
|
@ -97,9 +97,7 @@ class UpdateView(forms.ModalFormView):
|
|||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return iotronic.fleet_get(self.request,
|
||||
self.kwargs['fleet_id'],
|
||||
None)
|
||||
return iotronic.fleet_get(self.request, self.kwargs['fleet_id'], None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:fleets:index")
|
||||
exceptions.handle(self.request,
|
||||
|
@ -146,7 +144,7 @@ class DetailView(tabs.TabView):
|
|||
fleet_id = self.kwargs['fleet_id']
|
||||
try:
|
||||
fleet = iotronic.fleet_get(self.request, fleet_id, None)
|
||||
boards = iotronic.fleet_get_boards(self.request, fleet_id)
|
||||
boards = iotronic.fleet_get_devices(self.request, fleet_id)
|
||||
|
||||
# LOG.debug('Boards: %s', boards)
|
||||
|
||||
|
|
|
@ -93,11 +93,11 @@ class InjectPluginForm(forms.SelfHandlingForm):
|
|||
|
||||
onboot = forms.BooleanField(label=_("On Boot"), required=False)
|
||||
|
||||
board_list = forms.MultipleChoiceField(
|
||||
label=_("Boards List"),
|
||||
device_list = forms.MultipleChoiceField(
|
||||
label=_("Devices List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-inject-plugin'}),
|
||||
help_text=_("Select boards in this pool ")
|
||||
help_text=_("Select devices in this pool ")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -105,18 +105,18 @@ class InjectPluginForm(forms.SelfHandlingForm):
|
|||
super(InjectPluginForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
boardslist_length = len(kwargs["initial"]["board_list"])
|
||||
deviceslist_length = len(kwargs["initial"]["device_list"])
|
||||
|
||||
self.fields["board_list"].choices = kwargs["initial"]["board_list"]
|
||||
self.fields["board_list"].max_length = boardslist_length
|
||||
self.fields["device_list"].choices = kwargs["initial"]["device_list"]
|
||||
self.fields["device_list"].max_length = deviceslist_length
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
counter = 0
|
||||
|
||||
for board in data["board_list"]:
|
||||
for key, value in self.fields["board_list"].choices:
|
||||
if key == board:
|
||||
for device in data["device_list"]:
|
||||
for key, value in self.fields["device_list"].choices:
|
||||
if key == device:
|
||||
|
||||
try:
|
||||
inject = iotronic.plugin_inject(request, key,
|
||||
|
@ -126,13 +126,13 @@ class InjectPluginForm(forms.SelfHandlingForm):
|
|||
message_text = inject
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["board_list"]) - 1:
|
||||
if counter != len(data["device_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to inject plugin on board " \
|
||||
message_text = "Unable to inject plugin on device " \
|
||||
+ str(value) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
@ -148,12 +148,12 @@ class StartPluginForm(forms.SelfHandlingForm):
|
|||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
board_list = forms.MultipleChoiceField(
|
||||
label=_("Boards List"),
|
||||
device_list = forms.MultipleChoiceField(
|
||||
label=_("Devices List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable',
|
||||
'data-slug': 'slug-start-boards'}),
|
||||
help_text=_("Select boards in this pool ")
|
||||
'data-slug': 'slug-start-devices'}),
|
||||
help_text=_("Select devices in this pool ")
|
||||
)
|
||||
|
||||
parameters = forms.CharField(
|
||||
|
@ -170,10 +170,10 @@ class StartPluginForm(forms.SelfHandlingForm):
|
|||
super(StartPluginForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
boardslist_length = len(kwargs["initial"]["board_list"])
|
||||
deviceslist_length = len(kwargs["initial"]["device_list"])
|
||||
|
||||
self.fields["board_list"].choices = kwargs["initial"]["board_list"]
|
||||
self.fields["board_list"].max_length = boardslist_length
|
||||
self.fields["device_list"].choices = kwargs["initial"]["device_list"]
|
||||
self.fields["device_list"].max_length = deviceslist_length
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
|
@ -184,9 +184,9 @@ class StartPluginForm(forms.SelfHandlingForm):
|
|||
else:
|
||||
data["parameters"] = json.loads(data["parameters"])
|
||||
|
||||
for board in data["board_list"]:
|
||||
for key, value in self.fields["board_list"].choices:
|
||||
if key == board:
|
||||
for device in data["device_list"]:
|
||||
for key, value in self.fields["device_list"].choices:
|
||||
if key == device:
|
||||
|
||||
try:
|
||||
action = iotronic.plugin_action(request, key,
|
||||
|
@ -197,13 +197,13 @@ class StartPluginForm(forms.SelfHandlingForm):
|
|||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["board_list"]) - 1:
|
||||
if counter != len(data["device_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to start plugin on board " \
|
||||
message_text = "Unable to start plugin on device " \
|
||||
+ str(value) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
@ -225,11 +225,11 @@ class StopPluginForm(forms.SelfHandlingForm):
|
|||
help_text=_("OPTIONAL: seconds to wait before stopping the plugin")
|
||||
)
|
||||
|
||||
board_list = forms.MultipleChoiceField(
|
||||
label=_("Boards List"),
|
||||
device_list = forms.MultipleChoiceField(
|
||||
label=_("Devices List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-stop-boards'}),
|
||||
help_text=_("Select boards in this pool ")
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-stop-devices'}),
|
||||
help_text=_("Select devices in this pool ")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -237,10 +237,10 @@ class StopPluginForm(forms.SelfHandlingForm):
|
|||
super(StopPluginForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
boardslist_length = len(kwargs["initial"]["board_list"])
|
||||
deviceslist_length = len(kwargs["initial"]["device_list"])
|
||||
|
||||
self.fields["board_list"].choices = kwargs["initial"]["board_list"]
|
||||
self.fields["board_list"].max_length = boardslist_length
|
||||
self.fields["device_list"].choices = kwargs["initial"]["device_list"]
|
||||
self.fields["device_list"].max_length = deviceslist_length
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
|
@ -251,9 +251,9 @@ class StopPluginForm(forms.SelfHandlingForm):
|
|||
else:
|
||||
data["delay"] = {"delay": data["delay"]}
|
||||
|
||||
for board in data["board_list"]:
|
||||
for key, value in self.fields["board_list"].choices:
|
||||
if key == board:
|
||||
for device in data["device_list"]:
|
||||
for key, value in self.fields["device_list"].choices:
|
||||
if key == device:
|
||||
|
||||
try:
|
||||
action = iotronic.plugin_action(request, key,
|
||||
|
@ -264,13 +264,13 @@ class StopPluginForm(forms.SelfHandlingForm):
|
|||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["board_list"]) - 1:
|
||||
if counter != len(data["device_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to stop plugin on board " \
|
||||
message_text = "Unable to stop plugin on device " \
|
||||
+ str(value) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
@ -286,11 +286,11 @@ class CallPluginForm(forms.SelfHandlingForm):
|
|||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
board_list = forms.MultipleChoiceField(
|
||||
label=_("Boards List"),
|
||||
device_list = forms.MultipleChoiceField(
|
||||
label=_("Devices List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-call-boards'}),
|
||||
help_text=_("Select boards in this pool ")
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-call-devices'}),
|
||||
help_text=_("Select devices in this pool ")
|
||||
)
|
||||
|
||||
parameters = forms.CharField(
|
||||
|
@ -307,10 +307,10 @@ class CallPluginForm(forms.SelfHandlingForm):
|
|||
super(CallPluginForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
boardslist_length = len(kwargs["initial"]["board_list"])
|
||||
deviceslist_length = len(kwargs["initial"]["device_list"])
|
||||
|
||||
self.fields["board_list"].choices = kwargs["initial"]["board_list"]
|
||||
self.fields["board_list"].max_length = boardslist_length
|
||||
self.fields["device_list"].choices = kwargs["initial"]["device_list"]
|
||||
self.fields["device_list"].max_length = deviceslist_length
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
|
@ -321,9 +321,9 @@ class CallPluginForm(forms.SelfHandlingForm):
|
|||
else:
|
||||
data["parameters"] = json.loads(data["parameters"])
|
||||
|
||||
for board in data["board_list"]:
|
||||
for key, value in self.fields["board_list"].choices:
|
||||
if key == board:
|
||||
for device in data["device_list"]:
|
||||
for key, value in self.fields["device_list"].choices:
|
||||
if key == device:
|
||||
|
||||
try:
|
||||
action = iotronic.plugin_action(request, key,
|
||||
|
@ -334,13 +334,13 @@ class CallPluginForm(forms.SelfHandlingForm):
|
|||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["board_list"]) - 1:
|
||||
if counter != len(data["device_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call plugin on board " \
|
||||
message_text = "Unable to call plugin on device " \
|
||||
+ str(value) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
@ -356,11 +356,11 @@ class RemovePluginForm(forms.SelfHandlingForm):
|
|||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
board_list = forms.MultipleChoiceField(
|
||||
label=_("Boards List"),
|
||||
device_list = forms.MultipleChoiceField(
|
||||
label=_("Devices List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-remove-boards'}),
|
||||
help_text=_("Select boards in this pool ")
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-remove-devices'}),
|
||||
help_text=_("Select devices in this pool ")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -368,18 +368,18 @@ class RemovePluginForm(forms.SelfHandlingForm):
|
|||
super(RemovePluginForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
boardslist_length = len(kwargs["initial"]["board_list"])
|
||||
deviceslist_length = len(kwargs["initial"]["device_list"])
|
||||
|
||||
self.fields["board_list"].choices = kwargs["initial"]["board_list"]
|
||||
self.fields["board_list"].max_length = boardslist_length
|
||||
self.fields["device_list"].choices = kwargs["initial"]["device_list"]
|
||||
self.fields["device_list"].max_length = deviceslist_length
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
counter = 0
|
||||
|
||||
for board in data["board_list"]:
|
||||
for key, value in self.fields["board_list"].choices:
|
||||
if key == board:
|
||||
for device in data["device_list"]:
|
||||
for key, value in self.fields["device_list"].choices:
|
||||
if key == device:
|
||||
|
||||
try:
|
||||
iotronic.plugin_remove(request,
|
||||
|
@ -387,16 +387,16 @@ class RemovePluginForm(forms.SelfHandlingForm):
|
|||
data["uuid"])
|
||||
# LOG.debug("API: %s %s", plugin, request)
|
||||
message_text = "Plugin removed successfully from" \
|
||||
+ " board " + str(value) + "."
|
||||
+ " device " + str(value) + "."
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["board_list"]) - 1:
|
||||
if counter != len(data["device_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to remove plugin from board " \
|
||||
message_text = "Unable to remove plugin from device " \
|
||||
+ str(value) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
@ -458,8 +458,7 @@ class UpdatePluginForm(forms.SelfHandlingForm):
|
|||
"callable": data["callable"],
|
||||
"code": data["code"]})
|
||||
|
||||
messages.success(request, _("Plugin " + str(data["name"]) +
|
||||
" updated successfully."))
|
||||
messages.success(request, _("Plugin " + str(data["name"]) + " updated successfully."))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
|
|
|
@ -86,7 +86,7 @@ class CallPluginLink(tables.LinkAction):
|
|||
|
||||
class RemovePluginLink(tables.LinkAction):
|
||||
name = "remove"
|
||||
verbose_name = _("Remove Plugin from board(s)")
|
||||
verbose_name = _("Remove Plugin from device(s)")
|
||||
url = "horizon:iot:plugins:remove"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Call a plugin on board(s)." %}</p>
|
||||
<p>{% trans "Call a plugin on device(s)." %}</p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Inject a plugin into board(s)." %}</p>
|
||||
<p>{% trans "Inject a plugin into device(s)." %}</p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Remove a plugin from board(s)." %}</p>
|
||||
<p>{% trans "Remove a plugin from device(s)." %}</p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Start a plugin on board(s)." %}</p>
|
||||
<p>{% trans "Start a plugin on device(s)." %}</p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Stop a plugin on board(s)." %}</p>
|
||||
<p>{% trans "Stop a plugin on device(s)." %}</p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -42,7 +42,7 @@ class IndexView(tables.DataTableView):
|
|||
def get_data(self):
|
||||
plugins = []
|
||||
users = []
|
||||
|
||||
LOG.debug("REQUEST: %s", self.request)
|
||||
# Admin
|
||||
if policy.check((("iot", "iot:list_all_plugins"),), self.request):
|
||||
try:
|
||||
|
@ -128,17 +128,17 @@ class InjectView(forms.ModalFormView):
|
|||
def get_initial(self):
|
||||
plugin = self.get_object()
|
||||
|
||||
# Populate boards
|
||||
boards = iotronic.board_list(self.request, "online", None, None)
|
||||
boards.sort(key=lambda b: b.name)
|
||||
# Populate devices
|
||||
devices = iotronic.device_list(self.request, "online", None, None)
|
||||
devices.sort(key=lambda b: b.name)
|
||||
|
||||
board_list = []
|
||||
for board in boards:
|
||||
board_list.append((board.uuid, _(board.name)))
|
||||
device_list = []
|
||||
for device in devices:
|
||||
device_list.append((device.uuid, _(device.name)))
|
||||
|
||||
return {'uuid': plugin.uuid,
|
||||
'name': plugin.name,
|
||||
'board_list': board_list}
|
||||
'device_list': device_list}
|
||||
|
||||
|
||||
class StartView(forms.ModalFormView):
|
||||
|
@ -172,17 +172,17 @@ class StartView(forms.ModalFormView):
|
|||
def get_initial(self):
|
||||
plugin = self.get_object()
|
||||
|
||||
# Populate boards
|
||||
boards = iotronic.board_list(self.request, "online", None, None)
|
||||
boards.sort(key=lambda b: b.name)
|
||||
# Populate devices
|
||||
devices = iotronic.device_list(self.request, "online", None, None)
|
||||
devices.sort(key=lambda b: b.name)
|
||||
|
||||
board_list = []
|
||||
for board in boards:
|
||||
board_list.append((board.uuid, _(board.name)))
|
||||
device_list = []
|
||||
for device in devices:
|
||||
device_list.append((device.uuid, _(device.name)))
|
||||
|
||||
return {'uuid': plugin.uuid,
|
||||
'name': plugin.name,
|
||||
'board_list': board_list}
|
||||
'device_list': device_list}
|
||||
|
||||
|
||||
class StopView(forms.ModalFormView):
|
||||
|
@ -216,17 +216,17 @@ class StopView(forms.ModalFormView):
|
|||
def get_initial(self):
|
||||
plugin = self.get_object()
|
||||
|
||||
# Populate boards
|
||||
boards = iotronic.board_list(self.request, "online", None, None)
|
||||
boards.sort(key=lambda b: b.name)
|
||||
# Populate devices
|
||||
devices = iotronic.device_list(self.request, "online", None, None)
|
||||
devices.sort(key=lambda b: b.name)
|
||||
|
||||
board_list = []
|
||||
for board in boards:
|
||||
board_list.append((board.uuid, _(board.name)))
|
||||
device_list = []
|
||||
for device in devices:
|
||||
device_list.append((device.uuid, _(device.name)))
|
||||
|
||||
return {'uuid': plugin.uuid,
|
||||
'name': plugin.name,
|
||||
'board_list': board_list}
|
||||
'device_list': device_list}
|
||||
|
||||
|
||||
class CallView(forms.ModalFormView):
|
||||
|
@ -260,17 +260,17 @@ class CallView(forms.ModalFormView):
|
|||
def get_initial(self):
|
||||
plugin = self.get_object()
|
||||
|
||||
# Populate boards
|
||||
boards = iotronic.board_list(self.request, "online", None, None)
|
||||
boards.sort(key=lambda b: b.name)
|
||||
# Populate devices
|
||||
devices = iotronic.device_list(self.request, "online", None, None)
|
||||
devices.sort(key=lambda b: b.name)
|
||||
|
||||
board_list = []
|
||||
for board in boards:
|
||||
board_list.append((board.uuid, _(board.name)))
|
||||
device_list = []
|
||||
for device in devices:
|
||||
device_list.append((device.uuid, _(device.name)))
|
||||
|
||||
return {'uuid': plugin.uuid,
|
||||
'name': plugin.name,
|
||||
'board_list': board_list}
|
||||
'device_list': device_list}
|
||||
|
||||
|
||||
class RemoveView(forms.ModalFormView):
|
||||
|
@ -304,17 +304,17 @@ class RemoveView(forms.ModalFormView):
|
|||
def get_initial(self):
|
||||
plugin = self.get_object()
|
||||
|
||||
# Populate boards
|
||||
boards = iotronic.board_list(self.request, "online", None, None)
|
||||
boards.sort(key=lambda b: b.name)
|
||||
# Populate devices
|
||||
devices = iotronic.device_list(self.request, "online", None, None)
|
||||
devices.sort(key=lambda b: b.name)
|
||||
|
||||
board_list = []
|
||||
for board in boards:
|
||||
board_list.append((board.uuid, _(board.name)))
|
||||
device_list = []
|
||||
for device in devices:
|
||||
device_list.append((device.uuid, _(device.name)))
|
||||
|
||||
return {'uuid': plugin.uuid,
|
||||
'name': plugin.name,
|
||||
'board_list': board_list}
|
||||
'device_list': device_list}
|
||||
|
||||
|
||||
class UpdateView(forms.ModalFormView):
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import cPickle
|
||||
import json
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
|
||||
from openstack_dashboard.api import iotronic
|
||||
# from iotronic_ui.api import iotronic
|
||||
from openstack_dashboard import policy
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class InjectPluginForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
onboot = forms.BooleanField(label=_("On Boot"), required=False)
|
||||
|
||||
plugin_list = forms.MultipleChoiceField(
|
||||
label=_("Plugins List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-inject-plugin'}),
|
||||
help_text=_("Select plugin in this pool ")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(InjectPluginForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
pluginslist_length = len(kwargs["initial"]["plugin_list"])
|
||||
|
||||
self.fields["plugin_list"].choices = kwargs["initial"]["plugin_list"]
|
||||
self.fields["plugin_list"].max_length = pluginslist_length
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
counter = 0
|
||||
|
||||
for plugin in data["plugin_list"]:
|
||||
for key, value in self.fields["plugin_list"].choices:
|
||||
if key == plugin:
|
||||
|
||||
try:
|
||||
inject = iotronic.plugin_inject(request,
|
||||
data["uuid"],
|
||||
key,
|
||||
data["onboot"])
|
||||
# LOG.debug("API: %s %s", plugin, request)
|
||||
message_text = inject
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["plugin_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to inject plugin on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
break
|
||||
|
||||
|
||||
class CallPluginForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
# plugin_list = forms.MultipleChoiceField(
|
||||
plugin_list = forms.ChoiceField(
|
||||
label=_("Plugins List"),
|
||||
# widget=forms.SelectMultiple(
|
||||
widget=forms.Select(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-call-plugin'}),
|
||||
help_text=_("Select plugins in this pool ")
|
||||
)
|
||||
|
||||
parameters = forms.CharField(
|
||||
label=_("Parameters"),
|
||||
required=False,
|
||||
widget=forms.Textarea(
|
||||
attrs={'class': 'switchable',
|
||||
'data-slug': 'slug-callplugin-json'}),
|
||||
help_text=_("Plugin parameters")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(CallPluginForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
# pluginslist_length = len(kwargs["initial"]["plugin_list"])
|
||||
|
||||
self.fields["plugin_list"].choices = kwargs["initial"]["plugin_list"]
|
||||
# self.fields["plugin_list"].max_length = pluginslist_length
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
if not data["parameters"]:
|
||||
data["parameters"] = {}
|
||||
else:
|
||||
data["parameters"] = json.loads(data["parameters"])
|
||||
|
||||
try:
|
||||
action = iotronic.plugin_action(request,
|
||||
data["uuid"],
|
||||
data["plugin_list"],
|
||||
"PluginCall",
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to call plugin on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class StartPluginForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
# plugin_list = forms.MultipleChoiceField(
|
||||
plugin_list = forms.ChoiceField(
|
||||
label=_("Plugins List"),
|
||||
# widget=forms.SelectMultiple(
|
||||
widget=forms.Select(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-start-plugin'}),
|
||||
help_text=_("Select plugins in this pool ")
|
||||
)
|
||||
|
||||
parameters = forms.CharField(
|
||||
label=_("Parameters"),
|
||||
required=False,
|
||||
widget=forms.Textarea(
|
||||
attrs={'class': 'switchable',
|
||||
'data-slug': 'slug-startplugin-json'}),
|
||||
help_text=_("Plugin parameters")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(StartPluginForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
self.fields["plugin_list"].choices = kwargs["initial"]["plugin_list"]
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
if not data["parameters"]:
|
||||
data["parameters"] = {}
|
||||
else:
|
||||
data["parameters"] = json.loads(data["parameters"])
|
||||
|
||||
try:
|
||||
action = iotronic.plugin_action(request,
|
||||
data["uuid"],
|
||||
data["plugin_list"],
|
||||
"PluginStart",
|
||||
data["parameters"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to start plugin on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class StopPluginForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
delay = forms.IntegerField(
|
||||
label=_("Delay in secs"),
|
||||
required=False,
|
||||
help_text=_("OPTIONAL: seconds to wait before stopping the plugin")
|
||||
)
|
||||
|
||||
# plugin_list = forms.MultipleChoiceField(
|
||||
plugin_list = forms.ChoiceField(
|
||||
label=_("Plugins List"),
|
||||
# widget=forms.SelectMultiple(
|
||||
widget=forms.Select(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-stop-plugin'}),
|
||||
help_text=_("Select plugins in this pool ")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(StopPluginForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
|
||||
self.fields["plugin_list"].choices = kwargs["initial"]["plugin_list"]
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
# counter = 0
|
||||
|
||||
if not data["delay"]:
|
||||
data["delay"] = {}
|
||||
else:
|
||||
data["delay"] = {"delay": data["delay"]}
|
||||
|
||||
try:
|
||||
action = iotronic.plugin_action(request,
|
||||
data["uuid"],
|
||||
data["plugin_list"],
|
||||
"PluginStop",
|
||||
data["delay"])
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to stop plugin on device " \
|
||||
+ str(data["name"]) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class RemovePluginsForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
plugin_list = forms.MultipleChoiceField(
|
||||
label=_("Plugins List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable', 'data-slug': 'slug-remove-plugins'}),
|
||||
help_text=_("Select plugins in this pool ")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(RemovePluginsForm, self).__init__(*args, **kwargs)
|
||||
# input=kwargs.get('initial',{})
|
||||
self.fields["plugin_list"].choices = kwargs["initial"]["plugin_list"]
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
counter = 0
|
||||
|
||||
for plugin in data["plugin_list"]:
|
||||
for key, value in self.fields["plugin_list"].choices:
|
||||
if key == plugin:
|
||||
|
||||
try:
|
||||
iotronic.plugin_remove(request, data["uuid"], key)
|
||||
|
||||
message_text = "Plugin " + str(value) + \
|
||||
" removed successfully."
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["plugin_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to remove plugin " \
|
||||
+ str(value) + "."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
break
|
|
@ -0,0 +1,27 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import horizon
|
||||
from iotronic_ui.iot import dashboard
|
||||
|
||||
|
||||
class PluginsDevices(horizon.Panel):
|
||||
name = _("Devices")
|
||||
slug = "plugins_devices"
|
||||
|
||||
|
||||
dashboard.Iot.register(PluginsDevices)
|
|
@ -0,0 +1,128 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
from django import template
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ungettext_lazy
|
||||
|
||||
from horizon import tables
|
||||
|
||||
from openstack_dashboard import api
|
||||
# from iotronic_ui import api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DeviceFilterAction(tables.FilterAction):
|
||||
|
||||
# If uncommented it will appear the select menu list of fields
|
||||
# and filter button
|
||||
"""
|
||||
filter_type = "server"
|
||||
filter_choices = (("name", _("Device Name ="), True),
|
||||
("type", _("Type ="), True),
|
||||
("status", _("Status ="), True))
|
||||
"""
|
||||
|
||||
def filter(self, table, devices, filter_string):
|
||||
"""Naive case-insensitive search."""
|
||||
q = filter_string.lower()
|
||||
return [device for device in devices
|
||||
if q in device.name.lower()]
|
||||
|
||||
|
||||
def show_services(device_info):
|
||||
template_name = 'iot/plugins_devices/_cell_services.html'
|
||||
context = device_info._info
|
||||
# LOG.debug("CONTEXT: %s", context)
|
||||
return template.loader.render_to_string(template_name,
|
||||
context)
|
||||
|
||||
|
||||
class InjectPluginLink(tables.LinkAction):
|
||||
name = "inject"
|
||||
verbose_name = _("Inject Plugin")
|
||||
url = "horizon:iot:plugins_devices:inject"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
# policy_rules = (("iot", "iot:inject_plugin"),)
|
||||
|
||||
|
||||
class CallPluginLink(tables.LinkAction):
|
||||
name = "call"
|
||||
verbose_name = _("Call Plugin")
|
||||
url = "horizon:iot:plugins_devices:call"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
# policy_rules = (("iot", "iot:call_plugin"),)
|
||||
|
||||
|
||||
class StartPluginLink(tables.LinkAction):
|
||||
name = "start"
|
||||
verbose_name = _("Start Plugin")
|
||||
url = "horizon:iot:plugins_devices:start"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
# policy_rules = (("iot", "iot:start_plugin"),)
|
||||
|
||||
|
||||
class StopPluginLink(tables.LinkAction):
|
||||
name = "stop"
|
||||
verbose_name = _("Stop Plugin")
|
||||
url = "horizon:iot:plugins_devices:stop"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
# policy_rules = (("iot", "iot:stop_plugin"),)
|
||||
|
||||
|
||||
class RemovePluginsLink(tables.LinkAction):
|
||||
name = "removeplugins"
|
||||
verbose_name = _("Remove Plugin(s)")
|
||||
url = "horizon:iot:plugins_devices:removeplugins"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
# policy_rules = (("iot", "iot:remove_plugins"),)
|
||||
|
||||
|
||||
class DevicesTable(tables.DataTable):
|
||||
name = tables.WrappingColumn('name',
|
||||
link="horizon:iot:plugins_devices:detail",
|
||||
verbose_name=_('Device Name'))
|
||||
type = tables.Column('type', verbose_name=_('Type'))
|
||||
# mobile = tables.Column('mobile', verbose_name=_('Mobile'))
|
||||
lr_version = tables.Column('lr_version', verbose_name=_('LR version'))
|
||||
# fleet = tables.Column('fleet', verbose_name=_('Fleet ID'))
|
||||
fleet_name = tables.Column('fleet_name', verbose_name=_('Fleet Name'))
|
||||
# code = tables.Column('code', verbose_name=_('Code'))
|
||||
status = tables.Column('status', verbose_name=_('Status'))
|
||||
uuid = tables.Column('uuid', verbose_name=_('Device ID'))
|
||||
# location = tables.Column('location', verbose_name=_('Geo'))
|
||||
services = tables.Column(show_services, verbose_name=_('SSH Access'))
|
||||
# extra = tables.Column('extra', verbose_name=_('Extra'))
|
||||
|
||||
# Overriding get_object_id method because in IoT service the "id" is
|
||||
# identified by the field UUID
|
||||
def get_object_id(self, datum):
|
||||
return datum.uuid
|
||||
|
||||
class Meta(object):
|
||||
name = "devices"
|
||||
verbose_name = _("devices")
|
||||
row_actions = (InjectPluginLink, CallPluginLink, StartPluginLink,
|
||||
StopPluginLink, RemovePluginsLink,)
|
||||
table_actions = (DeviceFilterAction,)
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
# from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import tabs
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OverviewTab(tabs.Tab):
|
||||
name = _("Overview")
|
||||
slug = "overview"
|
||||
template_name = ("iot/plugins_devices/_detail_overview.html")
|
||||
|
||||
def get_context_data(self, request):
|
||||
|
||||
coordinates = self.tab_group.kwargs['device'].__dict__['location'][0]
|
||||
ports = self.tab_group.kwargs['device']._info['ports']
|
||||
services = self.tab_group.kwargs['device']._info['services']
|
||||
webservices = self.tab_group.kwargs['device']._info['webservices']
|
||||
plugins = self.tab_group.kwargs['device']._info['plugins']
|
||||
|
||||
return {"device": self.tab_group.kwargs['device'],
|
||||
"coordinates": coordinates,
|
||||
"services": services,
|
||||
"webservices": webservices,
|
||||
"ports": ports,
|
||||
"plugins": plugins,
|
||||
"is_superuser": request.user.is_superuser}
|
||||
|
||||
|
||||
class DeviceDetailTabs(tabs.TabGroup):
|
||||
slug = "device_details"
|
||||
# tabs = (OverviewTab, LogTab, ConsoleTab, AuditTab)
|
||||
tabs = (OverviewTab,)
|
||||
sticky = True
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Call a plugin on device." %}</p>
|
||||
{% endblock %}
|
|
@ -0,0 +1,16 @@
|
|||
{% load i18n %}
|
||||
{% if services %}
|
||||
{% for service in services %}
|
||||
{% if service.name == "ssh" %}
|
||||
<dd>ssh -p {{ service.public_port}} root@{{ service.wstun_ip }}</dd>
|
||||
{% elif service.name == "nodered" %}
|
||||
<dd>https://nodered.bla.bla.eu</dd>
|
||||
{% elif service.name == "http" %}
|
||||
<dd>https://{{ service.wstun_ip }}:{{ service.public_port }}</dd>
|
||||
{% else %}
|
||||
<dd>{{ service.name }} [{{ service.protocol }}] {{ service.port }} --> {{ service.public_port }}</dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
|
@ -0,0 +1,137 @@
|
|||
{% load i18n sizeformat %}
|
||||
|
||||
<div class="detail">
|
||||
|
||||
<h4>{% trans "Info" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ device.name }}</dd>
|
||||
<dt>{% trans "Status" %}</dt>
|
||||
<dd>{{ device.status }}</dd>
|
||||
<dt>{% trans "Type" %}</dt>
|
||||
<dd>{{ device.type }}</dd>
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ device.uuid }}</dd>
|
||||
<dt>{% trans "LR version" %}</dt>
|
||||
<dd>{{ device.lr_version }}</dd>
|
||||
<dt>{% trans "WAMP Agent" %}</dt>
|
||||
<dd>{{ device.agent }}</dd>
|
||||
<dt>{% trans "Code" %}</dt>
|
||||
<dd>{{ device.code }}</dd>
|
||||
<dt>{% trans "Creation data" %}</dt>
|
||||
<dd>{{ device.created_at }}</dd>
|
||||
<dt>{% trans "Location" %}</dt>
|
||||
<dd>Latitude: {{ coordinates.latitude }}</dd>
|
||||
<dd>Longitude: {{ coordinates.longitude }}</dd>
|
||||
<dd>Altitude: {{ coordinates.altitude }}</dd>
|
||||
<dt>{% trans "Connectivity" %}</dt>
|
||||
{% if device.connectivity.mac %}
|
||||
<dd>MAC: {{ device.connectivity.mac }}</dd>
|
||||
<dd>Interface: {{ device.connectivity.iface }}</dd>
|
||||
<dd>Local IP: {{ device.connectivity.local_ip }}</dd>
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Mobile" %}</dt>
|
||||
<dd>{{ device.mobile }}</dd>
|
||||
<dt>{% trans "Extra" %}</dt>
|
||||
<dd>{{ device.extra }}</dd>
|
||||
<dt>{% trans "Fleet Name" %}</dt>
|
||||
<dd>{{ device.fleet_name }}</dd>
|
||||
<dt>{% trans "Fleet ID" %}</dt>
|
||||
<dd>{{ device.fleet }}</dd>
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Ports" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if ports %}
|
||||
{% for port in ports %}
|
||||
<dt>{{ port.VIF_name }}</dt>
|
||||
<dd>{{ port.ip }}</dd>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if services %}
|
||||
{% for service in services %}
|
||||
<!--
|
||||
<dt>{{ service.name }} [{{ service.protocol }}] {{ service.port }}</dt>
|
||||
<dd>{{ service.public_port }}</dd>
|
||||
-->
|
||||
<!--
|
||||
<dt>{{ service.name }}</dt>
|
||||
<dd>[{{ service.protocol }}] L: {{ service.port }}; P: {{ service.public_port }}</dd>
|
||||
-->
|
||||
<dt>{{ service.name }}</dt>
|
||||
{% if service.name == "ssh" %}
|
||||
<dd>ssh -p {{ service.public_port}} root@{{ service.wstun_ip }}</dd>
|
||||
{% elif service.name == "nodered" %}
|
||||
<dd><a href="http://{{ service.wstun_ip }}:{{ service.public_port }}" target="_blank">http://{{ service.wstun_ip }}:{{ service.public_port }}</a></dd>
|
||||
{% else %}
|
||||
<dd>{{ service.name }} [{{ service.protocol }}] {{ service.port }} --> {{ service.public_port }}</dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Web Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if webservices %}
|
||||
{% for ws in webservices %}
|
||||
<dt>{{ ws.name }} [{{ ws.port }}]</dt>
|
||||
<dd>{{ ws.uuid }}</dd>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Plugins" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if plugins %}
|
||||
{% for plugin in plugins %}
|
||||
<dt>{{ plugin.name }}</dt>
|
||||
<dd>{{ plugin.uuid }}</dd>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!--<div id="mapdiv" style="min-height:300px; margin-bottom: 10px;" data-coordinates='[{"latitude": "{{ coordinates.latitude }}", "longitude": "{{ coordinates.longitude }}", "altitude": "{{ coordinates.altitude }}"}]'>-->
|
||||
<!--
|
||||
<div id="mapdiv" style="min-height:300px; margin-bottom: 10px;">
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
/*
|
||||
coordinates = JSON.parse(document.getElementById("mapdiv").getAttribute("data-coordinates"));
|
||||
lat = coordinates[0]["latitude"];
|
||||
lon = coordinates[0]["longitude"];
|
||||
alt = coordinates[0]["altitude"];
|
||||
*/
|
||||
var lat = "{{ coordinates.latitude }}";
|
||||
var lon = "{{ coordinates.longitude }}";
|
||||
var alt = "{{ coordinates.altitude }}";
|
||||
var label = "{{ board.name }}";
|
||||
var status = "{{ board.status }}";
|
||||
var updated = "{{ board.updated_at }}";
|
||||
|
||||
var array_coord = {"coordinates" : [{"lat": lat, "lon": lon, "alt": alt, "updated": updated, "label": label, "status": status}]}
|
||||
|
||||
render_map("mapdiv", array_coord);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
-->
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Inject a plugin into the device." %}</p>
|
||||
{% endblock %}
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Remove plugin(s) from this device." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Start a plugin on device(s)." %}</p>
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Stop a plugin on device(s)." %}</p>
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Call Plugin" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/plugins_devices/_call.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Devices" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Inject Plugin" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/plugins_devices/_inject.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Remove plugin(s) from this device." %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/plugins_devices/_removeplugins.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Start Plugin" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/plugins_devices/_start.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Stop Plugin" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/plugins_devices/_stop.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,19 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from horizon.test import helpers as test
|
||||
|
||||
|
||||
class DevicesTests(test.TestCase):
|
||||
# Unit tests for devices.
|
||||
def test_me(self):
|
||||
self.assertTrue(1 + 1 == 2)
|
|
@ -0,0 +1,36 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from iotronic_ui.iot.plugins_devices import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^(?P<device_id>[^/]+)/detail/$', views.DeviceDetailView.as_view(),
|
||||
name='detail'),
|
||||
url(r'^(?P<device_id>[^/]+)/inject/$', views.InjectView.as_view(),
|
||||
name='inject'),
|
||||
url(r'^(?P<device_id>[^/]+)/call/$', views.CallView.as_view(),
|
||||
name='call'),
|
||||
url(r'^(?P<device_id>[^/]+)/start/$', views.StartView.as_view(),
|
||||
name='start'),
|
||||
url(r'^(?P<device_id>[^/]+)/stop/$', views.StopView.as_view(),
|
||||
name='stop'),
|
||||
url(r'^(?P<device_id>[^/]+)/removeplugins/$',
|
||||
views.RemovePluginsView.as_view(), name='removeplugins'),
|
||||
]
|
|
@ -0,0 +1,468 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
# from horizon import messages
|
||||
from horizon import tables
|
||||
from horizon import tabs
|
||||
from horizon.utils import memoized
|
||||
|
||||
from openstack_dashboard import api
|
||||
# from iotronic_ui.api import iotronic
|
||||
from openstack_dashboard import policy
|
||||
|
||||
from iotronic_ui.iot.plugins_devices import forms as project_forms
|
||||
from iotronic_ui.iot.plugins_devices import tables as project_tables
|
||||
from iotronic_ui.iot.plugins_devices import tabs as project_tabs
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IndexView(tables.DataTableView):
|
||||
table_class = project_tables.DevicesTable
|
||||
template_name = 'iot/plugins_devices/index.html'
|
||||
page_title = _("Devices")
|
||||
|
||||
def get_data(self):
|
||||
devices = []
|
||||
|
||||
# Admin
|
||||
if policy.check((("iot", "iot:list_all_boards"),), self.request):
|
||||
try:
|
||||
devices = api.iotronic.device_list(self.request, None, None)
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve devices list.'))
|
||||
|
||||
# Admin_iot_project
|
||||
elif policy.check((("iot", "iot:list_project_boards"),), self.request):
|
||||
try:
|
||||
devices = api.iotronic.device_list(self.request, None, None)
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve user devices list.'))
|
||||
|
||||
# Other users
|
||||
else:
|
||||
try:
|
||||
devices = api.iotronic.device_list(self.request, None, None)
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve user devices list.'))
|
||||
|
||||
for device in devices:
|
||||
device_services = api.iotronic.services_on_device(self.request,
|
||||
device.uuid,
|
||||
True)
|
||||
|
||||
# x = api.iotronic.device_get(self.request, device.uuid, None)
|
||||
# LOG.debug('DEVICE: %s', x)
|
||||
# TO BE REMOVED
|
||||
# ------------------------------------------------------------
|
||||
filter_ws = []
|
||||
for service in device_services:
|
||||
# We are filtering the services that starts with "webservice"
|
||||
"""
|
||||
if ((service["name"] != "webservice") and
|
||||
(service["name"] != "webservice_ssl")):
|
||||
filter_ws.append(service)
|
||||
"""
|
||||
# We want to show only the "ssh" service
|
||||
if (service["name"] == "ssh"):
|
||||
service["wstun_ip"] = device.wstun_ip
|
||||
filter_ws.append(service)
|
||||
|
||||
device_services = filter_ws
|
||||
# ------------------------------------------------------------
|
||||
|
||||
# device.__dict__.update(dict(services=device_services))
|
||||
device._info.update(dict(services=device_services))
|
||||
|
||||
if device.fleet != None:
|
||||
fleet_info = api.iotronic.fleet_get(self.request,
|
||||
device.fleet,
|
||||
None)
|
||||
|
||||
device.fleet_name = fleet_info.name
|
||||
else:
|
||||
device.fleet_name = None
|
||||
|
||||
devices.sort(key=lambda b: b.name)
|
||||
return devices
|
||||
|
||||
|
||||
class DetailView(tabs.TabView):
|
||||
tab_group_class = project_tabs.DeviceDetailTabs
|
||||
template_name = 'horizon/common/_detail.html'
|
||||
page_title = "{{ device.name|default:device.uuid }}"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
device = self.get_data()
|
||||
context["device"] = device
|
||||
context["url"] = reverse(self.redirect_url)
|
||||
context["actions"] = self._get_actions(device)
|
||||
|
||||
return context
|
||||
|
||||
def _get_actions(self, device):
|
||||
table = project_tables.DevicesTable(self.request)
|
||||
return table.render_row_actions(device)
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_data(self):
|
||||
|
||||
device = []
|
||||
|
||||
device_id = self.kwargs['device_id']
|
||||
try:
|
||||
|
||||
device_ports = []
|
||||
|
||||
device = api.iotronic.device_get(self.request, device_id, None)
|
||||
|
||||
# FIX this problem with the new APIs
|
||||
# (remove the "if" clause with a better approach)
|
||||
# #################################################################
|
||||
ports = api.iotronic.port_list(self.request, device_id)
|
||||
|
||||
for port in ports:
|
||||
if port._info["board_uuid"] == device_id:
|
||||
device_ports.append(port._info)
|
||||
device._info.update(dict(ports=device_ports))
|
||||
# #################################################################
|
||||
|
||||
device_services = api.iotronic.services_on_device(self.request,
|
||||
device_id, True)
|
||||
|
||||
# We have to add the wstun_ip to the service
|
||||
for service in device_services:
|
||||
service["wstun_ip"] = device.wstun_ip
|
||||
|
||||
device._info.update(dict(services=device_services))
|
||||
|
||||
device_plugins = api.iotronic.plugins_on_device(self.request,
|
||||
device_id)
|
||||
|
||||
# Create a list with name and uuid
|
||||
p_list = []
|
||||
for p in device_plugins:
|
||||
p_list.append({"uuid": p._info["uuid"], "name": p.name})
|
||||
device_plugins = p_list
|
||||
|
||||
device._info.update(dict(plugins=device_plugins))
|
||||
|
||||
device_webservices = api.iotronic.webservices_on_device(self.request,
|
||||
device_id)
|
||||
|
||||
device._info.update(dict(webservices=device_webservices))
|
||||
|
||||
# Adding fleet name
|
||||
if device.fleet != None:
|
||||
fleet_info = api.iotronic.fleet_get(self.request,
|
||||
device.fleet,
|
||||
None)
|
||||
|
||||
device.fleet_name = fleet_info.name
|
||||
else:
|
||||
device.fleet_name = None
|
||||
|
||||
# Adding LR web service description
|
||||
lr_ws = api.iotronic.webservice_get_enabled_info(self.request,
|
||||
device_id)
|
||||
device._info.update(dict(lr_webservice=lr_ws))
|
||||
|
||||
except Exception:
|
||||
msg = ('Unable to retrieve device %s information') % {'name':
|
||||
device.name}
|
||||
exceptions.handle(self.request, msg, ignore=True)
|
||||
return device
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
device = self.get_data()
|
||||
return self.tab_group_class(request, device=device, **kwargs)
|
||||
|
||||
|
||||
class DeviceDetailView(DetailView):
|
||||
redirect_url = 'horizon:iot:plugins_devices:index'
|
||||
|
||||
def _get_actions(self, device):
|
||||
table = project_tables.DevicesTable(self.request)
|
||||
return table.render_row_actions(device)
|
||||
|
||||
|
||||
class InjectView(forms.ModalFormView):
|
||||
template_name = 'iot/plugins_devices/inject.html'
|
||||
modal_header = _("Inject Plugin")
|
||||
form_id = "inject_plugin_form"
|
||||
form_class = project_forms.InjectPluginForm
|
||||
submit_label = _("Inject Plugin")
|
||||
# submit_url = reverse_lazy("horizon:iot:plugins_devices:inject")
|
||||
submit_url = "horizon:iot:plugins_devices:inject"
|
||||
success_url = reverse_lazy('horizon:iot:plugins_devices:index')
|
||||
page_title = _("Inject Plugin")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:plugins_devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(InjectView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
# Populate plugins (not yet injected)
|
||||
plugins = api.iotronic.plugin_list(self.request, None, None,
|
||||
all_plugins=True)
|
||||
|
||||
plg_ondevice = api.iotronic.plugins_on_device(self.request,
|
||||
device.uuid)
|
||||
|
||||
diff = []
|
||||
if len(plg_ondevice) != 0:
|
||||
for p in plugins:
|
||||
count = 0
|
||||
for d in plg_ondevice:
|
||||
if d._info["uuid"] == p.uuid:
|
||||
break
|
||||
elif d._info["uuid"] != p.uuid and count == len(plg_ondevice) - 1:
|
||||
diff.append(p)
|
||||
else:
|
||||
count += 1
|
||||
plugins = diff
|
||||
|
||||
plugins.sort(key=lambda b: b.name)
|
||||
|
||||
plugin_list = []
|
||||
for plugin in plugins:
|
||||
plugin_list.append((plugin.uuid, _(plugin.name)))
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'plugin_list': plugin_list}
|
||||
|
||||
|
||||
class CallView(forms.ModalFormView):
|
||||
template_name = 'iot/plugins_devices/call.html'
|
||||
modal_header = _("Call Plugin")
|
||||
form_id = "call_plugin_form"
|
||||
form_class = project_forms.CallPluginForm
|
||||
submit_label = _("Call Plugin")
|
||||
# submit_url = reverse_lazy("horizon:iot:plugins_devices:call")
|
||||
submit_url = "horizon:iot:plugins_devices:call"
|
||||
success_url = reverse_lazy('horizon:iot:plugins_devices:index')
|
||||
page_title = _("Call Plugin")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:plugins_devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CallView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
# Populate plugins
|
||||
plugins = api.iotronic.plugin_list(self.request, None, None,
|
||||
all_plugins=True)
|
||||
plugins.sort(key=lambda b: b.name)
|
||||
|
||||
plugin_list = []
|
||||
for plugin in plugins:
|
||||
if plugin.callable == True:
|
||||
plugin_list.append((plugin.uuid, _(plugin.name)))
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'plugin_list': plugin_list}
|
||||
|
||||
|
||||
class StartView(forms.ModalFormView):
|
||||
template_name = 'iot/plugins_devices/start.html'
|
||||
modal_header = _("Start Plugin")
|
||||
form_id = "call_plugin_form"
|
||||
form_class = project_forms.StartPluginForm
|
||||
submit_label = _("Start Plugin")
|
||||
# submit_url = reverse_lazy("horizon:iot:plugins_devices:start")
|
||||
submit_url = "horizon:iot:plugins_devices:start"
|
||||
success_url = reverse_lazy('horizon:iot:plugins_devices:index')
|
||||
page_title = _("Start Plugin")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:plugins_devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(StartView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
# Populate plugins
|
||||
# plugins = api.iotronic.plugin_list(self.request, None, None,
|
||||
# all_plugins=True)
|
||||
plugins = api.iotronic.plugins_on_device(self.request, device.uuid)
|
||||
plugins.sort(key=lambda b: b.name)
|
||||
|
||||
plugin_list = []
|
||||
for plugin in plugins:
|
||||
if plugin.callable == False:
|
||||
plugin_list.append((plugin._info["uuid"], _(plugin.name)))
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'plugin_list': plugin_list}
|
||||
|
||||
|
||||
class StopView(forms.ModalFormView):
|
||||
template_name = 'iot/plugins_devices/stop.html'
|
||||
modal_header = _("Stop Plugin")
|
||||
form_id = "call_plugin_form"
|
||||
form_class = project_forms.StopPluginForm
|
||||
submit_label = _("Stop Plugin")
|
||||
# submit_url = reverse_lazy("horizon:iot:plugins_devices:stop")
|
||||
submit_url = "horizon:iot:plugins_devices:stop"
|
||||
success_url = reverse_lazy('horizon:iot:plugins_devices:index')
|
||||
page_title = _("Stop Plugin")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:plugins_devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(StopView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
# Populate plugins
|
||||
plugins = api.iotronic.plugin_list(self.request, None, None,
|
||||
all_plugins=True)
|
||||
plugins.sort(key=lambda b: b.name)
|
||||
|
||||
plugin_list = []
|
||||
for plugin in plugins:
|
||||
if plugin.callable == False:
|
||||
plugin_list.append((plugin.uuid, _(plugin.name)))
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'plugin_list': plugin_list}
|
||||
|
||||
|
||||
class RemovePluginsView(forms.ModalFormView):
|
||||
template_name = 'iot/plugins_devices/removeplugins.html'
|
||||
modal_header = _("Remove Plugins from device")
|
||||
form_id = "remove_deviceplugins_form"
|
||||
form_class = project_forms.RemovePluginsForm
|
||||
submit_label = _("Remove")
|
||||
# submit_url = reverse_lazy("horizon:iot:plugins_devices:removeplugins")
|
||||
submit_url = "horizon:iot:plugins_devices:removeplugins"
|
||||
success_url = reverse_lazy('horizon:iot:plugins_devices:index')
|
||||
page_title = _("Remove Plugins from device")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:plugins_devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(RemovePluginsView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
# Populate plugins
|
||||
# TO BE DONE.....filter by available on this device!!!
|
||||
# plugins = api.iotronic.plugin_list(self.request, None, None)
|
||||
plugins = api.iotronic.plugins_on_device(self.request, device.uuid)
|
||||
plugins.sort(key=lambda b: b.name)
|
||||
|
||||
plugin_list = []
|
||||
for plugin in plugins:
|
||||
plugin_list.append((plugin._info["uuid"], _(plugin.name)))
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'plugin_list': plugin_list}
|
|
@ -0,0 +1,115 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
|
||||
from openstack_dashboard.api import iotronic
|
||||
# from iotronic_ui.api import iotronic
|
||||
# from openstack_dashboard import policy
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EnableServiceForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
service_list = forms.MultipleChoiceField(
|
||||
label=_("Services List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable',
|
||||
'data-slug': 'slug-select-services'}),
|
||||
help_text=_("Add available services from this pool")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(EnableServiceForm, self).__init__(*args, **kwargs)
|
||||
self.fields["service_list"].choices = kwargs["initial"]["service_list"]
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
counter = 0
|
||||
for service in data["service_list"]:
|
||||
try:
|
||||
action = iotronic.service_action(request, data["uuid"],
|
||||
service, "ServiceEnable")
|
||||
|
||||
# message_text = "Service(s) enabled successfully."
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["service_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to enable service."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class DisableServiceForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
service_list = forms.MultipleChoiceField(
|
||||
label=_("Services List"),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={'class': 'switchable',
|
||||
'data-slug': 'slug-select-services'}),
|
||||
help_text=_("Select services to disable from this pool")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DisableServiceForm, self).__init__(*args, **kwargs)
|
||||
self.fields["service_list"].choices = kwargs["initial"]["service_list"]
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
counter = 0
|
||||
for service in data["service_list"]:
|
||||
try:
|
||||
action = iotronic.service_action(request, data["uuid"],
|
||||
service, "ServiceDisable")
|
||||
|
||||
# message_text = "Service(s) disabled successfully."
|
||||
message_text = action
|
||||
messages.success(request, _(message_text))
|
||||
|
||||
if counter != len(data["service_list"]) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to disable service."
|
||||
exceptions.handle(request, _(message_text))
|
|
@ -0,0 +1,27 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import horizon
|
||||
from iotronic_ui.iot import dashboard
|
||||
|
||||
|
||||
class ServicesDevices(horizon.Panel):
|
||||
name = _("Devices")
|
||||
slug = "services_devices"
|
||||
|
||||
|
||||
dashboard.Iot.register(ServicesDevices)
|
|
@ -0,0 +1,119 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
from django import template
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
# from django.utils.translation import ungettext_lazy
|
||||
|
||||
from horizon import tables
|
||||
|
||||
from openstack_dashboard import api
|
||||
# from iotronic_ui import api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DeviceFilterAction(tables.FilterAction):
|
||||
|
||||
# If uncommented it will appear the select menu list of fields
|
||||
# and filter button
|
||||
"""
|
||||
filter_type = "server"
|
||||
filter_choices = (("name", _("Device Name ="), True),
|
||||
("type", _("Type ="), True),
|
||||
("status", _("Status ="), True))
|
||||
"""
|
||||
|
||||
def filter(self, table, devices, filter_string):
|
||||
"""Naive case-insensitive search."""
|
||||
q = filter_string.lower()
|
||||
return [device for device in devices
|
||||
if q in device.name.lower()]
|
||||
|
||||
|
||||
def show_services(device_info):
|
||||
template_name = 'iot/services_devices/_cell_services.html'
|
||||
context = device_info._info
|
||||
# LOG.debug("CONTEXT: %s", context)
|
||||
return template.loader.render_to_string(template_name,
|
||||
context)
|
||||
|
||||
|
||||
class EnableServiceLink(tables.LinkAction):
|
||||
name = "enableservice"
|
||||
verbose_name = _("Enable Service(s)")
|
||||
url = "horizon:iot:services_devices:enableservice"
|
||||
classes = ("ajax-modal",)
|
||||
# icon = "plus"
|
||||
# policy_rules = (("iot", "iot:service_action"),)
|
||||
|
||||
|
||||
class DisableServiceLink(tables.LinkAction):
|
||||
name = "disableservice"
|
||||
verbose_name = _("Disable Service(s)")
|
||||
url = "horizon:iot:services_devices:disableservice"
|
||||
classes = ("ajax-modal",)
|
||||
# icon = "plus"
|
||||
# policy_rules = (("iot", "iot:service_action"),)
|
||||
|
||||
|
||||
class RestoreServices(tables.BatchAction):
|
||||
name = "restoreservices"
|
||||
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
return u"Restore ALL Services"
|
||||
|
||||
@staticmethod
|
||||
def action_past(count):
|
||||
return u"Restored ALL Services"
|
||||
|
||||
def allowed(self, request, device=None):
|
||||
return True
|
||||
|
||||
def action(self, request, device_id):
|
||||
api.iotronic.restore_services(request, device_id)
|
||||
|
||||
|
||||
class DevicesTable(tables.DataTable):
|
||||
name = tables.WrappingColumn('name',
|
||||
link="horizon:iot:services_devices:detail",
|
||||
verbose_name=_('Device Name'))
|
||||
type = tables.Column('type', verbose_name=_('Type'))
|
||||
# mobile = tables.Column('mobile', verbose_name=_('Mobile'))
|
||||
lr_version = tables.Column('lr_version', verbose_name=_('LR version'))
|
||||
# fleet = tables.Column('fleet', verbose_name=_('Fleet ID'))
|
||||
fleet_name = tables.Column('fleet_name', verbose_name=_('Fleet Name'))
|
||||
# code = tables.Column('code', verbose_name=_('Code'))
|
||||
status = tables.Column('status', verbose_name=_('Status'))
|
||||
uuid = tables.Column('uuid', verbose_name=_('Device ID'))
|
||||
# location = tables.Column('location', verbose_name=_('Geo'))
|
||||
services = tables.Column(show_services, verbose_name=_('SSH Access'))
|
||||
# extra = tables.Column('extra', verbose_name=_('Extra'))
|
||||
|
||||
# Overriding get_object_id method because in IoT service the "id" is
|
||||
# identified by the field UUID
|
||||
def get_object_id(self, datum):
|
||||
return datum.uuid
|
||||
|
||||
class Meta(object):
|
||||
name = "devices"
|
||||
verbose_name = _("devices")
|
||||
row_actions = (EnableServiceLink, DisableServiceLink,
|
||||
RestoreServices,)
|
||||
table_actions = (DeviceFilterAction,)
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
# from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import tabs
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OverviewTab(tabs.Tab):
|
||||
name = _("Overview")
|
||||
slug = "overview"
|
||||
template_name = ("iot/services_devices/_detail_overview.html")
|
||||
|
||||
def get_context_data(self, request):
|
||||
|
||||
coordinates = self.tab_group.kwargs['device'].__dict__['location'][0]
|
||||
ports = self.tab_group.kwargs['device']._info['ports']
|
||||
services = self.tab_group.kwargs['device']._info['services']
|
||||
webservices = self.tab_group.kwargs['device']._info['webservices']
|
||||
plugins = self.tab_group.kwargs['device']._info['plugins']
|
||||
|
||||
return {"device": self.tab_group.kwargs['device'],
|
||||
"coordinates": coordinates,
|
||||
"services": services,
|
||||
"webservices": webservices,
|
||||
"ports": ports,
|
||||
"plugins": plugins,
|
||||
"is_superuser": request.user.is_superuser}
|
||||
|
||||
|
||||
class DeviceDetailTabs(tabs.TabGroup):
|
||||
slug = "device_details"
|
||||
# tabs = (OverviewTab, LogTab, ConsoleTab, AuditTab)
|
||||
tabs = (OverviewTab,)
|
||||
sticky = True
|
|
@ -0,0 +1,16 @@
|
|||
{% load i18n %}
|
||||
{% if services %}
|
||||
{% for service in services %}
|
||||
{% if service.name == "ssh" %}
|
||||
<dd>ssh -p {{ service.public_port}} root@{{ service.wstun_ip }}</dd>
|
||||
{% elif service.name == "nodered" %}
|
||||
<dd>https://nodered.bla.bla.eu</dd>
|
||||
{% elif service.name == "http" %}
|
||||
<dd>https://{{ service.wstun_ip }}:{{ service.public_port }}</dd>
|
||||
{% else %}
|
||||
<dd>{{ service.name }} [{{ service.protocol }}] {{ service.port }} --> {{ service.public_port }}</dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
|
@ -0,0 +1,137 @@
|
|||
{% load i18n sizeformat %}
|
||||
|
||||
<div class="detail">
|
||||
|
||||
<h4>{% trans "Info" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ device.name }}</dd>
|
||||
<dt>{% trans "Status" %}</dt>
|
||||
<dd>{{ device.status }}</dd>
|
||||
<dt>{% trans "Type" %}</dt>
|
||||
<dd>{{ device.type }}</dd>
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ device.uuid }}</dd>
|
||||
<dt>{% trans "LR version" %}</dt>
|
||||
<dd>{{ device.lr_version }}</dd>
|
||||
<dt>{% trans "WAMP Agent" %}</dt>
|
||||
<dd>{{ device.agent }}</dd>
|
||||
<dt>{% trans "Code" %}</dt>
|
||||
<dd>{{ device.code }}</dd>
|
||||
<dt>{% trans "Creation data" %}</dt>
|
||||
<dd>{{ device.created_at }}</dd>
|
||||
<dt>{% trans "Location" %}</dt>
|
||||
<dd>Latitude: {{ coordinates.latitude }}</dd>
|
||||
<dd>Longitude: {{ coordinates.longitude }}</dd>
|
||||
<dd>Altitude: {{ coordinates.altitude }}</dd>
|
||||
<dt>{% trans "Connectivity" %}</dt>
|
||||
{% if device.connectivity.mac %}
|
||||
<dd>MAC: {{ device.connectivity.mac }}</dd>
|
||||
<dd>Interface: {{ device.connectivity.iface }}</dd>
|
||||
<dd>Local IP: {{ device.connectivity.local_ip }}</dd>
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Mobile" %}</dt>
|
||||
<dd>{{ device.mobile }}</dd>
|
||||
<dt>{% trans "Extra" %}</dt>
|
||||
<dd>{{ device.extra }}</dd>
|
||||
<dt>{% trans "Fleet Name" %}</dt>
|
||||
<dd>{{ device.fleet_name }}</dd>
|
||||
<dt>{% trans "Fleet ID" %}</dt>
|
||||
<dd>{{ device.fleet }}</dd>
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Ports" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if ports %}
|
||||
{% for port in ports %}
|
||||
<dt>{{ port.VIF_name }}</dt>
|
||||
<dd>{{ port.ip }}</dd>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if services %}
|
||||
{% for service in services %}
|
||||
<!--
|
||||
<dt>{{ service.name }} [{{ service.protocol }}] {{ service.port }}</dt>
|
||||
<dd>{{ service.public_port }}</dd>
|
||||
-->
|
||||
<!--
|
||||
<dt>{{ service.name }}</dt>
|
||||
<dd>[{{ service.protocol }}] L: {{ service.port }}; P: {{ service.public_port }}</dd>
|
||||
-->
|
||||
<dt>{{ service.name }}</dt>
|
||||
{% if service.name == "ssh" %}
|
||||
<dd>ssh -p {{ service.public_port}} root@{{ service.wstun_ip }}</dd>
|
||||
{% elif service.name == "nodered" %}
|
||||
<dd><a href="http://{{ service.wstun_ip }}:{{ service.public_port }}" target="_blank">http://{{ service.wstun_ip }}:{{ service.public_port }}</a></dd>
|
||||
{% else %}
|
||||
<dd>{{ service.name }} [{{ service.protocol }}] {{ service.port }} --> {{ service.public_port }}</dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Web Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if webservices %}
|
||||
{% for ws in webservices %}
|
||||
<dt>{{ ws.name }} [{{ ws.port }}]</dt>
|
||||
<dd>{{ ws.uuid }}</dd>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<h4>{% trans "Plugins" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% if plugins %}
|
||||
{% for plugin in plugins %}
|
||||
<dt>{{ plugin.name }}</dt>
|
||||
<dd>{{ plugin.id }}</dd>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<dd>--</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!--<div id="mapdiv" style="min-height:300px; margin-bottom: 10px;" data-coordinates='[{"latitude": "{{ coordinates.latitude }}", "longitude": "{{ coordinates.longitude }}", "altitude": "{{ coordinates.altitude }}"}]'>-->
|
||||
<!--
|
||||
<div id="mapdiv" style="min-height:300px; margin-bottom: 10px;">
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
/*
|
||||
coordinates = JSON.parse(document.getElementById("mapdiv").getAttribute("data-coordinates"));
|
||||
lat = coordinates[0]["latitude"];
|
||||
lon = coordinates[0]["longitude"];
|
||||
alt = coordinates[0]["altitude"];
|
||||
*/
|
||||
var lat = "{{ coordinates.latitude }}";
|
||||
var lon = "{{ coordinates.longitude }}";
|
||||
var alt = "{{ coordinates.altitude }}";
|
||||
var label = "{{ board.name }}";
|
||||
var status = "{{ board.status }}";
|
||||
var updated = "{{ board.updated_at }}";
|
||||
|
||||
var array_coord = {"coordinates" : [{"lat": lat, "lon": lon, "alt": alt, "updated": updated, "label": label, "status": status}]}
|
||||
|
||||
render_map("mapdiv", array_coord);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
-->
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Disable service(s) on the selected device." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Enable service(s) on the selected device." %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Disable" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/services_devices/_disableservice.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Enable" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'iot/services_devices/_enableservice.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Devices" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
|
@ -0,0 +1,19 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from horizon.test import helpers as test
|
||||
|
||||
|
||||
class DevicesTests(test.TestCase):
|
||||
# Unit tests for devices.
|
||||
def test_me(self):
|
||||
self.assertTrue(1 + 1 == 2)
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from iotronic_ui.iot.services_devices import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^(?P<device_id>[^/]+)/detail/$', views.DeviceDetailView.as_view(),
|
||||
name='detail'),
|
||||
url(r'^(?P<device_id>[^/]+)/enableservice/$',
|
||||
views.EnableServiceView.as_view(), name='enableservice'),
|
||||
url(r'^(?P<device_id>[^/]+)/disableservice/$',
|
||||
views.DisableServiceView.as_view(), name='disableservice'),
|
||||
]
|
|
@ -0,0 +1,358 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
# from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
# from horizon import messages
|
||||
from horizon import tables
|
||||
from horizon import tabs
|
||||
from horizon.utils import memoized
|
||||
|
||||
from openstack_dashboard import api
|
||||
# from iotronic_ui.api import iotronic
|
||||
from openstack_dashboard import policy
|
||||
|
||||
from iotronic_ui.iot.services_devices import forms as project_forms
|
||||
from iotronic_ui.iot.services_devices import tables as project_tables
|
||||
from iotronic_ui.iot.services_devices import tabs as project_tabs
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IndexView(tables.DataTableView):
|
||||
table_class = project_tables.DevicesTable
|
||||
template_name = 'iot/services_devices/index.html'
|
||||
page_title = _("Devices")
|
||||
|
||||
def get_data(self):
|
||||
devices = []
|
||||
|
||||
# Admin
|
||||
if policy.check((("iot", "iot:list_all_boards"),), self.request):
|
||||
try:
|
||||
devices = api.iotronic.device_list(self.request, None, None)
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve devices list.'))
|
||||
|
||||
# Admin_iot_project
|
||||
elif policy.check((("iot", "iot:list_project_boards"),), self.request):
|
||||
try:
|
||||
devices = api.iotronic.device_list(self.request, None, None)
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve user devices list.'))
|
||||
|
||||
# Other users
|
||||
else:
|
||||
try:
|
||||
devices = api.iotronic.device_list(self.request, None, None)
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve user devices list.'))
|
||||
|
||||
for device in devices:
|
||||
device_services = api.iotronic.services_on_device(self.request,
|
||||
device.uuid,
|
||||
True)
|
||||
|
||||
# x = api.iotronic.device_get(self.request, device.uuid, None)
|
||||
# LOG.debug('DEVICE: %s', x)
|
||||
# TO BE REMOVED
|
||||
# ------------------------------------------------------------
|
||||
filter_ws = []
|
||||
for service in device_services:
|
||||
# We are filtering the services that starts with "webservice"
|
||||
"""
|
||||
if ((service["name"] != "webservice") and
|
||||
(service["name"] != "webservice_ssl")):
|
||||
filter_ws.append(service)
|
||||
"""
|
||||
# We want to show only the "ssh" service
|
||||
if (service["name"] == "ssh"):
|
||||
service["wstun_ip"] = device.wstun_ip
|
||||
filter_ws.append(service)
|
||||
|
||||
device_services = filter_ws
|
||||
# ------------------------------------------------------------
|
||||
|
||||
# device.__dict__.update(dict(services=device_services))
|
||||
device._info.update(dict(services=device_services))
|
||||
|
||||
if device.fleet != None:
|
||||
fleet_info = api.iotronic.fleet_get(self.request,
|
||||
device.fleet,
|
||||
None)
|
||||
|
||||
device.fleet_name = fleet_info.name
|
||||
else:
|
||||
device.fleet_name = None
|
||||
|
||||
devices.sort(key=lambda b: b.name)
|
||||
# LOG.debug('DEVICES: %s', devices)
|
||||
return devices
|
||||
|
||||
|
||||
class DetailView(tabs.TabView):
|
||||
tab_group_class = project_tabs.DeviceDetailTabs
|
||||
template_name = 'horizon/common/_detail.html'
|
||||
page_title = "{{ device.name|default:device.uuid }}"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
device = self.get_data()
|
||||
context["device"] = device
|
||||
context["url"] = reverse(self.redirect_url)
|
||||
context["actions"] = self._get_actions(device)
|
||||
|
||||
return context
|
||||
|
||||
def _get_actions(self, device):
|
||||
table = project_tables.DevicesTable(self.request)
|
||||
return table.render_row_actions(device)
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_data(self):
|
||||
|
||||
device = []
|
||||
|
||||
device_id = self.kwargs['device_id']
|
||||
try:
|
||||
|
||||
device_ports = []
|
||||
|
||||
device = api.iotronic.device_get(self.request, device_id, None)
|
||||
|
||||
# FIX this problem with the new APIs
|
||||
# (remove the "if" clause with a better approach)
|
||||
# #################################################################
|
||||
ports = api.iotronic.port_list(self.request, device_id)
|
||||
|
||||
for port in ports:
|
||||
if port._info["board_uuid"] == device_id:
|
||||
device_ports.append(port._info)
|
||||
device._info.update(dict(ports=device_ports))
|
||||
# #################################################################
|
||||
|
||||
device_services = api.iotronic.services_on_device(self.request,
|
||||
device_id, True)
|
||||
|
||||
# We have to add the wstun_ip to the service
|
||||
for service in device_services:
|
||||
service["wstun_ip"] = device.wstun_ip
|
||||
|
||||
device._info.update(dict(services=device_services))
|
||||
|
||||
device_plugins = api.iotronic.plugins_on_device(self.request,
|
||||
device_id)
|
||||
device._info.update(dict(plugins=device_plugins))
|
||||
|
||||
device_webservices = api.iotronic.webservices_on_device(self.request,
|
||||
device_id)
|
||||
|
||||
# LOG.debug('DEVICE %s, WEB SERVICES: %s', device_id, device_webservices)
|
||||
device._info.update(dict(webservices=device_webservices))
|
||||
|
||||
# Adding fleet name
|
||||
if device.fleet != None:
|
||||
fleet_info = api.iotronic.fleet_get(self.request,
|
||||
device.fleet,
|
||||
None)
|
||||
|
||||
device.fleet_name = fleet_info.name
|
||||
else:
|
||||
device.fleet_name = None
|
||||
|
||||
# Adding LR web service description
|
||||
lr_ws = api.iotronic.webservice_get_enabled_info(self.request,
|
||||
device_id)
|
||||
device._info.update(dict(lr_webservice=lr_ws))
|
||||
|
||||
# LOG.debug("DEVICE: %s\n\n%s", device, device._info)
|
||||
|
||||
except Exception:
|
||||
msg = ('Unable to retrieve device %s information') % {'name':
|
||||
device.name}
|
||||
exceptions.handle(self.request, msg, ignore=True)
|
||||
return device
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
device = self.get_data()
|
||||
return self.tab_group_class(request, device=device, **kwargs)
|
||||
|
||||
|
||||
class EnableServiceView(forms.ModalFormView):
|
||||
template_name = 'iot/services_devices/enableservice.html'
|
||||
modal_header = _("Enable Service(s)")
|
||||
form_id = "service_enable_form"
|
||||
form_class = project_forms.EnableServiceForm
|
||||
submit_label = _("Enable")
|
||||
# submit_url = reverse_lazy("horizon:iot:services_devices:enableservice")
|
||||
submit_url = "horizon:iot:services_devices:enableservice"
|
||||
success_url = reverse_lazy('horizon:iot:services_devices:index')
|
||||
page_title = _("Action")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:services_devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(EnableServiceView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
# Populate available services
|
||||
cloud_services = api.iotronic.service_list(self.request, None)
|
||||
device_services = api.iotronic.services_on_device(self.request,
|
||||
device.uuid,
|
||||
True)
|
||||
cloud_services.sort(key=lambda b: b.name)
|
||||
service_list = []
|
||||
# LOG.debug('CLOUD SERVICES: %s', cloud_services)
|
||||
|
||||
for cloud_service in cloud_services:
|
||||
|
||||
uuid = cloud_service._info["uuid"]
|
||||
name = cloud_service._info["name"]
|
||||
|
||||
if len(device_services) == 0:
|
||||
|
||||
# BEFORE filtering necessity
|
||||
# service_list.append((cloud_service._info["uuid"],
|
||||
# _(cloud_service._info["name"])))
|
||||
|
||||
# AFTER filtering necessity
|
||||
# We are filtering the services that starts with "webservice"
|
||||
if ((name != "webservice") and (name != "webservice_ssl")):
|
||||
service_list.append((uuid, _(name)))
|
||||
|
||||
else:
|
||||
counter = 0
|
||||
for device_service in device_services:
|
||||
if device_service["uuid"] == cloud_service._info["uuid"]:
|
||||
break
|
||||
elif counter != len(device_services) - 1:
|
||||
counter += 1
|
||||
else:
|
||||
# BEFORE filtering necessity
|
||||
# service_list.append((uuid, _(name)))
|
||||
|
||||
# AFTER filtering necessity
|
||||
# We are filtering the services that starts
|
||||
# with "webservice"
|
||||
if ((name != "webservice") and ("name" != "webservice_ssl")):
|
||||
service_list.append((uuid, _(name)))
|
||||
|
||||
# LOG.debug('SERVICES: %s', service_list)
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'service_list': service_list}
|
||||
|
||||
|
||||
class DisableServiceView(forms.ModalFormView):
|
||||
template_name = 'iot/services_devices/disableservice.html'
|
||||
modal_header = _("Disable Service(s)")
|
||||
form_id = "service_disable_form"
|
||||
form_class = project_forms.DisableServiceForm
|
||||
submit_label = _("Disable")
|
||||
# submit_url = reverse_lazy("horizon:iot:services_devices:disableservice")
|
||||
submit_url = "horizon:iot:services_devices:disableservice"
|
||||
success_url = reverse_lazy('horizon:iot:services_devices:index')
|
||||
page_title = _("Action")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.iotronic.device_get(self.request,
|
||||
self.kwargs['device_id'],
|
||||
None)
|
||||
|
||||
except Exception:
|
||||
redirect = reverse("horizon:iot:services_devices:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get device information.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DisableServiceView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().uuid,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
device = self.get_object()
|
||||
|
||||
# Populate available services
|
||||
cloud_services = api.iotronic.service_list(self.request, None)
|
||||
device_services = api.iotronic.services_on_device(self.request,
|
||||
device.uuid,
|
||||
True)
|
||||
cloud_services.sort(key=lambda b: b.name)
|
||||
service_list = []
|
||||
|
||||
# BEFORE filtering necessity
|
||||
"""
|
||||
for cloud_service in cloud_services:
|
||||
for device_service in device_services:
|
||||
if device_service["uuid"] == cloud_service._info["uuid"]:
|
||||
service_list.append((cloud_service._info["uuid"],
|
||||
_(cloud_service._info["name"])))
|
||||
"""
|
||||
|
||||
# AFTER filtering necessity
|
||||
# We are filtering the services that starts with "webservice"
|
||||
# ------------------------------------------------------------
|
||||
for cloud_service in cloud_services:
|
||||
for device_service in device_services:
|
||||
if ((device_service["uuid"] == cloud_service._info["uuid"]) and ((device_service["name"] != "webservice") and (device_service["name"] != "webservice_ssl"))):
|
||||
service_list.append((cloud_service._info["uuid"], _(cloud_service._info["name"])))
|
||||
# ------------------------------------------------------------
|
||||
|
||||
return {'uuid': device.uuid,
|
||||
'name': device.name,
|
||||
'service_list': service_list}
|
||||
|
||||
|
||||
class DeviceDetailView(DetailView):
|
||||
redirect_url = 'horizon:iot:services_devices:index'
|
||||
|
||||
def _get_actions(self, device):
|
||||
table = project_tables.DevicesTable(self.request)
|
||||
return table.render_row_actions(device)
|
|
@ -82,6 +82,24 @@ def show_webservices(board_info):
|
|||
context)
|
||||
|
||||
|
||||
class RestoreServices(tables.BatchAction):
|
||||
name = "restoreservices"
|
||||
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
return u"Restore ALL Services"
|
||||
|
||||
@staticmethod
|
||||
def action_past(count):
|
||||
return u"Restored ALL Services"
|
||||
|
||||
def allowed(self, request, device=None):
|
||||
return True
|
||||
|
||||
def action(self, request, device_id):
|
||||
api.iotronic.restore_services(request, device_id)
|
||||
|
||||
|
||||
class WebservicesTable(tables.DataTable):
|
||||
|
||||
"""
|
||||
|
@ -90,11 +108,14 @@ class WebservicesTable(tables.DataTable):
|
|||
verbose_name=_('UUID'))
|
||||
"""
|
||||
board = tables.Column('name', verbose_name=_('Board Name'))
|
||||
status = tables.Column('status', verbose_name=_('Status'))
|
||||
|
||||
board_uuid = tables.Column('board_uuid',
|
||||
board_uuid = tables.Column('board_uuid',
|
||||
verbose_name=_('Board UUID'),
|
||||
hidden=True)
|
||||
|
||||
# ssh = tables.Column('ssh', verbose_name=_('SSH Access'))
|
||||
|
||||
webservices = tables.Column(show_webservices,
|
||||
verbose_name=_('Web Services'))
|
||||
|
||||
|
@ -116,6 +137,6 @@ class WebservicesTable(tables.DataTable):
|
|||
DisableWebservicesAction)
|
||||
table_actions = (WebserviceFilterAction, DisableWebservicesAction)
|
||||
"""
|
||||
row_actions = (ExposeWebserviceLink,
|
||||
UnexposeWebserviceLink)
|
||||
row_actions = (ExposeWebserviceLink, UnexposeWebserviceLink,
|
||||
RestoreServices,)
|
||||
table_actions = (WebserviceFilterAction,)
|
||||
|
|
|
@ -15,7 +15,7 @@ import logging
|
|||
# from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import tabs
|
||||
# from horizon import tabs
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ from horizon import exceptions
|
|||
from horizon import forms
|
||||
# from horizon import messages
|
||||
from horizon import tables
|
||||
from horizon import tabs
|
||||
# from horizon import tabs
|
||||
from horizon.utils import memoized
|
||||
|
||||
from openstack_dashboard.api import iotronic
|
||||
|
@ -28,7 +28,7 @@ from openstack_dashboard import policy
|
|||
|
||||
from iotronic_ui.iot.webservices import forms as project_forms
|
||||
from iotronic_ui.iot.webservices import tables as project_tables
|
||||
from iotronic_ui.iot.webservices import tabs as project_tabs
|
||||
# from iotronic_ui.iot.webservices import tabs as project_tabs
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -80,8 +80,22 @@ class IndexView(tables.DataTableView):
|
|||
# Append some information to the webservice
|
||||
# LOG.debug('WSS: %s', webservices)
|
||||
for ws_en in en_webservices:
|
||||
|
||||
board = iotronic.board_get(self.request, ws_en.board_uuid, None)
|
||||
"""
|
||||
services = iotronic.services_on_board(self.request,
|
||||
ws_en.board_uuid,
|
||||
True)
|
||||
LOG.debug('SERVICES: %s', services)
|
||||
ssh_access = "--"
|
||||
for service in services:
|
||||
if (service["name"] == "ssh"):
|
||||
ssh_access = "ssh -p " + str(service["public_port"]) +\
|
||||
" root@x.x.x.x"
|
||||
break
|
||||
"""
|
||||
ws_list = []
|
||||
ws_list.append({"local_port": "LR",
|
||||
"service_url": "https://" + ws_en.dns + "." + ws_en.zone})
|
||||
|
||||
for ws in webservices:
|
||||
if ws_en.board_uuid == ws.board_uuid:
|
||||
|
@ -93,8 +107,10 @@ class IndexView(tables.DataTableView):
|
|||
|
||||
ws_en.uuid = ws.uuid
|
||||
|
||||
board = iotronic.board_get(self.request, ws_en.board_uuid, None)
|
||||
# board = iotronic.board_get(self.request, ws_en.board_uuid, None)
|
||||
ws_en.name = board.name
|
||||
ws_en.status = board.status
|
||||
# ws_en.ssh = ssh_access
|
||||
ws_en._info.update(dict(webservices=ws_list))
|
||||
|
||||
return en_webservices
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
|
||||
from openstack_dashboard.api import iotronic
|
||||
# from iotronic_ui.api import iotronic
|
||||
# from openstack_dashboard import policy
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EnableWebServiceForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
dns = forms.CharField(label=_("Domain Name Server"))
|
||||
|
||||
# zone = forms.CharField(label=_("Zone"))
|
||||
zones_list = forms.ChoiceField(
|
||||
label=_("Zones List"),
|
||||
help_text=_("Select a zone from the list")
|
||||
)
|
||||
|
||||
email = forms.CharField(label=_("Email"))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(EnableWebServiceForm, self).__init__(*args, **kwargs)
|
||||
|
||||
zone_choices = kwargs["initial"]["zones_list"]
|
||||
self.fields["zones_list"].choices = zone_choices
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
try:
|
||||
iotronic.webservice_enable(request, data["uuid"],
|
||||
data["dns"], data["zones_list"],
|
||||
data["email"])
|
||||
|
||||
messages.success(request, _("Web Service enabled on device " + str(data["name"]) + "."))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to enable web service."
|
||||
exceptions.handle(request, _(message_text))
|
||||
|
||||
|
||||
class DisableWebServiceForm(forms.SelfHandlingForm):
|
||||
|
||||
uuid = forms.CharField(label=_("Device ID"), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(
|
||||
label=_('Device Name'),
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DisableWebServiceForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def handle(self, request, data):
|
||||
|
||||
try:
|
||||
iotronic.webservice_disable(request, data["uuid"])
|
||||
|
||||
messages.success(request, _("Web Service disabled on device " + str(data["name"]) + "."))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
message_text = "Unable to disable web service."
|
||||
exceptions.handle(request, _(message_text))
|
|
@ -0,0 +1,27 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import horizon
|
||||
from iotronic_ui.iot import dashboard
|
||||
|
||||
|
||||
class WebServicesDevices(horizon.Panel):
|
||||
name = _("Devices")
|
||||
slug = "webservices_devices"
|
||||
|
||||
|
||||
dashboard.Iot.register(WebServicesDevices)
|
|
@ -0,0 +1,117 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
from django import template
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
# from django.utils.translation import ungettext_lazy
|
||||
|
||||
from horizon import tables
|
||||
|
||||
from openstack_dashboard import api
|
||||
# from iotronic_ui import api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DeviceFilterAction(tables.FilterAction):
|
||||
|
||||
# If uncommented it will appear the select menu list of fields
|
||||
# and filter button
|
||||
"""
|
||||
filter_type = "server"
|
||||
filter_choices = (("name", _("Device Name ="), True),
|
||||
("type", _("Type ="), True),
|
||||
("status", _("Status ="), True))
|
||||
"""
|
||||
|
||||
def filter(self, table, devices, filter_string):
|
||||
"""Naive case-insensitive search."""
|
||||
q = filter_string.lower()
|
||||
return [device for device in devices
|
||||
if q in device.name.lower()]
|
||||
|
||||
|
||||
def show_services(device_info):
|
||||
template_name = 'iot/webservices_devices/_cell_services.html'
|
||||
context = device_info._info
|
||||
# LOG.debug("CONTEXT: %s", context)
|
||||
return template.loader.render_to_string(template_name,
|
||||
context)
|
||||
|
||||
|
||||
class EnableWebServiceLink(tables.LinkAction):
|
||||
name = "enablewebservice"
|
||||
verbose_name = _("Enable Web Services Manager")
|
||||
url = "horizon:iot:webservices_devices:enablewebservice"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class DisableWebServiceLink(tables.LinkAction):
|
||||
name = "disablewebservice"
|
||||
verbose_name = _("Disable Web Services Manager")
|
||||
url = "horizon:iot:webservices_devices:disablewebservice"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
|
||||
class RestoreServices(tables.BatchAction):
|
||||
name = "restoreservices"
|
||||
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
return u"Restore ALL Services"
|
||||
|
||||
@staticmethod
|
||||
def action_past(count):
|
||||
return u"Restored ALL Services"
|
||||
|
||||
def allowed(self, request, device=None):
|
||||
return True
|
||||
|
||||
def action(self, request, device_id):
|
||||
api.iotronic.restore_services(request, device_id)
|
||||
|
||||
|
||||
class DevicesTable(tables.DataTable):
|
||||
name = tables.WrappingColumn('name',
|
||||
link="horizon:iot:webservices_devices:detail",
|
||||
verbose_name=_('Device Name'))
|
||||
type = tables.Column('type', verbose_name=_('Type'))
|
||||
# mobile = tables.Column('mobile', verbose_name=_('Mobile'))
|
||||
lr_version = tables.Column('lr_version', verbose_name=_('LR version'))
|
||||
# fleet = tables.Column('fleet', verbose_name=_('Fleet ID'))
|
||||
fleet_name = tables.Column('fleet_name', verbose_name=_('Fleet Name'))
|
||||
# code = tables.Column('code', verbose_name=_('Code'))
|
||||
status = tables.Column('status', verbose_name=_('Status'))
|
||||
uuid = tables.Column('uuid', verbose_name=_('Device ID'))
|
||||
# location = tables.Column('location', verbose_name=_('Geo'))
|
||||
services = tables.Column(show_services, verbose_name=_('SSH Access'))
|
||||
# extra = tables.Column('extra', verbose_name=_('Extra'))
|
||||
|
||||
# Overriding get_object_id method because in IoT service the "id" is
|
||||
# identified by the field UUID
|
||||
def get_object_id(self, datum):
|
||||
return datum.uuid
|
||||
|
||||
class Meta(object):
|
||||
name = "devices"
|
||||
verbose_name = _("devices")
|
||||
row_actions = (RestoreServices, EnableWebServiceLink,
|
||||
DisableWebServiceLink)
|
||||
table_actions = (DeviceFilterAction,)
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2017-2019 MDSLAB - University of Messina All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
author = "Carmelo Romeo <carmelo.romeo85@gmail.com>"
|
||||
|
||||
import logging
|
||||
|
||||
# from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import tabs
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OverviewTab(tabs.Tab):
|
||||
name = _("Overview")
|
||||
slug = "overview"
|
||||
template_name = ("iot/webservices_devices/_detail_overview.html")
|
||||
|
||||
def get_context_data(self, request):
|
||||
|
||||
coordinates = self.tab_group.kwargs['device'].__dict__['location'][0]
|
||||
ports = self.tab_group.kwargs['device']._info['ports']
|
||||
services = self.tab_group.kwargs['device']._info['services']
|
||||
webservices = self.tab_group.kwargs['device']._info['webservices']
|
||||
plugins = self.tab_group.kwargs['device']._info['plugins']
|
||||
|
||||
return {"device": self.tab_group.kwargs['device'],
|
||||
"coordinates": coordinates,
|
||||
"services": services,
|
||||
"webservices": webservices,
|
||||
"ports": ports,
|
||||
"plugins": plugins,
|
||||
"is_superuser": request.user.is_superuser}
|
||||
|
||||
|
||||
class DeviceDetailTabs(tabs.TabGroup):
|
||||
slug = "device_details"
|
||||
# tabs = (OverviewTab, LogTab, ConsoleTab, AuditTab)
|
||||
tabs = (OverviewTab,)
|
||||
sticky = True
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue