Browse Source

Introduced management of webservices and added the corresponding menu items in the board panel, moved fleet panel, updated the api and fixed a path in README.rst

Change-Id: Ia99967e57fa88053692237709161cafc1fcdc2c2
Carmelo Romeo 4 months ago
parent
commit
748db492e9
35 changed files with 1017 additions and 138 deletions
  1. 1
    1
      README.rst
  2. 94
    1
      iotronic_ui/api/iotronic.py
  3. 23
    0
      iotronic_ui/enabled/_6040_iot_webservices_panel.py
  4. 0
    0
      iotronic_ui/enabled/_6050_iot_fleets_panel.py
  5. 64
    3
      iotronic_ui/iot/boards/forms.py
  6. 21
    1
      iotronic_ui/iot/boards/tables.py
  7. 2
    0
      iotronic_ui/iot/boards/tabs.py
  8. 13
    0
      iotronic_ui/iot/boards/templates/boards/_detail_overview.html
  9. 8
    0
      iotronic_ui/iot/boards/templates/boards/_disablewebservice.html
  10. 8
    0
      iotronic_ui/iot/boards/templates/boards/_enablewebservice.html
  11. 7
    0
      iotronic_ui/iot/boards/templates/boards/disablewebservice.html
  12. 7
    0
      iotronic_ui/iot/boards/templates/boards/enablewebservice.html
  13. 6
    2
      iotronic_ui/iot/boards/urls.py
  14. 117
    2
      iotronic_ui/iot/boards/views.py
  15. 2
    1
      iotronic_ui/iot/dashboard.py
  16. 0
    61
      iotronic_ui/iot/fleets/forms.py
  17. 0
    11
      iotronic_ui/iot/fleets/tables.py
  18. 0
    7
      iotronic_ui/iot/fleets/templates/fleets/action.html
  19. 0
    2
      iotronic_ui/iot/fleets/urls.py
  20. 0
    45
      iotronic_ui/iot/fleets/views.py
  21. 0
    0
      iotronic_ui/iot/webservices/__init__.py
  22. 103
    0
      iotronic_ui/iot/webservices/forms.py
  23. 28
    0
      iotronic_ui/iot/webservices/panel.py
  24. 121
    0
      iotronic_ui/iot/webservices/tables.py
  25. 47
    0
      iotronic_ui/iot/webservices/tabs.py
  26. 8
    0
      iotronic_ui/iot/webservices/templates/webservices/_cell_webservices.html
  27. 27
    0
      iotronic_ui/iot/webservices/templates/webservices/_detail_overview.html
  28. 2
    1
      iotronic_ui/iot/webservices/templates/webservices/_expose.html
  29. 8
    0
      iotronic_ui/iot/webservices/templates/webservices/_unexpose.html
  30. 7
    0
      iotronic_ui/iot/webservices/templates/webservices/expose.html
  31. 7
    0
      iotronic_ui/iot/webservices/templates/webservices/index.html
  32. 7
    0
      iotronic_ui/iot/webservices/templates/webservices/unexpose.html
  33. 19
    0
      iotronic_ui/iot/webservices/tests.py
  34. 26
    0
      iotronic_ui/iot/webservices/urls.py
  35. 234
    0
      iotronic_ui/iot/webservices/views.py

+ 1
- 1
README.rst View File

@@ -43,7 +43,7 @@ If you want to enable logs for a better debug follow the following steps or just
43 43
 
44 44
     mkdir /var/log/horizon
45 45
     touch /var/log/horizon/horizon.log
46
-    chown -R horizon:horizon horizon
46
+    chown -R horizon:horizon /var/log/horizon
47 47
 
48 48
     vim /etc/openstack-dashboard/local_settings.py
49 49
 

+ 94
- 1
iotronic_ui/api/iotronic.py View File

@@ -15,7 +15,7 @@
15 15
 
16 16
 from iotronicclient import client as iotronic_client
17 17
 # from django.conf import settings
18
-# from django.utils.translation import ugettext_lazy as _
18
+from django.utils.translation import ugettext_lazy as _
19 19
 
20 20
 # from horizon import exceptions
21 21
 from horizon.utils.memoized import memoized  # noqa
@@ -260,3 +260,96 @@ def fleet_get_boards(request, fleet_id):
260 260
     """Get fleet boards."""
261 261
     return iotronicclient(request).fleet.boards_in_fleet(fleet=fleet_id)
262 262
 
263
+
264
+# WEBSERVICES MANAGEMENT
265
+def webservice_list(request, detail=None):
266
+    """Get web services list."""
267
+    return iotronicclient(request).webservice.list()
268
+
269
+
270
+def webservice_enabled_list(request):
271
+    """Get enabled web services list."""
272
+    return iotronicclient(request).enabledwebservice.list()
273
+
274
+
275
+def webservice_get_enabled_info(request, board_id, detail=None):
276
+    """Get the information of the enabled webservices."""
277
+    ws_info = []
278
+
279
+    ws_enabled = iotronicclient(request).enabledwebservice.list()
280
+
281
+    for ws in ws_enabled:
282
+        if ws.board_uuid == board_id:
283
+            ws_info = ws
284
+            break
285
+
286
+    return ws_info
287
+
288
+
289
+def webservices_on_board(request, board_id, fields=None):
290
+    """Get web services on board list."""
291
+    webservices = iotronicclient(request).webserviceonboard.list(board_id,
292
+                                                                 fields)
293
+
294
+    detailed_webservices = []
295
+    # fields = {"name", "port", "uuid"}
296
+
297
+    for ws in webservices:
298
+        detailed_webservices.append({"name": ws._info["name"],
299
+                                     "port": ws._info["port"],
300
+                                     "uuid": ws._info["uuid"]})
301
+
302
+    return detailed_webservices
303
+
304
+
305
+def webservice_get(request, webservice_id, fields):
306
+    """Get web service info."""
307
+    return iotronicclient(request).webservice.get(webservice_id, fields)
308
+
309
+
310
+def webservice_expose(request, board_id, name, port, secure):
311
+    """Expose a web service."""
312
+    return iotronicclient(request).webserviceonboard.expose(board_id,
313
+                                                            name,
314
+                                                            port,
315
+                                                            secure)
316
+
317
+
318
+def webservice_unexpose(request, webservice_id):
319
+    """Unexpose a web service from a board."""
320
+    return iotronicclient(request).webservice.delete(webservice_id)
321
+
322
+
323
+def webservice_enable(request, board, dns, zone, email):
324
+    """Enable web service."""
325
+    return iotronicclient(request).webserviceonboard.enable_webservice(board,
326
+                                                                       dns,
327
+                                                                       zone,
328
+                                                                       email)
329
+
330
+
331
+def webservice_disable(request, board):
332
+    """Disable web service."""
333
+    return iotronicclient(request).webserviceonboard.disable_webservice(board)
334
+
335
+
336
+def boards_no_webservice(request):
337
+    """Get all the boards that have not webservice enabled."""
338
+
339
+    boards_no_ws_enabled = []
340
+
341
+    board_list = iotronicclient(request).board.list()
342
+    board_list.sort(key=lambda b: b.name)
343
+
344
+    board_ws_list = iotronicclient(request).enabledwebservice.list()
345
+
346
+    for board in board_list:
347
+        for i in range(len(board_ws_list)):
348
+            if board.uuid == board_ws_list[i].board_uuid:
349
+                break
350
+            elif ((board.uuid != board_ws_list[i].board_uuid) and
351
+                 (i==len(board_ws_list)-1)):
352
+                boards_no_ws_enabled.append((board.uuid, _(board.name)))
353
+
354
+    # LOG.debug('COMPLEMENTARY %s', boards_no_ws_enabled)
355
+    return boards_no_ws_enabled

+ 23
- 0
iotronic_ui/enabled/_6040_iot_webservices_panel.py View File

@@ -0,0 +1,23 @@
1
+# Licensed under the Apache License, Version 2.0 (the "License");
2
+# you may not use this file except in compliance with the License.
3
+# You may obtain a copy of the License at
4
+#
5
+#    http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+# Unless required by applicable law or agreed to in writing, software
8
+# distributed under the License is distributed on an "AS IS" BASIS,
9
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+# See the License for the specific language governing permissions and
11
+# limitations under the License.
12
+
13
+# The slug of the panel to be added to HORIZON_CONFIG. Required.
14
+PANEL = 'webservices'
15
+# The slug of the dashboard the PANEL associated with. Required.
16
+PANEL_DASHBOARD = 'iot'
17
+# The slug of the panel group the PANEL is associated with.
18
+PANEL_GROUP = 'iot'
19
+# If set, it will update the default panel of the PANEL_DASHBOARD.
20
+DEFAULT_PANEL = ''
21
+
22
+# Python panel class of the PANEL to be added.
23
+ADD_PANEL = 'iotronic_ui.iot.webservices.panel.Webservices'

iotronic_ui/enabled/_6040_iot_fleets_panel.py → iotronic_ui/enabled/_6050_iot_fleets_panel.py View File


+ 64
- 3
iotronic_ui/iot/boards/forms.py View File

@@ -34,7 +34,8 @@ class CreateBoardForm(forms.SelfHandlingForm):
34 34
     # MODIFY ---> options: yun, server
35 35
     type = forms.ChoiceField(
36 36
         label=_("Type"),
37
-        choices=[('yun', _('YUN')), ('server', _('Server'))],
37
+        # choices=[('yun', _('YUN')), ('server', _('Server'))],
38
+        choices=[('gateway', _('Gateway')), ('server', _('Server'))],
38 39
         widget=forms.Select(
39 40
             attrs={'class': 'switchable', 'data-slug': 'slug-type'},
40 41
         )
@@ -175,7 +176,7 @@ class UpdateBoardForm(forms.SelfHandlingForm):
175 176
 
176 177
 class EnableServiceForm(forms.SelfHandlingForm):
177 178
 
178
-    uuid = forms.CharField(label=_("Plugin ID"), widget=forms.HiddenInput)
179
+    uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
179 180
 
180 181
     name = forms.CharField(
181 182
         label=_('Board Name'),
@@ -216,9 +217,10 @@ class EnableServiceForm(forms.SelfHandlingForm):
216 217
                 exceptions.handle(request, _(message_text))
217 218
 
218 219
 
220
+"""
219 221
 class DisableServiceForm(forms.SelfHandlingForm):
220 222
 
221
-    uuid = forms.CharField(label=_("Plugin ID"), widget=forms.HiddenInput)
223
+    uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
222 224
 
223 225
     name = forms.CharField(
224 226
         label=_('Board Name'),
@@ -257,6 +259,7 @@ class DisableServiceForm(forms.SelfHandlingForm):
257 259
             except Exception:
258 260
                 message_text = "Unable to disable service."
259 261
                 exceptions.handle(request, _(message_text))
262
+"""
260 263
 
261 264
 
262 265
 class AttachPortForm(forms.SelfHandlingForm):
@@ -352,6 +355,64 @@ class DetachPortForm(forms.SelfHandlingForm):
352 355
                 exceptions.handle(request, _(message_text))
353 356
 
354 357
 
358
+class EnableWebServiceForm(forms.SelfHandlingForm):
359
+
360
+    uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
361
+
362
+    name = forms.CharField(
363
+        label=_('Board Name'),
364
+        widget=forms.TextInput(attrs={'readonly': 'readonly'})
365
+    )
366
+
367
+    dns = forms.CharField(label=_("Domain Name Server"))
368
+    zone = forms.CharField(label=_("Zone"))
369
+    email = forms.CharField(label=_("Email"))
370
+
371
+    def __init__(self, *args, **kwargs):
372
+        super(EnableWebServiceForm, self).__init__(*args, **kwargs)
373
+
374
+    def handle(self, request, data):
375
+
376
+        try:
377
+            iotronic.webservice_enable(request, data["uuid"],
378
+                                       data["dns"], data["zone"],
379
+                                       data["email"])
380
+
381
+            messages.success(request, _("Web Service enabled on board " +
382
+                                        str(data["name"]) + "."))
383
+            return True
384
+
385
+        except Exception:
386
+            message_text = "Unable to enable web service."
387
+            exceptions.handle(request, _(message_text))
388
+
389
+
390
+class DisableWebServiceForm(forms.SelfHandlingForm):
391
+
392
+    uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
393
+
394
+    name = forms.CharField(
395
+        label=_('Board Name'),
396
+        widget=forms.TextInput(attrs={'readonly': 'readonly'})
397
+    )
398
+
399
+    def __init__(self, *args, **kwargs):
400
+        super(DisableWebServiceForm, self).__init__(*args, **kwargs)
401
+
402
+    def handle(self, request, data):
403
+
404
+        try:
405
+            iotronic.webservice_disable(request, data["uuid"])
406
+
407
+            messages.success(request, _("Web Service disabled on board " +
408
+                                        str(data["name"]) + "."))
409
+            return True
410
+
411
+        except Exception:
412
+            message_text = "Unable to disable web service."
413
+            exceptions.handle(request, _(message_text))
414
+
415
+
355 416
 class RemovePluginsForm(forms.SelfHandlingForm):
356 417
 
357 418
     uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)

+ 21
- 1
iotronic_ui/iot/boards/tables.py View File

@@ -73,6 +73,7 @@ class EnableServiceLink(tables.LinkAction):
73 73
     # policy_rules = (("iot", "iot:service_action"),)
74 74
 
75 75
 
76
+"""
76 77
 class DisableServiceLink(tables.LinkAction):
77 78
     name = "disableservice"
78 79
     verbose_name = _("Disable Service(s)")
@@ -80,6 +81,7 @@ class DisableServiceLink(tables.LinkAction):
80 81
     classes = ("ajax-modal",)
81 82
     # icon = "plus"
82 83
     # policy_rules = (("iot", "iot:service_action"),)
84
+"""
83 85
 
84 86
 
85 87
 class RemovePluginsLink(tables.LinkAction):
@@ -116,6 +118,22 @@ class DetachPortLink(tables.LinkAction):
116 118
     icon = "plus"
117 119
 
118 120
 
121
+class EnableWebServiceLink(tables.LinkAction):
122
+    name = "enablewebservice"
123
+    verbose_name = _("Enable Web Services")
124
+    url = "horizon:iot:boards:enablewebservice"
125
+    classes = ("ajax-modal",)
126
+    icon = "plus"
127
+
128
+
129
+class DisableWebServiceLink(tables.LinkAction):
130
+    name = "disablewebservice"
131
+    verbose_name = _("Disable Web Services")
132
+    url = "horizon:iot:boards:disablewebservice"
133
+    classes = ("ajax-modal",)
134
+    icon = "plus"
135
+
136
+
119 137
 class DeleteBoardsAction(tables.DeleteAction):
120 138
     @staticmethod
121 139
     def action_present(count):
@@ -191,8 +209,10 @@ class BoardsTable(tables.DataTable):
191 209
     class Meta(object):
192 210
         name = "boards"
193 211
         verbose_name = _("boards")
194
-        row_actions = (EditBoardLink, EnableServiceLink, DisableServiceLink,
212
+        # row_actions = (EditBoardLink, EnableServiceLink, DisableServiceLink,
213
+        row_actions = (EditBoardLink, EnableServiceLink,
195 214
                        RestoreServices, AttachPortLink, DetachPortLink,
215
+                       EnableWebServiceLink, DisableWebServiceLink,
196 216
                        RemovePluginsLink, RemoveServicesLink,
197 217
                        DeleteBoardsAction)
198 218
         table_actions = (BoardFilterAction, CreateBoardLink,

+ 2
- 0
iotronic_ui/iot/boards/tabs.py View File

@@ -36,11 +36,13 @@ class OverviewTab(tabs.Tab):
36 36
         coordinates = self.tab_group.kwargs['board'].__dict__['location'][0]
37 37
         ports = self.tab_group.kwargs['board']._info['ports']
38 38
         services = self.tab_group.kwargs['board']._info['services']
39
+        webservices = self.tab_group.kwargs['board']._info['webservices']
39 40
         plugins = self.tab_group.kwargs['board']._info['plugins']
40 41
 
41 42
         return {"board": self.tab_group.kwargs['board'],
42 43
                 "coordinates": coordinates,
43 44
                 "services": services,
45
+                "webservices": webservices,
44 46
                 "ports": ports,
45 47
                 "plugins": plugins,
46 48
                 "is_superuser": request.user.is_superuser}

+ 13
- 0
iotronic_ui/iot/boards/templates/boards/_detail_overview.html View File

@@ -57,6 +57,19 @@
57 57
       {% endif %}
58 58
     </dl>
59 59
 
60
+  <h4>{% trans "Web Services" %}</h4>
61
+    <hr class="header_rule">
62
+    <dl class="dl-horizontal">
63
+      {% if webservices %}
64
+        {% for ws in webservices %}
65
+            <dt>{{ ws.name }} [{{ ws.port }}]</dt>
66
+            <dd>{{ ws.uuid }}</dd>
67
+        {% endfor %}
68
+      {% else %}
69
+        <dd>--</dd>
70
+      {% endif %}
71
+    </dl>
72
+
60 73
   <h4>{% trans "Plugins" %}</h4>
61 74
     <hr class="header_rule">
62 75
     <dl class="dl-horizontal">

+ 8
- 0
iotronic_ui/iot/boards/templates/boards/_disablewebservice.html View File

@@ -0,0 +1,8 @@
1
+{% extends "horizon/common/_modal_form.html" %}
2
+{% load i18n %}
3
+
4
+{% block modal-body-right %}
5
+  <h3>{% trans "Description:" %}</h3>
6
+  <p>{% trans "Disable web service(s) on the selected board." %}</p>
7
+{% endblock %}
8
+

+ 8
- 0
iotronic_ui/iot/boards/templates/boards/_enablewebservice.html View File

@@ -0,0 +1,8 @@
1
+{% extends "horizon/common/_modal_form.html" %}
2
+{% load i18n %}
3
+
4
+{% block modal-body-right %}
5
+  <h3>{% trans "Description:" %}</h3>
6
+  <p>{% trans "Enable web service(s) on the selected board." %}</p>
7
+{% endblock %}
8
+

+ 7
- 0
iotronic_ui/iot/boards/templates/boards/disablewebservice.html View File

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

+ 7
- 0
iotronic_ui/iot/boards/templates/boards/enablewebservice.html View File

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

+ 6
- 2
iotronic_ui/iot/boards/urls.py View File

@@ -26,9 +26,13 @@ urlpatterns = [
26 26
         views.RemoveServicesView.as_view(), name='removeservices'),
27 27
     url(r'^(?P<board_id>[^/]+)/enableservice/$',
28 28
         views.EnableServiceView.as_view(), name='enableservice'),
29
-    url(r'^(?P<board_id>[^/]+)/disableservice/$',
30
-        views.DisableServiceView.as_view(), name='disableservice'),
29
+    # url(r'^(?P<board_id>[^/]+)/disableservice/$',
30
+    #     views.DisableServiceView.as_view(), name='disableservice'),
31 31
     url(r'^(?P<board_id>[^/]+)/attachport/$',
32
+        views.EnableWebServiceView.as_view(), name='enablewebservice'),
33
+    url(r'^(?P<board_id>[^/]+)/enablewebservice/$',
34
+        views.DisableWebServiceView.as_view(), name='disablewebservice'),
35
+    url(r'^(?P<board_id>[^/]+)/disablewebservice/$',
32 36
         views.AttachPortView.as_view(), name='attachport'),
33 37
     url(r'^(?P<board_id>[^/]+)/detachport/$',
34 38
         views.DetachPortView.as_view(), name='detachport'),

+ 117
- 2
iotronic_ui/iot/boards/views.py View File

@@ -75,6 +75,18 @@ class IndexView(tables.DataTableView):
75 75
                                                             board.uuid,
76 76
                                                             True)
77 77
 
78
+            # TO BE REMOVED
79
+            # We are filtering the services that starts with "webservice"
80
+            # ------------------------------------------------------------
81
+            filter_ws = []
82
+            for service in board_services:
83
+                if ((service["name"] != "webservice") and 
84
+                   (service["name"] != "webservice_ssl")):
85
+                    filter_ws.append(service)
86
+
87
+            board_services = filter_ws
88
+            # ------------------------------------------------------------
89
+
78 90
             # board.__dict__.update(dict(services=board_services))
79 91
             board._info.update(dict(services=board_services))
80 92
 
@@ -205,6 +217,7 @@ class EnableServiceView(forms.ModalFormView):
205 217
                 'service_list': service_list}
206 218
 
207 219
 
220
+"""
208 221
 class DisableServiceView(forms.ModalFormView):
209 222
     template_name = 'iot/boards/disableservice.html'
210 223
     modal_header = _("Disable Service(s)")
@@ -246,15 +259,31 @@ class DisableServiceView(forms.ModalFormView):
246 259
 
247 260
         service_list = []
248 261
 
262
+
263
+        # BEFORE filtering necessity
264
+        # for cloud_service in cloud_services:
265
+        #     for board_service in board_services:
266
+        #         if board_service["uuid"] == cloud_service._info["uuid"]:
267
+        #             service_list.append((cloud_service._info["uuid"],
268
+        #                                 _(cloud_service._info["name"])))
269
+
270
+        # AFTER filtering necessity
271
+        # We are filtering the services that starts with "webservice"
272
+        # ------------------------------------------------------------
273
+
249 274
         for cloud_service in cloud_services:
250 275
             for board_service in board_services:
251
-                if board_service["uuid"] == cloud_service._info["uuid"]:
276
+                if ((board_service["uuid"] == cloud_service._info["uuid"]) and
277
+                   ((board_service["name"] != "webservice") and
278
+                   (board_service["name"] != "webservice_ssl"))): 
252 279
                     service_list.append((cloud_service._info["uuid"],
253 280
                                         _(cloud_service._info["name"])))
281
+        # ------------------------------------------------------------
254 282
 
255 283
         return {'uuid': board.uuid,
256 284
                 'name': board.name,
257 285
                 'service_list': service_list}
286
+"""
258 287
 
259 288
 
260 289
 class AttachPortView(forms.ModalFormView):
@@ -357,6 +386,80 @@ class DetachPortView(forms.ModalFormView):
357 386
                 'ports': ports}
358 387
 
359 388
 
389
+class EnableWebServiceView(forms.ModalFormView):
390
+    template_name = 'iot/boards/enablewebservice.html'
391
+    modal_header = _("Enable Web Service(s)")
392
+    form_id = "webservice_enable_form"
393
+    form_class = project_forms.EnableWebServiceForm
394
+    submit_label = _("Enable")
395
+    # submit_url = reverse_lazy("horizon:iot:boards:enablewebservice")
396
+    submit_url = "horizon:iot:boards:enablewebservice"
397
+    success_url = reverse_lazy('horizon:iot:boards:index')
398
+    page_title = _("Enable")
399
+
400
+    @memoized.memoized_method
401
+    def get_object(self):
402
+        try:
403
+            return api.iotronic.board_get(self.request,
404
+                                          self.kwargs['board_id'],
405
+                                          None)
406
+
407
+        except Exception:
408
+            redirect = reverse("horizon:iot:boards:index")
409
+            exceptions.handle(self.request,
410
+                              _('Unable to get board information.'),
411
+                              redirect=redirect)
412
+
413
+    def get_context_data(self, **kwargs):
414
+        context = super(EnableWebServiceView, self).get_context_data(**kwargs)
415
+        args = (self.get_object().uuid,)
416
+        context['submit_url'] = reverse(self.submit_url, args=args)
417
+        return context
418
+
419
+    def get_initial(self):
420
+        board = self.get_object()
421
+
422
+        return {'uuid': board.uuid,
423
+                'name': board.name}
424
+
425
+
426
+class DisableWebServiceView(forms.ModalFormView):
427
+    template_name = 'iot/boards/disablewebservice.html'
428
+    modal_header = _("Disable Web Service(s)")
429
+    form_id = "webservice_disable_form"
430
+    form_class = project_forms.DisableWebServiceForm
431
+    submit_label = _("Disable")
432
+    # submit_url = reverse_lazy("horizon:iot:boards:disablewebservice")
433
+    submit_url = "horizon:iot:boards:disablewebservice"
434
+    success_url = reverse_lazy('horizon:iot:boards:index')
435
+    page_title = _("Disable")
436
+
437
+    @memoized.memoized_method
438
+    def get_object(self):
439
+        try:
440
+            return api.iotronic.board_get(self.request,
441
+                                          self.kwargs['board_id'],
442
+                                          None)
443
+
444
+        except Exception:
445
+            redirect = reverse("horizon:iot:boards:index")
446
+            exceptions.handle(self.request,
447
+                              _('Unable to get board information.'),
448
+                              redirect=redirect)
449
+
450
+    def get_context_data(self, **kwargs):
451
+        context = super(DisableWebServiceView, self).get_context_data(**kwargs)
452
+        args = (self.get_object().uuid,)
453
+        context['submit_url'] = reverse(self.submit_url, args=args)
454
+        return context
455
+
456
+    def get_initial(self):
457
+        board = self.get_object()
458
+
459
+        return {'uuid': board.uuid,
460
+                'name': board.name}
461
+
462
+
360 463
 class RemovePluginsView(forms.ModalFormView):
361 464
     template_name = 'iot/boards/removeplugins.html'
362 465
     modal_header = _("Remove Plugins from board")
@@ -445,7 +548,15 @@ class RemoveServicesView(forms.ModalFormView):
445 548
 
446 549
         service_list = []
447 550
         for service in services:
448
-            service_list.append((service["uuid"], _(service["name"])))
551
+            # service_list.append((service["uuid"], _(service["name"])))
552
+
553
+            # TO BE REMOVED
554
+            # ###########################################################
555
+            # We are filtering the services that starts with "webservice"
556
+            if ((service["name"] != "webservice") and
557
+               (service["name"] != "webservice_ssl")):
558
+                service_list.append((service["uuid"], _(service["name"])))
559
+            # ###########################################################
449 560
 
450 561
         return {'uuid': board.uuid,
451 562
                 'name': board.name,
@@ -501,6 +612,10 @@ class DetailView(tabs.TabView):
501 612
                                                           board_id)
502 613
             board._info.update(dict(plugins=board_plugins))
503 614
 
615
+            board_webservices = api.iotronic.webservices_on_board(self.request,
616
+                                                                  board_id)
617
+            board._info.update(dict(webservices=board_webservices))
618
+
504 619
             # Adding fleet name
505 620
             if board.fleet != None:
506 621
                 fleet_info = api.iotronic.fleet_get(self.request,

+ 2
- 1
iotronic_ui/iot/dashboard.py View File

@@ -18,7 +18,8 @@ import horizon
18 18
 class Iot(horizon.Dashboard):
19 19
     name = _("IoT")
20 20
     slug = "iot"
21
-    panels = ('boards', 'plugins', 'services', 'fleets')  # Add your panels here.
21
+    panels = ('boards', 'plugins', 'services',
22
+              'webservices', 'fleets')  # Add your panels here.
22 23
 
23 24
     # Specify the slug of the dashboard's default panel.
24 25
     default_panel = 'boards'

+ 0
- 61
iotronic_ui/iot/fleets/forms.py View File

@@ -88,64 +88,3 @@ class UpdateFleetForm(forms.SelfHandlingForm):
88 88
 
89 89
         except Exception:
90 90
             exceptions.handle(request, _('Unable to update fleet.'))
91
-
92
-
93
-class FleetActionForm(forms.SelfHandlingForm):
94
-
95
-    uuid = forms.CharField(label=_("Plugin ID"), widget=forms.HiddenInput)
96
-
97
-    name = forms.CharField(
98
-        label=_('Fleet Name'),
99
-        widget=forms.TextInput(attrs={'readonly': 'readonly'})
100
-    )
101
-
102
-    board_list = forms.MultipleChoiceField(
103
-        label=_("Boards List"),
104
-        widget=forms.SelectMultiple(
105
-            attrs={'class': 'switchable', 'data-slug': 'slug-select-boards'}),
106
-        help_text=_("Select boards in this pool")
107
-    )
108
-
109
-    action = forms.ChoiceField(
110
-        label=_("Action"),
111
-        choices=[('FleetEnable', _('Enable')),
112
-                 ('FleetDisable', _('Disable')),
113
-                 ('FleetRestore', _('Restore'))],
114
-        widget=forms.Select(
115
-            attrs={'class': 'switchable', 'data-slug': 'slug-action'},
116
-        )
117
-    )
118
-
119
-    def __init__(self, *args, **kwargs):
120
-
121
-        super(FleetActionForm, self).__init__(*args, **kwargs)
122
-        # input=kwargs.get('initial',{})
123
-
124
-        self.fields["board_list"].choices = kwargs["initial"]["board_list"]
125
-
126
-    def handle(self, request, data):
127
-
128
-        counter = 0
129
-
130
-        for board in data["board_list"]:
131
-            for key, value in self.fields["board_list"].choices:
132
-                if key == board:
133
-
134
-                    try:
135
-                        action = iotronic.fleet_action(request, key,
136
-                                                         data["uuid"],
137
-                                                         data["action"])
138
-                        message_text = action
139
-                        messages.success(request, _(message_text))
140
-
141
-                        if counter != len(data["board_list"]) - 1:
142
-                            counter += 1
143
-                        else:
144
-                            return True
145
-
146
-                    except Exception:
147
-                        message_text = "Unable to execute action on board " \
148
-                                       + str(value) + "."
149
-                        exceptions.handle(request, _(message_text))
150
-
151
-                    break

+ 0
- 11
iotronic_ui/iot/fleets/tables.py View File

@@ -40,15 +40,6 @@ class EditFleetLink(tables.LinkAction):
40 40
     # policy_rules = (("iot", "iot:update_fleet"),)
41 41
 
42 42
 
43
-class ActionFleetLink(tables.LinkAction):
44
-    name = "action"
45
-    verbose_name = _("Fleet Action")
46
-    url = "horizon:iot:fleets:action"
47
-    classes = ("ajax-modal",)
48
-    # icon = "plus"
49
-    # policy_rules = (("iot", "iot:fleet_action"),)
50
-
51
-
52 43
 class DeleteFleetsAction(tables.DeleteAction):
53 44
     @staticmethod
54 45
     def action_present(count):
@@ -93,8 +84,6 @@ class FleetsTable(tables.DataTable):
93 84
     class Meta(object):
94 85
         name = "fleets"
95 86
         verbose_name = _("fleets")
96
-        # row_actions = (EditFleetLink, ActionFleetLink,
97
-        #                DeleteFleetsAction)
98 87
         row_actions = (EditFleetLink, DeleteFleetsAction)
99 88
         table_actions = (FleetFilterAction, CreateFleetLink,
100 89
                          DeleteFleetsAction)

+ 0
- 7
iotronic_ui/iot/fleets/templates/fleets/action.html View File

@@ -1,7 +0,0 @@
1
-{% extends 'base.html' %}
2
-{% load i18n %}
3
-{% block title %}{% trans "Execute Action" %}{% endblock %}
4
-
5
-{% block main %}
6
-    {% include 'iot/fleets/_action.html' %}
7
-{% endblock %}

+ 0
- 2
iotronic_ui/iot/fleets/urls.py View File

@@ -20,8 +20,6 @@ urlpatterns = [
20 20
     url(r'^create/$', views.CreateView.as_view(), name='create'),
21 21
     url(r'^(?P<fleet_id>[^/]+)/update/$', views.UpdateView.as_view(),
22 22
         name='update'),
23
-    url(r'^(?P<fleet_id>[^/]+)/action/$', views.ActionView.as_view(),
24
-        name='action'),
25 23
     url(r'^(?P<fleet_id>[^/]+)/detail/$', views.FleetDetailView.as_view(),
26 24
         name='detail'),
27 25
 ]

+ 0
- 45
iotronic_ui/iot/fleets/views.py View File

@@ -120,51 +120,6 @@ class UpdateView(forms.ModalFormView):
120 120
                 'description': fleet.description}
121 121
 
122 122
 
123
-class ActionView(forms.ModalFormView):
124
-    template_name = 'iot/fleets/action.html'
125
-    modal_header = _("Fleet Action")
126
-    form_id = "fleet_action_form"
127
-    form_class = project_forms.FleetActionForm
128
-    submit_label = _("Fleet Action")
129
-    # submit_url = reverse_lazy("horizon:iot:fleets:action")
130
-    submit_url = "horizon:iot:fleets:action"
131
-    success_url = reverse_lazy('horizon:iot:fleets:index')
132
-    page_title = _("Fleet Action")
133
-
134
-    @memoized.memoized_method
135
-    def get_object(self):
136
-        try:
137
-            return iotronic.fleet_get(self.request,
138
-                                        self.kwargs['fleet_id'],
139
-                                        None)
140
-        except Exception:
141
-            redirect = reverse("horizon:iot:fleets:index")
142
-            exceptions.handle(self.request,
143
-                              _('Unable to get fleet information.'),
144
-                              redirect=redirect)
145
-
146
-    def get_context_data(self, **kwargs):
147
-        context = super(ActionView, self).get_context_data(**kwargs)
148
-        args = (self.get_object().uuid,)
149
-        context['submit_url'] = reverse(self.submit_url, args=args)
150
-        return context
151
-
152
-    def get_initial(self):
153
-        fleet = self.get_object()
154
-
155
-        # Populate boards
156
-        boards = iotronic.board_list(self.request, "online", None, None)
157
-        boards.sort(key=lambda b: b.name)
158
-
159
-        board_list = []
160
-        for board in boards:
161
-            board_list.append((board.uuid, _(board.name)))
162
-
163
-        return {'uuid': fleet.uuid,
164
-                'name': fleet.name,
165
-                'board_list': board_list}
166
-
167
-
168 123
 class DetailView(tabs.TabView):
169 124
     tab_group_class = project_tabs.FleetDetailTabs
170 125
     template_name = 'horizon/common/_detail.html'

+ 0
- 0
iotronic_ui/iot/webservices/__init__.py View File


+ 103
- 0
iotronic_ui/iot/webservices/forms.py View File

@@ -0,0 +1,103 @@
1
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+# not use this file except in compliance with the License. You may obtain
3
+# a copy of the License at
4
+#
5
+#      http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+# Unless required by applicable law or agreed to in writing, software
8
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+# License for the specific language governing permissions and limitations
11
+# under the License.
12
+
13
+import logging
14
+
15
+from django.utils.translation import ugettext_lazy as _
16
+
17
+from horizon import exceptions
18
+from horizon import forms
19
+from horizon import messages
20
+
21
+from openstack_dashboard.api import iotronic
22
+from openstack_dashboard import policy
23
+
24
+LOG = logging.getLogger(__name__)
25
+
26
+
27
+class ExposeWebserviceForm(forms.SelfHandlingForm):
28
+
29
+    uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
30
+
31
+    name = forms.CharField(
32
+        label=_('Board Name'),
33
+        widget=forms.TextInput(attrs={'readonly': 'readonly'})
34
+    )
35
+
36
+    ws_name = forms.CharField(label=_("Web Service Name"))
37
+
38
+    port = forms.IntegerField(
39
+        label=_("Port"),
40
+        help_text=_("The port used by the service")
41
+    )
42
+
43
+    secure = forms.BooleanField(label=_("Secure"), initial=True)
44
+
45
+    def __init__(self, *args, **kwargs):
46
+        super(ExposeWebserviceForm, self).__init__(*args, **kwargs)
47
+
48
+    def handle(self, request, data):
49
+        try:
50
+            iotronic.webservice_expose(request, data["uuid"],
51
+                                       data["ws_name"], data["port"],
52
+                                       data["secure"])
53
+
54
+            messages.success(request, _("Web Service " + str(data["name"]) +
55
+                                        " exposed successfully on port " +
56
+                                        str(data["port"]) + "."))
57
+            return True
58
+
59
+        except Exception:
60
+            exceptions.handle(request, _('Unable to expose web service.'))
61
+
62
+
63
+class UnexposeWebserviceForm(forms.SelfHandlingForm):
64
+
65
+    uuid = forms.CharField(label=_("Board ID"), widget=forms.HiddenInput)
66
+
67
+    name = forms.CharField(
68
+        label=_('Board Name'),
69
+        widget=forms.TextInput(attrs={'readonly': 'readonly'})
70
+    )
71
+
72
+    ws_onboard = forms.MultipleChoiceField(
73
+        label=_("Web Services on board"),
74
+        widget=forms.SelectMultiple(
75
+            attrs={'class': 'switchable',
76
+                   'data-slug': 'slug-select-webservices'}),
77
+        help_text=_("Select a webservice from the list")
78
+    )
79
+
80
+    def __init__(self, *args, **kwargs):
81
+
82
+        super(UnexposeWebserviceForm, self).__init__(*args, **kwargs)
83
+        self.fields["ws_onboard"].choices = kwargs["initial"]["ws_onboard"]
84
+
85
+    def handle(self, request, data):
86
+
87
+        counter = 0
88
+        for ws in data["ws_onboard"]:
89
+            try:
90
+                iotronic.webservice_unexpose(request, ws)
91
+
92
+                message_text = "Web Service(s) unexposed successfully."
93
+                messages.success(request, _(message_text))
94
+
95
+                if counter != len(data["ws_onboard"]) - 1:
96
+                    counter += 1
97
+                else:
98
+                    return True
99
+
100
+            except Exception:
101
+                LOG.debug("HERE")
102
+                message_text = "Unable to unexpose web service."
103
+                exceptions.handle(request, _(message_text))

+ 28
- 0
iotronic_ui/iot/webservices/panel.py View File

@@ -0,0 +1,28 @@
1
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+# not use this file except in compliance with the License. You may obtain
3
+# a copy of the License at
4
+#
5
+#      http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+# Unless required by applicable law or agreed to in writing, software
8
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+# License for the specific language governing permissions and limitations
11
+# under the License.
12
+
13
+from django.utils.translation import ugettext_lazy as _
14
+
15
+import horizon
16
+
17
+# from openstack_dashboard.api import keystone
18
+from iotronic_ui.iot import dashboard
19
+
20
+
21
+class Webservices(horizon.Panel):
22
+    name = _("Web Services")
23
+    slug = "webservices"
24
+    # permissions = ('openstack.webservices.iot', )
25
+    # policy_rules = (("iot", "iot:list_all_webservices"),)
26
+
27
+
28
+dashboard.Iot.register(Webservices)

+ 121
- 0
iotronic_ui/iot/webservices/tables.py View File

@@ -0,0 +1,121 @@
1
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+# not use this file except in compliance with the License. You may obtain
3
+# a copy of the License at
4
+#
5
+#      http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+# Unless required by applicable law or agreed to in writing, software
8
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+# License for the specific language governing permissions and limitations
11
+# under the License.
12
+
13
+import logging
14
+
15
+from django import template
16
+from django.utils.translation import ugettext_lazy as _
17
+from django.utils.translation import ungettext_lazy
18
+
19
+from horizon import tables
20
+
21
+from openstack_dashboard import api
22
+
23
+LOG = logging.getLogger(__name__)
24
+
25
+
26
+class ExposeWebserviceLink(tables.LinkAction):
27
+    name = "expose"
28
+    verbose_name = _("Expose")
29
+    url = "horizon:iot:webservices:expose"
30
+    classes = ("ajax-modal",)
31
+    icon = "plus"
32
+    # policy_rules = (("iot", "iot:expose_webservice"),)
33
+
34
+
35
+class UnexposeWebserviceLink(tables.LinkAction):
36
+    name = "unexpose"
37
+    verbose_name = _("Unexpose")
38
+    url = "horizon:iot:webservices:unexpose"
39
+    classes = ("ajax-modal",)
40
+    icon = "plus"
41
+    # policy_rules = (("iot", "iot:unexpose_webservice"),)
42
+
43
+
44
+"""
45
+class DisableWebservicesAction(tables.DeleteAction):
46
+    @staticmethod
47
+    def action_present(count):
48
+        return ungettext_lazy(
49
+            u"Disable",
50
+            u"Disable Web Services",
51
+            count
52
+        )
53
+
54
+    @staticmethod
55
+    def action_past(count):
56
+        return ungettext_lazy(
57
+            u"Disabled Web Service",
58
+            u"Disabled Web Services",
59
+            count
60
+        )
61
+    # policy_rules = (("iot", "iot:disable_webservice"),)
62
+
63
+    def delete(self, request, board_id):
64
+        api.iotronic.webservice_disable(request, board_id)
65
+"""
66
+
67
+
68
+class WebserviceFilterAction(tables.FilterAction):
69
+
70
+    def filter(self, table, webservices, filter_string):
71
+        # Naive case-insensitive search.
72
+        q = filter_string.lower()
73
+        return [webservice for webservice in webservices
74
+                if q in webservice.name.lower()]
75
+
76
+
77
+def show_webservices(board_info):
78
+    template_name = 'iot/webservices/_cell_webservices.html'
79
+    context = board_info._info
80
+    # LOG.debug("CONTEXT: %s", context)
81
+    return template.loader.render_to_string(template_name,
82
+                                            context)
83
+
84
+
85
+class WebservicesTable(tables.DataTable):
86
+
87
+    """
88
+    uuid = tables.WrappingColumn('uuid',
89
+                                 link="horizon:iot:webservices:detail",
90
+                                 verbose_name=_('UUID'))
91
+    """
92
+    board = tables.Column('name', verbose_name=_('Board Name'))
93
+
94
+    board_uuid = tables.Column('board_uuid', 
95
+                               verbose_name=_('Board UUID'),
96
+                               hidden=True)
97
+
98
+    webservices = tables.Column(show_webservices,
99
+                                verbose_name=_('Web Services'))
100
+
101
+    http = tables.Column('http_port', verbose_name=_('HTTP'))
102
+    https = tables.Column('https_port', verbose_name=_('HTTPS'))
103
+
104
+    # Overriding get_object_id method because in IoT webservice the "id" is
105
+    # identified by the field UUID
106
+    def get_object_id(self, datum):
107
+        # LOG.debug('SELF: %s', self)
108
+        return datum.board_uuid
109
+
110
+    class Meta(object):
111
+        name = "webservices"
112
+        verbose_name = _("Web Services")
113
+        """
114
+        row_actions = (ExposeWebserviceLink,
115
+                       UnexposeWebserviceLink,
116
+                       DisableWebservicesAction)
117
+        table_actions = (WebserviceFilterAction, DisableWebservicesAction)
118
+        """
119
+        row_actions = (ExposeWebserviceLink,
120
+                       UnexposeWebserviceLink)
121
+        table_actions = (WebserviceFilterAction,)

+ 47
- 0
iotronic_ui/iot/webservices/tabs.py View File

@@ -0,0 +1,47 @@
1
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+# not use this file except in compliance with the License. You may obtain
3
+# a copy of the License at
4
+#
5
+#      http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+# Unless required by applicable law or agreed to in writing, software
8
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+# License for the specific language governing permissions and limitations
11
+# under the License.
12
+
13
+import logging
14
+
15
+# from django.core.urlresolvers import reverse
16
+from django.utils.translation import ugettext_lazy as _
17
+
18
+from horizon import tabs
19
+
20
+LOG = logging.getLogger(__name__)
21
+
22
+
23
+"""
24
+class OverviewTab(tabs.Tab):
25
+    name = _("Overview")
26
+    slug = "overview"
27
+    template_name = ("iot/webservices/_detail_overview.html")
28
+
29
+    def get_context_data(self, request):
30
+        # coordinates = self.tab_group.kwargs['board'].__dict__["location"][0]
31
+        # LOG.debug('IOT INFO: %s', coordinates)
32
+
33
+        board_name = self.tab_group.kwargs['webservice']._info['board_name']
34
+        board_uuid = self.tab_group.kwargs['webservice']._info['board_uuid']
35
+
36
+        return {"webservice": self.tab_group.kwargs['webservice'],
37
+                "board_uuid": board_uuid,
38
+                "board_name": board_name,
39
+                "is_superuser": request.user.is_superuser}
40
+
41
+
42
+class WebserviceDetailTabs(tabs.TabGroup):
43
+    slug = "webservice_details"
44
+    # tabs = (OverviewTab, LogTab, ConsoleTab, AuditTab)
45
+    tabs = (OverviewTab,)
46
+    sticky = True
47
+"""

+ 8
- 0
iotronic_ui/iot/webservices/templates/webservices/_cell_webservices.html View File

@@ -0,0 +1,8 @@
1
+{% load i18n %}
2
+{% if webservices %}
3
+    {% for ws in webservices %}
4
+        <dd><a target="_blank" href="{{ ws.service_url}}">{{ ws.service_url}}</a></dd>
5
+    {% endfor %}
6
+{% else %}
7
+    <dd>--</dd>
8
+{% endif %}

+ 27
- 0
iotronic_ui/iot/webservices/templates/webservices/_detail_overview.html View File

@@ -0,0 +1,27 @@
1
+{% load i18n sizeformat %}
2
+
3
+<div class="detail">
4
+  <dl class="dl-horizontal">
5
+    <dt>{% trans "Name" %}</dt>
6
+    <dd>{{ webservice.name }}</dd>
7
+    <dt>{% trans "Port" %}</dt>
8
+    <dd>{{ webservice.port }}</dd>
9
+    <dt>{% trans "ID" %}</dt>
10
+    <dd>{{ webservice.uuid }}</dd>
11
+    <dt>{% trans "Created At" %}</dt>
12
+    <dd>{{ webservice.created_at }}</dd>
13
+    <dt>{% trans "extra" %}</dt>
14
+    <dd>{{ webservice.extra }}</dd>
15
+  </dl>
16
+
17
+  <h4>{% trans "Board" %}</h4>
18
+    <hr class="header_rule">
19
+    <dl class="dl-horizontal">
20
+      {% if board_uuid %}
21
+          <dt>{{ board_name }}</dt>
22
+          <dd>{{ board_uuid }}</dd>
23
+      {% else %}
24
+          <dd>--</dd>
25
+      {% endif %}
26
+    </dl>
27
+</div>

iotronic_ui/iot/fleets/templates/fleets/_action.html → iotronic_ui/iot/webservices/templates/webservices/_expose.html View File

@@ -3,5 +3,6 @@
3 3
 
4 4
 {% block modal-body-right %}
5 5
   <h3>{% trans "Description:" %}</h3>
6
-  <p>{% trans "Execute action on board(s)." %}</p>
6
+  <p>{% trans "Expose a new Web Service." %}</p>
7 7
 {% endblock %}
8
+

+ 8
- 0
iotronic_ui/iot/webservices/templates/webservices/_unexpose.html View File

@@ -0,0 +1,8 @@
1
+{% extends "horizon/common/_modal_form.html" %}
2
+{% load i18n %}
3
+
4
+{% block modal-body-right %}
5
+  <h3>{% trans "Description:" %}</h3>
6
+  <p>{% trans "Unexpose Web Service(s)." %}</p>
7
+{% endblock %}
8
+

+ 7
- 0
iotronic_ui/iot/webservices/templates/webservices/expose.html View File

@@ -0,0 +1,7 @@
1
+{% extends 'base.html' %}
2
+{% load i18n %}
3
+{% block title %}{% trans "Insert Web Service" %}{% endblock %}
4
+
5
+{% block main %}
6
+    {% include 'iot/webservices/_expose.html' %}
7
+{% endblock %}

+ 7
- 0
iotronic_ui/iot/webservices/templates/webservices/index.html View File

@@ -0,0 +1,7 @@
1
+{% extends 'base.html' %}
2
+{% load i18n %}
3
+{% block title %}{% trans "Web Services" %}{% endblock %}
4
+
5
+{% block main %}
6
+    {{ table.render }}
7
+{% endblock %}

+ 7
- 0
iotronic_ui/iot/webservices/templates/webservices/unexpose.html View File

@@ -0,0 +1,7 @@
1
+{% extends 'base.html' %}
2
+{% load i18n %}
3
+{% block title %}{% trans "Unexpose Web Service" %}{% endblock %}
4
+
5
+{% block main %}
6
+    {% include 'iot/webservices/_unexpose.html' %}
7
+{% endblock %}

+ 19
- 0
iotronic_ui/iot/webservices/tests.py View File

@@ -0,0 +1,19 @@
1
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+# not use this file except in compliance with the License. You may obtain
3
+# a copy of the License at
4
+#
5
+#      http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+# Unless required by applicable law or agreed to in writing, software
8
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+# License for the specific language governing permissions and limitations
11
+# under the License.
12
+
13
+from horizon.test import helpers as test
14
+
15
+
16
+class FleetsTests(test.TestCase):
17
+    # Unit tests for boards.
18
+    def test_me(self):
19
+        self.assertTrue(1 + 1 == 2)

+ 26
- 0
iotronic_ui/iot/webservices/urls.py View File

@@ -0,0 +1,26 @@
1
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+# not use this file except in compliance with the License. You may obtain
3
+# a copy of the License at
4
+#
5
+#      http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+# Unless required by applicable law or agreed to in writing, software
8
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+# License for the specific language governing permissions and limitations
11
+# under the License.
12
+
13
+from django.conf.urls import url
14
+
15
+from iotronic_ui.iot.webservices import views
16
+
17
+
18
+urlpatterns = [
19
+    url(r'^$', views.IndexView.as_view(), name='index'),
20
+    url(r'^(?P<board_id>[^/]+)/expose/$',
21
+        views.ExposeView.as_view(), name='expose'),
22
+    url(r'^(?P<board_id>[^/]+)/unexpose/$',
23
+        views.UnexposeView.as_view(), name='unexpose'),
24
+    # url(r'^(?P<webservice_id>[^/]+)/detail/$', views.WebserviceDetailView.as_view(),
25
+    #     name='detail'),
26
+]

+ 234
- 0
iotronic_ui/iot/webservices/views.py View File

@@ -0,0 +1,234 @@
1
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+# not use this file except in compliance with the License. You may obtain
3
+# a copy of the License at
4
+#
5
+#      http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+# Unless required by applicable law or agreed to in writing, software
8
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+# License for the specific language governing permissions and limitations
11
+# under the License.
12
+
13
+import logging
14
+
15
+from django.core.urlresolvers import reverse
16
+from django.core.urlresolvers import reverse_lazy
17
+from django.utils.translation import ugettext_lazy as _
18
+
19
+from horizon import exceptions
20
+from horizon import forms
21
+# from horizon import messages
22
+from horizon import tables
23
+from horizon import tabs
24
+from horizon.utils import memoized
25
+
26
+from openstack_dashboard.api import iotronic
27
+from openstack_dashboard import policy
28
+
29
+from iotronic_ui.iot.webservices import forms as project_forms
30
+from iotronic_ui.iot.webservices import tables as project_tables
31
+from iotronic_ui.iot.webservices import tabs as project_tabs
32
+
33
+
34
+LOG = logging.getLogger(__name__)
35
+
36
+
37
+class IndexView(tables.DataTableView):
38
+    table_class = project_tables.WebservicesTable
39
+    template_name = 'iot/webservices/index.html'
40
+    page_title = _("Web Services")
41
+
42
+    def get_data(self):
43
+        webservices = []
44
+        en_webservices = []
45
+
46
+        # Admin
47
+        if policy.check((("iot", "iot:list_all_webservices"),), self.request):
48
+            try:
49
+                webservices = iotronic.webservice_list(self.request,
50
+                                                       None)
51
+                en_webservices = iotronic.webservice_enabled_list(self.request)
52
+
53
+            except Exception:
54
+                exceptions.handle(self.request,
55
+                                  _('Unable to retrieve webservices list.'))
56
+
57
+        # Admin_iot_project
58
+        elif policy.check((("iot", "iot:list_project_webservices"),),
59
+                          self.request):
60
+            try:
61
+                webservices = iotronic.webservice_list(self.request,
62
+                                                       None)
63
+                en_webservices = iotronic.webservice_enabled_list(self.request)
64
+
65
+            except Exception:
66
+                exceptions.handle(self.request,
67
+                                  _('Unable to retrieve webservices list.'))
68
+
69
+        # Other users
70
+        else:
71
+            try:
72
+                webservices = iotronic.webservice_list(self.request,
73
+                                                       None)
74
+                en_webservices = iotronic.webservice_enabled_list(self.request)
75
+
76
+            except Exception:
77
+                exceptions.handle(self.request,
78
+                                  _('Unable to retrieve webservices list.'))
79
+
80
+        # Append some information to the webservice
81
+        # LOG.debug('WSS: %s', webservices)
82
+        for ws_en in en_webservices:
83
+
84
+            ws_list = []
85
+
86
+            for ws in webservices:
87
+                if ws_en.board_uuid == ws.board_uuid:
88
+
89
+                    service_url = "https://" + ws.name + "." + ws_en.dns + "." + ws_en.zone
90
+                    ws_list.append({"service_url": service_url})
91
+
92
+                    ws_en.uuid = ws.uuid
93
+
94
+            board = iotronic.board_get(self.request, ws_en.board_uuid, None)
95
+            ws_en.name = board.name
96
+            ws_en._info.update(dict(webservices=ws_list))
97
+
98
+        # LOG.debug('WS: %s', en_webservices)
99
+        return en_webservices
100
+
101
+
102
+class ExposeView(forms.ModalFormView):
103
+    template_name = 'iot/webservices/expose.html'
104
+    modal_header = _("Expose Web Service")
105
+    form_id = "expose_webservice_form"
106
+    form_class = project_forms.ExposeWebserviceForm
107
+    submit_label = _("Expose")
108
+    submit_url = "horizon:iot:webservices:expose"
109
+    success_url = reverse_lazy('horizon:iot:webservices:index')
110
+    page_title = _("Expose Web Service")
111
+
112
+    @memoized.memoized_method
113
+    def get_object(self):
114
+        try:
115
+            return iotronic.board_get(self.request,
116
+                                      self.kwargs['board_id'],
117
+                                      None)
118
+        except Exception:
119
+            redirect = reverse("horizon:iot:webservices:index")
120
+            exceptions.handle(self.request,
121
+                              _('Unable to get webservice information.'),
122
+                              redirect=redirect)
123
+
124
+    def get_context_data(self, **kwargs):
125
+        context = super(ExposeView, self).get_context_data(**kwargs)
126
+        args = (self.get_object().uuid,)
127
+        context['submit_url'] = reverse(self.submit_url, args=args)
128
+        return context
129
+
130
+    def get_initial(self):
131
+        board = self.get_object()
132
+
133
+        return {'uuid': board.uuid, 'name': board.name}
134
+
135
+
136
+class UnexposeView(forms.ModalFormView):
137
+    template_name = 'iot/webservices/unexpose.html'
138
+    modal_header = _("Unexpose Web Service")
139
+    form_id = "unexpose_webservice_form"
140
+    form_class = project_forms.UnexposeWebserviceForm
141
+    submit_label = _("Unexpose")
142
+    submit_url = "horizon:iot:webservices:unexpose"
143
+    success_url = reverse_lazy('horizon:iot:webservices:index')
144
+    page_title = _("Unexpose Web Service")
145
+
146
+    @memoized.memoized_method
147
+    def get_object(self):
148
+        try:
149
+            return iotronic.board_get(self.request,
150
+                                      self.kwargs['board_id'],
151
+                                      None)
152
+        except Exception:
153
+            redirect = reverse("horizon:iot:webservices:index")
154
+            exceptions.handle(self.request,
155
+                              _('Unable to get webservice information.'),
156
+                              redirect=redirect)
157
+
158
+    def get_context_data(self, **kwargs):
159
+        context = super(UnexposeView, self).get_context_data(**kwargs)
160
+        args = (self.get_object().uuid,)
161
+        context['submit_url'] = reverse(self.submit_url, args=args)
162
+        return context
163
+
164
+    def get_initial(self):
165
+        board = self.get_object()
166
+
167
+        # Populate web services on board
168
+        ws_onboard = iotronic.webservices_on_board(self.request, board.uuid)
169
+        ws_onboard.sort(key=lambda b: b["name"])
170
+
171
+        ws_onboard_list = []
172
+        for ws in ws_onboard:
173
+            ws_onboard_list.append((ws["uuid"], _(ws["name"])))
174
+
175
+        return {'uuid': board.uuid,
176
+                'name': board.name,
177
+                'ws_onboard': ws_onboard_list}
178
+
179
+
180
+"""
181
+class DetailView(tabs.TabView):
182
+    tab_group_class = project_tabs.WebserviceDetailTabs
183
+    template_name = 'horizon/common/_detail.html'
184
+    page_title = "{{ webservice.name|default:webservice.uuid }}"
185
+
186
+    def get_context_data(self, **kwargs):
187
+        context = super(DetailView, self).get_context_data(**kwargs)
188
+        webservice = self.get_data()
189
+        context["webservice"] = webservice
190
+        context["url"] = reverse(self.redirect_url)
191
+        context["actions"] = self._get_actions(webservice)
192
+
193
+        return context
194
+
195
+    def _get_actions(self, webservice):
196
+        table = project_tables.WebservicesTable(self.request)
197
+        return table.render_row_actions(webservice)
198
+
199
+    @memoized.memoized_method
200
+    def get_data(self):
201
+        webservice = []
202
+
203
+        webservice_id = self.kwargs['webservice_id']
204
+        try:
205
+            webservice = iotronic.webservice_get(self.request,
206
+                                                 webservice_id,
207
+                                                 None)
208
+            board = iotronic.board_get(self.request,
209
+                                       webservice.board_uuid,
210
+                                       None)
211
+
212
+            webservice._info.update({u'board_name': board.name})
213
+            webservice.board_name = board.name
214
+            # LOG.debug('WS: %s', webservice)
215
+
216
+        except Exception:
217
+            s = webservice.name
218
+            msg = ('Unable to retrieve webservice %s information') % {'name': s}
219
+            exceptions.handle(self.request, msg, ignore=True)
220
+
221
+        return webservice
222
+
223
+    def get_tabs(self, request, *args, **kwargs):
224
+        webservice = self.get_data()
225
+        return self.tab_group_class(request, webservice=webservice, **kwargs)
226
+
227
+
228
+class WebserviceDetailView(DetailView):
229
+    redirect_url = 'horizon:iot:webservices:index'
230
+
231
+    def _get_actions(self, webservice):
232
+        table = project_tables.WebservicesTable(self.request)
233
+        return table.render_row_actions(webservice)
234
+"""

Loading…
Cancel
Save