Code cleaned after Vancouver Demo

Change-Id: I9746ec6bec06f8edf2e1b01a320ca3bfab780980
This commit is contained in:
Carmelo Romeo 2018-05-25 15:32:52 +02:00
parent 081b93987b
commit d8547deb54
46 changed files with 888 additions and 770 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
.tox
.idea
iotronic_ui.egg-info
build
*.pyc
AUTHORS
Authors
ChangeLog

View File

@ -1,85 +0,0 @@
Metadata-Version: 1.1
Name: iotronic-ui
Version: 0.0.0
Summary: Iotronic plugin for the OpenStack Dashboard
Home-page: http://www.openstack.org/
Author: OpenStack
Author-email: openstack-dev@lists.openstack.org
License: UNKNOWN
Description: ===============================
IoTronic Panels
===============================
Iotronic plugin for the OpenStack Dashboard
* Free software: Apache license
* Source: http://git.openstack.org/cgit/openstack/iotronic_ui
* Bugs: http://bugs.launchpad.net/None
Features
--------
* TODO
Enabling in DevStack
--------------------
Add this repo as an external repository into your ``local.conf`` file::
[[local|localrc]]
enable_plugin iotronic_ui https://github.com/openstack/iotronic_ui
Manual Installation
-------------------
Begin by cloning the Horizon and IoTronic Panels repositories::
git clone https://github.com/openstack/horizon
git clone https://github.com/openstack/iotronic_ui
Create a virtual environment and install Horizon dependencies::
cd horizon
python tools/install_venv.py
Set up your ``local_settings.py`` file::
cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py
Open up the copied ``local_settings.py`` file in your preferred text
editor. You will want to customize several settings:
- ``OPENSTACK_HOST`` should be configured with the hostname of your
OpenStack server. Verify that the ``OPENSTACK_KEYSTONE_URL`` and
``OPENSTACK_KEYSTONE_DEFAULT_ROLE`` settings are correct for your
environment. (They should be correct unless you modified your
OpenStack server to change them.)
Install IoTronic Panels with all dependencies in your virtual environment::
tools/with_venv.sh pip install -e ../iotronic_ui/
And enable it in Horizon::
ln -s ../iotronic_ui/iotronic_ui/enabled/_90_project_iot_panelgroup.py openstack_dashboard/local/enabled
ln -s ../iotronic_ui/iotronic_ui/enabled/_91_project_iot_boardss_panel.py openstack_dashboard/local/enabled
To run horizon with the newly enabled IoTronic Panels plugin run::
./run_tests.sh --runserver 0.0.0.0:8080
to have the application start on port 8080 and the horizon dashboard will be
available in your browser at http://localhost:8080/
Platform: UNKNOWN
Classifier: Environment :: OpenStack
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5

View File

@ -1,88 +0,0 @@
CONTRIBUTING.rst
HACKING.rst
LICENSE
MANIFEST.in
README.rst
babel-django.cfg
babel-djangojs.cfg
manage.py
package.json
requirements.txt
setup.cfg
setup.py
test-requirements.txt
test-shim.js
tox.ini
doc/Makefile
doc/source/conf.py
doc/source/index.rst
doc/source/configuration/index.rst
doc/source/contributor/api.rst
doc/source/contributor/index.rst
doc/source/install/index.rst
iotronic_ui/__init__.py
iotronic_ui.egg-info/PKG-INFO
iotronic_ui.egg-info/SOURCES.txt
iotronic_ui.egg-info/dependency_links.txt
iotronic_ui.egg-info/not-zip-safe
iotronic_ui.egg-info/pbr.json
iotronic_ui.egg-info/requires.txt
iotronic_ui.egg-info/top_level.txt
iotronic_ui/api/iotronic.py
iotronic_ui/enabled/_6000_iot.py
iotronic_ui/enabled/_6010_iot_boards_panel.py
iotronic_ui/enabled/_6020_iot_plugins_panel.py
iotronic_ui/iot/__init__.py
iotronic_ui/iot/dashboard.py
iotronic_ui/iot/boards/__init__.py
iotronic_ui/iot/boards/forms.py
iotronic_ui/iot/boards/panel.py
iotronic_ui/iot/boards/tables.py
iotronic_ui/iot/boards/tabs.py
iotronic_ui/iot/boards/tests.py
iotronic_ui/iot/boards/urls.py
iotronic_ui/iot/boards/views.py
iotronic_ui/iot/boards/templates/boards/_create.html
iotronic_ui/iot/boards/templates/boards/_detail_overview.html
iotronic_ui/iot/boards/templates/boards/_removeplugins.html
iotronic_ui/iot/boards/templates/boards/_update.html
iotronic_ui/iot/boards/templates/boards/create.html
iotronic_ui/iot/boards/templates/boards/index.html
iotronic_ui/iot/boards/templates/boards/removeplugins.html
iotronic_ui/iot/boards/templates/boards/update.html
iotronic_ui/iot/plugins/__init__.py
iotronic_ui/iot/plugins/forms.py
iotronic_ui/iot/plugins/panel.py
iotronic_ui/iot/plugins/tables.py
iotronic_ui/iot/plugins/tabs.py
iotronic_ui/iot/plugins/tests.py
iotronic_ui/iot/plugins/urls.py
iotronic_ui/iot/plugins/views.py
iotronic_ui/iot/plugins/templates/plugins/_call.html
iotronic_ui/iot/plugins/templates/plugins/_create.html
iotronic_ui/iot/plugins/templates/plugins/_detail_overview.html
iotronic_ui/iot/plugins/templates/plugins/_inject.html
iotronic_ui/iot/plugins/templates/plugins/_remove.html
iotronic_ui/iot/plugins/templates/plugins/_start.html
iotronic_ui/iot/plugins/templates/plugins/_stop.html
iotronic_ui/iot/plugins/templates/plugins/_update.html
iotronic_ui/iot/plugins/templates/plugins/call.html
iotronic_ui/iot/plugins/templates/plugins/create.html
iotronic_ui/iot/plugins/templates/plugins/index.html
iotronic_ui/iot/plugins/templates/plugins/inject.html
iotronic_ui/iot/plugins/templates/plugins/remove.html
iotronic_ui/iot/plugins/templates/plugins/start.html
iotronic_ui/iot/plugins/templates/plugins/stop.html
iotronic_ui/iot/plugins/templates/plugins/update.html
iotronic_ui/iot/static/iot/images/blue-circle.png
iotronic_ui/iot/static/iot/images/green-circle.png
iotronic_ui/iot/static/iot/images/marker-icon-green.png
iotronic_ui/iot/static/iot/images/marker-icon-red.png
iotronic_ui/iot/static/iot/images/marker-icon.png
iotronic_ui/iot/static/iot/images/marker-shadow.png
iotronic_ui/iot/static/iot/images/red-circle.png
iotronic_ui/iot/static/iot/js/iot.js
iotronic_ui/iot/static/iot/scss/iot.scss
iotronic_ui/iot/templates/iot/base.html
tools/tox_install.sh
tools/tox_install.sh_ORIG

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@
{"git_version": "4902c1d", "is_release": false}

View File

@ -1,6 +0,0 @@
pbr!=2.1.0,>=2.0.0
Babel!=2.4.0,>=2.3.4
Django<2.0,>=1.8
django-babel>=0.5.1
django-compressor>=2.0
django-pyscss>=2.0.2

View File

@ -1 +0,0 @@
iotronic_ui

View File

@ -43,14 +43,12 @@ def iotronicclient(request):
# BOARD MANAGEMENT
def board_list(request, status=None, detail=None, project=None):
"""List boards."""
boards = iotronicclient(request).board.list(status, detail, project)
return boards
return iotronicclient(request).board.list(status, detail, project)
def board_get(request, board_id, fields):
"""Get board info."""
board = iotronicclient(request).board.get(board_id, fields)
return board
return iotronicclient(request).board.get(board_id, fields)
def board_create(request, code, mobile, location, type, name):
@ -60,30 +58,26 @@ def board_create(request, code, mobile, location, type, name):
"location": location,
"type": type,
"name": name}
board = iotronicclient(request).board.create(**params)
return board
iotronicclient(request).board.create(**params)
def board_update(request, board_id, patch):
"""Update board."""
board = iotronicclient(request).board.update(board_id, patch)
return board
iotronicclient(request).board.update(board_id, patch)
def board_delete(request, board_id):
"""Delete board."""
board = iotronicclient(request).board.delete(board_id)
return board
iotronicclient(request).board.delete(board_id)
# PLUGIN MANAGEMENT (Cloud Side)
def plugin_list(request, detail=None, project=None, with_public=False,
all_plugins=False):
"""List plugins."""
plugins = iotronicclient(request).plugin.list(detail, project, \
with_public=with_public, \
all_plugins=all_plugins)
return plugins
return iotronicclient(request).plugin.list(detail, project,
with_public=with_public,
all_plugins=all_plugins)
def plugin_get(request, plugin_id, fields):
@ -99,53 +93,43 @@ def plugin_create(request, name, public, callable, code, parameters):
"callable": callable,
"code": code,
"parameters": parameters}
plugin = iotronicclient(request).plugin.create(**params)
return plugin
iotronicclient(request).plugin.create(**params)
def plugin_update(request, plugin_id, patch):
"""Update plugin."""
plugin = iotronicclient(request).plugin.update(plugin_id, patch)
return plugin
iotronicclient(request).plugin.update(plugin_id, patch)
def plugin_delete(request, plugin_id):
"""Delete plugin."""
plugin = iotronicclient(request).plugin.delete(plugin_id)
return plugin
return iotronicclient(request).plugin.delete(plugin_id)
# PLUGIN MANAGEMENT (Board Side)
def plugin_inject(request, board_id, plugin_id, onboot):
"""Inject plugin on board(s)."""
plugin = iotronicclient(request).plugin_injection. \
plugin_inject(board_id, \
plugin_id, \
onboot)
return plugin
return iotronicclient(request).plugin_injection.plugin_inject(board_id,
plugin_id,
onboot)
def plugin_action(request, board_id, plugin_id, action, params={}):
"""Start/Stop/Call actions on board(s)."""
plugin = iotronicclient(request).plugin_injection. \
plugin_action(board_id,
plugin_id,
action,
params)
return plugin
return iotronicclient(request).plugin_injection.plugin_action(
board_id, plugin_id, action, params)
def plugin_remove(request, board_id, plugin_id):
"""Inject plugin on board(s)."""
plugin = iotronicclient(request).plugin_injection. \
plugin_remove(board_id, plugin_id)
return plugin
"""Remove plugin from board."""
iotronicclient(request).plugin_injection.plugin_remove(board_id,
plugin_id)
def plugins_on_board(request, board_id):
"""Plugins on board."""
plugins = iotronicclient(request).plugin_injection. \
plugins_on_board(board_id)
plugins = iotronicclient(request).plugin_injection.plugins_on_board(
board_id)
detailed_plugins = []
# fields = {"name", "public", "callable"}
@ -161,14 +145,12 @@ def plugins_on_board(request, board_id):
# SERVICE MANAGEMENT
def service_list(request, detail=None):
"""List services."""
services = iotronicclient(request).service.list(detail)
return services
return iotronicclient(request).service.list(detail)
def service_get(request, service_id, fields):
"""Get service info."""
service = iotronicclient(request).service.get(service_id, fields)
return service
return iotronicclient(request).service.get(service_id, fields)
def service_create(request, name, port, protocol):
@ -176,36 +158,34 @@ def service_create(request, name, port, protocol):
params = {"name": name,
"port": port,
"protocol": protocol}
service = iotronicclient(request).service.create(**params)
return service
iotronicclient(request).service.create(**params)
def service_update(request, service_id, patch):
"""Update service."""
service = iotronicclient(request).service.update(service_id, patch)
return service
iotronicclient(request).service.update(service_id, patch)
def service_delete(request, service_id):
"""Delete service."""
service = iotronicclient(request).service.delete(service_id)
return service
iotronicclient(request).service.delete(service_id)
def services_on_board(request, board_id, detail=False):
"""List services on board."""
services = iotronicclient(request).exposed_service \
.services_on_board(board_id)
services = iotronicclient(request).exposed_service.services_on_board(
board_id)
if detail:
detailed_services = []
fields = {"name", "port", "protocol"}
for service in services:
details = iotronicclient(request). \
service.get(service._info["service"], fields)
details = iotronicclient(request).service.get(
service._info["service"], fields)
detailed_services.append({"name": details._info["name"],
detailed_services.append({"uuid": service._info["service"],
"name": details._info["name"],
"public_port":
service._info["public_port"],
"port": details._info["port"],
@ -219,14 +199,29 @@ def services_on_board(request, board_id, detail=False):
def service_action(request, board_id, service_id, action):
"""Action on service."""
service_action = iotronicclient(request).exposed_service. \
service_action(board_id, service_id, action)
return service_action
return iotronicclient(request).exposed_service.service_action(board_id,
service_id,
action)
def restore_services(request, board_id):
"""Restore services."""
service_restore = iotronicclient(request).exposed_service. \
restore_services(board_id)
return service_restore
return iotronicclient(request).exposed_service.restore_services(board_id)
# PORTS MANAGEMENT
def port_list(request, board_id):
"""Get ports attached to a board."""
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,
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)

View File

@ -67,12 +67,13 @@ class CreateBoardForm(forms.SelfHandlingForm):
"longitude": str(data["longitude"]),
"altitude": str(data["altitude"])}]
board = iotronic.board_create(request, data["code"],
data["mobile"], data["location"],
data["type"], data["name"])
messages.success(request, _("Board created successfully."))
iotronic.board_create(request, data["code"],
data["mobile"], data["location"],
data["type"], data["name"])
messages.success(request, _("Board created successfully."))
return True
return board
except Exception:
exceptions.handle(request, _('Unable to create board.'))
@ -82,49 +83,54 @@ class UpdateBoardForm(forms.SelfHandlingForm):
name = forms.CharField(label=_("Board Name"))
mobile = forms.BooleanField(label=_("Mobile"), required=False)
"""
latitude = forms.FloatField(label=_("Latitude"))
longitude = forms.FloatField(label=_("Longitude"))
altitude = forms.FloatField(label=_("Altitude"))
"""
def __init__(self, *args, **kwargs):
super(UpdateBoardForm, self).__init__(*args, **kwargs)
# LOG.debug("MELO INITIAL: %s", kwargs["initial"])
# LOG.debug("INITIAL: %s", kwargs["initial"])
LOG.debug("MELO Manager: %s", policy.check((("iot", "iot_manager"),),
self.request))
LOG.debug("MELO Admin: %s", policy.check((("iot", "iot_admin"),),
self.request))
# LOG.debug("Manager: %s", policy.check((("iot", "iot_manager"),),
# self.request))
# LOG.debug("Admin: %s", policy.check((("iot", "iot_admin"),),
# self.request))
# Admin
if policy.check((("iot", "iot:update_boards"),), self.request):
# LOG.debug("MELO ADMIN")
# 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("MELO NO-edit IOT ADMIN")
# LOG.debug("NO-edit IOT ADMIN")
pass
# Other users
else:
if self.request.user.id != kwargs["initial"]["owner"]:
# LOG.debug("MELO IMMUTABLE FIELDS")
# LOG.debug("IMMUTABLE FIELDS")
self.fields["name"].widget.attrs = {'readonly': 'readonly'}
self.fields["mobile"].widget.attrs = {'disabled': 'disabled'}
"""
self.fields["latitude"].widget.attrs = {'readonly':
'readonly'}
self.fields["longitude"].widget.attrs = {'readonly':
'readonly'}
self.fields["altitude"].widget.attrs = {'readonly':
'readonly'}
"""
def handle(self, request, data):
try:
"""
data["location"] = [{"latitude": str(data["latitude"]),
"longitude": str(data["longitude"]),
"altitude": str(data["altitude"])}]
@ -132,13 +138,196 @@ class UpdateBoardForm(forms.SelfHandlingForm):
{"name": data["name"],
"mobile": data["mobile"],
"location": data["location"]})
"""
iotronic.board_update(request, data["uuid"],
{"name": data["name"],
"mobile": data["mobile"]})
messages.success(request, _("Board updated successfully."))
return True
except Exception:
exceptions.handle(request, _('Unable to update board.'))
class EnableServiceForm(forms.SelfHandlingForm):
uuid = forms.CharField(label=_("Plugin ID"), widget=forms.HiddenInput)
name = forms.CharField(
label=_('Board 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=_("Plugin ID"), widget=forms.HiddenInput)
name = forms.CharField(
label=_('Board 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))
class AttachPortForm(forms.SelfHandlingForm):
uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
name = forms.CharField(
label=_('Board 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 board " + str(data["name"]) + \
" completed successfully"
messages.success(request, _(message_text))
return True
except Exception:
message_text = "Unable to attach port on board " + \
str(data["name"])
exceptions.handle(request, _(message_text))
class DetachPortForm(forms.SelfHandlingForm):
uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
name = forms.CharField(
label=_('Board 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 board " + \
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 board " + str(data["name"])
exceptions.handle(request, _(message_text))
class RemovePluginsForm(forms.SelfHandlingForm):
uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
@ -159,11 +348,7 @@ class RemovePluginsForm(forms.SelfHandlingForm):
super(RemovePluginsForm, self).__init__(*args, **kwargs)
# input=kwargs.get('initial',{})
boardslist_length = len(kwargs["initial"]["board_list"])
self.fields["plugin_list"].choices = kwargs["initial"]["plugin_list"]
self.fields["plugin_list"].max_length = boardslist_length
def handle(self, request, data):
@ -174,13 +359,8 @@ class RemovePluginsForm(forms.SelfHandlingForm):
if key == plugin:
try:
board = None
iotronic.plugin_remove(request, data["uuid"], key)
# LOG.debug('INJECT: %s %s', plugin, value)
# board = iotronic.plugin_create(request, data["name"],
# data["public"],
# data["callable"],
# data["code"])
message_text = "Plugin " + str(value) + \
" removed successfully."
messages.success(request, _(message_text))
@ -188,10 +368,64 @@ class RemovePluginsForm(forms.SelfHandlingForm):
if counter != len(data["plugin_list"]) - 1:
counter += 1
else:
return board
return True
except Exception:
message_text = "Unable to remove plugin " \
+ str(value) + "."
exceptions.handle(request, _(message_text))
break
class RemoveServicesForm(forms.SelfHandlingForm):
uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
name = forms.CharField(
label=_('Board Name'),
widget=forms.TextInput(attrs={'readonly': 'readonly'})
)
service_list = forms.MultipleChoiceField(
label=_("Services List"),
widget=forms.SelectMultiple(
attrs={'class': 'switchable',
'data-slug': 'slug-remove-services'}),
help_text=_("Select services in this pool")
)
def __init__(self, *args, **kwargs):
super(RemoveServicesForm, self).__init__(*args, **kwargs)
# input=kwargs.get('initial',{})
self.fields["service_list"].choices = kwargs["initial"]["service_list"]
def handle(self, request, data):
counter = 0
for service in data["service_list"]:
for key, value in self.fields["service_list"].choices:
if key == service:
try:
disable = iotronic.service_action(request,
data["uuid"],
key,
"ServiceDisable")
message_text = disable
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 " \
+ str(value) + "."
exceptions.handle(request, _(message_text))
break

View File

@ -15,6 +15,7 @@ from django.utils.translation import ugettext_lazy as _
import horizon
# from openstack_dashboard.api import keystone
from iotronic_ui.iot import dashboard
class Boards(horizon.Panel):
@ -31,3 +32,6 @@ class Boards(horizon.Panel):
return False
return super(Roles, self).can_access(context)
"""
dashboard.Iot.register(Boards)

View File

@ -64,13 +64,56 @@ class RestoreServices(tables.BatchAction):
api.iotronic.restore_services(request, board_id)
class EnableServiceLink(tables.LinkAction):
name = "enableservice"
verbose_name = _("Enable Service(s)")
url = "horizon:iot:boards: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:boards:disableservice"
classes = ("ajax-modal",)
# icon = "plus"
# policy_rules = (("iot", "iot:service_action"),)
class RemovePluginsLink(tables.LinkAction):
name = "removeplugins"
verbose_name = _("Remove Plugin(s)")
url = "horizon:iot:boards:removeplugins"
classes = ("ajax-modal",)
icon = "plus"
# policy_rules = (("iot", "iot:create_board"),)
# policy_rules = (("iot", "iot:remove_plugins"),)
class RemoveServicesLink(tables.LinkAction):
name = "removeservices"
verbose_name = _("Remove Service(s)")
url = "horizon:iot:boards:removeservices"
classes = ("ajax-modal",)
icon = "plus"
# policy_rules = (("iot", "iot:remove_services"),)
class AttachPortLink(tables.LinkAction):
name = "attachport"
verbose_name = _("Attach Port")
url = "horizon:iot:boards:attachport"
classes = ("ajax-modal",)
icon = "plus"
class DetachPortLink(tables.LinkAction):
name = "detachport"
verbose_name = _("Detach Port")
url = "horizon:iot:boards:detachport"
classes = ("ajax-modal",)
icon = "plus"
class DeleteBoardsAction(tables.DeleteAction):
@ -117,6 +160,7 @@ class BoardFilterAction(tables.FilterAction):
return [board for board in boards
if q in board.name.lower()]
def show_services(board_info):
template_name = 'iot/boards/_cell_services.html'
context = board_info._info
@ -145,7 +189,9 @@ class BoardsTable(tables.DataTable):
class Meta(object):
name = "boards"
verbose_name = _("boards")
row_actions = (EditBoardLink, RestoreServices,
RemovePluginsLink, DeleteBoardsAction)
table_actions = (BoardFilterAction, CreateBoardLink,
RestoreServices, DeleteBoardsAction)
row_actions = (EditBoardLink, EnableServiceLink, DisableServiceLink,
RestoreServices, AttachPortLink, DetachPortLink,
RemovePluginsLink, RemoveServicesLink,
DeleteBoardsAction)
table_actions = (BoardFilterAction, CreateBoardLink,
DeleteBoardsAction)

View File

@ -21,7 +21,7 @@ LOG = logging.getLogger(__name__)
"""
import inspect
LOG.debug('MELO CLASSES: %s',
LOG.debug('CLASSES: %s',
inspect.getmembers(tabs, predicate=inspect.isclass))
"""
@ -34,12 +34,14 @@ class OverviewTab(tabs.Tab):
def get_context_data(self, request):
coordinates = self.tab_group.kwargs['board'].__dict__['location'][0]
ports = self.tab_group.kwargs['board']._info['ports']
services = self.tab_group.kwargs['board']._info['services']
plugins = self.tab_group.kwargs['board']._info['plugins']
return {"board": self.tab_group.kwargs['board'],
"coordinates": coordinates,
"services": services,
"ports": ports,
"plugins": plugins,
"is_superuser": request.user.is_superuser}

View File

@ -0,0 +1,8 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% block modal-body-right %}
<h3>{% trans "Description:" %}</h3>
<p>{% trans "Attach port to the selected board." %}</p>
{% endblock %}

View File

@ -0,0 +1,8 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% block modal-body-right %}
<h3>{% trans "Description:" %}</h3>
<p>{% trans "Detach one or more attached ports from the board." %}</p>
{% endblock %}

View File

@ -22,26 +22,50 @@
<dd>{{ board.mobile }}</dd>
<dt>{% trans "Extra" %}</dt>
<dd>{{ board.extra }}</dd>
<dt>{% trans "Services" %}</dt>
{% if services %}
</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 %}
<dd>{{ service.name }} [{{ service.protocol }}] {{ service.port }} --> {{ service.public_port }}</dd>
<dt>{{ service.name }} [{{ service.protocol }}] {{ service.port }}</dt>
<dd>{{ service.public_port }}</dd>
{% endfor %}
{% else %}
{% else %}
<dd>--</dd>
{% endif %}
<dt>{% trans "Plugins" %}</dt>
{% if plugins %}
{% for plugin in plugins %}
<dd>{{ plugin.name }}</dd>
{% endfor %}
{% else %}
<dd>--</dd>
{% endif %}
{% 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(){
@ -64,4 +88,4 @@
});
</script>
</div>
-->

View File

@ -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 board." %}</p>
{% endblock %}

View File

@ -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 board." %}</p>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Attach" %}{% endblock %}
{% block main %}
{% include 'iot/boards/_attachport.html' %}
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Detach" %}{% endblock %}
{% block main %}
{% include 'iot/boards/_detachport.html' %}
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Disable" %}{% endblock %}
{% block main %}
{% include 'iot/boards/_disableservice.html' %}
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Enable" %}{% endblock %}
{% block main %}
{% include 'iot/boards/_enableservice.html' %}
{% endblock %}

View File

@ -3,5 +3,5 @@
{% block title %}{% trans "Remove service(s)." %}{% endblock %}
{% block main %}
{% include 'iot/services/_remove.html' %}
{% include 'iot/boards/_removeservices.html' %}
{% endblock %}

View File

@ -22,6 +22,16 @@ urlpatterns = [
name='update'),
url(r'^(?P<board_id>[^/]+)/removeplugins/$',
views.RemovePluginsView.as_view(), name='removeplugins'),
url(r'^(?P<board_id>[^/]+)/removeservices/$',
views.RemoveServicesView.as_view(), name='removeservices'),
url(r'^(?P<board_id>[^/]+)/enableservice/$',
views.EnableServiceView.as_view(), name='enableservice'),
url(r'^(?P<board_id>[^/]+)/disableservice/$',
views.DisableServiceView.as_view(), name='disableservice'),
url(r'^(?P<board_id>[^/]+)/attachport/$',
views.AttachPortView.as_view(), name='attachport'),
url(r'^(?P<board_id>[^/]+)/detachport/$',
views.DetachPortView.as_view(), name='detachport'),
url(r'^(?P<board_id>[^/]+)/detail/$', views.BoardDetailView.as_view(),
name='detail'),
]

View File

@ -23,7 +23,8 @@ from horizon import tables
from horizon import tabs
from horizon.utils import memoized
from openstack_dashboard.api import iotronic
# from openstack_dashboard.api import iotronic
from openstack_dashboard import api
from openstack_dashboard import policy
from iotronic_ui.iot.boards import forms as project_forms
@ -42,25 +43,10 @@ class IndexView(tables.DataTableView):
def get_data(self):
boards = []
# FROM
"""
if policy.check((("identity", "identity:list_roles"),), self.request):
try:
boards = iotronic.board_list(self.request, None, None)
# LOG.debug('IOT BOARDS: %s', boards)
except Exception:
exceptions.handle(self.request,
_('Unable to retrieve boards list.'))
else:
msg = _("Insufficient privilege level to view boards information.")
messages.info(self.request, msg)
"""
# TO
# Admin
if policy.check((("iot", "iot:list_all_boards"),), self.request):
try:
boards = iotronic.board_list(self.request, None, None)
boards = api.iotronic.board_list(self.request, None, None)
except Exception:
exceptions.handle(self.request,
@ -69,7 +55,7 @@ class IndexView(tables.DataTableView):
# Admin_iot_project
elif policy.check((("iot", "iot:list_project_boards"),), self.request):
try:
boards = iotronic.board_list(self.request, None, None)
boards = api.iotronic.board_list(self.request, None, None)
except Exception:
exceptions.handle(self.request,
@ -78,14 +64,16 @@ class IndexView(tables.DataTableView):
# Other users
else:
try:
boards = iotronic.board_list(self.request, None, None)
boards = api.iotronic.board_list(self.request, None, None)
except Exception:
exceptions.handle(self.request,
_('Unable to retrieve user boards list.'))
for board in boards:
board_services = iotronic.services_on_board(self.request, board.uuid, True)
board_services = api.iotronic.services_on_board(self.request,
board.uuid,
True)
# board.__dict__.update(dict(services=board_services))
board._info.update(dict(services=board_services))
@ -116,8 +104,9 @@ class UpdateView(forms.ModalFormView):
@memoized.memoized_method
def get_object(self):
try:
return iotronic.board_get(self.request, self.kwargs['board_id'],
None)
return api.iotronic.board_get(self.request,
self.kwargs['board_id'],
None)
except Exception:
redirect = reverse("horizon:iot:boards:index")
exceptions.handle(self.request,
@ -143,12 +132,226 @@ class UpdateView(forms.ModalFormView):
'altitude': location["altitude"]}
class EnableServiceView(forms.ModalFormView):
template_name = 'iot/boards/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:boards:enableservice")
submit_url = "horizon:iot:boards:enableservice"
success_url = reverse_lazy('horizon:iot:boards:index')
page_title = _("Action")
@memoized.memoized_method
def get_object(self):
try:
return api.iotronic.board_get(self.request,
self.kwargs['board_id'],
None)
except Exception:
redirect = reverse("horizon:iot:boards:index")
exceptions.handle(self.request,
_('Unable to get board 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):
board = self.get_object()
# Populate available services
cloud_services = api.iotronic.service_list(self.request, None)
board_services = api.iotronic.services_on_board(self.request,
board.uuid,
True)
service_list = []
for cloud_service in cloud_services:
if len(board_services) == 0:
service_list.append((cloud_service._info["uuid"],
_(cloud_service._info["name"])))
else:
counter = 0
for board_service in board_services:
if board_service["uuid"] == cloud_service._info["uuid"]:
break
elif counter != len(board_services) - 1:
counter += 1
else:
service_list.append((cloud_service._info["uuid"],
_(cloud_service._info["name"])))
return {'uuid': board.uuid,
'name': board.name,
'service_list': service_list}
class DisableServiceView(forms.ModalFormView):
template_name = 'iot/boards/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:boards:disableservice")
submit_url = "horizon:iot:boards:disableservice"
success_url = reverse_lazy('horizon:iot:boards:index')
page_title = _("Action")
@memoized.memoized_method
def get_object(self):
try:
return api.iotronic.board_get(self.request,
self.kwargs['board_id'],
None)
except Exception:
redirect = reverse("horizon:iot:boards:index")
exceptions.handle(self.request,
_('Unable to get board 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):
board = self.get_object()
# Populate available services
cloud_services = api.iotronic.service_list(self.request, None)
board_services = api.iotronic.services_on_board(self.request,
board.uuid,
True)
service_list = []
for cloud_service in cloud_services:
for board_service in board_services:
if board_service["uuid"] == cloud_service._info["uuid"]:
service_list.append((cloud_service._info["uuid"],
_(cloud_service._info["name"])))
return {'uuid': board.uuid,
'name': board.name,
'service_list': service_list}
class AttachPortView(forms.ModalFormView):
template_name = 'iot/boards/attachport.html'
modal_header = _("Attach")
form_id = "attach_boardport_form"
form_class = project_forms.AttachPortForm
submit_label = _("Attach")
# submit_url = reverse_lazy("horizon:iot:boards:attachport")
submit_url = "horizon:iot:boards:attachport"
success_url = reverse_lazy('horizon:iot:boards:index')
page_title = _("Attach port")
@memoized.memoized_method
def get_object(self):
try:
return api.iotronic.board_get(self.request,
self.kwargs['board_id'],
None)
except Exception:
redirect = reverse("horizon:iot:boards:index")
exceptions.handle(self.request,
_('Unable to get board 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):
board = self.get_object()
# Populate networks
networks = api.neutron.network_list(self.request)
net_choices = []
for net in networks:
for subnet in net["subnets"]:
net_choices.append((net["id"] + ':' + subnet["id"],
_(net["name"] + ':' + subnet["name"])))
return {'uuid': board.uuid,
'name': board.name,
'networks_list': net_choices}
class DetachPortView(forms.ModalFormView):
template_name = 'iot/boards/detachport.html'
modal_header = _("Detach")
form_id = "detach_boardport_form"
form_class = project_forms.DetachPortForm
submit_label = _("Detach")
# submit_url = reverse_lazy("horizon:iot:boards:detachport")
submit_url = "horizon:iot:boards:detachport"
success_url = reverse_lazy('horizon:iot:boards:index')
page_title = _("Detach port")
@memoized.memoized_method
def get_object(self):
try:
return api.iotronic.board_get(self.request,
self.kwargs['board_id'],
None)
except Exception:
redirect = reverse("horizon:iot:boards:index")
exceptions.handle(self.request,
_('Unable to get board 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):
board = self.get_object()
ports = api.iotronic.port_list(self.request, board.uuid)
# TO BE REMOVED (change it once the port_list per board is
# completed and tested !
# ################################################################
# LOG.debug("PORTS: %s", ports)
filtered_ports = []
for port in ports:
if port._info["board_uuid"] == board.uuid:
filtered_ports.append((port._info["uuid"],
_(port._info["ip"])))
ports = filtered_ports
# ################################################################
# Populate board ports
return {'uuid': board.uuid,
'name': board.name,
'ports': ports}
class RemovePluginsView(forms.ModalFormView):
template_name = 'iot/boards/removeplugins.html'
modal_header = _("Remove Plugins from board")
form_id = "remove_boardplugins_form"
form_class = project_forms.RemovePluginsForm
submit_label = _("Remove Plugins from board")
submit_label = _("Remove")
# submit_url = reverse_lazy("horizon:iot:boards:removeplugins")
submit_url = "horizon:iot:boards:removeplugins"
success_url = reverse_lazy('horizon:iot:boards:index')
@ -157,8 +360,9 @@ class RemovePluginsView(forms.ModalFormView):
@memoized.memoized_method
def get_object(self):
try:
return iotronic.board_get(self.request, self.kwargs['board_id'],
None)
return api.iotronic.board_get(self.request,
self.kwargs['board_id'],
None)
except Exception:
redirect = reverse("horizon:iot:boards:index")
exceptions.handle(self.request,
@ -176,49 +380,74 @@ class RemovePluginsView(forms.ModalFormView):
# Populate plugins
# TO BE DONE.....filter by available on this board!!!
# plugins = iotronic.plugin_list(self.request, None, None)
plugins = iotronic.plugins_on_board(self.request, board.uuid)
# plugins = api.iotronic.plugin_list(self.request, None, None)
plugins = api.iotronic.plugins_on_board(self.request, board.uuid)
plugins.sort(key=lambda b: b.name)
plugins.sort(key=lambda b: b["name"])
plugin_list = []
for plugin in plugins:
plugin_list.append((plugin.uuid, _(plugin.name)))
plugin_list.append((plugin["id"], _(plugin["name"])))
return {'uuid': board.uuid,
'name': board.name,
'plugin_list': plugin_list}
class RemoveServicesView(forms.ModalFormView):
template_name = 'iot/boards/removeservices.html'
modal_header = _("Remove Services from board")
form_id = "remove_boardservices_form"
form_class = project_forms.RemoveServicesForm
submit_label = _("Remove")
# submit_url = reverse_lazy("horizon:iot:boards:removeservices")
submit_url = "horizon:iot:boards:removeservices"
success_url = reverse_lazy('horizon:iot:boards:index')
page_title = _("Remove Services from board")
@memoized.memoized_method
def get_object(self):
try:
return api.iotronic.board_get(self.request,
self.kwargs['board_id'],
None)
except Exception:
redirect = reverse("horizon:iot:boards:index")
exceptions.handle(self.request,
_('Unable to get board information.'),
redirect=redirect)
def get_context_data(self, **kwargs):
context = super(RemoveServicesView, 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):
board = self.get_object()
# Populate services
services = api.iotronic.services_on_board(self.request,
board.uuid,
True)
services.sort(key=lambda b: b["name"])
service_list = []
for service in services:
service_list.append((service["uuid"], _(service["name"])))
return {'uuid': board.uuid,
'name': board.name,
'service_list': service_list}
class DetailView(tabs.TabView):
# FROM
"""
tab_group_class = project_tabs.InstanceDetailTabs
template_name = 'horizon/common/_detail.html'
redirect_url = 'horizon:project:instances:index'
page_title = "{{ instance.name|default:instance.id }}"
image_url = 'horizon:project:images:images:detail'
volume_url = 'horizon:project:volumes:volumes:detail'
"""
# TO
tab_group_class = project_tabs.BoardDetailTabs
template_name = 'horizon/common/_detail.html'
page_title = "{{ board.name|default:board.uuid }}"
def get_context_data(self, **kwargs):
context = super(DetailView, self).get_context_data(**kwargs)
# FROM
"""
instance = self.get_data()
if instance.image:
instance.image_url = reverse(self.image_url,
args=[instance.image['id']])
instance.volume_url = self.volume_url
context["instance"] = instance
context["url"] = reverse(self.redirect_url)
context["actions"] = self._get_actions(instance)
"""
# TO
board = self.get_data()
context["board"] = board
context["url"] = reverse(self.redirect_url)
@ -226,94 +455,38 @@ class DetailView(tabs.TabView):
return context
# FROM
"""
def _get_actions(self, instance):
table = project_tables.InstancesTable(self.request)
return table.render_row_actions(instance)
"""
# TO
def _get_actions(self, board):
table = project_tables.BoardsTable(self.request)
return table.render_row_actions(board)
# FROM
"""
@memoized.memoized_method
def get_data(self):
instance_id = self.kwargs['instance_id']
try:
instance = api.nova.server_get(self.request, instance_id)
except Exception:
redirect = reverse(self.redirect_url)
exceptions.handle(self.request,
_('Unable to retrieve details for '
'instance "%s".') % instance_id,
redirect=redirect)
# Not all exception types handled above will result in a redirect.
# Need to raise here just in case.
raise exceptions.Http302(redirect)
choices = project_tables.STATUS_DISPLAY_CHOICES
instance.status_label = (
filters.get_display_label(choices, instance.status))
try:
instance.volumes = api.nova.instance_volumes_list(self.request,
instance_id)
# Sort by device name
instance.volumes.sort(key=lambda vol: vol.device)
except Exception:
msg = _('Unable to retrieve volume list for instance '
'"%(name)s" (%(id)s).') % {'name': instance.name,
'id': instance_id}
exceptions.handle(self.request, msg, ignore=True)
try:
instance.full_flavor = api.nova.flavor_get(
self.request, instance.flavor["id"])
except Exception:
msg = _('Unable to retrieve flavor information for instance '
'"%(name)s" (%(id)s).') % {'name': instance.name,
'id': instance_id}
exceptions.handle(self.request, msg, ignore=True)
try:
instance.security_groups = api.network.server_security_groups(
self.request, instance_id)
except Exception:
msg = _('Unable to retrieve security groups for instance '
'"%(name)s" (%(id)s).') % {'name': instance.name,
'id': instance_id}
exceptions.handle(self.request, msg, ignore=True)
try:
api.network.servers_update_addresses(self.request, [instance])
except Exception:
msg = _('Unable to retrieve IP addresses from Neutron for '
'instance "%(name)s" (%(id)s).') % {'name': instance.name,
'id': instance_id}
exceptions.handle(self.request, msg, ignore=True)
return instance
"""
# TO
@memoized.memoized_method
def get_data(self):
board_id = self.kwargs['board_id']
try:
board_services = []
board_plugins = []
board_ports = []
board = iotronic.board_get(self.request, board_id, None)
board_services = iotronic.services_on_board(self.request, board_id, True)
board = api.iotronic.board_get(self.request, board_id, None)
# FIX this problem with the new APIs
# (remove the "if" clause with a better approach)
# #################################################################
ports = api.iotronic.port_list(self.request, board_id)
for port in ports:
if port._info["board_uuid"] == board_id:
board_ports.append(port._info)
board._info.update(dict(ports=board_ports))
# #################################################################
board_services = api.iotronic.services_on_board(self.request,
board_id, True)
board._info.update(dict(services=board_services))
board_plugins = iotronic.plugins_on_board(self.request, board_id)
board_plugins = api.iotronic.plugins_on_board(self.request,
board_id)
board._info.update(dict(plugins=board_plugins))
# LOG.debug("BOARD: %s\n\n%s", board, board._info)
except Exception:
@ -322,14 +495,6 @@ class DetailView(tabs.TabView):
exceptions.handle(self.request, msg, ignore=True)
return board
# FROM
"""
def get_tabs(self, request, *args, **kwargs):
instance = self.get_data()
return self.tab_group_class(request, instance=instance, **kwargs)
"""
# TO
def get_tabs(self, request, *args, **kwargs):
board = self.get_data()
return self.tab_group_class(request, board=board, **kwargs)

View File

@ -23,4 +23,5 @@ class Iot(horizon.Dashboard):
# Specify the slug of the dashboard's default panel.
default_panel = 'boards'
horizon.register(Iot)

View File

@ -68,18 +68,17 @@ class CreatePluginForm(forms.SelfHandlingForm):
data["parameters"] = json.loads(data["parameters"])
try:
plugin = iotronic.plugin_create(request, data["name"],
data["public"], data["callable"],
data["code"], data["parameters"])
LOG.debug("MELO API REQ: %s", request)
iotronic.plugin_create(request, data["name"],
data["public"], data["callable"],
data["code"], data["parameters"])
messages.success(request, _("Plugin created successfully."))
return plugin
return True
# except iot_exceptions.ClientException:
except Exception:
# LOG.debug("MELO API REQ EXC: %s", request)
# LOG.debug("MELO API REQ (DICT): %s", exceptions.__dict__)
# LOG.debug("API REQ EXC: %s", request)
# LOG.debug("API REQ (DICT): %s", exceptions.__dict__)
exceptions.handle(request, _('Unable to create plugin.'))
@ -97,7 +96,7 @@ class InjectPluginForm(forms.SelfHandlingForm):
board_list = forms.MultipleChoiceField(
label=_("Boards List"),
widget=forms.SelectMultiple(
attrs={'class': 'switchable', 'data-slug': 'slug-inject-boards'}),
attrs={'class': 'switchable', 'data-slug': 'slug-inject-plugin'}),
help_text=_("Select boards in this pool ")
)
@ -120,19 +119,18 @@ class InjectPluginForm(forms.SelfHandlingForm):
if key == board:
try:
plugin = None
plugin = iotronic.plugin_inject(request, key,
inject = iotronic.plugin_inject(request, key,
data["uuid"],
data["onboot"])
# LOG.debug("MELO API: %s %s", plugin, request)
message_text = "Plugin injected successfully on " \
"board " + str(value) + "."
# LOG.debug("API: %s %s", plugin, request)
message_text = inject
messages.success(request, _(message_text))
if counter != len(data["board_list"]) - 1:
counter += 1
else:
return plugin
return True
except Exception:
message_text = "Unable to inject plugin on board " \
+ str(value) + "."
@ -191,20 +189,19 @@ class StartPluginForm(forms.SelfHandlingForm):
if key == board:
try:
plugin = None
plugin = iotronic.plugin_action(request, key,
action = iotronic.plugin_action(request, key,
data["uuid"],
"PluginStart",
data["parameters"])
# LOG.debug("MELO API: %s %s", plugin, request)
message_text = "Plugin started successfully on board "\
+ str(value) + "."
# LOG.debug("API: %s %s", plugin, request)
message_text = action
messages.success(request, _(message_text))
if counter != len(data["board_list"]) - 1:
counter += 1
else:
return plugin
return True
except Exception:
message_text = "Unable to start plugin on board " \
+ str(value) + "."
@ -259,20 +256,19 @@ class StopPluginForm(forms.SelfHandlingForm):
if key == board:
try:
plugin = None
plugin = iotronic.plugin_action(request, key,
action = iotronic.plugin_action(request, key,
data["uuid"],
"PluginStop",
data["delay"])
# LOG.debug("MELO API: %s %s", plugin, request)
message_text = "Plugin stopped successfully on board "\
+ str(value) + "."
# LOG.debug("API: %s %s", plugin, request)
message_text = action
messages.success(request, _(message_text))
if counter != len(data["board_list"]) - 1:
counter += 1
else:
return plugin
return True
except Exception:
message_text = "Unable to stop plugin on board " \
+ str(value) + "."
@ -330,20 +326,19 @@ class CallPluginForm(forms.SelfHandlingForm):
if key == board:
try:
plugin = None
plugin = iotronic.plugin_action(request, key,
action = iotronic.plugin_action(request, key,
data["uuid"],
"PluginCall",
data["parameters"])
# LOG.debug("MELO API: %s %s", plugin, request)
message_text = "Plugin called successfully on board " \
+ str(value) + "."
message_text = action
messages.success(request, _(message_text))
if counter != len(data["board_list"]) - 1:
counter += 2
counter += 1
else:
return plugin
return True
except Exception:
message_text = "Unable to call plugin on board " \
+ str(value) + "."
@ -387,10 +382,10 @@ class RemovePluginForm(forms.SelfHandlingForm):
if key == board:
try:
plugin = None
plugin = iotronic.plugin_remove(request, key,
data["uuid"])
# LOG.debug("MELO API: %s %s", plugin, request)
iotronic.plugin_remove(request,
key,
data["uuid"])
# LOG.debug("API: %s %s", plugin, request)
message_text = "Plugin removed successfully from" \
+ " board " + str(value) + "."
messages.success(request, _(message_text))
@ -398,7 +393,8 @@ class RemovePluginForm(forms.SelfHandlingForm):
if counter != len(data["board_list"]) - 1:
counter += 1
else:
return plugin
return True
except Exception:
message_text = "Unable to remove plugin from board " \
+ str(value) + "."
@ -411,34 +407,7 @@ class UpdatePluginForm(forms.SelfHandlingForm):
uuid = forms.CharField(label=_("Plugin ID"), widget=forms.HiddenInput)
owner = forms.CharField(label=_("Owner"), widget=forms.HiddenInput)
"""
name = forms.CharField(label=_("Plugin Name"))
public = forms.ChoiceField(label=_("Public"))
callable = forms.ChoiceField(label=_("Callable"))
code = forms.CharField(label=_("Code"))
"""
name = forms.CharField(label=_("Plugin Name"))
"""
public = forms.ChoiceField(
label=_("Public"),
choices =[('false', _('False')), ('true', _('True'))],
widget=forms.Select(
attrs={'class': 'switchable', 'data-slug': 'slug-public'},
)
)
callable = forms.ChoiceField(
label=_("Callable"),
choices =[('false', _('False')), ('true', _('True'))],
widget=forms.Select(
attrs={'class': 'switchable', 'data-slug': 'slug-callable'},
)
)
"""
public = forms.BooleanField(label=_("Public"), required=False)
callable = forms.BooleanField(label=_("Callable"), required=False)
@ -454,16 +423,16 @@ class UpdatePluginForm(forms.SelfHandlingForm):
# Admin
if policy.check((("iot", "iot:update_plugins"),), self.request):
# LOG.debug("MELO ADMIN")
# LOG.debug("ADMIN")
pass
# Admin_iot_project
elif policy.check((("iot", "iot:update_project_plugins"),),
self.request):
# LOG.debug("MELO IOT ADMIN")
# LOG.debug("IOT ADMIN")
if self.request.user.id != kwargs["initial"]["owner"]:
# LOG.debug("MELO NO-edit IOT ADMIN")
# LOG.debug("NO-edit IOT ADMIN")
self.fields["name"].widget.attrs = {'readonly': 'readonly'}
self.fields["public"].widget.attrs = {'disabled': 'disabled'}
self.fields["callable"].widget.attrs = {'disabled': 'disabled'}
@ -472,7 +441,7 @@ class UpdatePluginForm(forms.SelfHandlingForm):
# Other users
else:
if self.request.user.id != kwargs["initial"]["owner"]:
# LOG.debug("MELO IMMUTABLE FIELDS")
# LOG.debug("IMMUTABLE FIELDS")
self.fields["name"].widget.attrs = {'readonly': 'readonly'}
self.fields["public"].widget.attrs = {'disabled': 'disabled'}
self.fields["callable"].widget.attrs = {'disabled': 'disabled'}
@ -481,7 +450,6 @@ class UpdatePluginForm(forms.SelfHandlingForm):
def handle(self, request, data):
try:
# LOG.debug("MELO DATA: %s", data)
data["code"] = cPickle.dumps(str(data["code"]))
iotronic.plugin_update(request, data["uuid"],
@ -489,7 +457,10 @@ class UpdatePluginForm(forms.SelfHandlingForm):
"public": data["public"],
"callable": data["callable"],
"code": data["code"]})
messages.success(request, _("Plugin updated successfully."))
messages.success(request, _("Plugin " + str(data["name"]) +
" updated successfully."))
return True
except Exception:
exceptions.handle(request, _('Unable to update plugin.'))

View File

@ -14,9 +14,14 @@ from django.utils.translation import ugettext_lazy as _
import horizon
from iotronic_ui.iot import dashboard
class Plugins(horizon.Panel):
name = _("Plugins")
slug = "plugins"
# policy_rules = (("iot", "iot:list_all_plugins"),
# ("iot", "iot:list_project_plugins"))
dashboard.Iot.register(Plugins)

View File

@ -28,7 +28,7 @@ class CreatePluginLink(tables.LinkAction):
url = "horizon:iot:plugins:create"
classes = ("ajax-modal",)
icon = "plus"
# policy_rules = (("iot", "iot:create_board"),)
# policy_rules = (("iot", "iot:create_plugin"),)
class EditPluginLink(tables.LinkAction):
@ -37,12 +37,12 @@ class EditPluginLink(tables.LinkAction):
url = "horizon:iot:plugins:update"
classes = ("ajax-modal",)
icon = "pencil"
# policy_rules = (("iot", "iot:update_board"),)
# policy_rules = (("iot", "iot:update_plugin"),)
"""
def allowed(self, request, plugin):
# LOG.debug("MELO ALLOWED: %s %s %s", self, request, plugin)
# LOG.debug("MELO user: %s", request.user.id)
# LOG.debug("ALLOWED: %s %s %s", self, request, plugin)
# LOG.debug("user: %s", request.user.id)
return True
"""
@ -54,7 +54,7 @@ class InjectPluginLink(tables.LinkAction):
url = "horizon:iot:plugins:inject"
classes = ("ajax-modal",)
icon = "plus"
# policy_rules = (("iot", "iot:create_board"),)
# policy_rules = (("iot", "iot:inject_plugin"),)
class StartPluginLink(tables.LinkAction):
@ -63,7 +63,7 @@ class StartPluginLink(tables.LinkAction):
url = "horizon:iot:plugins:start"
classes = ("ajax-modal",)
icon = "plus"
# policy_rules = (("iot", "iot:create_board"),)
# policy_rules = (("iot", "iot:start_plugin"),)
class StopPluginLink(tables.LinkAction):
@ -72,7 +72,7 @@ class StopPluginLink(tables.LinkAction):
url = "horizon:iot:plugins:stop"
classes = ("ajax-modal",)
icon = "plus"
# policy_rules = (("iot", "iot:create_board"),)
# policy_rules = (("iot", "iot:stop_plugin"),)
class CallPluginLink(tables.LinkAction):
@ -81,7 +81,7 @@ class CallPluginLink(tables.LinkAction):
url = "horizon:iot:plugins:call"
classes = ("ajax-modal",)
icon = "plus"
# policy_rules = (("iot", "iot:create_board"),)
# policy_rules = (("iot", "iot:call_plugin"),)
class RemovePluginLink(tables.LinkAction):
@ -90,7 +90,7 @@ class RemovePluginLink(tables.LinkAction):
url = "horizon:iot:plugins:remove"
classes = ("ajax-modal",)
icon = "plus"
# policy_rules = (("iot", "iot:create_board"),)
# policy_rules = (("iot", "iot:remove_plugin"),)
class DeletePluginsAction(tables.DeleteAction):
@ -109,7 +109,7 @@ class DeletePluginsAction(tables.DeleteAction):
u"Deleted Plugins",
count
)
# policy_rules = (("iot", "iot:delete_board"),)
# policy_rules = (("iot", "iot:delete_plugin"),)
"""
def allowed(self, request, role):
@ -140,14 +140,14 @@ class PluginsTable(tables.DataTable):
# Overriding get_object_id method because in IoT service the "id" is
# identified by the field UUID
def get_object_id(self, datum):
# LOG.debug("MELO datum %s", datum)
# LOG.debug("datum %s", datum)
return datum.uuid
# Overriding get_row_actions method because we need to discriminate
# between Sync and Async plugins
def get_row_actions(self, datum):
actions = super(PluginsTable, self).get_row_actions(datum)
# LOG.debug("MELO ACTIONS: %s %s", actions[0].name, datum.name)
# LOG.debug("ACTIONS: %s %s", actions[0].name, datum.name)
selected_row_actions = []

View File

@ -18,6 +18,8 @@ from iotronic_ui.iot.plugins import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^create/$', views.CreateView.as_view(), name='create'),
url(r'^(?P<plugin_id>[^/]+)/update/$', views.UpdateView.as_view(),
name='update'),
url(r'^(?P<plugin_id>[^/]+)/inject/$', views.InjectView.as_view(),
name='inject'),
url(r'^(?P<plugin_id>[^/]+)/start/$', views.StartView.as_view(),
@ -28,8 +30,6 @@ urlpatterns = [
name='call'),
url(r'^(?P<plugin_id>[^/]+)/remove/$', views.RemoveView.as_view(),
name='remove'),
url(r'^(?P<plugin_id>[^/]+)/update/$', views.UpdateView.as_view(),
name='update'),
url(r'^(?P<plugin_id>[^/]+)/detail/$', views.PluginDetailView.as_view(),
name='detail'),
]

View File

@ -67,13 +67,6 @@ class IndexView(tables.DataTableView):
# Other users
else:
# FROM
"""
msg = _("Insufficient privilege level to view
plugins information.")
messages.info(self.request, msg)
"""
# TO
try:
plugins = iotronic.plugin_list(self.request, None, None,
with_public=True)

View File

@ -41,17 +41,18 @@ class CreateServiceForm(forms.SelfHandlingForm):
def handle(self, request, data):
try:
# LOG.error("DATA: %s", data)
service = iotronic.service_create(request, data["name"],
data["port"], data["protocol"])
messages.success(request, _("Service created successfully."))
iotronic.service_create(request, data["name"],
data["port"], data["protocol"])
messages.success(request, _("Service " + str(data["name"]) +
" created successfully."))
return True
return service
except Exception:
exceptions.handle(request, _('Unable to create service.'))
class UpdateBoardForm(forms.SelfHandlingForm):
class UpdateServiceForm(forms.SelfHandlingForm):
uuid = forms.CharField(label=_("Service ID"), widget=forms.HiddenInput)
name = forms.CharField(label=_("Service Name"))
port = forms.IntegerField(label=_("Port"))
@ -65,23 +66,23 @@ class UpdateBoardForm(forms.SelfHandlingForm):
def __init__(self, *args, **kwargs):
super(UpdateBoardForm, self).__init__(*args, **kwargs)
super(UpdateServiceForm, self).__init__(*args, **kwargs)
# Admin
if policy.check((("iot", "iot:update_services"),), self.request):
# LOG.debug("MELO ADMIN")
# 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("MELO NO-edit IOT ADMIN")
# LOG.debug("NO-edit IOT ADMIN")
pass
# Other users
else:
if self.request.user.id != kwargs["initial"]["owner"]:
# LOG.debug("MELO IMMUTABLE FIELDS")
# LOG.debug("IMMUTABLE FIELDS")
self.fields["name"].widget.attrs = {'readonly': 'readonly'}
self.fields["port"].widget.attrs = {'readonly': 'readonly'}
self.fields["protocol"].widget.attrs = {'readonly': 'readonly'}
@ -89,12 +90,13 @@ class UpdateBoardForm(forms.SelfHandlingForm):
def handle(self, request, data):
try:
iotronic.service_update(request, data["uuid"],
{"name": data["name"],
"port": data["port"],
"protocol": data["protocol"]})
{"name": data["name"],
"port": data["port"],
"protocol": data["protocol"]})
messages.success(request, _("Service updated successfully."))
return True
except Exception:
exceptions.handle(request, _('Unable to update service.'))
@ -117,7 +119,9 @@ class ServiceActionForm(forms.SelfHandlingForm):
action = forms.ChoiceField(
label=_("Action"),
choices=[('ServiceEnable', _('Enable')), ('ServiceDisable', _('Disable')), ('ServiceRestore', _('Restore'))],
choices=[('ServiceEnable', _('Enable')),
('ServiceDisable', _('Disable')),
('ServiceRestore', _('Restore'))],
widget=forms.Select(
attrs={'class': 'switchable', 'data-slug': 'slug-action'},
)
@ -128,10 +132,7 @@ class ServiceActionForm(forms.SelfHandlingForm):
super(ServiceActionForm, self).__init__(*args, **kwargs)
# input=kwargs.get('initial',{})
boardslist_length = len(kwargs["initial"]["board_list"])
self.fields["board_list"].choices = kwargs["initial"]["board_list"]
# self.fields["board_list"].max_length = boardslist_length
def handle(self, request, data):
@ -142,60 +143,20 @@ class ServiceActionForm(forms.SelfHandlingForm):
if key == board:
try:
action = None
action = iotronic.service_action(request, key,
data["uuid"],
data["action"])
message_text = "Action executed successfully on " \
"board " + str(value) + "."
data["uuid"],
data["action"])
message_text = action
messages.success(request, _(message_text))
if counter != len(data["board_list"]) - 1:
counter += 1
else:
return action
return True
except Exception:
message_text = "Unable to execute action on board " \
+ str(value) + "."
exceptions.handle(request, _(message_text))
break
class RemoveServicesForm(forms.SelfHandlingForm):
uuid = forms.CharField(label=_("Service ID"), widget=forms.HiddenInput)
name = forms.CharField(
label=_('Service Name'),
widget=forms.TextInput(attrs={'readonly': 'readonly'})
)
port = forms.IntegerField(
label=_("Port"),
widget=forms.TextInput(attrs={'readonly': 'readonly'})
)
protocol = forms.ChoiceField(
label=_("Protocol"),
choices=[('TCP', _('TCP')), ('UDP', _('UDP'))],
widget=forms.TextInput(attrs={'readonly': 'readonly'})
)
def __init__(self, *args, **kwargs):
super(RemoveServicesForm, self).__init__(*args, **kwargs)
# input=kwargs.get('initial',{})
def handle(self, request, data):
try:
message_text = "Service "+str(data["name"])+" deleted successfully."
iotronic.service_delete(request, data["uuid"])
messages.success(request, _(message_text))
return True
except Exception:
message_text = "Unable to delete service "+str(data["name"])+"."
exceptions.handle(request, _(message_text))

View File

@ -15,6 +15,7 @@ from django.utils.translation import ugettext_lazy as _
import horizon
# from openstack_dashboard.api import keystone
from iotronic_ui.iot import dashboard
class Services(horizon.Panel):
@ -23,3 +24,5 @@ class Services(horizon.Panel):
permissions = ('openstack.services.iot', )
# policy_rules = (("iot", "iot:list_all_services"),)
dashboard.Iot.register(Services)

View File

@ -22,7 +22,6 @@ from openstack_dashboard import api
LOG = logging.getLogger(__name__)
class CreateServiceLink(tables.LinkAction):
name = "create"
verbose_name = _("Create Service")
@ -32,7 +31,7 @@ class CreateServiceLink(tables.LinkAction):
# policy_rules = (("iot", "iot:create_service"),)
class EditBoardLink(tables.LinkAction):
class EditServiceLink(tables.LinkAction):
name = "edit"
verbose_name = _("Edit")
url = "horizon:iot:services:update"
@ -41,17 +40,6 @@ class EditBoardLink(tables.LinkAction):
# policy_rules = (("iot", "iot:update_service"),)
"""
class RemoveServicesLink(tables.LinkAction):
name = "remove"
verbose_name = _("Remove Service(s)")
url = "horizon:iot:services:remove"
classes = ("ajax-modal",)
icon = "plus"
# policy_rules = (("iot", "iot:delete_service"),)
"""
class ActionServiceLink(tables.LinkAction):
name = "action"
verbose_name = _("Service Action")
@ -106,11 +94,7 @@ class ServicesTable(tables.DataTable):
class Meta(object):
name = "services"
verbose_name = _("services")
row_actions = (EditBoardLink, ActionServiceLink,
row_actions = (EditServiceLink, ActionServiceLink,
DeleteServicesAction)
table_actions = (ServiceFilterAction, CreateServiceLink,
DeleteServicesAction)
# row_actions = (EditBoardLink, RemovePluginsLink, DeleteBoardsAction)
# table_actions = (BoardFilterAction, CreateBoardLink,
# DeleteBoardsAction)
DeleteServicesAction)

View File

@ -22,8 +22,6 @@ urlpatterns = [
name='update'),
url(r'^(?P<service_id>[^/]+)/action/$', views.ActionView.as_view(),
name='action'),
url(r'^(?P<service_id>[^/]+)/remove/$',
views.RemoveServicesView.as_view(), name='remove'),
url(r'^(?P<service_id>[^/]+)/detail/$', views.ServiceDetailView.as_view(),
name='detail'),
]

View File

@ -52,7 +52,8 @@ class IndexView(tables.DataTableView):
_('Unable to retrieve services list.'))
# Admin_iot_project
elif policy.check((("iot", "iot:list_project_services"),), self.request):
elif policy.check((("iot", "iot:list_project_services"),),
self.request):
try:
services = iotronic.service_list(self.request, None)
@ -87,7 +88,7 @@ class UpdateView(forms.ModalFormView):
template_name = 'iot/services/update.html'
modal_header = _("Update Service")
form_id = "update_service_form"
form_class = project_forms.UpdateBoardForm
form_class = project_forms.UpdateServiceForm
submit_label = _("Update Service")
submit_url = "horizon:iot:services:update"
success_url = reverse_lazy('horizon:iot:services:index')
@ -96,8 +97,9 @@ class UpdateView(forms.ModalFormView):
@memoized.memoized_method
def get_object(self):
try:
return iotronic.service_get(self.request, self.kwargs['service_id'],
None)
return iotronic.service_get(self.request,
self.kwargs['service_id'],
None)
except Exception:
redirect = reverse("horizon:iot:services:index")
exceptions.handle(self.request,
@ -133,8 +135,9 @@ class ActionView(forms.ModalFormView):
@memoized.memoized_method
def get_object(self):
try:
return iotronic.service_get(self.request, self.kwargs['service_id'],
None)
return iotronic.service_get(self.request,
self.kwargs['service_id'],
None)
except Exception:
redirect = reverse("horizon:iot:services:index")
exceptions.handle(self.request,
@ -163,43 +166,6 @@ class ActionView(forms.ModalFormView):
'board_list': board_list}
class RemoveServicesView(forms.ModalFormView):
template_name = 'iot/services/remove.html'
modal_header = _("Remove Service")
form_id = "remove_service_form"
form_class = project_forms.RemoveServicesForm
submit_label = _("Remove Service")
# submit_url = reverse_lazy("horizon:iot:boards:removeplugins")
submit_url = "horizon:iot:services:remove"
success_url = reverse_lazy('horizon:iot:services:index')
page_title = _("Remove Service")
@memoized.memoized_method
def get_object(self):
try:
return iotronic.service_get(self.request, self.kwargs['service_id'],
None)
except Exception:
redirect = reverse("horizon:iot:services:index")
exceptions.handle(self.request,
_('Unable to get service information.'),
redirect=redirect)
def get_context_data(self, **kwargs):
context = super(RemoveServicesView, 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):
service = self.get_object()
return {'uuid': service.uuid,
'name': service.name,
'port': service.port,
'protocol': service.protocol}
class DetailView(tabs.TabView):
tab_group_class = project_tabs.ServiceDetailTabs
template_name = 'horizon/common/_detail.html'
@ -224,8 +190,8 @@ class DetailView(tabs.TabView):
try:
service = iotronic.service_get(self.request, service_id, None)
except Exception:
msg = ('Unable to retrieve service %s information') % {'name':
service.name}
s = service.name
msg = ('Unable to retrieve service %s information') % {'name': s}
exceptions.handle(self.request, msg, ignore=True)
return service

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 797 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,122 +0,0 @@
/* Additional JavaScript for iot. */
//alert('MELO');
//var image_url = 'https://ing-res-17.me.trigrid.it/iotronic/';
var images_url = 'http://'+location.host+'/dashboard/static/iot/images/';
var markers = [];
markers = L.markerClusterGroup({
spiderfyOnMaxZoom: false,
disableClusteringAtZoom: 17
});
var marker_red = L.icon({
iconUrl: images_url+'marker-icon-red.png',
iconAnchor:[12.5, 41],
shadowUrl: images_url+'marker-shadow.png'
});
var marker_green = L.icon({
iconUrl: images_url+'marker-icon-green.png',
iconAnchor:[12.5, 41],
shadowUrl: images_url+'marker-shadow.png'
});
var marker_blue = L.icon({
iconUrl: images_url+'marker-icon.png',
iconAnchor:[12.5, 41],
shadowUrl: images_url+'marker-shadow.png'
});
var labels = [];
var latitude = [];
var longitude = [];
var altitude = [];
var statuses = [];
var last_update = [];
function render_map(map_id, coordinates){
var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osm = new L.TileLayer(osmUrl, {});
var lat = 38.20523;
var lon = 15.55972;
if(coordinates["coordinates"].length ==1){
lat = coordinates["coordinates"][0].lat;
lon = coordinates["coordinates"][0].lon;
}
var map = L.map(map_id, {scrollWheelZoom:false, worldCopyJump: true}).setView([lat, lon], 12);
map.addLayer(osm);
//Copyright
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://osm.org/copyright">OpenStreetMap</a> - by <b>MDSLab</b>'
}).addTo(map);
//var marker = L.marker([lat, lon]);
//marker.setIcon(marker_red);
coord = coordinates["coordinates"];
for(var i=0;i<coord.length;i++){
labels.push(coord[i].label);
latitude.push(parseFloat(coord[i].lat));
longitude.push(parseFloat(coord[i].lon));
altitude.push(parseFloat(coord[i].alt));
statuses.push(coord[i].status);
last_update.push(coord[i].updated);
var marker = L.marker([coord[i].lat, coord[i].lon]);
marker.setIcon(choose_marker(coord[i].status));
marker.on('click', function(e){
var latlng = JSON.stringify(e.latlng);
var obj = $.parseJSON('[' + latlng + ']');
var lat = JSON.stringify(obj[0].lat);
var lon = JSON.stringify(obj[0].lng);
sel = 0;
for(j=0; j<labels.length; j++){
if(latitude[j]==lat && longitude[j]==lon){
sel = j;
break;
}
}
var img = '<img src="'+images_url+'blue-circle.png" width=10 height=10>';
if(statuses[sel] == "online")
img = '<img src="'+images_url+'green-circle.png" width=10 height=10>';
if(statuses[sel] == "offline")
img = '<img src="'+images_url+'red-circle.png" width=10 height=10>';
var open_popup = '<div>';
var default_popup = '<center>'+img +' <b>'+labels[sel]+'</b></center><br />' +
'<center><b>'+last_update[sel]+'</b></center><br />'+
'Latitude: <b>'+latitude[sel]+ '</b><br />' +
'Longitude: <b>'+longitude[sel]+'</b><br />' +
'Altitude: <b>'+altitude[sel]+'</b><br /><br />';
global_popup = open_popup + default_popup +"</div>";
var popup = L.popup().setLatLng(e.latlng).setContent(global_popup).openOn(map);
});
markers.addLayer(marker);
}
map.addLayer(markers);
//return map;
}
function choose_marker(status){
if(status=="online") return marker_green;
else if(status =="offline") return marker_red;
else return marker_blue;
}

View File

@ -1,7 +0,0 @@
/* Additional SCSS for {{ dash_name }}. */
/*
#mapdiv {
min-height: 300px;
}
*/