summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-12-05 17:09:26 +0000
committerGerrit Code Review <review@openstack.org>2013-12-05 17:09:26 +0000
commit127e0195ad8b870a97ceaa6344c40e720d9db4b6 (patch)
tree2a82adb1cecb02914168dcbab652e057d9a28daa
parentc3096ea60897155f62d31403103aae384f39b4b8 (diff)
parent25a466fe0795a7ad46fe11e82c0b3caca91678f6 (diff)
downloadtuskar-ui-127e0195ad8b870a97ceaa6344c40e720d9db4b6.tar.gz
Merge "New structure of panels"
-rw-r--r--tuskar_ui/infrastructure/dashboard.py64
-rw-r--r--tuskar_ui/infrastructure/deploy_block_storage/__init__.py (renamed from tuskar_ui/infrastructure/resource_management/__init__.py)0
-rw-r--r--tuskar_ui/infrastructure/deploy_block_storage/panel.py27
-rw-r--r--tuskar_ui/infrastructure/deploy_block_storage/urls.py (renamed from tuskar_ui/infrastructure/service_management/urls.py)4
-rw-r--r--tuskar_ui/infrastructure/deploy_block_storage/views.py18
-rw-r--r--tuskar_ui/infrastructure/deploy_compute/__init__.py (renamed from tuskar_ui/infrastructure/resource_management/flavors/__init__.py)0
-rw-r--r--tuskar_ui/infrastructure/deploy_compute/panel.py27
-rw-r--r--tuskar_ui/infrastructure/deploy_compute/urls.py (renamed from tuskar_ui/infrastructure/service_management/tests.py)14
-rw-r--r--tuskar_ui/infrastructure/deploy_compute/views.py18
-rw-r--r--tuskar_ui/infrastructure/deploy_controller/__init__.py (renamed from tuskar_ui/infrastructure/resource_management/nodes/__init__.py)0
-rw-r--r--tuskar_ui/infrastructure/deploy_controller/panel.py27
-rw-r--r--tuskar_ui/infrastructure/deploy_controller/urls.py (renamed from tuskar_ui/infrastructure/service_management/views.py)15
-rw-r--r--tuskar_ui/infrastructure/deploy_controller/views.py18
-rw-r--r--tuskar_ui/infrastructure/deploy_object_storage/__init__.py (renamed from tuskar_ui/infrastructure/resource_management/racks/__init__.py)0
-rw-r--r--tuskar_ui/infrastructure/deploy_object_storage/panel.py27
-rw-r--r--tuskar_ui/infrastructure/deploy_object_storage/urls.py (renamed from tuskar_ui/infrastructure/resource_management/flavors/urls.py)14
-rw-r--r--tuskar_ui/infrastructure/deploy_object_storage/views.py18
-rw-r--r--tuskar_ui/infrastructure/deploy_overview/__init__.py (renamed from tuskar_ui/infrastructure/resource_management/resource_classes/__init__.py)0
-rw-r--r--tuskar_ui/infrastructure/deploy_overview/panel.py (renamed from tuskar_ui/infrastructure/resource_management/panel.py)8
-rw-r--r--tuskar_ui/infrastructure/deploy_overview/urls.py23
-rw-r--r--tuskar_ui/infrastructure/deploy_overview/views.py18
-rw-r--r--tuskar_ui/infrastructure/images_overview/__init__.py (renamed from tuskar_ui/infrastructure/service_management/__init__.py)0
-rw-r--r--tuskar_ui/infrastructure/images_overview/panel.py27
-rw-r--r--tuskar_ui/infrastructure/images_overview/urls.py23
-rw-r--r--tuskar_ui/infrastructure/images_overview/views.py18
-rw-r--r--tuskar_ui/infrastructure/logs_overview/__init__.py0
-rw-r--r--tuskar_ui/infrastructure/logs_overview/panel.py27
-rw-r--r--tuskar_ui/infrastructure/logs_overview/urls.py23
-rw-r--r--tuskar_ui/infrastructure/logs_overview/views.py18
-rw-r--r--tuskar_ui/infrastructure/networks_overview/__init__.py0
-rw-r--r--tuskar_ui/infrastructure/networks_overview/panel.py27
-rw-r--r--tuskar_ui/infrastructure/networks_overview/urls.py23
-rw-r--r--tuskar_ui/infrastructure/networks_overview/views.py18
-rw-r--r--tuskar_ui/infrastructure/overview/panel.py4
-rw-r--r--tuskar_ui/infrastructure/resource_management/flavors/forms.py80
-rw-r--r--tuskar_ui/infrastructure/resource_management/flavors/tabs.py35
-rw-r--r--tuskar_ui/infrastructure/resource_management/flavors/tests.py69
-rw-r--r--tuskar_ui/infrastructure/resource_management/flavors/views.py75
-rw-r--r--tuskar_ui/infrastructure/resource_management/forms.py33
-rw-r--r--tuskar_ui/infrastructure/resource_management/nodes/forms.py98
-rw-r--r--tuskar_ui/infrastructure/resource_management/nodes/tables.py104
-rw-r--r--tuskar_ui/infrastructure/resource_management/nodes/tabs.py56
-rw-r--r--tuskar_ui/infrastructure/resource_management/nodes/tests.py91
-rw-r--r--tuskar_ui/infrastructure/resource_management/nodes/urls.py30
-rw-r--r--tuskar_ui/infrastructure/resource_management/nodes/views.py70
-rw-r--r--tuskar_ui/infrastructure/resource_management/racks/forms.py153
-rw-r--r--tuskar_ui/infrastructure/resource_management/racks/tables.py126
-rw-r--r--tuskar_ui/infrastructure/resource_management/racks/tabs.py53
-rw-r--r--tuskar_ui/infrastructure/resource_management/racks/tests.py411
-rw-r--r--tuskar_ui/infrastructure/resource_management/racks/urls.py43
-rw-r--r--tuskar_ui/infrastructure/resource_management/racks/views.py250
-rw-r--r--tuskar_ui/infrastructure/resource_management/racks/workflows.py266
-rw-r--r--tuskar_ui/infrastructure/resource_management/resource_classes/forms.py75
-rw-r--r--tuskar_ui/infrastructure/resource_management/resource_classes/tables.py217
-rw-r--r--tuskar_ui/infrastructure/resource_management/resource_classes/tabs.py79
-rw-r--r--tuskar_ui/infrastructure/resource_management/resource_classes/tests.py656
-rw-r--r--tuskar_ui/infrastructure/resource_management/resource_classes/urls.py52
-rw-r--r--tuskar_ui/infrastructure/resource_management/resource_classes/views.py196
-rw-r--r--tuskar_ui/infrastructure/resource_management/resource_classes/workflows.py350
-rw-r--r--tuskar_ui/infrastructure/resource_management/tabs.py118
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision.html29
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision_info.html71
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision_progress.html8
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/flavors/_detail_overview.html31
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/flavors/detail.html24
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/index.html25
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/_detail_overview.html258
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/detail.html25
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/unracked.html30
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/provision.html11
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_create.html22
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_detail_overview.html323
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_edit.html22
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_edit_status.html23
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_index_table.html4
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_rack_nodes_step.html17
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_upload.html37
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/create.html11
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/detail.html60
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/edit.html11
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/edit_status.html11
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/upload.html11
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_action.html22
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_flavors.html1
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_overview.html239
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_racks.html1
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_flavors_step.html35
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_index_table.html3
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_table_step.html5
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/action.html9
-rw-r--r--tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/detail.html63
-rw-r--r--tuskar_ui/infrastructure/resource_management/tests.py95
-rw-r--r--tuskar_ui/infrastructure/resource_management/urls.py45
-rw-r--r--tuskar_ui/infrastructure/resource_management/views.py52
-rw-r--r--tuskar_ui/infrastructure/resources_archived/__init__.py0
-rw-r--r--tuskar_ui/infrastructure/resources_archived/panel.py27
-rw-r--r--tuskar_ui/infrastructure/resources_archived/urls.py23
-rw-r--r--tuskar_ui/infrastructure/resources_archived/views.py18
-rw-r--r--tuskar_ui/infrastructure/resources_management/__init__.py0
-rw-r--r--tuskar_ui/infrastructure/resources_management/panel.py27
-rw-r--r--tuskar_ui/infrastructure/resources_management/urls.py23
-rw-r--r--tuskar_ui/infrastructure/resources_management/views.py18
-rw-r--r--tuskar_ui/infrastructure/resources_overview/__init__.py0
-rw-r--r--tuskar_ui/infrastructure/resources_overview/panel.py27
-rw-r--r--tuskar_ui/infrastructure/resources_overview/urls.py23
-rw-r--r--tuskar_ui/infrastructure/resources_overview/views.py18
-rw-r--r--tuskar_ui/infrastructure/resources_resource/__init__.py0
-rw-r--r--tuskar_ui/infrastructure/resources_resource/panel.py (renamed from tuskar_ui/infrastructure/service_management/panel.py)10
-rw-r--r--tuskar_ui/infrastructure/resources_resource/urls.py23
-rw-r--r--tuskar_ui/infrastructure/resources_resource/views.py18
-rw-r--r--tuskar_ui/infrastructure/resources_unallocated/__init__.py0
-rw-r--r--tuskar_ui/infrastructure/resources_unallocated/panel.py27
-rw-r--r--tuskar_ui/infrastructure/resources_unallocated/urls.py23
-rw-r--r--tuskar_ui/infrastructure/resources_unallocated/views.py18
-rw-r--r--tuskar_ui/infrastructure/service_management/templates/service_management/index.html12
115 files changed, 833 insertions, 5470 deletions
diff --git a/tuskar_ui/infrastructure/dashboard.py b/tuskar_ui/infrastructure/dashboard.py
index 23b61863..311ba525 100644
--- a/tuskar_ui/infrastructure/dashboard.py
+++ b/tuskar_ui/infrastructure/dashboard.py
@@ -17,11 +17,71 @@ from django.utils.translation import ugettext_lazy as _ # noqa
import horizon
+class InfrastructureOverview(horizon.PanelGroup):
+ slug = "infrastructure_overview"
+ name = _("Overview")
+ panels = (
+ 'overview',
+ )
+
+
+class Deployment(horizon.PanelGroup):
+ slug = "deploy"
+ name = _("Deployment")
+ panels = (
+ 'deploy_overview',
+ 'deploy_controller',
+ 'deploy_compute',
+ 'deploy_object_storage',
+ 'deploy_block_storage',
+ )
+
+
+class Resources(horizon.PanelGroup):
+ slug = "nodes"
+ name = _("Resources")
+ panels = (
+ 'resources_overview',
+ 'resources_resource',
+ 'resources_management',
+ 'resources_unallocated',
+ 'resources_archived',
+ )
+
+
+class Networks(horizon.PanelGroup):
+ slug = "networks"
+ name = _("Networks")
+ panels = (
+ 'networks_overview',
+ )
+
+
+class Images(horizon.PanelGroup):
+ slug = "images"
+ name = _("Images")
+ panels = (
+ 'images_overview',
+ )
+
+
+class Logs(horizon.PanelGroup):
+ slug = "logs"
+ name = _("Logs")
+ panels = (
+ 'logs_overview',
+ )
+
+
class Infrastructure(horizon.Dashboard):
name = _("Infrastructure")
slug = "infrastructure"
- panels = ('resource_management',)
- default_panel = 'resource_management'
+ panels = (
+ InfrastructureOverview,
+ Deployment,
+ Resources,
+ )
+ default_panel = 'overview'
permissions = ('openstack.roles.admin',)
diff --git a/tuskar_ui/infrastructure/resource_management/__init__.py b/tuskar_ui/infrastructure/deploy_block_storage/__init__.py
index e69de29b..e69de29b 100644
--- a/tuskar_ui/infrastructure/resource_management/__init__.py
+++ b/tuskar_ui/infrastructure/deploy_block_storage/__init__.py
diff --git a/tuskar_ui/infrastructure/deploy_block_storage/panel.py b/tuskar_ui/infrastructure/deploy_block_storage/panel.py
new file mode 100644
index 00000000..780e5340
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_block_storage/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class BlockStorage(horizon.Panel):
+ name = _("Block Storage")
+ slug = "deploy_block_storage"
+
+
+dashboard.Infrastructure.register(BlockStorage)
diff --git a/tuskar_ui/infrastructure/service_management/urls.py b/tuskar_ui/infrastructure/deploy_block_storage/urls.py
index 23dcbd5f..79685177 100644
--- a/tuskar_ui/infrastructure/service_management/urls.py
+++ b/tuskar_ui/infrastructure/deploy_block_storage/urls.py
@@ -1,4 +1,4 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
+# -*- coding: utf8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
@@ -14,7 +14,7 @@
from django.conf.urls import defaults
-from tuskar_ui.infrastructure.service_management import views
+from tuskar_ui.infrastructure.deploy_block_storage import views
urlpatterns = defaults.patterns(
diff --git a/tuskar_ui/infrastructure/deploy_block_storage/views.py b/tuskar_ui/infrastructure/deploy_block_storage/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_block_storage/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/resource_management/flavors/__init__.py b/tuskar_ui/infrastructure/deploy_compute/__init__.py
index e69de29b..e69de29b 100644
--- a/tuskar_ui/infrastructure/resource_management/flavors/__init__.py
+++ b/tuskar_ui/infrastructure/deploy_compute/__init__.py
diff --git a/tuskar_ui/infrastructure/deploy_compute/panel.py b/tuskar_ui/infrastructure/deploy_compute/panel.py
new file mode 100644
index 00000000..d7d3d576
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_compute/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class Compute(horizon.Panel):
+ name = _("Compute")
+ slug = "deploy_compute"
+
+
+dashboard.Infrastructure.register(Compute)
diff --git a/tuskar_ui/infrastructure/service_management/tests.py b/tuskar_ui/infrastructure/deploy_compute/urls.py
index e0f8c290..983c24ae 100644
--- a/tuskar_ui/infrastructure/service_management/tests.py
+++ b/tuskar_ui/infrastructure/deploy_compute/urls.py
@@ -1,4 +1,4 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
+# -*- coding: utf8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
@@ -12,10 +12,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from openstack_dashboard.test import helpers as test
+from django.conf.urls import defaults
+from tuskar_ui.infrastructure.deploy_compute import views
-class Service_ManagementTests(test.TestCase):
- # Unit tests for service_management.
- def test_me(self):
- self.assertTrue(1 + 1 == 2)
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/deploy_compute/views.py b/tuskar_ui/infrastructure/deploy_compute/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_compute/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/resource_management/nodes/__init__.py b/tuskar_ui/infrastructure/deploy_controller/__init__.py
index e69de29b..e69de29b 100644
--- a/tuskar_ui/infrastructure/resource_management/nodes/__init__.py
+++ b/tuskar_ui/infrastructure/deploy_controller/__init__.py
diff --git a/tuskar_ui/infrastructure/deploy_controller/panel.py b/tuskar_ui/infrastructure/deploy_controller/panel.py
new file mode 100644
index 00000000..90ba46d6
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_controller/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class Controller(horizon.Panel):
+ name = _("Controller")
+ slug = "deploy_controller"
+
+
+dashboard.Infrastructure.register(Controller)
diff --git a/tuskar_ui/infrastructure/service_management/views.py b/tuskar_ui/infrastructure/deploy_controller/urls.py
index 6c0c027a..ab9a548d 100644
--- a/tuskar_ui/infrastructure/service_management/views.py
+++ b/tuskar_ui/infrastructure/deploy_controller/urls.py
@@ -1,4 +1,4 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
+# -*- coding: utf8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
@@ -12,13 +12,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from horizon import views
+from django.conf.urls import defaults
+from tuskar_ui.infrastructure.deploy_controller import views
-class IndexView(views.APIView):
- # A very simple class-based view...
- template_name = 'infrastructure/service_management/index.html'
- def get_data(self, request, context, *args, **kwargs):
- # Add data to the context here...
- return context
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/deploy_controller/views.py b/tuskar_ui/infrastructure/deploy_controller/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_controller/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/resource_management/racks/__init__.py b/tuskar_ui/infrastructure/deploy_object_storage/__init__.py
index e69de29b..e69de29b 100644
--- a/tuskar_ui/infrastructure/resource_management/racks/__init__.py
+++ b/tuskar_ui/infrastructure/deploy_object_storage/__init__.py
diff --git a/tuskar_ui/infrastructure/deploy_object_storage/panel.py b/tuskar_ui/infrastructure/deploy_object_storage/panel.py
new file mode 100644
index 00000000..95bf4f49
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_object_storage/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class ObjectStorage(horizon.Panel):
+ name = _("Object Storage")
+ slug = "deploy_object_storage"
+
+
+dashboard.Infrastructure.register(ObjectStorage)
diff --git a/tuskar_ui/infrastructure/resource_management/flavors/urls.py b/tuskar_ui/infrastructure/deploy_object_storage/urls.py
index 18bd85fd..882e9e56 100644
--- a/tuskar_ui/infrastructure/resource_management/flavors/urls.py
+++ b/tuskar_ui/infrastructure/deploy_object_storage/urls.py
@@ -1,5 +1,4 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
+# -*- coding: utf8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
@@ -15,15 +14,10 @@
from django.conf.urls import defaults
-from tuskar_ui.infrastructure.resource_management.flavors import views
-
+from tuskar_ui.infrastructure.deploy_object_storage import views
-VIEW_MOD = 'tuskar_ui.infrastructure.' \
- 'resource_management.flavors.views'
urlpatterns = defaults.patterns(
- VIEW_MOD,
- defaults.url(r'^(?P<flavor_id>[^/]+)/$',
- views.DetailView.as_view(),
- name='detail')
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
)
diff --git a/tuskar_ui/infrastructure/deploy_object_storage/views.py b/tuskar_ui/infrastructure/deploy_object_storage/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_object_storage/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/__init__.py b/tuskar_ui/infrastructure/deploy_overview/__init__.py
index e69de29b..e69de29b 100644
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/__init__.py
+++ b/tuskar_ui/infrastructure/deploy_overview/__init__.py
diff --git a/tuskar_ui/infrastructure/resource_management/panel.py b/tuskar_ui/infrastructure/deploy_overview/panel.py
index 6d302f85..8761cadb 100644
--- a/tuskar_ui/infrastructure/resource_management/panel.py
+++ b/tuskar_ui/infrastructure/deploy_overview/panel.py
@@ -19,9 +19,9 @@ import horizon
from tuskar_ui.infrastructure import dashboard
-class Resource_Management(horizon.Panel):
- name = _("Resource Management")
- slug = "resource_management"
+class DeploymentOverview(horizon.Panel):
+ name = _("Overview")
+ slug = "deploy_overview"
-dashboard.Infrastructure.register(Resource_Management)
+dashboard.Infrastructure.register(DeploymentOverview)
diff --git a/tuskar_ui/infrastructure/deploy_overview/urls.py b/tuskar_ui/infrastructure/deploy_overview/urls.py
new file mode 100644
index 00000000..b98691d3
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_overview/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import defaults
+
+from tuskar_ui.infrastructure.deploy_overview import views
+
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/deploy_overview/views.py b/tuskar_ui/infrastructure/deploy_overview/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/deploy_overview/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/service_management/__init__.py b/tuskar_ui/infrastructure/images_overview/__init__.py
index e69de29b..e69de29b 100644
--- a/tuskar_ui/infrastructure/service_management/__init__.py
+++ b/tuskar_ui/infrastructure/images_overview/__init__.py
diff --git a/tuskar_ui/infrastructure/images_overview/panel.py b/tuskar_ui/infrastructure/images_overview/panel.py
new file mode 100644
index 00000000..ff391346
--- /dev/null
+++ b/tuskar_ui/infrastructure/images_overview/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class ImagesOverview(horizon.Panel):
+ name = _("Overview")
+ slug = "images_overview"
+
+
+dashboard.Infrastructure.register(ImagesOverview)
diff --git a/tuskar_ui/infrastructure/images_overview/urls.py b/tuskar_ui/infrastructure/images_overview/urls.py
new file mode 100644
index 00000000..71000913
--- /dev/null
+++ b/tuskar_ui/infrastructure/images_overview/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import defaults
+
+from tuskar_ui.infrastructure.images_overview import views
+
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/images_overview/views.py b/tuskar_ui/infrastructure/images_overview/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/images_overview/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/logs_overview/__init__.py b/tuskar_ui/infrastructure/logs_overview/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tuskar_ui/infrastructure/logs_overview/__init__.py
diff --git a/tuskar_ui/infrastructure/logs_overview/panel.py b/tuskar_ui/infrastructure/logs_overview/panel.py
new file mode 100644
index 00000000..1effb660
--- /dev/null
+++ b/tuskar_ui/infrastructure/logs_overview/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class LogsOverview(horizon.Panel):
+ name = _("Overview")
+ slug = "logs_overview"
+
+
+dashboard.Infrastructure.register(LogsOverview)
diff --git a/tuskar_ui/infrastructure/logs_overview/urls.py b/tuskar_ui/infrastructure/logs_overview/urls.py
new file mode 100644
index 00000000..05d7bfda
--- /dev/null
+++ b/tuskar_ui/infrastructure/logs_overview/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import defaults
+
+from tuskar_ui.infrastructure.logs_overview import views
+
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/logs_overview/views.py b/tuskar_ui/infrastructure/logs_overview/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/logs_overview/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/networks_overview/__init__.py b/tuskar_ui/infrastructure/networks_overview/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tuskar_ui/infrastructure/networks_overview/__init__.py
diff --git a/tuskar_ui/infrastructure/networks_overview/panel.py b/tuskar_ui/infrastructure/networks_overview/panel.py
new file mode 100644
index 00000000..30f63c78
--- /dev/null
+++ b/tuskar_ui/infrastructure/networks_overview/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class NetworksOverview(horizon.Panel):
+ name = _("Overview")
+ slug = "networks_overview"
+
+
+dashboard.Infrastructure.register(NetworksOverview)
diff --git a/tuskar_ui/infrastructure/networks_overview/urls.py b/tuskar_ui/infrastructure/networks_overview/urls.py
new file mode 100644
index 00000000..a80bae82
--- /dev/null
+++ b/tuskar_ui/infrastructure/networks_overview/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import defaults
+
+from tuskar_ui.infrastructure.networks_overview import views
+
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/networks_overview/views.py b/tuskar_ui/infrastructure/networks_overview/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/networks_overview/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/overview/panel.py b/tuskar_ui/infrastructure/overview/panel.py
index 6d150eb7..cd20476f 100644
--- a/tuskar_ui/infrastructure/overview/panel.py
+++ b/tuskar_ui/infrastructure/overview/panel.py
@@ -16,10 +16,12 @@ from django.utils.translation import ugettext_lazy as _ # noqa
import horizon
+from tuskar_ui.infrastructure import dashboard
+
class Overview(horizon.Panel):
name = _("Overview")
slug = "overview"
-#dashboard.Infrastructure.register(Overview)
+dashboard.Infrastructure.register(Overview)
diff --git a/tuskar_ui/infrastructure/resource_management/flavors/forms.py b/tuskar_ui/infrastructure/resource_management/flavors/forms.py
deleted file mode 100644
index 92065723..00000000
--- a/tuskar_ui/infrastructure/resource_management/flavors/forms.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.forms import formsets
-from django.utils import datastructures
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import forms
-
-from tuskar_ui import forms as tuskar_forms
-
-
-CAPACITIES = datastructures.SortedDict([
- # (name, (label, unit, required)),
- ('cpu', (_('VCPU'), '', True)),
- ('memory', (_('RAM (MB)'), 'MB', True)),
- ('storage', (_('Root Disk (GB)'), 'GB', True)),
- ('ephemeral_disk', (_('Ephemeral Disk (GB)'), 'GB', False)),
- ('swap_disk', (_('Swap Disk (GB)'), 'GB', False)),
-])
-
-
-class FlavorForm(forms.Form):
- id = forms.IntegerField(widget=forms.HiddenInput(), required=False)
- name = forms.RegexField(label=_("Name"),
- max_length=25,
- regex=r'^[\w\.\- ]+$',
- error_messages={'invalid': _(
- 'Name may only '
- 'contain letters, numbers, underscores, '
- 'periods and hyphens.')},
- widget=forms.TextInput(attrs={
- 'class': 'input input-small',
- }))
-
- def __init__(self, *args, **kwargs):
- super(FlavorForm, self).__init__(*args, **kwargs)
-
- for name, (label, unit, required) in CAPACITIES.items():
- self.fields[name] = forms.IntegerField(
- label=label,
- min_value=0,
- required=required,
- widget=tuskar_forms.NumberInput(attrs={
- 'class': 'input number_input_slim',
- }))
-
-
-class BaseFlavorFormSet(formsets.BaseFormSet):
- def clean(self):
- if any(self.errors):
- # Don't bother validating the formset unless each form is valid
- # on its own
- return
- names = {}
- for form in self.forms:
- name = form.cleaned_data.get('name')
- if not name:
- continue
- if name in names:
- message = _("This value repeats, but it should be unique.")
- other_form = names[name]
- form._errors['name'] = form.error_class([message])
- other_form._errors['name'] = other_form.error_class([message])
- names[name] = form
-
-
-FlavorFormset = formsets.formset_factory(FlavorForm, extra=1, can_delete=True,
- formset=BaseFlavorFormSet)
diff --git a/tuskar_ui/infrastructure/resource_management/flavors/tabs.py b/tuskar_ui/infrastructure/resource_management/flavors/tabs.py
deleted file mode 100644
index e56cbab2..00000000
--- a/tuskar_ui/infrastructure/resource_management/flavors/tabs.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import tabs
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "flavor_overview_tab"
- template_name = ("infrastructure/resource_management/flavors/"
- "_detail_overview.html")
- preload = False
-
- def get_context_data(self, request):
- return {"flavor": self.tab_group.kwargs['flavor'],
- 'resource_class': self.tab_group.kwargs['resource_class']}
-
-
-class FlavorDetailTabs(tabs.TabGroup):
- slug = "flavor_detail_tabs"
- tabs = (OverviewTab,)
- sticky = True
diff --git a/tuskar_ui/infrastructure/resource_management/flavors/tests.py b/tuskar_ui/infrastructure/resource_management/flavors/tests.py
deleted file mode 100644
index 13af7bdb..00000000
--- a/tuskar_ui/infrastructure/resource_management/flavors/tests.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django import http
-import mox
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.test import helpers as test
-
-
-class FlavorsTests(test.BaseAdminViewTests):
-
- @test.create_stubs({tuskar.Flavor: ('get',),
- tuskar.ResourceClass: ('get',)})
- def test_detail_flavor(self):
- flavor = self.tuskar_flavors.list()[1]
- resource_class = self.tuskar_resource_classes.first()
-
- tuskar.ResourceClass.get(mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- tuskar.Flavor.get(mox.IsA(http.HttpRequest),
- resource_class.id,
- flavor.id).AndReturn(flavor)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:resource_classes:'
- 'flavors:detail',
- args=[resource_class.id, flavor.id])
- res = self.client.get(url)
- self.assertTemplateUsed(res,
- 'infrastructure/resource_management/'
- 'flavors/detail.html')
-
- @test.create_stubs({tuskar.Flavor: ('get',)})
- def test_detail_flavor_exception(self):
- flavor = self.tuskar_flavors.list()[1]
- resource_class = self.tuskar_resource_classes.first()
-
- tuskar.Flavor.get(mox.IsA(http.HttpRequest),
- resource_class.id,
- flavor.id).AndRaise(self.exceptions.tuskar)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:resource_classes:'
- 'flavors:detail',
- args=[resource_class.id, flavor.id])
- res = self.client.get(url)
-
- self.assertRedirectsNoFollow(
- res,
- urlresolvers.reverse('horizon:infrastructure:resource_management:'
- 'index'))
diff --git a/tuskar_ui/infrastructure/resource_management/flavors/views.py b/tuskar_ui/infrastructure/resource_management/flavors/views.py
deleted file mode 100644
index 8d033544..00000000
--- a/tuskar_ui/infrastructure/resource_management/flavors/views.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import tabs as horizon_tabs
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.infrastructure.resource_management.flavors import tabs
-
-
-class DetailView(horizon_tabs.TabView):
- tab_group_class = tabs.FlavorDetailTabs
- template_name = ('infrastructure/resource_management/flavors/detail.html')
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["flavor"] = self.get_flavor_data()
- context["resource_class"] = self.get_resource_class_data()
- return context
-
- def get_flavor_data(self):
- if not hasattr(self, "_flavor"):
- try:
- flavor_id = self.kwargs['flavor_id']
- resource_class_id = self.kwargs['resource_class_id']
- flavor = tuskar.Flavor.get(
- self.request, resource_class_id, flavor_id)
- except Exception:
- redirect = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- exceptions.handle(self.request,
- _('Unable to retrieve details for '
- 'flavor "%s".') % flavor_id,
- redirect=redirect)
- self._flavor = flavor
- return self._flavor
-
- def get_resource_class_data(self):
- if not hasattr(self, "_resource_class"):
- try:
- resource_class_id = self.kwargs['resource_class_id']
- resource_class = tuskar.ResourceClass.get(self.request,
- resource_class_id)
- except Exception:
- redirect = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- exceptions.handle(self.request,
- _('Unable to retrieve details for resource '
- 'class "%s".') % resource_class_id,
- redirect=redirect)
- self._resource_class = resource_class
- return self._resource_class
-
- def get_tabs(self, request, *args, **kwargs):
- flavor = self.get_flavor_data()
- resource_class = self.get_resource_class_data()
- return self.tab_group_class(request,
- flavor=flavor,
- resource_class=resource_class,
- **kwargs)
diff --git a/tuskar_ui/infrastructure/resource_management/forms.py b/tuskar_ui/infrastructure/resource_management/forms.py
deleted file mode 100644
index 5f80d1f7..00000000
--- a/tuskar_ui/infrastructure/resource_management/forms.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from tuskar_ui import api as tuskar
-
-
-class Provision(forms.SelfHandlingForm):
- def handle(self, request, data):
- try:
- tuskar.Rack.provision_all(request)
- except Exception:
- exceptions.handle(request, _("Unable to start provisioning."))
- else:
- msg = _('Started provisioning.')
- messages.success(request, msg)
- return True
diff --git a/tuskar_ui/infrastructure/resource_management/nodes/forms.py b/tuskar_ui/infrastructure/resource_management/nodes/forms.py
deleted file mode 100644
index 68b5566e..00000000
--- a/tuskar_ui/infrastructure/resource_management/nodes/forms.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import django.forms
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-import tuskar_ui.forms
-
-
-class NodeForm(django.forms.Form):
- id = django.forms.IntegerField(
- required=False,
- widget=django.forms.HiddenInput())
-
- service_host = django.forms.CharField(
- label=_("Service Host"),
- widget=django.forms.TextInput(attrs={'class': 'input input-mini'}),
- required=True)
- mac_address = tuskar_ui.forms.MACField(
- label=_("MAC Address"),
- widget=django.forms.TextInput(attrs={'class': 'input input-mini'}),
- required=True)
-
- # Hardware Specifications
- cpus = django.forms.IntegerField(
- label=_("CPUs"), required=True,
- min_value=1, widget=tuskar_ui.forms.NumberInput(attrs={
- 'class': 'input number_input_slim',
- }))
- memory_mb = django.forms.IntegerField(
- label=_("Memory"), required=True, min_value=1,
- widget=tuskar_ui.forms.NumberInput(attrs={
- 'class': 'input number_input_slim',
- }))
- local_gb = django.forms.IntegerField(
- label=_("Local Disk (GB)"), min_value=1,
- widget=tuskar_ui.forms.NumberInput(attrs={
- 'class': 'input number_input_slim',
- }), required=True)
-
- # Power Management
- pm_address = django.forms.GenericIPAddressField(
- widget=django.forms.TextInput(attrs={'class': 'input input-mini'}),
- label=_("Power Management IP"), required=False)
- pm_user = django.forms.CharField(
- label=_("Power Management User"),
- widget=django.forms.TextInput(attrs={'class': 'input input-mini'}),
- required=False)
- pm_password = django.forms.CharField(
- label=_("Power Management Password"),
- required=False, widget=django.forms.PasswordInput(
- render_value=False,
- attrs={'class': 'input input-mini'}))
-
- # Access
- terminal_port = django.forms.IntegerField(
- label=_("Terminal Port"),
- required=False, min_value=0, max_value=1024,
- widget=tuskar_ui.forms.NumberInput(attrs={
- 'class': 'input number_input_slim',
- }))
-
-
-class BaseNodeFormSet(django.forms.formsets.BaseFormSet):
- def clean(self):
- if any(self.errors):
- # Don't bother validating the formset unless each form is valid
- # on its own
- return
- unique_fields = ('mac_address', 'pm_address')
- values = dict((field, {}) for field in unique_fields)
- for form in self.forms:
- for field in unique_fields:
- value = form.cleaned_data.get(field)
- if not value:
- continue
- if value in values[field]:
- message = _("This value repeats, but it should be unique.")
- other_form = values[field][value]
- form._errors[field] = form.error_class([message])
- other_form._errors[field] = other_form.error_class(
- [message])
- values[field][value] = form
-
-
-NodeFormset = django.forms.formsets.formset_factory(
- NodeForm, extra=1, can_delete=True, formset=BaseNodeFormSet)
diff --git a/tuskar_ui/infrastructure/resource_management/nodes/tables.py b/tuskar_ui/infrastructure/resource_management/nodes/tables.py
deleted file mode 100644
index 9ea5d1f5..00000000
--- a/tuskar_ui/infrastructure/resource_management/nodes/tables.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import tables
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.infrastructure.resource_management.nodes import forms \
- as nodes_forms
-import tuskar_ui.tables
-
-
-class DeleteNodes(tables.DeleteAction):
- data_type_singular = _("Node")
- data_type_plural = _("Nodes")
-
- def delete(self, request, obj_id):
- try:
- baremetal_node = tuskar.BaremetalNode.get(request, obj_id)
- baremetal_node.tuskar_node.remove_from_rack(request)
- except Exception:
- exceptions.handle(request, _("Error deleting node."))
- return False
-
-
-class NodesFilterAction(tables.FilterAction):
- def filter(self, table, nodes, filter_string):
- """Naive case-insensitive search."""
- q = filter_string.lower()
- # This is used both for Tuskar and Baremetal nodes.
- return [node for node in nodes if q in node.name.lower()]
-
-
-class NodesTable(tables.DataTable):
- service_host = tables.Column(
- "service_host",
- verbose_name=_("Service Host"),
- link=("horizon:infrastructure:resource_management:nodes:detail"))
- mac_address = tables.Column("mac_address", verbose_name=_("MAC Address"))
- pm_address = tables.Column("pm_address",
- verbose_name=_("Management Address"))
- status = tables.Column("status", verbose_name=_("Status"))
- usage = tables.Column("usage", verbose_name=_("Usage"))
-
- class Meta:
- name = "nodes_table"
- verbose_name = _("Nodes")
- table_actions = (DeleteNodes, NodesFilterAction)
- row_actions = (DeleteNodes,)
-
- def get_object_display(self, datum):
- return datum.service_host
-
-
-class UnrackedNodesTable(NodesTable):
-
- class Meta:
- name = "unracked_nodes"
- verbose_name = _("Unracked Nodes")
- table_actions = ()
- row_actions = ()
-
-
-class NodesFormsetTable(tuskar_ui.tables.FormsetDataTable):
- service_host = tables.Column('service_host',
- verbose_name=_("Service Host"))
- mac_address = tables.Column('mac_address', verbose_name=_("MAC Address"))
-
- cpus = tables.Column('cpus', verbose_name=_("CPUs"))
- memory_mb = tables.Column('memory_mb', verbose_name=_("Memory (MB)"))
- local_gb = tables.Column('local_gb', verbose_name=_("Local Disk (GB)"))
-
- pm_address = tables.Column('pm_address',
- verbose_name=_("Power Management IP"))
- pm_user = tables.Column('pm_user', verbose_name=_("Power Management User"))
- pm_password = tables.Column('pm_password',
- verbose_name=_("Power Management Password"))
-
- terminal_port = tables.Column('terminal_port',
- verbose_name=_("Terminal Port"))
-
- # This is needed for the formset with can_delete=True
- DELETE = tables.Column('DELETE', verbose_name=_("Delete"))
-
- formset_class = nodes_forms.NodeFormset
-
- class Meta:
- name = "nodes"
- verbose_name = _("Nodes")
- table_actions = ()
- multi_select = False
diff --git a/tuskar_ui/infrastructure/resource_management/nodes/tabs.py b/tuskar_ui/infrastructure/resource_management/nodes/tabs.py
deleted file mode 100644
index 8359da53..00000000
--- a/tuskar_ui/infrastructure/resource_management/nodes/tabs.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import messages
-from horizon import tabs
-import novaclient
-import requests
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "node_overview_tab"
- template_name = ("infrastructure/resource_management/nodes/"
- "_detail_overview.html")
- preload = False
-
- def get_context_data(self, request):
- baremetal_node = self.tab_group.kwargs['baremetal_node']
- tuskar_node = baremetal_node.tuskar_node
- if tuskar_node:
- try:
- running_instances = len(tuskar_node.running_virtual_machines)
- except (requests.exceptions.ConnectionError,
- novaclient.exceptions.Unauthorized):
- running_instances = _("Unknown")
- messages.warning(
- request,
- _("Can't retrieve the running instances"
- "from the overcloud."))
- else:
- running_instances = _("None")
-
- return {
- 'baremetal_node': baremetal_node,
- 'tuskar_node': tuskar_node,
- 'running_instances': running_instances,
- }
-
-
-class NodeDetailTabs(tabs.TabGroup):
- slug = "node_detail_tabs"
- tabs = (OverviewTab,)
- sticky = True
diff --git a/tuskar_ui/infrastructure/resource_management/nodes/tests.py b/tuskar_ui/infrastructure/resource_management/nodes/tests.py
deleted file mode 100644
index 0f059d26..00000000
--- a/tuskar_ui/infrastructure/resource_management/nodes/tests.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django import http
-
-import mox
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.test import helpers as test
-
-
-class NodeViewTests(test.BaseAdminViewTests):
- unracked_page = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:nodes:unracked')
-
- @test.create_stubs({tuskar.BaremetalNode: ('list_unracked',), })
- def test_unracked(self):
- unracked_baremetal_nodes = self.baremetal_unracked_nodes.list()
-
- tuskar.BaremetalNode.list_unracked(
- mox.IsA(http.HttpRequest)).AndReturn(unracked_baremetal_nodes)
- self.mox.ReplayAll()
-
- res = self.client.get(self.unracked_page)
- self.assertTemplateUsed(
- res,
- 'infrastructure/resource_management/nodes/unracked.html')
-
- unracked_nodes_table = res.context['unracked_nodes_table'].data
- self.assertItemsEqual(unracked_nodes_table, unracked_baremetal_nodes)
-
- @test.create_stubs({
- tuskar.BaremetalNode: ('get',),
- tuskar.TuskarNode: ('list', 'running_virtual_machines',
- 'list_flavors'),
- tuskar.Rack: ('get',),
- })
- def test_detail_node(self):
- baremetal_node = self.baremetal_nodes.first()
- tuskar_nodes = self.tuskar_nodes.list()
- rack = self.tuskar_racks.first()
-
- tuskar.BaremetalNode.get(mox.IsA(http.HttpRequest),
- baremetal_node.id).AndReturn(baremetal_node)
- tuskar.TuskarNode.list(None).AndReturn(tuskar_nodes)
- tuskar.Rack.get(None, rack.id).AndReturn(rack)
- tuskar.BaremetalNode.get(None,
- baremetal_node.id).AndReturn(baremetal_node)
- self.mox.ReplayAll()
-
- tuskar.TuskarNode.running_virtual_machines = []
- tuskar.TuskarNode.list_flavors = []
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:nodes:detail',
- args=[baremetal_node.id])
- res = self.client.get(url)
- self.assertTemplateUsed(
- res, 'infrastructure/resource_management/nodes/detail.html')
-
- @test.create_stubs({tuskar.BaremetalNode: ('get',)})
- def test_detail_node_exception(self):
- baremetal_node = self.baremetal_nodes.first()
-
- tuskar.BaremetalNode.get(
- mox.IsA(http.HttpRequest),
- baremetal_node.id).AndRaise(self.exceptions.tuskar)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:nodes:detail',
- args=[baremetal_node.id])
- res = self.client.get(url)
-
- self.assertRedirectsNoFollow(
- res,
- urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index'))
diff --git a/tuskar_ui/infrastructure/resource_management/nodes/urls.py b/tuskar_ui/infrastructure/resource_management/nodes/urls.py
deleted file mode 100644
index c714773f..00000000
--- a/tuskar_ui/infrastructure/resource_management/nodes/urls.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls import defaults
-
-from tuskar_ui.infrastructure.resource_management.nodes import views
-
-
-NODES = r'^(?P<node_id>[^/]+)/%s$'
-VIEW_MOD = 'tuskar_ui.infrastructure.resource_management.nodes.views'
-
-
-urlpatterns = defaults.patterns(
- VIEW_MOD,
- defaults.url(NODES % 'detail', views.DetailView.as_view(), name='detail'),
- defaults.url(r'^unracked/$',
- views.UnrackedView.as_view(),
- name='unracked'),
-)
diff --git a/tuskar_ui/infrastructure/resource_management/nodes/views.py b/tuskar_ui/infrastructure/resource_management/nodes/views.py
deleted file mode 100644
index 99829841..00000000
--- a/tuskar_ui/infrastructure/resource_management/nodes/views.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import tables as horizon_tables
-from horizon import tabs as horizon_tabs
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.infrastructure.resource_management.nodes import tables
-from tuskar_ui.infrastructure.resource_management.nodes import tabs
-
-
-class UnrackedView(horizon_tables.DataTableView):
- table_class = tables.UnrackedNodesTable
- template_name = 'infrastructure/resource_management/nodes/unracked.html'
-
- def get_data(self):
- try:
- baremetal_nodes = tuskar.BaremetalNode.list_unracked(self.request)
- except Exception:
- baremetal_nodes = []
- exceptions.handle(self.request,
- _('Unable to retrieve baremetal nodes.'))
- return baremetal_nodes
-
-
-class DetailView(horizon_tabs.TabView):
- tab_group_class = tabs.NodeDetailTabs
- template_name = 'infrastructure/resource_management/nodes/detail.html'
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["baremetal_node"] = self.get_data()
- context["tuskar_node"] = self.get_data().tuskar_node
- return context
-
- def get_data(self):
- if not hasattr(self, "_baremetal_node"):
- baremetal_node_id = self.kwargs['node_id']
- try:
- baremetal_node = tuskar.BaremetalNode.get(self.request,
- baremetal_node_id)
- except Exception:
- redirect = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- exceptions.handle(self.request,
- _('Unable to retrieve details for '
- 'node "%s".') % baremetal_node_id,
- redirect=redirect)
- self._baremetal_node = baremetal_node
- return self._baremetal_node
-
- def get_tabs(self, request, *args, **kwargs):
- baremetal_node = self.get_data()
- return self.tab_group_class(
- request, baremetal_node=baremetal_node, **kwargs)
diff --git a/tuskar_ui/infrastructure/resource_management/racks/forms.py b/tuskar_ui/infrastructure/resource_management/racks/forms.py
deleted file mode 100644
index cc25e3fe..00000000
--- a/tuskar_ui/infrastructure/resource_management/racks/forms.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import django.forms
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from tuskar_ui import api as tuskar
-
-import base64
-import csv
-import logging
-import StringIO
-
-LOG = logging.getLogger(__name__)
-
-
-class UploadRack(forms.SelfHandlingForm):
- csv_file = forms.FileField(label=_("Choose CSV File"),
- help_text=("CSV file with rack definitions"),
- required=False)
- uploaded_data = forms.CharField(widget=forms.HiddenInput(),
- required=False)
-
- def clean_csv_file(self):
- csv_file = self.cleaned_data['csv_file']
- data = csv_file.read() if csv_file else None
-
- if 'upload' in self.request.POST:
- if not csv_file:
- raise django.forms.ValidationError(_('CSV file not set.'))
- else:
- try:
- CSVRack.from_str(data)
- except Exception:
- LOG.exception("Failed to parse rack CSV file.")
- raise django.forms.ValidationError(
- _('Failed to parse CSV file.'))
- return data
-
- def clean_uploaded_data(self):
- data = self.cleaned_data['uploaded_data']
- if 'add_racks' in self.request.POST:
- if not data:
- raise django.forms.ValidationError(_('Upload CSV file first'))
- elif 'upload' in self.request.POST:
- # reset obsolete uploaded data
- self.data['uploaded_data'] = None
- return data
-
- def handle(self, request, data):
- if 'upload' in self.request.POST:
- # if upload button was pressed, stay on the same page
- # but show content of the CSV file in table
- racks_str = self.cleaned_data['csv_file']
- self.initial['racks'] = CSVRack.from_str(racks_str)
- self.data['uploaded_data'] = base64.b64encode(racks_str)
- return False
- else:
- fails = []
- successes = []
- racks_str = self.cleaned_data['uploaded_data']
- racks = CSVRack.from_str(base64.b64decode(racks_str))
- # get the resource class ids by resource class names
- rclass_ids = dict((rc.name, rc.id) for rc in
- tuskar.ResourceClass.list(request))
- for rack in racks:
- try:
- tuskar.Rack.create(
- request,
- name=rack.name,
- resource_class_id=rclass_ids[rack.resource_class],
- location=rack.region,
- subnet=rack.subnet,
- )
- # FIXME: will have to handle nodes once proper attributes
- # for nodes are added
- successes.append(rack.name)
- except Exception:
- LOG.exception("Exception in processing rack CSV file.")
- fails.append(rack.name)
- if successes:
- messages.success(request,
- _('Added %d racks.') % len(successes))
- if fails:
- messages.error(request,
- _('Failed to add following racks: %s') %
- (',').join(fails))
- return True
-
-
-class CSVRack:
- def __init__(self, **kwargs):
- self.id = kwargs['id']
- self.name = kwargs['name']
- self.resource_class = kwargs['resource_class']
- self.region = kwargs['region']
- self.subnet = kwargs['subnet']
- self.nodes = kwargs['nodes']
-
- @classmethod
- def from_str(cls, csv_str):
- racks = []
- csvreader = csv.reader(StringIO.StringIO(csv_str), delimiter=',')
- for row in csvreader:
- # ignore empty rows
- if not row:
- continue
- racks.append(cls(id=row[0],
- name=row[0],
- resource_class=row[1],
- subnet=row[2],
- region=row[3],
- nodes=row[4].split()))
- return racks
-
- def nodes_count(self):
- return len(self.nodes)
-
-
-class UpdateRackStatus(forms.SelfHandlingForm):
-
- def handle(self, request, data):
- try:
- rack = self.initial.get('rack', None)
- action = request.GET.get('action')
- rack.state = {
- 'start': 'active',
- 'unprovision': 'unprovisioned',
- 'reboot': 'active',
- 'shutdown': 'off',
- }[action]
- rack = tuskar.Rack.update(request, rack.id, {'state': rack.state})
- except Exception:
- exceptions.handle(request, _("Unable to update Rack status."))
- else:
- msg = _('Updated rack "%s" status.') % rack.name
- messages.success(request, msg)
- return True
diff --git a/tuskar_ui/infrastructure/resource_management/racks/tables.py b/tuskar_ui/infrastructure/resource_management/racks/tables.py
deleted file mode 100644
index 07e05f03..00000000
--- a/tuskar_ui/infrastructure/resource_management/racks/tables.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import tables
-
-from tuskar_ui import api as tuskar
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteRacks(tables.DeleteAction):
- data_type_singular = _("Rack")
- data_type_plural = _("Racks")
-
- def delete(self, request, obj_id):
- tuskar.Rack.delete(request, obj_id)
-
-
-class CreateRack(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Rack")
- url = "horizon:infrastructure:resource_management:racks:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class UploadRack(tables.LinkAction):
- name = "upload"
- verbose_name = _("Upload Rack")
- url = "horizon:infrastructure:resource_management:racks:upload"
- classes = ("ajax-modal", "btn-upload")
-
-
-class EditRack(tables.LinkAction):
- name = "edit"
- verbose_name = _("Edit Rack")
- url = "horizon:infrastructure:resource_management:racks:edit"
- classes = ("ajax-modal", "btn-edit")
-
-
-class RacksFilterAction(tables.FilterAction):
-
- def filter(self, table, racks, filter_string):
- """Naive case-insensitive search."""
- q = filter_string.lower()
- return [rack for rack in racks
- if q in rack.name.lower()]
-
-
-class UpdateRow(tables.Row):
- ajax = True
-
- def get_data(self, request, rack_id):
- rack = tuskar.Rack.get(request, rack_id)
- return rack
-
-
-def _usage_filter(vm_capacity):
- if vm_capacity and vm_capacity.value:
- return "{0:.0f} %".format(
- round((100.0 / vm_capacity.value) * vm_capacity.usage))
-
-
-class RacksTable(tables.DataTable):
- STATUS_CHOICES = (
- ("unprovisioned", False),
- ("provisioning", None),
- ("active", True),
- ("error", False),
- )
- name = tables.Column('name',
- link=("horizon:infrastructure:resource_management"
- ":racks:detail"),
- verbose_name=_("Rack Name"))
- subnet = tables.Column('subnet', verbose_name=_("IP Subnet"))
- resource_class = tables.Column(
- 'resource_class',
- verbose_name=_("Class"),
- filters=(lambda resource_class: getattr(resource_class, 'name', None),)
- )
- node_count = tables.Column('nodes_count', verbose_name=_("Nodes"))
- state = tables.Column('state',
- verbose_name=_("State"),
- status=True,
- status_choices=STATUS_CHOICES)
-
- usage = tables.Column(
- 'vm_capacity',
- verbose_name=_("Usage"),
- filters=(_usage_filter,),
- )
-
- class Meta:
- name = "racks"
- row_class = UpdateRow
- status_columns = ["state"]
- verbose_name = _("Racks")
- table_actions = (UploadRack, CreateRack, DeleteRacks,
- RacksFilterAction)
- row_actions = (EditRack, DeleteRacks)
-
-
-class UploadRacksTable(tables.DataTable):
- name = tables.Column("name")
- subnet = tables.Column("subnet")
- nodes_count = tables.Column("nodes_count")
- #region = tables.Column("region")
-
- class Meta:
- name = "uploaded_racks"
- verbose_name = " "
diff --git a/tuskar_ui/infrastructure/resource_management/racks/tabs.py b/tuskar_ui/infrastructure/resource_management/racks/tabs.py
deleted file mode 100644
index a474680b..00000000
--- a/tuskar_ui/infrastructure/resource_management/racks/tabs.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import tabs
-
-from tuskar_ui.infrastructure.resource_management.nodes import tables
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "rack_overview_tab"
- template_name = ("infrastructure/resource_management/racks/"
- "_detail_overview.html")
-
- def get_context_data(self, request):
- return {"rack": self.tab_group.kwargs['rack']}
-
-
-class NodesTab(tabs.TableTab):
- table_classes = (tables.NodesTable,)
- name = _("Nodes")
- slug = "nodes"
- template_name = "horizon/common/_detail_table.html"
-
- def get_nodes_table_data(self):
- try:
- rack = self.tab_group.kwargs['rack']
- baremetal_nodes = rack.list_baremetal_nodes
- except Exception:
- baremetal_nodes = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve node list.'))
- return baremetal_nodes
-
-
-class RackDetailTabs(tabs.TabGroup):
- slug = "rack_detail_tabs"
- tabs = (OverviewTab, NodesTab)
- sticky = True
diff --git a/tuskar_ui/infrastructure/resource_management/racks/tests.py b/tuskar_ui/infrastructure/resource_management/racks/tests.py
deleted file mode 100644
index 24932ee5..00000000
--- a/tuskar_ui/infrastructure/resource_management/racks/tests.py
+++ /dev/null
@@ -1,411 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django import http
-
-import mox
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.test import helpers as test
-
-import base64
-import tempfile
-
-
-class RackViewTests(test.BaseAdminViewTests):
- index_page = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
-
- index_page_racks_tab = (urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index') +
- "?tab=resource_management_tabs__racks_tab")
-
- @test.create_stubs({tuskar.ResourceClass: ('list',)})
- def test_create_rack_get(self):
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:create')
- rack = self.client.get(url)
-
- self.assertEqual(rack.status_code, 200)
- self.assertTemplateUsed(rack,
- 'infrastructure/_workflow_base.html')
-
- # FIXME (mawagner) - After moving EditRack to use workflows, we need
- # to circle back and fix these tests.
- #
- @test.create_stubs({tuskar.Rack: ('list', 'create',),
- tuskar.ResourceClass: ('list',),
- tuskar.BaremetalNode: ('create',)})
- def test_create_rack_post(self):
- baremetal_node = self.baremetal_nodes.first()
-
- tuskar.Rack.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_racks.list())
- tuskar.BaremetalNode.create(
- mox.IsA(http.HttpRequest),
- service_host='New Node',
- cpus=1,
- memory_mb=1024,
- local_gb=10,
- prov_mac_address='AA:BB:CC:DD:EE:FF',
- pm_address=u'',
- pm_user=u'',
- pm_password=u'',
- terminal_port=None).AndReturn(baremetal_node)
- tuskar.Rack.create(
- mox.IsA(http.HttpRequest),
- name='New Rack',
- resource_class_id=u'1',
- location='Tokyo',
- subnet='1.2.3.4/24',
- baremetal_nodes=[{'id': '11'}]).AndReturn(None)
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
-
- self.mox.ReplayAll()
-
- data = {
- 'name': 'New Rack',
- 'resource_class_id': u'1',
- 'location': 'Tokyo',
- 'subnet': '1.2.3.4/24',
- 'nodes-TOTAL_FORMS': 1,
- 'nodes-INITIAL_FORMS': 0,
- 'nodes-MAX_NUM_FORMS': 1024,
- 'nodes-0-service_host': 'New Node',
- 'nodes-0-mac_address': 'aa:bb:cc:dd:ee:ff',
- 'nodes-0-cpus': u'1',
- 'nodes-0-memory_mb': u'1024',
- 'nodes-0-local_gb': u'10',
- }
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:create')
- resp = self.client.post(url, data)
- self.assertRedirectsNoFollow(resp, self.index_page_racks_tab)
-
- @test.create_stubs({tuskar.Rack: ('get', 'list_tuskar_nodes'),
- tuskar.ResourceClass: ('list',)})
- def test_edit_rack_get(self):
- rack = self.tuskar_racks.first()
-
- tuskar.Rack.get(
- mox.IsA(http.HttpRequest), rack.id).AndReturn(rack)
- tuskar.Rack.list_tuskar_nodes = []
- tuskar.Rack.get(mox.IsA(http.HttpRequest), rack.id).AndReturn(rack)
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:edit', args=[1])
- res = self.client.get(url)
- self.assertEqual(res.status_code, 200)
- self.assertTemplateUsed(res, 'infrastructure/_workflow_base.html')
-
- @test.create_stubs({
- tuskar.Rack: ('get', 'list', 'update', 'list_tuskar_nodes'),
- tuskar.ResourceClass: ('list',),
- })
- def test_edit_rack_post(self):
- rack = self.tuskar_racks.first()
-
- rack_data = {
- 'name': 'Updated Rack',
- 'resource_class_id': u'1',
- 'rack_id': u'1',
- 'location': 'New Location',
- 'subnet': '127.10.10.0/24',
- 'baremetal_nodes': [],
- }
-
- data = {
- 'name': 'Updated Rack',
- 'resource_class_id': u'1',
- 'rack_id': u'1',
- 'location': 'New Location',
- 'subnet': '127.10.10.0/24',
- 'nodes-TOTAL_FORMS': 0,
- 'nodes-INITIAL_FORMS': 0,
- 'nodes-MAX_NUM_FORMS': 1024,
- }
-
- tuskar.Rack.get(
- mox.IsA(http.HttpRequest), rack.id).AndReturn(rack)
- tuskar.Rack.list_tuskar_nodes = []
- tuskar.Rack.get(
- mox.IsA(http.HttpRequest), rack.id).AndReturn(rack)
- tuskar.Rack.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_racks.list())
- tuskar.Rack.update(mox.IsA(http.HttpRequest), rack.id, rack_data)
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:edit',
- args=[rack.id])
- response = self.client.post(url, data)
- self.assertNoFormErrors(response)
- self.assertMessageCount(success=1)
- self.assertRedirectsNoFollow(response, self.index_page_racks_tab)
-
- @test.create_stubs({tuskar.Rack: ('get',)})
- def test_edit_status_rack_get(self):
- rack = self.tuskar_racks.first()
-
- tuskar.Rack.\
- get(mox.IsA(http.HttpRequest), rack.id).\
- AndReturn(rack)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:edit_status',
- args=[rack.id])
- res = self.client.get(url)
- self.assertEqual(res.status_code, 200)
- self.assertTemplateUsed(
- res,
- 'infrastructure/resource_management/racks/edit_status.html')
-
- @test.create_stubs({tuskar.Rack: ('get', 'update')})
- def test_edit_status_update_rack_post(self):
- rack = self.tuskar_racks.first()
-
- tuskar.Rack.\
- get(mox.IsA(http.HttpRequest), rack.id).\
- AndReturn(rack)
- tuskar.Rack.update(mox.IsA(http.HttpRequest), rack.id,
- {'state': 'active'}).AndReturn(rack)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:edit_status',
- args=[rack.id]) + "?action=start"
- response = self.client.post(url)
-
- self.assertNoFormErrors(response)
- self.assertMessageCount(success=1)
- self.assertRedirectsNoFollow(response, self.index_page)
-
- @test.create_stubs({tuskar.Rack: ('delete', 'list')})
- def test_delete_rack(self):
- rack_id = u'1'
- tuskar.Rack.delete(
- mox.IsA(http.HttpRequest), rack_id).AndReturn(None)
- tuskar.Rack.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_racks.list())
-
- self.mox.ReplayAll()
- data = {'action': 'racks__delete__%s' % rack_id}
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:index')
- result = self.client.post(url, data)
- self.assertRedirectsNoFollow(result, self.index_page)
-
- def test_upload_rack_get(self):
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:upload')
- rack = self.client.get(url)
-
- self.assertEqual(rack.status_code, 200)
- self.assertTemplateUsed(
- rack, 'infrastructure/resource_management/racks/upload.html')
-
- def test_upload_rack_upload(self):
- csv_data = ('Rack1,rclass1,192.168.111.0/24,regionX,f0:dd:f1:da:f9:b5 '
- 'f2:de:f1:da:f9:66 f2:de:ff:da:f9:67')
- temp_file = tempfile.TemporaryFile()
- temp_file.write(csv_data)
- temp_file.flush()
- temp_file.seek(0)
-
- data = {'csv_file': temp_file, 'upload': '1'}
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:upload')
- resp = self.client.post(url, data)
- self.assertTemplateUsed(
- resp, 'infrastructure/resource_management/racks/upload.html')
- self.assertNoFormErrors(resp)
- self.assertEqual(resp.context['form']['uploaded_data'].value(),
- base64.b64encode(csv_data))
-
- def test_upload_rack_upload_with_error(self):
- data = {'upload': '1'}
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:upload')
- resp = self.client.post(url, data)
- self.assertTemplateUsed(
- resp, 'infrastructure/resource_management/racks/upload.html')
- self.assertFormErrors(resp, 1)
- self.assertEqual(resp.context['form']['uploaded_data'].value(),
- None)
-
- @test.create_stubs({tuskar.Rack: ('create',),
- tuskar.ResourceClass: ('list',)})
- def test_upload_rack_create(self):
- tuskar.Rack.create(mox.IsA(http.HttpRequest),
- name='Rack1',
- resource_class_id='1',
- location='regionX',
- subnet='192.168.111.0/24').AndReturn(None)
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
- self.mox.ReplayAll()
- csv_data = ('Rack1,rclass1,192.168.111.0/24,regionX,f0:dd:f1:da:f9:b5 '
- 'f2:de:f1:da:f9:66 f2:de:ff:da:f9:67')
-
- data = {'uploaded_data': base64.b64encode(csv_data), 'add_racks': '1'}
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:upload')
- resp = self.client.post(url, data)
- self.assertRedirectsNoFollow(resp, self.index_page)
- self.assertMessageCount(success=1)
- self.assertMessageCount(error=0)
-
- @test.create_stubs({
- tuskar.Rack: ('get', 'list_tuskar_nodes', 'list_flavors'),
- tuskar.ResourceClass: ('get',),
- })
- def test_detail_rack(self):
- rack = self.tuskar_racks.first()
- rack.request = self.request
- resource_class = self.tuskar_resource_classes.first()
-
- tuskar.Rack.get(mox.IsA(http.HttpRequest),
- rack.id).AndReturn(rack)
- tuskar.ResourceClass.get(mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
- self.mox.ReplayAll()
-
- tuskar.Rack.list_tuskar_nodes = []
- tuskar.Rack.list_flavors = []
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:detail',
- args=[rack.id])
- res = self.client.get(url)
- self.assertTemplateUsed(res, "infrastructure/resource_management/"
- "racks/detail.html")
-
- # FIXME: test actual json output once we stop using mock data
- def test_usage_data_rack(self):
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:usage_data')
- res = self.client.get(url)
- self.assertEquals(res['Content-Type'], 'application/json')
-
- # FIXME: test actual json output once we stop using mock data
- @test.create_stubs({tuskar.Rack: ('get',)})
- def test_top_communicating_rack(self):
- rack = self.tuskar_racks.first()
-
- tuskar.Rack.get(mox.IsA(http.HttpRequest),
- rack.id).AndReturn(rack)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:'
- 'top_communicating', args=[rack.id])
- res = self.client.get(url)
- self.assertEquals(res['Content-Type'], 'application/json')
-
- # FIXME: test actual json output once we stop using mock data
- @test.create_stubs({tuskar.Rack: ('get',)})
- def test_node_health_rack(self):
- rack = self.tuskar_racks.first()
-
- tuskar.Rack.get(mox.IsA(http.HttpRequest),
- rack.id).AndReturn(rack)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:'
- 'node_health', args=[rack.id])
- res = self.client.get(url)
- self.assertEquals(res['Content-Type'], 'application/json')
-
- @test.create_stubs({tuskar.Rack: ('get',)})
- def test_check_state_rack(self):
- rack = self.tuskar_racks.first()
-
- tuskar.Rack.get(mox.IsA(http.HttpRequest),
- rack.id).AndReturn(rack)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:racks:'
- 'check_state', args=[rack.id])
- res = self.client.get(url)
- state_json = '{"state": "active"}'
-
- self.assertEquals(res['Content-Type'], 'application/json')
- self.assertEquals(res.content, state_json)
-
- @test.create_stubs({
- tuskar.Rack: ('get', 'list_baremetal_nodes', 'update',
- 'list_tuskar_nodes'),
- tuskar.BaremetalNode: ('get',),
- tuskar.TuskarNode: ('list',),
- })
- def test_node_delete(self):
- rack = self.tuskar_racks.first()
- rack.request = self.request
- baremetal_nodes = self.baremetal_nodes.list()
- baremetal_node = baremetal_nodes[0]
- baremetal_node.request = self.request
- tuskar_nodes = self.tuskar_nodes.list()
-
- tuskar.Rack.get(mox.IsA(http.HttpRequest), rack.id).AndReturn(rack)
- tuskar.BaremetalNode.get(mox.IsA(http.HttpRequest),
- baremetal_node.id).AndReturn(baremetal_node)
- tuskar.TuskarNode.list(
- mox.IsA(http.HttpRequest)).AndReturn(tuskar_nodes)
- tuskar.Rack.get(None, rack.id).AndReturn(rack) # called by node.rack
- tuskar.Rack.update(mox.IsA(http.HttpRequest), rack.id, {
- 'baremetal_nodes': [{'id': node.id}
- for node in baremetal_nodes
- if node.id != baremetal_node.id],
- }).AndReturn(rack)
-
- tuskar.Rack.list_baremetal_nodes = baremetal_nodes
- tuskar.Rack.list_tuskar_nodes = tuskar_nodes
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:racks:detail',
- args=[rack.id])
- form_data = {'action': 'nodes_table__delete__%s' % baremetal_node.id}
- response = self.client.post(url, form_data)
- self.assertNoFormErrors(response)
- self.assertMessageCount(success=1)
- self.assertRedirectsNoFollow(response, url)
diff --git a/tuskar_ui/infrastructure/resource_management/racks/urls.py b/tuskar_ui/infrastructure/resource_management/racks/urls.py
deleted file mode 100644
index 58a1cf58..00000000
--- a/tuskar_ui/infrastructure/resource_management/racks/urls.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import urls
-
-from tuskar_ui.infrastructure.resource_management.racks import views
-
-RACKS = r'^(?P<rack_id>[^/]+)/%s$'
-VIEW_MOD = 'tuskar_ui.infrastructure.resource_management.racks.views'
-
-
-urlpatterns = urls.patterns(
- VIEW_MOD,
- urls.url(r'^create/$', views.CreateView.as_view(), name='create'),
- urls.url(r'^upload/$', views.UploadView.as_view(), name='upload'),
- urls.url(r'^usage_data$',
- views.UsageDataView.as_view(),
- name='usage_data'),
- urls.url(RACKS % 'edit/', views.EditView.as_view(), name='edit'),
- urls.url(RACKS % 'detail_edit/',
- views.DetailEditView.as_view(),
- name='detail_edit'),
- urls.url(RACKS % 'edit_status/',
- views.EditRackStatusView.as_view(),
- name='edit_status'),
- urls.url(RACKS % 'detail', views.DetailView.as_view(), name='detail'),
- urls.url(RACKS % 'top_communicating.json',
- 'top_communicating',
- name='top_communicating'),
- urls.url(RACKS % 'node_health.json', 'node_health', name='node_health'),
- urls.url(RACKS % 'check_state.json', 'check_state', name='check_state'),
-)
diff --git a/tuskar_ui/infrastructure/resource_management/racks/views.py b/tuskar_ui/infrastructure/resource_management/racks/views.py
deleted file mode 100644
index d28dbb82..00000000
--- a/tuskar_ui/infrastructure/resource_management/racks/views.py
+++ /dev/null
@@ -1,250 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import datetime
-import json
-import logging
-import random
-
-from django.core.serializers import json as json_serializer
-from django.core import urlresolvers
-from django import http
-
-from django.utils import simplejson
-from django.utils.translation import ugettext_lazy as _ # noqa
-from django.views import generic
-
-from horizon import exceptions
-from horizon import forms as horizon_forms
-from horizon import tabs as horizon_tabs
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.infrastructure.resource_management.racks import forms
-from tuskar_ui.infrastructure.resource_management.racks import tables
-from tuskar_ui.infrastructure.resource_management.racks import tabs
-from tuskar_ui.infrastructure.resource_management.racks import workflows
-from tuskar_ui import workflows as tuskar_workflows
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateView(tuskar_workflows.WorkflowView):
- workflow_class = workflows.CreateRack
-
- def get_initial(self):
- pass
-
-
-class UploadView(horizon_forms.ModalFormView):
- form_class = forms.UploadRack
- template_name = 'infrastructure/resource_management/racks/upload.html'
- success_url = urlresolvers.reverse_lazy(
- 'horizon:infrastructure:resource_management:index')
-
- def get_context_data(self, **kwargs):
- context = super(UploadView, self).get_context_data(**kwargs)
- context['racks_table'] = tables.UploadRacksTable(
- self.request, kwargs['form'].initial.get('racks', []))
- return context
-
-
-class EditView(tuskar_workflows.WorkflowView):
- workflow_class = workflows.EditRack
-
- def get_initial(self):
- obj = tuskar.Rack.get(self.request, self.kwargs['rack_id'])
- # mac_str = "\n".join(x.mac_address for x in obj.list_tuskar_nodes)
- return {'name': obj.name, 'resource_class_id': obj.resource_class_id,
- 'location': obj.location, 'subnet': obj.subnet,
- 'state': obj.state, 'rack_id': self.kwargs['rack_id']}
-
-
-class DetailEditView(EditView):
- workflow_class = workflows.DetailEditRack
-
-
-class EditRackStatusView(horizon_forms.ModalFormView):
- form_class = forms.UpdateRackStatus
- template_name = 'infrastructure/resource_management/racks/edit_status.html'
-
- def get_success_url(self):
- # Redirect to previous url
- default_url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- return self.request.META.get('HTTP_REFERER', default_url)
-
- def get_context_data(self, **kwargs):
- context = super(EditRackStatusView, self).get_context_data(**kwargs)
- context['rack_id'] = self.kwargs['rack_id']
- context['action'] = context['form'].initial.get('action', None)
- return context
-
- def get_initial(self):
- try:
- rack = tuskar.Rack.get(
- self.request, self.kwargs['rack_id'])
- action = self.request.GET.get('action')
- except Exception:
- exceptions.handle(self.request,
- _("Unable to retrieve rack data."))
- return {'rack': rack,
- 'action': action}
-
-
-class DetailView(horizon_tabs.TabbedTableView):
- tab_group_class = tabs.RackDetailTabs
- template_name = 'infrastructure/resource_management/racks/detail.html'
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["rack"] = self.get_data()
- return context
-
- def get_data(self):
- if not hasattr(self, "_rack"):
- try:
- rack_id = self.kwargs['rack_id']
- rack = tuskar.Rack.get(self.request, rack_id)
- except Exception:
- redirect = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- exceptions.handle(
- self.request,
- _('Unable to retrieve details for rack "%s".') % rack_id,
- redirect=redirect)
- self._rack = rack
- return self._rack
-
- def get_tabs(self, request, *args, **kwargs):
- rack = self.get_data()
- return self.tab_group_class(request, rack=rack,
- **kwargs)
-
-
-class UsageDataView(generic.View):
-
- def get(self, request, *args, **kwargs):
- interval = request.GET.get('interval', '1w')
- series = request.GET.get('series', "")
- series = series.split(',')
-
- if interval == '12h':
- data_count = 12
- timedelta_param = 'hours'
- elif interval == '24h':
- data_count = 24
- timedelta_param = 'hours'
- elif interval == '1m':
- data_count = 30
- timedelta_param = 'days'
- elif interval == '1y':
- data_count = 52
- timedelta_param = 'weeks'
- else:
- # default is 1 week
- data_count = 7
- timedelta_param = 'days'
-
- values = []
- for i in range(data_count):
- timediff = datetime.timedelta(**{timedelta_param: i})
- current_value = {'date': datetime.datetime.now() - timediff}
-
- for usage_type in series:
- current_value[usage_type] = random.randint(1, 9)
-
- values.append(current_value)
-
- return http.HttpResponse(
- json.dumps(values, cls=json_serializer.DjangoJSONEncoder),
- mimetype='application/json')
-
-
-def top_communicating(request, rack_id=None):
- # FIXME replace mock data
- random.seed()
- data = []
- statuses = ["Insane level of communication",
- "High level of communication",
- "Normal level of communication",
- "Low level of communication"]
-
- rack = tuskar.Rack.get(request, rack_id)
- for tuskar_node_id in rack.tuskar_node_ids:
- status = random.randint(0, 3)
- percentage = random.randint(0, 100)
-
- tooltip = ("<p>Node: <strong>{0}</strong></p><p>{1}</p>").format(
- tuskar_node_id, statuses[status])
-
- data.append({'tooltip': tooltip,
- 'status': statuses[status],
- 'scale': 'linear_color_scale',
- 'percentage': percentage,
- 'id': "FIXME_RACK id",
- 'name': "FIXME name",
- 'url': "FIXME url"})
-
- data.sort(key=lambda x: x['percentage'])
-
- # FIXME dynamically set the max domain, based on data
- settings = {'scale': 'linear_color_scale',
- 'domain': [0, max([datum['percentage'] for datum in data])],
- 'range': ["#000060", "#99FFFF"]}
- res = {'data': data,
- 'settings': settings}
- return http.HttpResponse(simplejson.dumps(res),
- mimetype="application/json")
-
-
-def node_health(request, rack_id=None):
- # FIXME replace mock data
- random.seed()
- data = []
- statuses = ["Good", "Warnings", "Disaster"]
- colors = ["rgb(244,244,244)", "rgb(240,170,0)", "rgb(200,0,0)"]
-
- rack = tuskar.Rack.get(request, rack_id)
-
- for tuskar_node_id in rack.tuskar_node_ids:
- rand_index = random.randint(0, 2)
- percentage = (2 - rand_index) * 50
- color = colors[rand_index]
-
- tooltip = ("<p>Node: <strong>{0}</strong></p><p>{1}</p>").format(
- tuskar_node_id, statuses[rand_index])
-
- data.append({'tooltip': tooltip,
- 'color': color,
- 'status': statuses[rand_index],
- 'percentage': percentage,
- 'id': tuskar_node_id,
- 'name': tuskar_node_id,
- 'url': "FIXME url"})
-
- data.sort(key=lambda x: x['percentage'])
-
- res = {'data': data}
- return http.HttpResponse(simplejson.dumps(res),
- mimetype="application/json")
-
-
-def check_state(request, rack_id=None):
- rack = tuskar.Rack.get(request, rack_id)
-
- res = {'state': rack.state}
-
- return http.HttpResponse(simplejson.dumps(res),
- mimetype="application/json")
diff --git a/tuskar_ui/infrastructure/resource_management/racks/workflows.py b/tuskar_ui/infrastructure/resource_management/racks/workflows.py
deleted file mode 100644
index cca10bcc..00000000
--- a/tuskar_ui/infrastructure/resource_management/racks/workflows.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-from horizon import workflows
-
-import requests
-
-from tuskar_ui import api as tuskar
-from tuskar_ui import forms as tuskar_forms
-from tuskar_ui.infrastructure.resource_management.nodes import tables \
- as nodes_tables
-import tuskar_ui.workflows
-
-
-class RackCreateInfoAction(workflows.Action):
- name = forms.RegexField(label=_("Name"),
- max_length=25,
- regex=r'^[\w\.\- ]+$',
- error_messages={'invalid': _(
- 'Name may only '
- 'contain letters, numbers, underscores, '
- 'periods and hyphens.')})
- location = forms.CharField(label=_("Location"))
- subnet = tuskar_forms.NetworkField(label=_("IP Subnet"))
- resource_class_id = forms.ChoiceField(label=_("Resource Class"))
-
- def clean(self):
- cleaned_data = super(RackCreateInfoAction, self).clean()
- name = cleaned_data.get('name')
- rack_id = self.initial.get('rack_id', None)
- subnet = cleaned_data.get('subnet')
- try:
- racks = tuskar.Rack.list(self.request)
- except Exception:
- racks = []
- exceptions.check_message(['Connection', 'refused'],
- _("Unable to retrieve rack list."))
- raise
-
- # Validations: detect duplicates
- for rack in racks:
- other_record = rack_id != rack.id
- if rack.name == name and other_record:
- raise forms.ValidationError(
- _('The name %s is already used by another rack.')
- % name)
- if rack.subnet == subnet and other_record:
- raise forms.ValidationError(
- _('The subnet is already assigned to rack %s.')
- % (rack.name))
-
- return cleaned_data
-
- def __init__(self, request, *args, **kwargs):
- super(RackCreateInfoAction, self).__init__(request, *args, **kwargs)
- resource_class_id_choices = [('', _("Select a Resource Class"))]
- for rc in tuskar.ResourceClass.list(request):
- resource_class_id_choices.append((rc.id, rc.name))
- self.fields['resource_class_id'].choices = resource_class_id_choices
-
- class Meta:
- name = _("Rack Settings")
-
-
-class CreateRackInfo(workflows.Step):
- action_class = RackCreateInfoAction
-
- contributes = ('name', 'resource_class_id', 'subnet', 'location')
-
- def get_racks_data():
- pass
-
-
-class EditRackInfo(CreateRackInfo):
- depends_on = ('rack_id',)
-
-
-class NodeCreateAction(workflows.Action):
- class Meta:
- name = _("Create Nodes")
- help_text = _("Here you can create the nodes for this rack.")
-
- def clean(self):
- cleaned_data = super(NodeCreateAction, self).clean()
- table = self.initial.get('_tables', {}).get('nodes')
- if table:
- formset = table.get_formset()
- if formset.is_valid():
- cleaned_data['nodes'] = [
- form.cleaned_data for form in formset
- if form.cleaned_data
- and not form.cleaned_data.get('DELETE')]
- else:
- raise forms.ValidationError(_("Errors in the nodes list."))
- return cleaned_data
-
-
-class NodeEditAction(NodeCreateAction):
- class Meta:
- name = _("Edit Nodes")
- help_text = _("Here you can edit the nodes for this rack.")
-
-
-class CreateNodes(tuskar_ui.workflows.TableStep):
- action_class = NodeCreateAction
- contributes = ('nodes',)
- table_classes = (nodes_tables.NodesFormsetTable,)
- template_name = (
- 'infrastructure/resource_management/racks/_rack_nodes_step.html')
-
- def get_nodes_data(self):
- return []
-
-
-class EditNodes(CreateNodes):
- action_class = NodeEditAction
- depends_on = ('rack_id',)
-
- def get_nodes_data(self):
- rack_id = self.workflow.context['rack_id']
- rack = tuskar.Rack.get(self.workflow.request, rack_id)
- return rack.list_baremetal_nodes
-
-
-class CreateRack(workflows.Workflow):
- default_steps = (CreateRackInfo, CreateNodes)
- slug = "create_rack"
- name = _("Add Rack")
- success_url = 'horizon:infrastructure:resource_management:index'
- success_message = _("Rack created.")
- failure_message = _("Unable to create rack.")
-
- # FIXME active tabs coflict
- # When on page with tabs, the workflow with more steps is used,
- # there is a conflict of active tabs and it always shows the
- # first tab after an action. So I explicitly specify to what
- # tab it should redirect after action, until the coflict will
- # be fixed in Horizon.
- def get_index_url(self):
- """This URL is used both as success and failure URL."""
- return "%s?tab=resource_management_tabs__racks_tab" %\
- urlresolvers.reverse('horizon:infrastructure:resource_management:'
- 'index')
-
- def get_success_url(self):
- return self.get_index_url()
-
- def get_failure_url(self):
- return self.get_index_url()
-
- def create_or_update_baremetal_node(self, baremetal_node_data):
- """Creates (if id=='') or updates (otherwise) a baremetal node."""
- if baremetal_node_data['id'] not in ('', None):
- baremetal_node_id = unicode(baremetal_node_data['id'])
- # TODO(rdopieralski) there is currently no way to update
- # a baremetal node
- #
- # tuskar.BaremetalNode.update(
- # self.request,
- # node_id=node_id,
- # service_host=baremetal_node_data['service_host'],
- # cpus=baremetal_node_data['cpus'],
- # memory_mb=baremetal_node_data['memory_mb'],
- # local_gb=baremetal_node_data['local_gb'],
- # prov_mac_address=baremetal_node_data['mac_address'],
- # pm_address=baremetal_node_data['pm_address'],
- # pm_user=baremetal_node_data['pm_user'],
- # pm_password=baremetal_node_data['pm_password'],
- # terminal_port=baremetal_node_data['terminal_port'])
- return baremetal_node_id
- else:
- baremetal_node = tuskar.BaremetalNode.create(
- self.request,
- service_host=baremetal_node_data['service_host'],
- cpus=baremetal_node_data['cpus'],
- memory_mb=baremetal_node_data['memory_mb'],
- local_gb=baremetal_node_data['local_gb'],
- prov_mac_address=baremetal_node_data['mac_address'],
- pm_address=baremetal_node_data['pm_address'],
- pm_user=baremetal_node_data['pm_user'],
- pm_password=baremetal_node_data['pm_password'],
- terminal_port=baremetal_node_data['terminal_port'])
- return baremetal_node.id
-
- def handle(self, request, data):
- # First, create and/or update nodes
- baremetal_node_ids = []
- for baremetal_node_data in data['nodes']:
- try:
- baremetal_node_id = self.create_or_update_baremetal_node(
- baremetal_node_data)
- except Exception:
- exceptions.handle(self.request, _("Unable to update node."))
- return False
- else:
- # Rack.create takes a list of dicts with BaremetalNode ids
- baremetal_node_ids.append({'id': baremetal_node_id})
- try:
- # Then, register the Rack, including the nodes
- tuskar.Rack.create(
- request, name=data['name'],
- resource_class_id=data['resource_class_id'],
- location=data['location'], subnet=data['subnet'],
- baremetal_nodes=baremetal_node_ids)
-
- return True
- except requests.ConnectionError:
- messages.error(request,
- _("Unable to connect to Nova Baremetal. Please "
- "check your configuration."))
- return False
- except Exception:
- exceptions.handle(request, _("Unable to create rack."))
- return False
-
-
-class EditRack(CreateRack):
- default_steps = (EditRackInfo, EditNodes)
- slug = "edit_rack"
- name = _("Edit Rack")
- success_url = 'horizon:infrastructure:resource_management:index'
- success_message = _("Rack updated.")
- failure_message = _("Unable to update rack.")
-
- def handle(self, request, data):
- baremetal_nodes_data = data.pop('nodes')
- baremetal_node_ids = [
- {'id': self.create_or_update_baremetal_node(baremetal_node_data)}
- for baremetal_node_data in baremetal_nodes_data]
- try:
- rack_id = self.context['rack_id']
- data['baremetal_nodes'] = baremetal_node_ids
- tuskar.Rack.update(request, rack_id, data)
- return True
- except Exception:
- exceptions.handle(request, _("Unable to update rack."))
- return False
-
-
-class DetailEditRack(EditRack):
- success_url = 'horizon:infrastructure:resource_management:racks:detail'
-
- def get_success_url(self):
- rack_id = self.context['rack_id']
- return urlresolvers.reverse(self.success_url, args=(rack_id,))
-
- def get_failure_url(self):
- rack_id = self.context['rack_id']
- return urlresolvers.reverse(self.success_url, args=(rack_id,))
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/forms.py b/tuskar_ui/infrastructure/resource_management/resource_classes/forms.py
deleted file mode 100644
index 7682c5bb..00000000
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/forms.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-import django.forms
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from tuskar_ui import api as tuskar
-
-import logging
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteForm(forms.SelfHandlingForm):
- def __init__(self, request, *args, **kwargs):
- super(DeleteForm, self).__init__(request, *args, **kwargs)
-
- resource_class = self.initial.get('resource_class', None)
- self.command = DeleteCommand(request, resource_class)
-
- def handle(self, request, data):
- try:
- self.command.execute()
-
- messages.success(request, self.command.msg)
- return True
- except Exception:
- exceptions.handle(request, _("Unable to delete Resource Class."))
-
-
-# TODO(this command will be reused in table, so code is not duplicated)
-class DeleteCommand(object):
- def __init__(self, request, resource_class):
- self.resource_class = resource_class
- self.request = request
- self.header = (_("Deleting resource class '%s.'")
- % self.resource_class.name)
- self.msg = ""
-
- def execute(self):
- try:
- tuskar.ResourceClass.delete(self.request,
- self.resource_class.id)
- self.msg = (_('Successfully deleted Class "%s".')
- % self.resource_class.name)
- except Exception:
- self.msg = _('Failed to delete Class %s') % self.resource_class.id
- LOG.info(self.msg)
- redirect = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- exceptions.handle(self.request, self.msg, redirect=redirect)
-
-
-class SelectRack(django.forms.Form):
- id = django.forms.IntegerField(widget=django.forms.HiddenInput())
- selected = django.forms.BooleanField(required=False)
-
-
-SelectRackFormset = django.forms.formsets.formset_factory(SelectRack, extra=0)
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/tables.py b/tuskar_ui/infrastructure/resource_management/resource_classes/tables.py
deleted file mode 100644
index d16b5abe..00000000
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/tables.py
+++ /dev/null
@@ -1,217 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-import re
-
-from django.core import urlresolvers
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import tables
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.infrastructure.resource_management.flavors\
- import forms as flavors_forms
-from tuskar_ui.infrastructure.resource_management.racks\
- import tables as racks_tables
-from tuskar_ui.infrastructure.resource_management import resource_classes
-from tuskar_ui.infrastructure.resource_management.resource_classes\
- import forms
-import tuskar_ui.tables
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateResourceClass(tables.LinkAction):
- name = "create_class"
- verbose_name = _("Create Class")
- url = "horizon:infrastructure:resource_management:resource_classes:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class UpdateResourceClass(tables.LinkAction):
- name = "edit_class"
- verbose_name = _("Edit Class")
- url = "horizon:infrastructure:resource_management:resource_classes:update"
- classes = ("ajax-modal", "btn-edit")
-
-
-class DeleteResourceClass(tables.DeleteAction):
- data_type_singular = _("Resource Class")
- data_type_plural = _("Resource Classes")
-
- def delete(self, request, obj_id):
- try:
- tuskar.ResourceClass.delete(request, obj_id)
- except Exception:
- msg = _('Failed to delete resource class %s') % obj_id
- LOG.info(msg)
- redirect = urlresolvers.reverse(
- "horizon:infrastructure:resource_management:index")
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class ResourcesClassFilterAction(tables.FilterAction):
- def filter(self, table, instances, filter_string):
- pass
-
-
-class ResourceClassesTable(tables.DataTable):
- name = tables.Column(
- "name", link=("horizon:infrastructure:"
- "resource_management:resource_classes:detail"),
- verbose_name=_("Class Name"))
- service_type = tables.Column("service_type", verbose_name=_("Class Type"))
- racks_count = tables.Column("racks_count", verbose_name=_("Racks"),
- empty_value="0")
- nodes_count = tables.Column("nodes_count", verbose_name=_("Nodes"),
- empty_value="0")
-
- class Meta:
- name = "resource_classes"
- verbose_name = ("Classes")
- table_actions = (ResourcesClassFilterAction, CreateResourceClass,
- DeleteResourceClass)
- row_actions = (UpdateResourceClass, DeleteResourceClass)
-
-
-class FlavorsFilterAction(tables.FilterAction):
- def filter(self, table, instances, filter_string):
- pass
-
-
-class RacksFilterAction(tables.FilterAction):
- def filter(self, table, instances, filter_string):
- pass
-
-
-class RacksTable(racks_tables.RacksTable):
- class Meta:
- name = "racks_table"
- verbose_name = _("Racks")
- table_actions = (RacksFilterAction,)
-
-
-class RacksFormsetTable(tuskar_ui.tables.FormsetDataTableMixin, RacksTable):
- formset_class = forms.SelectRackFormset
-
- class Meta:
- name = "racks"
- verbose_name = _("Racks")
- multi_select = False
- table_actions = (RacksFilterAction,)
-
- def __init__(self, *args, **kwargs):
- # Adding a column at the left of the table.
- selected = tables.Column('selected', verbose_name="", sortable=False)
- selected.classes.append('narrow')
- selected.table = self
- self._columns.insert(0, 'selected', selected)
- super(RacksFormsetTable, self).__init__(*args, **kwargs)
-
-
-class UpdateRacksClass(tables.LinkAction):
- name = "edit_flavors"
- verbose_name = _("Edit Racks")
-
- classes = ("ajax-modal", "btn-edit")
-
- def get_link_url(self, datum=None):
- url = ("horizon:infrastructure:resource_management:resource_classes:"
- "update_racks")
- return "%s?step=%s" % (
- urlresolvers.reverse(
- url,
- args=(self.table.kwargs['resource_class_id'],)),
- resource_classes.workflows.RacksAction.slug)
-
-
-class UpdateFlavorsClass(tables.LinkAction):
- name = "edit_flavors"
- verbose_name = _("Edit Flavors")
- classes = ("ajax-modal", "btn-edit")
-
- def get_link_url(self, datum=None):
- url = ("horizon:infrastructure:resource_management:resource_classes:"
- "update_flavors")
- resource_class_id = self.table.kwargs.get('resource_class_id')
- return "%s?step=%s" % (
- urlresolvers.reverse(url, args=(resource_class_id,)),
- resource_classes.workflows.ResourceClassFlavorsAction.slug)
-
-
-class FlavorsTable(tables.DataTable):
- def get_flavor_detail_link(datum):
- # FIXME - horizon Column.get_link_url does not allow to access GET
- # params
- resource_class_id = re.findall("[0-9]+", datum.request.path)[-1]
- return urlresolvers.reverse(
- "horizon:infrastructure:resource_management:resource_classes:"
- "flavors:detail", args=(resource_class_id, datum.id))
-
- name = tables.Column(
- 'name',
- link=get_flavor_detail_link,
- verbose_name=_('Flavor Name'),
- )
- cpu = tables.Column(
- "cpu",
- verbose_name=_('VCPU'),
- filters=(lambda x: getattr(x, 'value', ''),)
- )
- memory = tables.Column(
- "memory",
- verbose_name=_('RAM (MB)'),
- filters=(lambda x: getattr(x, 'value', ''),)
- )
- storage = tables.Column(
- "storage",
- verbose_name=_('Root Disk (GB)'),
- filters=(lambda x: getattr(x, 'value', ''),)
- )
- ephemeral_disk = tables.Column(
- "ephemeral_disk",
- verbose_name=_('Ephemeral Disk (GB)'),
- filters=(lambda x: getattr(x, 'value', ''),)
- )
- swap_disk = tables.Column(
- "swap_disk",
- verbose_name=_('Swap Disk (MB)'),
- filters=(lambda x: getattr(x, 'value', ''),)
- )
- max_vms = tables.Column("max_vms", verbose_name=_("Max. VMs"))
-
- class Meta:
- name = "flavors_table"
- verbose_name = _("Flavors")
- table_actions = (FlavorsFilterAction, UpdateFlavorsClass)
-
-
-class FlavorsFormsetTable(tuskar_ui.tables.FormsetDataTableMixin,
- FlavorsTable):
-
- name = tables.Column(
- 'name',
- verbose_name=_('Flavor Name'),
- )
- DELETE = tables.Column('DELETE', verbose_name=_("Delete"))
- formset_class = flavors_forms.FlavorFormset
-
- class Meta:
- name = "flavors"
- verbose_name = _("Flavors")
- table_actions = ()
- multi_select = False
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/tabs.py b/tuskar_ui/infrastructure/resource_management/resource_classes/tabs.py
deleted file mode 100644
index fcdbbf5a..00000000
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/tabs.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import tabs
-
-from tuskar_ui.infrastructure.resource_management.resource_classes\
- import tables
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = ("infrastructure/resource_management/resource_classes/"
- "_detail_overview.html")
- # FIXME charts doesnt work if uncommented
- #preload = False
-
- def get_context_data(self, request):
- return {"resource_class": self.tab_group.kwargs['resource_class']}
-
-
-class RacksTab(tabs.TableTab):
- table_classes = (tables.RacksTable,)
- name = _("Racks")
- slug = "racks"
- template_name = ("infrastructure/resource_management/resource_classes/"
- "_detail_racks.html")
-
- def get_racks_table_data(self):
- try:
- resource_class = self.tab_group.kwargs['resource_class']
- racks = resource_class.list_racks
- except Exception:
- racks = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve rack list.'))
- return racks
-
-
-class FlavorsTab(tabs.TableTab):
- table_classes = (tables.FlavorsTable,)
- name = _("Flavors")
- slug = "flavors"
- template_name = ("infrastructure/resource_management/resource_classes/"
- "_detail_flavors.html")
-
- def get_flavors_table_data(self):
- try:
- resource_class = self.tab_group.kwargs['resource_class']
- flavors = resource_class.list_flavors
- except Exception:
- flavors = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve flavor list.'))
- return flavors
-
- def allowed(self, request):
- resource_class = self.tab_group.kwargs['resource_class']
- return resource_class.service_type == "compute"
-
-
-class ResourceClassDetailTabs(tabs.TabGroup):
- slug = "resource_class_details"
- tabs = (OverviewTab, RacksTab, FlavorsTab)
- sticky = True
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/tests.py b/tuskar_ui/infrastructure/resource_management/resource_classes/tests.py
deleted file mode 100644
index 94fac9ee..00000000
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/tests.py
+++ /dev/null
@@ -1,656 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django import http
-from django.utils import simplejson
-
-import mox
-
-from openstack_dashboard.api import glance
-from openstack_dashboard.test.test_data import glance_data
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.test import helpers as test
-
-
-class ResourceClassViewTests(test.BaseAdminViewTests):
- def setUp(self):
- super(ResourceClassViewTests, self).setUp()
- # Add the .images attribute for testing glance api call
- glance_data.data(self)
-
- @test.create_stubs({
- tuskar.Rack: ('list',),
- tuskar.ResourceClass: ('get',),
- glance: ('image_list_detailed',),
- })
- def test_create_resource_class_get(self):
- all_racks = self.tuskar_racks.list()
- rc = self.tuskar_resource_classes.first()
-
- glance.image_list_detailed(mox.IsA(http.HttpRequest)).AndReturn(
- (self.images.list(), False))
- tuskar.Rack.list(
- mox.IsA(http.HttpRequest), True).AndReturn(all_racks)
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), rc.id).AndReturn(rc)
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'create')
- res = self.client.get(url)
- self.assertEqual(res.status_code, 200)
-
- @test.create_stubs({
- tuskar.ResourceClass: ('list', 'create', 'set_racks'),
- tuskar.Rack: ('list',),
- glance: ('image_list_detailed',),
- })
- def test_create_resource_class_post(self):
- new_resource_class = self.tuskar_resource_classes.first()
- new_unique_name = "unique_name_for_sure"
- new_flavors = []
- image_id = self.images.list()[0].id
-
- add_racks_ids = []
-
- glance.image_list_detailed(mox.IsA(http.HttpRequest)).AndReturn(
- (self.images.list(), False))
- tuskar.Rack.list(
- mox.IsA(http.HttpRequest), True).AndReturn([])
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
- tuskar.ResourceClass.create(
- mox.IsA(http.HttpRequest),
- name=new_unique_name,
- service_type=new_resource_class.service_type,
- image_id=image_id,
- flavors=new_flavors).AndReturn(new_resource_class)
- tuskar.ResourceClass.set_racks(mox.IsA(http.HttpRequest),
- add_racks_ids)
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'create')
- form_data = {
- 'name': new_unique_name,
- 'service_type': new_resource_class.service_type,
- 'image_id': image_id,
- 'flavors-TOTAL_FORMS': 0,
- 'flavors-INITIAL_FORMS': 0,
- 'flavors-MAX_NUM_FORMS': 1000,
- 'racks-TOTAL_FORMS': 0,
- 'racks-INITIAL_FORMS': 0,
- 'racks-MAX_NUM_FORMS': 1000,
- }
- res = self.client.post(url, form_data)
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
-
- redirect_url = (
- "%s?tab=resource_management_tabs__resource_classes_tab" %
- urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:index'))
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({
- tuskar.ResourceClass: ('list', 'create', 'set_racks'),
- tuskar.Rack: ('list',),
- glance: ('image_list_detailed',),
- })
- def test_create_resource_class_post_exception(self):
- new_resource_class = self.tuskar_resource_classes.first()
- new_unique_name = "unique_name_for_sure"
- new_flavors = []
- image_id = self.images.list()[0].id
-
- glance.image_list_detailed(mox.IsA(http.HttpRequest)).AndReturn(
- (self.images.list(), False))
- tuskar.Rack.list(
- mox.IsA(http.HttpRequest), True).AndReturn([])
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
- tuskar.ResourceClass.\
- create(mox.IsA(http.HttpRequest), name=new_unique_name,
- service_type=new_resource_class.service_type,
- image_id=image_id,
- flavors=new_flavors).\
- AndRaise(self.exceptions.tuskar)
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:'
- 'resource_classes:create')
- form_data = {
- 'name': new_unique_name,
- 'service_type': new_resource_class.service_type,
- 'image_id': image_id,
- 'flavors-TOTAL_FORMS': 0,
- 'flavors-INITIAL_FORMS': 0,
- 'flavors-MAX_NUM_FORMS': 1000,
- 'racks-TOTAL_FORMS': 0,
- 'racks-INITIAL_FORMS': 0,
- 'racks-MAX_NUM_FORMS': 1000,
- }
- res = self.client.post(url, form_data)
- self.assertRedirectsNoFollow(
- res,
- ("%s?tab=resource_management_tabs__resource_classes_tab" %
- urlresolvers.
- reverse("horizon:infrastructure:resource_management:index")))
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list_flavors', 'racks_ids',
- 'all_racks'),
- glance: ('image_list_detailed',),
- })
- def test_edit_resource_class_get(self):
- resource_class = self.tuskar_resource_classes.first()
- all_flavors = []
- all_racks = []
-
- glance.image_list_detailed(mox.IsA(http.HttpRequest)).AndReturn(
- (self.images.list(), False))
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- # get_flavors_data in workflows.py
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- # get_racks_data in workflows.py
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- self.mox.ReplayAll()
-
- # FIXME I should probably track the racks and flavors methods
- # so maybe they shouldn't be a @property
- # properties set
- tuskar.ResourceClass.all_racks = all_racks
- tuskar.ResourceClass.list_flavors = all_flavors
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'update',
- args=[resource_class.id])
- res = self.client.get(url)
- self.assertEqual(res.status_code, 200)
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list_flavors',
- 'racks_ids', 'all_racks'),
- glance: ('image_list_detailed',),
- })
- def test_edit_resource_class_get_exception(self):
- resource_class = self.tuskar_resource_classes.first()
-
- tuskar.ResourceClass.\
- get(mox.IsA(http.HttpRequest), resource_class.id)\
- .AndRaise(self.exceptions.tuskar)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:'
- 'resource_classes:update',
- args=[resource_class.id])
- res = self.client.get(url)
- self.assertRedirectsNoFollow(
- res, urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index'))
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks',
- 'list_flavors', 'all_racks', 'racks_ids'),
- tuskar.Rack: ('list',),
- glance: ('image_list_detailed',),
- })
- def test_edit_resource_class_post(self):
- resource_class = self.tuskar_resource_classes.first()
- image_id = self.images.list()[0].id
-
- add_racks_ids = []
-
- glance.image_list_detailed(mox.IsA(http.HttpRequest)).AndReturn(
- (self.images.list(), False))
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
- resource_class)
- tuskar.ResourceClass.all_racks = []
- tuskar.ResourceClass.racks_ids = []
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
- resource_class)
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
- resource_class)
- tuskar.ResourceClass.list_flavors = []
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
- tuskar.ResourceClass.update(mox.IsA(http.HttpRequest),
- resource_class.id,
- name=resource_class.name,
- service_type=resource_class.service_type,
- image_id=image_id,
- flavors=[]).AndReturn(resource_class)
- tuskar.ResourceClass.set_racks(mox.IsA(http.HttpRequest),
- add_racks_ids)
- self.mox.ReplayAll()
-
- form_data = {
- 'resource_class_id': resource_class.id,
- 'name': resource_class.name,
- 'service_type': resource_class.service_type,
- 'image_id': image_id,
- 'flavors-TOTAL_FORMS': 0,
- 'flavors-INITIAL_FORMS': 0,
- 'flavors-MAX_NUM_FORMS': 1000,
- 'racks-TOTAL_FORMS': 0,
- 'racks-INITIAL_FORMS': 0,
- 'racks-MAX_NUM_FORMS': 1000,
- }
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'update',
- args=[resource_class.id])
- res = self.client.post(url, form_data)
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
-
- redirect_url = (
- "%s?tab=resource_management_tabs__resource_classes_tab" %
- urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:index'))
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({tuskar.ResourceClass: ('delete', 'list')})
- def test_delete_resource_class(self):
- resource_class = self.tuskar_resource_classes.first()
- all_resource_classes = self.tuskar_resource_classes.list()
-
- tuskar.ResourceClass.delete(mox.IsA(http.HttpRequest),
- resource_class.id)
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(all_resource_classes)
- self.mox.ReplayAll()
-
- form_data = {'action':
- 'resource_classes__delete__%s' % resource_class.id}
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- res = self.client.post(url, form_data)
-
- redirect_url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({tuskar.ResourceClass: ('delete', 'list')})
- def test_delete_resource_class_exception(self):
- resource_class = self.tuskar_resource_classes.first()
- all_resource_classes = self.tuskar_resource_classes.list()
-
- tuskar.ResourceClass.delete(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndRaise(self.exceptions.tuskar)
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).\
- AndReturn(all_resource_classes)
- self.mox.ReplayAll()
-
- form_data = {'action':
- 'resource_classes__delete__%s' % resource_class.id}
- res = self.client.post(
- urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index'),
- form_data)
- # FIXME: there should be a better test than this, but the message
- # is unreadable in a redirect response
- self.assertRedirectsNoFollow(
- res, urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index'))
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list_flavors', 'list_racks',
- 'tuskar_nodes')
- })
- def test_detail_get(self):
- resource_class = self.tuskar_resource_classes.first()
- flavors = []
- racks = []
-
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).\
- AndReturn(resource_class)
- self.mox.ReplayAll()
-
- tuskar.ResourceClass.list_flavors = flavors
- tuskar.ResourceClass.list_racks = racks
- tuskar.ResourceClass.tuskar_nodes = []
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'detail',
- args=[resource_class.id])
- res = self.client.get(url)
- self.assertItemsEqual(res.context['flavors_table_table'].data, flavors)
- self.assertItemsEqual(res.context['racks_table_table'].data, racks)
- self.assertEqual(res.status_code, 200)
- self.assertTemplateUsed(
- res,
- 'infrastructure/resource_management/resource_classes/detail.html')
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get',)
- })
- def test_detail_action_get(self):
- resource_class = self.tuskar_resource_classes.first()
-
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'detail_action', args=[resource_class.id]) + "?action=delete"
- res = self.client.get(url)
- self.assertEqual(res.status_code, 200)
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'delete')
- })
- def test_detail_action_post(self):
- resource_class = self.tuskar_resource_classes.first()
-
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
- tuskar.ResourceClass.delete(mox.IsA(http.HttpRequest),
- resource_class.id)
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'detail_action', args=[resource_class.id]) + "?action=delete"
- res = self.client.post(url)
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
-
- redirect_url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:index')
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list_racks')
- })
- def test_rack_health_get(self):
- resource_class = self.tuskar_resource_classes.first()
- racks = [self.tuskar_racks.first()]
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).\
- AndReturn(resource_class)
- self.mox.ReplayAll()
-
- tuskar.ResourceClass.list_racks = racks
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:'
- 'resource_classes:rack_health', args=[resource_class.id])
- res = self.client.get(url)
- data = simplejson.loads(res.content)['data']
-
- # FIXME: this is dummy data right now, just assert its presence
- self.assertEqual(len(data), 1)
- self.assertEqual(data[0]['name'], 'rack1')
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list_flavors', 'list_racks')
- })
- def test_detail_get_exception(self):
- resource_class = self.tuskar_resource_classes.first()
-
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).\
- AndRaise(self.exceptions.tuskar)
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:'
- 'resource_classes:detail', args=[resource_class.id])
- res = self.client.get(url)
- self.assertRedirectsNoFollow(
- res, urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index'))
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list_flavors',
- 'racks_ids', 'all_racks'),
- glance: ('image_list_detailed',),
- })
- def test_detail_edit_racks_get(self):
- resource_class = self.tuskar_resource_classes.first()
- all_flavors = []
- all_racks = []
-
- glance.image_list_detailed(mox.IsA(http.HttpRequest)).AndReturn(
- (self.images.list(), False))
- tuskar.ResourceClass.get(mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- # get_flavors_data in workflows.py
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- # get_racks_data in workflows.py
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- self.mox.ReplayAll()
-
- # FIXME I should probably track the racks and flavors methods
- # so maybe they shouldn't be a @property
- # properties set
- tuskar.ResourceClass.all_racks = all_racks
- tuskar.ResourceClass.list_flavors = all_flavors
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'update_racks',
- args=[resource_class.id])
- res = self.client.get(url)
- self.assertEqual(res.status_code, 200)
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks',
- 'list_flavors', 'all_racks', 'racks_ids'),
- glance: ('image_list_detailed',),
- })
- def test_detail_edit_racks_post(self):
- resource_class = self.tuskar_resource_classes.first()
- image_id = self.images.list()[0].id
- add_racks_ids = []
-
- glance.image_list_detailed(mox.IsA(http.HttpRequest)).AndReturn(
- (self.images.list(), False))
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
- resource_class)
- tuskar.ResourceClass.all_racks = []
- tuskar.ResourceClass.racks_ids = []
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
- resource_class)
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
- resource_class)
- tuskar.ResourceClass.list_flavors = []
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
- tuskar.ResourceClass.update(mox.IsA(http.HttpRequest),
- resource_class.id,
- name=resource_class.name,
- service_type=resource_class.service_type,
- image_id=image_id,
- flavors=[]).AndReturn(resource_class)
- tuskar.ResourceClass.set_racks(mox.IsA(http.HttpRequest),
- add_racks_ids)
- self.mox.ReplayAll()
-
- form_data = {
- 'resource_class_id': resource_class.id,
- 'name': resource_class.name,
- 'service_type': resource_class.service_type,
- 'image_id': image_id,
- 'flavors-TOTAL_FORMS': 0,
- 'flavors-INITIAL_FORMS': 0,
- 'flavors-MAX_NUM_FORMS': 1000,
- 'racks-TOTAL_FORMS': 0,
- 'racks-INITIAL_FORMS': 0,
- 'racks-MAX_NUM_FORMS': 1000,
- }
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'update_racks',
- args=[resource_class.id])
- res = self.client.post(url, form_data)
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
-
- detail_url = ('horizon:infrastructure:resource_management:'
- 'resource_classes:detail')
- redirect_url = (
- "%s?tab=resource_class_details__racks" %
- urlresolvers.reverse(detail_url, args=(resource_class.id,)))
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list_flavors',
- 'racks_ids', 'all_racks'),
- glance: ('image_list_detailed',),
- })
- def test_detail_edit_flavors_get(self):
- resource_class = self.tuskar_resource_classes.first()
- all_flavors = []
- all_racks = []
-
- glance.image_list_detailed(mox.IsA(http.HttpRequest)).AndReturn(
- (self.images.list(), False))
- tuskar.ResourceClass.get(mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- # get_flavors_data in workflows.py
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- # get_racks_data in workflows.py
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
-
- self.mox.ReplayAll()
-
- # FIXME I should probably track the racks and flavors methods
- # so maybe they shouldn't be a @property
- # properties set
- tuskar.ResourceClass.all_racks = all_racks
- tuskar.ResourceClass.list_flavors = all_flavors
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'update_flavors',
- args=[resource_class.id])
- res = self.client.get(url)
- self.assertEqual(res.status_code, 200)
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks',
- 'list_flavors', 'all_racks', 'racks_ids'),
- tuskar.Rack: ('list',),
- glance: ('image_list_detailed',),
- })
- def test_detail_edit_flavors_post(self):
- resource_class = self.tuskar_resource_classes.first()
- image_id = self.images.list()[0].id
- add_racks_ids = []
-
- glance.image_list_detailed(mox.IsA(http.HttpRequest)).AndReturn(
- (self.images.list(), False))
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
- resource_class)
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
- resource_class)
- tuskar.ResourceClass.all_racks = []
- tuskar.ResourceClass.racks_ids = []
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest), resource_class.id).AndReturn(
- resource_class)
- tuskar.ResourceClass.list_flavors = []
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(
- self.tuskar_resource_classes.list())
- tuskar.ResourceClass.update(mox.IsA(http.HttpRequest),
- resource_class.id,
- name=resource_class.name,
- service_type=resource_class.service_type,
- image_id=image_id,
- flavors=[]).AndReturn(resource_class)
- tuskar.ResourceClass.set_racks(mox.IsA(http.HttpRequest),
- add_racks_ids)
- self.mox.ReplayAll()
-
- form_data = {
- 'resource_class_id': resource_class.id,
- 'name': resource_class.name,
- 'service_type': resource_class.service_type,
- 'image_id': image_id,
- 'flavors-TOTAL_FORMS': 0,
- 'flavors-INITIAL_FORMS': 0,
- 'flavors-MAX_NUM_FORMS': 1000,
- 'racks-TOTAL_FORMS': 0,
- 'racks-INITIAL_FORMS': 0,
- 'racks-MAX_NUM_FORMS': 1000,
- }
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:resource_classes:'
- 'update_flavors',
- args=[resource_class.id])
- res = self.client.post(url, form_data)
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
-
- redirect_url = ('horizon:infrastructure:resource_management:'
- 'resource_classes:detail')
- redirect_url = "%s?tab=resource_class_details__flavors" % (
- urlresolvers.reverse(redirect_url, args=(resource_class.id,)))
- self.assertRedirectsNoFollow(res, redirect_url)
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/urls.py b/tuskar_ui/infrastructure/resource_management/resource_classes/urls.py
deleted file mode 100644
index dbc4ab1c..00000000
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/urls.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls import defaults
-
-from tuskar_ui.infrastructure.resource_management.flavors\
- import urls as flavor_urls
-from tuskar_ui.infrastructure.resource_management.resource_classes import views
-
-
-RESOURCE_CLASS = r'^(?P<resource_class_id>[^/]+)/%s$'
-VIEW_MOD = ('tuskar_ui.infrastructure.resource_management.resource_classes.'
- 'views')
-
-urlpatterns = defaults.patterns(
- VIEW_MOD,
- defaults.url(r'^create/$', views.CreateView.as_view(), name='create'),
- defaults.url(r'^(?P<resource_class_id>[^/]+)/$',
- views.DetailView.as_view(),
- name='detail'),
- defaults.url(RESOURCE_CLASS % 'update',
- views.UpdateView.as_view(),
- name='update'),
- defaults.url(RESOURCE_CLASS % 'detail_action',
- views.DetailActionView.as_view(),
- name='detail_action'),
- defaults.url(RESOURCE_CLASS % 'detail_update',
- views.DetailUpdateView.as_view(),
- name='detail_update'),
- defaults.url(RESOURCE_CLASS % 'update_racks',
- views.UpdateRacksView.as_view(),
- name='update_racks'),
- defaults.url(RESOURCE_CLASS % 'update_flavors',
- views.UpdateFlavorsView.as_view(),
- name='update_flavors'),
- defaults.url(RESOURCE_CLASS % 'rack_health.json',
- 'rack_health',
- name='rack_health'),
- defaults.url(r'^(?P<resource_class_id>[^/]+)/flavors/',
- defaults.include(flavor_urls, namespace='flavors')),
-)
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/views.py b/tuskar_ui/infrastructure/resource_management/resource_classes/views.py
deleted file mode 100644
index 786f2579..00000000
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/views.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing resource classes
-"""
-import logging
-import random
-
-from django.core import urlresolvers
-import django.http
-from django.utils import simplejson
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import forms as horizon_forms
-from horizon import tabs as horizon_tabs
-
-from tuskar_ui import api as tuskar
-
-from tuskar_ui.infrastructure.resource_management.resource_classes import forms
-from tuskar_ui.infrastructure.resource_management.resource_classes import tabs
-from tuskar_ui.infrastructure.resource_management.resource_classes\
- import workflows
-from tuskar_ui import workflows as tuskar_workflows
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateView(tuskar_workflows.WorkflowView):
- workflow_class = workflows.CreateResourceClass
-
- def get_initial(self):
- pass
-
-
-class UpdateView(tuskar_workflows.WorkflowView):
- workflow_class = workflows.UpdateResourceClass
-
- def get_context_data(self, **kwargs):
- context = super(UpdateView, self).get_context_data(**kwargs)
- context["resource_class_id"] = self.kwargs['resource_class_id']
- return context
-
- def _get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- resource_class_id = self.kwargs['resource_class_id']
- try:
- self._object = \
- tuskar.ResourceClass.get(self.request,
- resource_class_id)
- except Exception:
- redirect = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:index')
- msg = _('Unable to retrieve resource class details.')
- exceptions.handle(self.request, msg, redirect=redirect)
-
- return self._object
-
- def get_initial(self):
- resource_class = self._get_object()
-
- return {
- 'resource_class_id': resource_class.id,
- 'name': resource_class.name,
- 'service_type': resource_class.service_type,
- 'image_id': resource_class.image_id,
- }
-
-
-class DetailUpdateView(UpdateView):
- workflow_class = workflows.DetailUpdateWorkflow
-
-
-class UpdateRacksView(UpdateView):
- workflow_class = workflows.UpdateRacksWorkflow
-
-
-class UpdateFlavorsView(UpdateView):
- workflow_class = workflows.UpdateFlavorsWorkflow
-
-
-class DetailView(horizon_tabs.TabView):
- tab_group_class = tabs.ResourceClassDetailTabs
- template_name = ('infrastructure/resource_management/resource_classes/'
- 'detail.html')
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["resource_class"] = self.get_data()
- return context
-
- def get_data(self):
- if not hasattr(self, "_resource_class"):
- try:
- resource_class_id = self.kwargs['resource_class_id']
- resource_class = tuskar.ResourceClass.get(self.request,
- resource_class_id)
- except Exception:
- redirect = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:index')
- exceptions.handle(self.request,
- _('Unable to retrieve details for '
- 'resource class "%s".')
- % resource_class_id, redirect=redirect)
- self._resource_class = resource_class
- return self._resource_class
-
- def get_tabs(self, request, *args, **kwargs):
- resource_class = self.get_data()
- return self.tab_group_class(request, resource_class=resource_class,
- **kwargs)
-
-
-class DetailActionView(horizon_forms.ModalFormView):
- template_name = ('infrastructure/resource_management/'
- 'resource_classes/action.html')
-
- def get_form(self, form_class):
- """Returns an instance of the form to be used in this view."""
- try:
- action = self.request.GET.get('action')
- if action == "delete":
- form_class = forms.DeleteForm
-
- return form_class(self.request, **self.get_form_kwargs())
- except Exception:
- exceptions.handle(self.request, _("Unable to build an Action."))
-
- def get_success_url(self):
- # FIXME this should be set on form level
- return urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:index')
-
- def get_context_data(self, **kwargs):
- context = super(DetailActionView, self).get_context_data(**kwargs)
- context['resource_class_id'] = self.kwargs['resource_class_id']
- context['action'] = context['form'].initial.get('action', None)
- context['header'] = context['form'].command.header
- return context
-
- def get_initial(self):
- try:
- resource_class = tuskar.ResourceClass.get(
- self.request, self.kwargs['resource_class_id'])
- action = self.request.GET.get('action')
- except Exception:
- exceptions.handle(self.request,
- _("Unable to retrieve resource class data."))
- return {'resource_class': resource_class,
- 'action': action}
-
-
-def rack_health(request, resource_class_id=None):
- # FIXME replace mock data
- random.seed()
- data = []
- statuses = ["Good", "Warnings", "Disaster"]
- colors = ["rgb(244,244,244)", "rgb(240,170,0)", "rgb(200,0,0)"]
-
- resource_class = (tuskar.ResourceClass.get(request,
- resource_class_id))
- for rack in resource_class.list_racks:
- rand_index = random.randint(0, 2)
- percentage = (2 - rand_index) * 50
- color = colors[rand_index]
-
- tooltip = ("<p>Rack: <strong>{0}</strong></p><p>{1}</p>").format(
- rack.name,
- statuses[rand_index])
-
- data.append({'tooltip': tooltip,
- 'color': color,
- 'status': statuses[rand_index],
- 'percentage': percentage,
- 'id': rack.id,
- 'name': rack.name,
- 'url': "FIXME url"})
-
- data.sort(key=lambda x: x['percentage'])
-
- res = {'data': data}
- return django.http.HttpResponse(simplejson.dumps(res),
- mimetype="application/json")
diff --git a/tuskar_ui/infrastructure/resource_management/resource_classes/workflows.py b/tuskar_ui/infrastructure/resource_management/resource_classes/workflows.py
deleted file mode 100644
index 08227106..00000000
--- a/tuskar_ui/infrastructure/resource_management/resource_classes/workflows.py
+++ /dev/null
@@ -1,350 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import forms
-from horizon import workflows
-from openstack_dashboard.api import glance
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.infrastructure.resource_management.flavors\
- import forms as flavors_forms
-from tuskar_ui.infrastructure.resource_management.resource_classes\
- import tables
-import tuskar_ui.workflows
-
-
-TEMPLATE_PREFIX = 'infrastructure/resource_management/resource_classes/'
-URL_PREFIX = 'horizon:infrastructure:resource_management:'
-
-
-class ResourceClassInfoAction(workflows.Action):
- name = forms.CharField(max_length=255,
- label=_("Class Name"),
- help_text="",
- required=True)
- service_type = forms.ChoiceField(label=_('Class Type'),
- required=True,
- choices=[('', ''),
- ('controller',
- ('Controller')),
- ('compute',
- ('Compute')),
- ('object_storage',
- ('Object Storage')),
- ('block_storage',
- ('Block Storage')),
- ],
- widget=forms.Select(
- attrs={'class': 'switchable'})
- )
- image_id = forms.ChoiceField(
- label=_('Provisioning Image'),
- required=True,
- choices=[],
- widget=forms.Select(attrs={'class': 'switchable'}),
- )
-
- def __init__(self, *args, **kwargs):
- super(ResourceClassInfoAction, self).__init__(*args, **kwargs)
- try:
- images, more = glance.image_list_detailed(self.request)
- except Exception:
- exceptions.handle(self.request,
- _('Unable to retrieve image list.'))
- else:
- self.fields['image_id'].choices = [
- (image.id, image.name) for image in images]
-
- def clean(self):
- cleaned_data = super(ResourceClassInfoAction, self).clean()
-
- name = cleaned_data.get('name')
- resource_class_id = self.initial.get('resource_class_id', None)
- try:
- resource_classes = tuskar.ResourceClass.list(self.request)
- except Exception:
- resource_classes = []
- msg = _('Unable to get resource class list')
- exceptions.check_message(["Connection", "refused"], msg)
- raise
- for resource_class in resource_classes:
- if resource_class.name == name and \
- resource_class_id != resource_class.id:
- raise forms.ValidationError(
- _('The name "%s" is already used by'
- ' another resource class.')
- % name
- )
- return cleaned_data
-
- class Meta:
- name = _("Class Settings")
- help_text = _("From here you can fill in the class settings.")
-
-
-class CreateResourceClassInfo(workflows.Step):
- action_class = ResourceClassInfoAction
- contributes = ("name", "service_type", "image_id")
-
-
-class ResourceClassFlavorsAction(workflows.Action):
- def clean(self):
- cleaned_data = super(ResourceClassFlavorsAction, self).clean()
- table = self.initial.get('_tables', {}).get('flavors')
- if table:
- formset = table.get_formset()
- if formset.is_valid():
- cleaned_data['flavors'] = [form.cleaned_data
- for form in formset
- if form.cleaned_data
- and not form.cleaned_data['DELETE']]
- else:
- raise forms.ValidationError(_('Errors in the flavors list.'))
- return cleaned_data
-
- class Meta:
- name = _("Flavors")
- help_text = _("From here you can add flavors to the class.")
-
-
-class CreateResourceClassFlavors(tuskar_ui.workflows.TableStep):
- table_classes = (tables.FlavorsFormsetTable,)
-
- action_class = ResourceClassFlavorsAction
- template_name = TEMPLATE_PREFIX + '_flavors_step.html'
- contributes = ("flavors",)
-
- def get_flavors_data(self):
- try:
- resource_class_id = self.workflow.context.get("resource_class_id")
- if resource_class_id:
- resource_class = tuskar.ResourceClass.get(
- self.workflow.request, resource_class_id)
- flavors = resource_class.list_flavors
- else:
- flavors = []
- except Exception:
- flavors = []
- exceptions.handle(self.workflow.request,
- _('Unable to retrieve resource flavors list.'))
- return flavors
-
-
-class RacksAction(workflows.Action):
- class Meta:
- name = _("Racks")
-
- def clean(self):
- cleaned_data = super(RacksAction, self).clean()
- table = self.initial.get('_tables', {}).get('racks')
- if table:
- formset = table.get_formset()
- if formset.is_valid():
- cleaned_data['racks_object_ids'] = [
- form.cleaned_data['id'] for form in formset
- if form.cleaned_data and
- form.cleaned_data.get('selected') and
- not form.cleaned_data.get('DELETE')]
- else:
- raise forms.ValidationError(_('Errors in the racks table.'))
- return cleaned_data
-
-
-class CreateRacks(tuskar_ui.workflows.TableStep):
- table_classes = (tables.RacksFormsetTable,)
-
- action_class = RacksAction
- contributes = ("racks_object_ids")
- template_name = TEMPLATE_PREFIX + '_table_step.html'
-
- def contribute(self, data, context):
- context.update(data)
- return context
-
- def get_racks_data(self):
- try:
- resource_class_id = self.workflow.context.get("resource_class_id")
- if resource_class_id:
- resource_class = tuskar.ResourceClass.get(
- self.workflow.request,
- resource_class_id)
- selected_racks = resource_class.racks_ids
- racks = resource_class.all_racks
- for rack in racks:
- rack.selected = (rack.id in selected_racks)
- else:
- racks = tuskar.Rack.list(self.workflow.request, True)
- except Exception:
- racks = []
- exceptions.handle(self.workflow.request,
- _('Unable to retrieve racks list.'))
-
- return racks
-
-
-class ResourceClassWorkflowMixin:
- # FIXME active tabs coflict
- # When on page with tabs, the workflow with more steps is used,
- # there is a conflict of active tabs and it always shows the
- # first tab after an action. So I explicitly specify to what
- # tab it should redirect after action, until the coflict will
- # be fixed in Horizon.
- def get_index_url(self):
- # This url is used both as success and failure url
- return "%s?tab=resource_management_tabs__resource_classes_tab" % (
- urlresolvers.reverse(URL_PREFIX + 'index'))
-
- def get_success_url(self):
- return self.get_index_url()
-
- def get_failure_url(self):
- return self.get_index_url()
-
- def format_status_message(self, message):
- name = self.context.get('name')
- return message % name
-
- def _get_flavors(self, request, data):
- flavors = []
- for flavor in data.get('flavors') or []:
- capacities = []
- for name, info in flavors_forms.CAPACITIES.items():
- label, unit, required = info
- value = flavor.get(name, '')
- if value is None:
- value = ''
- capacities.append({'name': name, 'value': str(value),
- 'unit': unit})
- # FIXME: for now just use blank max_vms
- flavors.append({'name': flavor['name'], 'capacities': capacities,
- 'max_vms': None, 'id': data.get('id')})
- return flavors
-
- def _add_racks(self, request, data, resource_class):
- ids_to_add = data.get('racks_object_ids') or []
- resource_class.set_racks(request, ids_to_add)
-
-
-class CreateResourceClass(ResourceClassWorkflowMixin, workflows.Workflow):
- default_steps = (CreateResourceClassInfo, CreateResourceClassFlavors,
- CreateRacks)
-
- slug = "create_resource_class"
- name = _("Create Class")
- finalize_button_name = _("Create Class")
- success_message = _('Created class "%s".')
- failure_message = _('Unable to create class "%s".')
-
- def _create_resource_class_info(self, request, data):
- try:
- if data['service_type'] == 'compute':
- flavors = self._get_flavors(request, data)
- else:
- flavors = []
- return tuskar.ResourceClass.create(
- request,
- name=data['name'],
- service_type=data['service_type'],
- image_id=data['image_id'],
- flavors=flavors)
- except Exception:
- redirect = self.get_failure_url()
- exceptions.handle(request,
- _('Unable to create resource class.'),
- redirect=redirect)
- return None
-
- def handle(self, request, data):
- resource_class = self._create_resource_class_info(request, data)
- self._add_racks(request, data, resource_class)
- return True
-
-
-class UpdateResourceClassInfo(CreateResourceClassInfo):
- depends_on = ("resource_class_id",)
-
-
-class UpdateResourceClassFlavors(CreateResourceClassFlavors):
- depends_on = ("resource_class_id",)
-
-
-class UpdateRacks(CreateRacks):
- depends_on = ("resource_class_id",)
-
-
-class UpdateResourceClass(ResourceClassWorkflowMixin, workflows.Workflow):
- default_steps = (UpdateResourceClassInfo, UpdateResourceClassFlavors,
- UpdateRacks)
-
- slug = "update_resource_class"
- name = _("Update Class")
- finalize_button_name = _("Update Class")
- success_message = _('Updated class "%s".')
- failure_message = _('Unable to update class "%s".')
-
- def _update_resource_class_info(self, request, data):
- try:
- if data['service_type'] == 'compute':
- flavors = self._get_flavors(request, data)
- else:
- flavors = []
- return tuskar.ResourceClass.update(
- request,
- data['resource_class_id'],
- name=data['name'],
- service_type=data['service_type'],
- image_id=data['image_id'],
- flavors=flavors)
- except Exception:
- redirect = self.get_failure_url()
- exceptions.handle(request,
- _('Unable to create resource class.'),
- redirect=redirect)
- return None
-
- def handle(self, request, data):
- resource_class = self._update_resource_class_info(request, data)
- self._add_racks(request, data, resource_class)
- return True
-
-
-class DetailUpdateWorkflow(UpdateResourceClass):
- def get_index_url(self):
- # This url is used both as success and failure url
- url = URL_PREFIX + "resource_classes:detail"
- resource_class_id = self.context["resource_class_id"]
- return "%s?tab=resource_class_details__overview" % (
- urlresolvers.reverse(url, args=(resource_class_id,)))
-
-
-class UpdateFlavorsWorkflow(UpdateResourceClass):
- def get_index_url(self):
- # This url is used both as success and failure url
- url = URL_PREFIX + "resource_classes:detail"
- resource_class_id = self.context["resource_class_id"]
- return "%s?tab=resource_class_details__flavors" % (
- urlresolvers.reverse(url, args=(resource_class_id,)))
-
-
-class UpdateRacksWorkflow(UpdateResourceClass):
- def get_index_url(self):
- # This url is used both as success and failure url
- url = URL_PREFIX + "resource_classes:detail"
- resource_class_id = self.context["resource_class_id"]
- return "%s?tab=resource_class_details__racks" % (
- urlresolvers.reverse(url, args=(resource_class_id,)))
diff --git a/tuskar_ui/infrastructure/resource_management/tabs.py b/tuskar_ui/infrastructure/resource_management/tabs.py
deleted file mode 100644
index 7273fea1..00000000
--- a/tuskar_ui/infrastructure/resource_management/tabs.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# Vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _ # noqa
-
-from horizon import exceptions
-from horizon import tabs
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.infrastructure.resource_management.racks\
- import tables as racks_tables
-from tuskar_ui.infrastructure.resource_management.resource_classes\
- import tables as resource_classes_tables
-
-
-def get_provision_racks_and_state(racks):
- unprovisioned_racks = [rack for rack in racks
- if not rack.is_provisioned]
- provisioning_racks = [rack for rack in racks
- if rack.is_provisioning]
- if provisioning_racks:
- state = 'provisioning'
- elif unprovisioned_racks:
- state = 'unprovisioned'
- else:
- state = 'provisioned'
- return unprovisioned_racks, provisioning_racks, state
-
-
-class ProvisioningInfoMixin(object):
- def get_provisioning_racks_data(self):
- try:
- racks = tuskar.Rack.list(self.request)
- except Exception:
- racks = []
- exceptions.handle(self.request, _("Unable to retrieve racks."))
- return racks
-
- def get_context_data(self, request=None, **kwargs):
- # XXX get_context_data has different signatures in different views
- if request:
- context = super(ProvisioningInfoMixin, self).get_context_data(
- request, **kwargs)
- else:
- context = super(ProvisioningInfoMixin, self).get_context_data(
- **kwargs)
- (unprovisioned_racks, provisioning_racks, state) = (
- get_provision_racks_and_state(self.
- get_provisioning_racks_data()))
- context.update({
- 'unprovisioned_racks': unprovisioned_racks,
- 'provisioning_racks': provisioning_racks,
- 'provisioning_state': state,
- })
- return context
-
-
-class RacksTab(ProvisioningInfoMixin, tabs.TableTab):
- table_classes = (racks_tables.RacksTable,)
- name = _("Racks")
- slug = "racks_tab"
- template_name = ("infrastructure/resource_management/"
- "racks/_index_table.html")
-
- def get_racks_data(self):
- try:
- racks = tuskar.Rack.list(self.request)
- except Exception:
- racks = []
- exceptions.handle(self.request,
- _('Unable to retrieve racks.'))
- return racks
-
- def get_context_data(self, request):
- context = super(RacksTab, self).get_context_data(request)
- try:
- context["baremetal_nodes"] = tuskar.BaremetalNode.list_unracked(
- self.request)
- except Exception:
- context["baremetal_nodes"] = []
- exceptions.handle(request,
- _("Unable to retrieve baremetal nodes."))
- return context
-
-
-class ResourceClassesTab(ProvisioningInfoMixin, tabs.TableTab):
- table_classes = (resource_classes_tables.ResourceClassesTable,)
- name = _("Classes")
- slug = "resource_classes_tab"
- template_name = ("infrastructure/resource_management/"
- "resource_classes/_index_table.html")
- #preload = False buggy, checkboxes doesn't work wit table actions
-
- def get_resource_classes_data(self):
- try:
- resource_classes = tuskar.ResourceClass.list(self.request)
- except Exception:
- resource_classes = []
- exceptions.handle(self.request,
- _('Unable to retrieve resource classes list.'))
- return resource_classes
-
-
-class ResourceManagementTabs(tabs.TabGroup):
- slug = "resource_management_tabs"
- tabs = (ResourceClassesTab, RacksTab)
- sticky = True
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision.html
deleted file mode 100644
index 04c920e8..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}provision_form{% endblock %}
-{% block form_action %}{% url 'horizon:infrastructure:resource_management:provision' %}{% endblock %}
-
-{% block modal_id %}provision_modal{% endblock %}
-{% block modal-header %}{% trans "Provisioning Confirmation" %}{% endblock %}
-
-{% block modal-body %}
-<div>
- <p>{% trans "You are about to provision the following unprovisioned racks:" %}
- <ol>
- {% for rack in unprovisioned_racks %}
- <li>{{ rack.name }}</li>
- {% endfor %}
- </ol></p>
- <p>{% trans "This operation cannot be undone. Are you sure you want to do that?" %}</p>
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary" type="submit" value="{% trans "Provision" %}" />
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision_info.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision_info.html
deleted file mode 100644
index 3fb8e0aa..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision_info.html
+++ /dev/null
@@ -1,71 +0,0 @@
-{% load i18n %}
-{% load url from future %}
-
-<div class="provisioning-state">
-{% if provisioning_state == "unprovisioned" %}
- <div class="well well-small clearfix">
- <a class="btn btn-primary btn-small ajax-modal pull-right"
- href="{% url 'horizon:infrastructure:resource_management:provision' %}">
- {% trans "Provision Deployment" %}
- </a>
- {% trans "Some racks are not provisioned yet." %}
- </div>
-{% endif %}
-</div>
-
-<script>
-// A global to make sure we only run this once.
-var provisioning_state_initialized;
-
-(function () {
- var init_check_state = function () {
- if (provisioning_state_initialized) {
- // Already initialized.
- return;
- };
- provisioning_state_initialized = true;
- var divs = $('div.provisioning-state');
- var old_state = '{{ provisioning_state|escapejs }}';
- var url = '{% filter escapejs %}{% url "horizon:infrastructure:resource_management:provisioning_state" %}{% endfilter %}';
- var progress_html = '{% filter escapejs %}{% include "infrastructure/resource_management/_provision_progress.html" %}{% endfilter %}';
- var success_html = '<div class="alert alert-block alert-success"><a href="#" class="close" data-dismiss="alert">×</a>{% filter escapejs %}{% trans "Provisioning succeeded." %}{%endfilter %}</div>';
- var error_html = '<div class="alert alert-block alert-error"><a href="#" class="close" data-dismiss="alert">×</a>{% filter escapejs %}{% trans "Provisioning state unavailable." %}{% endfilter %}</div>';
-
- var check_state = function () {
- $.getJSON(url).done(function(data) {
- var new_state = data['state'];
- if (old_state === new_state) {
- // Nothing to see here, move along.
- return;
- };
- if (new_state === 'provisioning') {
- divs.html(progress_html);
- } else if (old_state === 'provisioning') {
- // Provisioning finished, don't poll anymore.
- window.clearInterval(interval_id);
- divs.html(success_html);
- };
- old_state = new_state;
- }).fail(function(jqxhr, textStatus, error) {
- window.clearInterval(interval_id);
- divs.html(error_html);
- });
- };
-
- if (old_state == 'provisioning') {
- // Only display progress if js is enabled.
- divs.html(progress_html);
- };
- if (old_state !== 'provisioned') {
- // Only poll when unprovisioned or provisioning.
- var interval_id = window.setInterval(check_state, 20000);
- };
- };
-
- if (typeof($) !== 'undefined') {
- $(init_check_state);
- } else {
- addHorizonLoadEvent(init_check_state);
- }
-}());
-</script>
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision_progress.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision_progress.html
deleted file mode 100644
index 4989e8a1..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/_provision_progress.html
+++ /dev/null
@@ -1,8 +0,0 @@
-{% load i18n %}
-<div class="well well-small clearfix">
- <div class="progress progress-striped active pull-right"
- style="width:20%; margin: auto 0;">
- <div class="bar" style="width:100%"></div>
- </div>
- {% trans "Provisioning deployment…" %}
-</div>
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/flavors/_detail_overview.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/flavors/_detail_overview.html
deleted file mode 100644
index b0c97dc5..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/flavors/_detail_overview.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{% load i18n sizeformat %}
-{% load url from future %}
-
-<div class="info row-fluid detail">
- <div class="span4">
- <h4>{% trans "About" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ flavor.name|default:_("None") }}</dd>
- <dt>{% trans "Resource Class" %}</dt>
- <dd>{{ resource_class.name|default:_("None") }}</dd>
- </dl>
- </div>
- <div class="span4">
- <h4>{% trans "Specification" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "VCPU" %}</dt>
- <dd>{{ flavor.cpu.value }}</dd>
- <dt>{% trans "RAM" %}</dt>
- <dd>{{ flavor.memory.value }} {{ flavor.memory.unit }}</dd>
- <dt>{% trans "Root Disk" %}</dt>
- <dd>{{ flavor.storage.value }} {{ flavor.storage.unit }}</dd>
- <dt>{% trans "Ephemeral Disk" %}</dt>
- <dd>{{ flavor.ephemeral_disk.value }} {{ flavor.ephemeral_disk.unit }}</dd>
- <dt>{% trans "Swap Disk" %}</dt>
- <dd>{{ flavor.swap_disk.value }} {{ flavor.swap_disk.unit }}</dd>
- </dl>
- </div>
-</div>
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/flavors/detail.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/flavors/detail.html
deleted file mode 100644
index 80229834..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/flavors/detail.html
+++ /dev/null
@@ -1,24 +0,0 @@
-{% extends 'infrastructure/base_detail.html' %}
-{% load i18n %}
-{% load url from future %}
-{% block title %}{% trans "Flavor Detail"%}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Flavor Detail") %}
-{% endblock page_header %}
-
-{% block actions %}
-{% endblock %}
-
-{% block breadcrumbs %}
- <div class="breadcrumbs">
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__resource_classes_tab" >{% trans 'Home' %}</a>
- <span class="separator"></span>
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__resource_classes_tab" >{% trans 'Classes'%}</a>
- <span class="separator"></span>
- <a href="{% url 'horizon:infrastructure:resource_management:resource_classes:detail' resource_class.id %}" >{{ resource_class.name }}</a>
- <span class="separator"></span>
- </div>
-{% endblock breadcrumbs %}
-
-{% block name %}{{ flavor.name }}{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/index.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/index.html
deleted file mode 100644
index 11d1d8ad..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/index.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% load url from future %}
-{% block title %}{% trans "Resource Management" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Resource Management") %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- <div class="breadcrumbs">
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__resource_classes_tab" >Home</a>
- <span class="separator"></span>
- </div>
- </div>
-</div>
-
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/_detail_overview.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/_detail_overview.html
deleted file mode 100644
index b661b6ee..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/_detail_overview.html
+++ /dev/null
@@ -1,258 +0,0 @@
-{% load i18n sizeformat %}
-{% load url from future %}
-{% load chart_helpers %}
-
-<div class="info row-fluid detail">
- <div class="span4">
- <h4>{% trans "About" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "MAC Address" %}</dt>
- <dd>{{ baremetal_node.mac_address|default:_("None") }}</dd>
- <dt>{% trans "IPs" %}</dt>
- <dd>{{ baremetal_node.ip_address_other|default:_("None") }}</dd>
- <dt>{% trans "Management IP" %}</dt>
- <dd>{{ baremetal_node.pm_address|default:_("None") }}</dd>
- <dt>{% trans "Power Management" %}</dt>
- <dd>{{ tuskar_node.rack.power_management|default:_("-") }}</dd>
- <dt>{% trans "Status" %}</dt>
- <dd>{{ baremetal_node.status|default:_("None") }}</dd>
- </dl>
- </div>
- <div class="span4">
- <h4>{% trans "Resource Assignment" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Rack" %}</dt>
- {% if tuskar_node.rack %}
- <dd><a href="{% url 'horizon:infrastructure:resource_management:racks:detail' tuskar_node.rack_id %}">{{ tuskar_node.rack.name|default:_("None") }}</a></dd>
- {% else %}
- <dd>{% trans "None" %}</dd>
- {% endif %}
- <!--<dt>{% trans "Region" %}</dt>
- <dd>{{ tuskar_node.region|default:_("None") }}</dd>-->
- <dt>{% trans "Node Type" %}</dt>
- <dd>{{ tuskar_node.type|default:_("none") }}</dd>
- <dt>{% trans "Provisioned Image" %}</dt>
- <dd>{{ tuskar_node.image|default:_("None") }}</dd>
- <dt>{% trans "Running Instances" %}</dt>
- <dd>{{ running_instances }}</dd>
- </dl>
- </div>
- <div class="span4">
- <h4>{% trans "Capacities" %}</h4>
- <hr class="header_rule">
- <table class="capacities">
- <tr>
- <td class="capacity_label">{% trans "CPU" %}:</td>
- {% if tuskar_node.is_provisioned %}
- <td>
- <div id="cpu_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart"
- data-capacity-limit="{{ tuskar_node.cpu.value }}"
- data-capacity-used="{{ tuskar_node.cpu.usage }}"
- data-average-capacity-used="{{ 2 }}">
- </div>
- </td>
- <td>
- <a href="#" data-chart-type="modal_line_chart" data-url="/infrastructure/resource_management/racks/usage_data" data-series="cpu">{{ tuskar_node.cpu.usage }}/{{ tuskar_node.cpu.value }} {{ tuskar_node.cpu.unit }}</a>
- </td>
- {% else %}
- <td>
- <div id="cpu_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart">
- </div>
- </td>
- <td></td>
- {% endif %}
- </tr>
- <tr>
- <td class="capacity_label">{% trans "RAM" %}:</td>
- {% if tuskar_node.is_provisioned %}
- <td>
- <div id="ram_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart"
- data-capacity-limit="{{ tuskar_node.ram.value }}"
- data-capacity-used="{{ tuskar_node.ram.usage }}"
- data-average-capacity-used="{{ 12 }}">
- </div>
- </td>
- <td>
- <a href="#" data-chart-type="modal_line_chart" data-url="/infrastructure/resource_management/racks/usage_data" data-series="ram">{{ tuskar_node.ram.usage }}/{{ tuskar_node.ram.value }} {{ tuskar_node.ram.unit }}</a>
- </td>
- {% else %}
- <td>
- <div id="ram_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart">
- </div>
- </td>
- <td></td>
- {% endif %}
- </tr>
- <tr>
- <td class="capacity_label">{% trans "Storage" %}:</td>
- {% if tuskar_node.is_provisioned %}
- <td>
- <div id="storage_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart"
- data-capacity-limit="{{ tuskar_node.storage.value }}"
- data-capacity-used="{{ tuskar_node.storage.usage }}"
- data-average-capacity-used="{{ 6 }}">
- </div>
- </td>
- <td>
- <a href="#" data-chart-type="modal_line_chart" data-url="/infrastructure/resource_management/racks/usage_data" data-series="storage">{{ tuskar_node.storage.usage }}/{{ tuskar_node.storage.value }} {{ tuskar_node.storage.unit }}</a>
- </td>
- {% else %}
- <td>
- <div id="storage_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart">
- </div>
- </td>
- <td></td>
- {% endif %}
- </tr>
- <tr>
- <td class="capacity_label">{% trans "Network" %}:</td>
- {% if tuskar_node.is_provisioned %}
- <td>
- <div id="network_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart"
- data-capacity-limit="{{ tuskar_node.network.value }}"
- data-capacity-used="{{ tuskar_node.network.usage }}"
- data-average-capacity-used="{{ 40 }}">
- </div>
- </td>
- <td>
- <a href="#" data-chart-type="modal_line_chart" data-url="/infrastructure/resource_management/racks/usage_data" data-series="network">{{ tuskar_node.network.usage }}/{{ tuskar_node.network.value }} {{ tuskar_node.network.unit }}</a>
- </td>
- {% else %}
- <td>
- <div id="network_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart">
- </div>
- </td>
- <td></td>
- {% endif %}
- </tr>
- </table>
- </div>
-</div>
-
-<div class="row-fluid detail">
- <div class="span6">
- <h4>{% trans "Summary of Instances and Usage" %}</h4>
- <hr class="header_rule">
- {% if tuskar_node.is_provisioned %}
- <div>
- <strong>{{ tuskar_node.running_instances }}</strong> instances
- <strong>{{ tuskar_node.remaining_capacity }}%</strong> capacity remaining
- </div>
- <div class="flavor_usage_bar"
- data-popup-free='{{ tuskar_node|remaining_capacity_by_flavors }}'
- data-single-bar-orientation="horizontal"
- data-single-bar-height="50"
- data-single-bar-width="100%"
- data-single-bar-used="{{ tuskar_node|all_used_instances }}"
- data-single-bar-auto-scale-selector=".flavors_scale_selector"
- data-single-bar-color-scale-range='["#000060", "#99FFFF"]'>
- </div>
-
- <table class="flavor_usages">
- <tr>
- {% for flavor in tuskar_node.list_flavors %}
- <td class="flavor_usage_label">
- <a href="{% url 'horizon:infrastructure:resource_management:resource_classes:flavors:detail' tuskar_node.rack.resource_class.id flavor.id %}">{{ flavor.name }}</a>
- </td>
- {% endfor %}
- </tr>
- <tr>
- {% for flavor in tuskar_node.list_flavors %}
- <td>
- <div class="flavor_usage_bar flavors_scale_selector"
- data-popup-average='<p>Average capacity consumed by instances of {{flavor.name}} flavor in {{tuskar_node.name}} class.</p>
- <p>{{ flavor.used_instances }}%, <strong>{{ flavor.used_instances }} instances</strong></p>'
- data-single-bar-orientation="vertical"
- data-single-bar-height="100%"
- data-single-bar-width="40"
- data-single-bar-used="{{ flavor.used_instances }}"
- data-single-bar-average-used="{{ 50 }}"
- data-single-bar-auto-scale-selector=".flavors_scale_selector"
- data-single-bar-color-scale-range='["#000060", "#99FFFF"]'>
- </div>
- </td>
- {% endfor %}
- </tr>
- <tr>
- {% for flavor in tuskar_node.list_flavors %}
- <td class="modal_chart flavor_usage_text"><a href="{{ "#" }}">{{ flavor.used_instances }}%</a></td>
- {% endfor %}
- </tr>
- <tr>
- {% for flavor in tuskar_node.list_flavors %}
- <td class="flavor_usage_text">{{ flavor.used_instances }} inst.</td>
- {% endfor %}
- </tr>
- </table>
-
- {% else %}
- <p>{% trans "No data available yet." %}</p>
- {% endif %}
- </div>
-
- <div class="span6">
- <h4>{% trans "Active alerts" %}</h4>
- <hr class="header_rule">
- {% if tuskar_node.is_provisioned %}
- <ul>
- {% for alert in tuskar_node.alerts %}
- <li><i class="icon-warning-sign"></i>{{ alert.message }}</li>
- {% endfor %}
- </ul>
- {% else %}
- <p>{% trans "No data available yet." %}</p>
- {% endif %}
- </div>
-</div>
-
-<div class="row-fluid detail">
- <div class="span6">
- <h4>{% trans "Top Communicating Nodes" %}</h4>
- <hr class="header_rule">
- {% if tuskar_node.is_provisioned %}
- <div class="communication_charts_wrapper">
- <div class="communication_chart_wrapper">
- <h5>The most contacting</h5>
- <div id="most_contacting_racks"
- class="communication_chart"
- data-chart-type="circles_chart"
- data-url="{% url 'horizon:infrastructure:resource_management:racks:top_communicating' tuskar_node.rack_id %}?cond=from"
- data-time="now"
- data-size="22">
- </div>
- </div>
- <div class="communication_chart_connection"></div>
- <div class="communication_chart_wrapper">
- <h5>The most contacted</h5>
- <div id="most_contacted_racks"
- class="communication_chart"
- data-chart-type="circles_chart"
- data-url="{% url 'horizon:infrastructure:resource_management:racks:top_communicating' tuskar_node.rack.id %}?cond=to"
- data-time="now"
- data-size="22">
- </div>
- </div>
- </div>
- {% else %}
- <p>{% trans "No data available yet." %}</p>
- {% endif %}
- </div>
-</div>
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/detail.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/detail.html
deleted file mode 100644
index 1da1dd9d..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/detail.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends 'infrastructure/base_detail.html' %}
-{% load i18n %}
-{% load url from future %}
-{% block title %}{% trans "Node Detail"%}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Node Detail") %}
-{% endblock page_header %}
-
-{% block breadcrumbs %}
- <div class="breadcrumbs">
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__resource_classes_tab" >Home</a>
- <span class="separator"></span>
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__racks_tab" >Racks</a>
- <span class="separator"></span>
- {% if tuskar_node %}
- <a href="{% url 'horizon:infrastructure:resource_management:racks:detail' tuskar_node.rack_id %}">{{ tuskar_node.rack.name }}</a>
- {% else %}
- <a href="{% url 'horizon:infrastructure:resource_management:nodes:unracked' %}" >Unracked Nodes</a>
- {% endif %}
- <span class="separator"></span>
- </div>
-{% endblock breadcrumbs %}
-
-{% block name %}{{ baremetal_node.mac_address }}{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/unracked.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/unracked.html
deleted file mode 100644
index 15c016ba..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/nodes/unracked.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% load url from future %}
-{% block title %}{% trans "Resource Management" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Resource Management") %}
-{% endblock page_header %}
-
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- <div class="breadcrumbs">
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__resource_classes_tab" >Home</a>
- <span class="separator"></span>
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__racks_tab" >Racks</a>
- <span class="separator"></span>
- </div>
-
- <h3>{% trans "Unracked Nodes" %}</h3>
- </div>
-</div>
-
-<div class="row-fluid">
- <div class="span12">
- {{ table.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/provision.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/provision.html
deleted file mode 100644
index cc251c02..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/provision.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Start Provisioning Confirmation" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Provision Deployment") %}
-{% endblock page_header %}
-
-{% block infrastructure_main %}
- {% include "infrastructure/resource_management/_provision.html" %}
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_create.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_create.html
deleted file mode 100644
index 491ad77d..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_create.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_rack_form{% endblock %}
-{% block form_action %}{% url 'horizon:infrastructure:resource_management:racks:create' %}{% endblock %}
-
-{% block modal_id %}create_rack_modal{% endblock %}
-{% block modal-header %}{% trans "Create Rack" %}{% endblock %}
-
-{% block modal-body %}
-<div>
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Rack" %}" />
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_detail_overview.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_detail_overview.html
deleted file mode 100644
index 8bfd028b..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_detail_overview.html
+++ /dev/null
@@ -1,323 +0,0 @@
-{% load i18n sizeformat %}
-{% load url from future %}
-{% load chart_helpers %}
-
-{% if not rack.is_provisioned or rack.is_provisioning %}
- <div class="info row-fluid detail">
- <div class="span12">
- <div data-state="{{rack.state}}"
- data-url="{% url 'horizon:infrastructure:resource_management:racks:check_state' rack.id %}"
- data-interval="20000"
- class="overall-state provision-block">
- {% if not rack.is_provisioned %}
- <div class="well clearfix">
- <p class="pull-right">
- {% trans "To make it ready to use," %}
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__racks_tab">
- {% trans "provision your whole deployment." %}
- </a>
- </p>
- {% trans "Rack is not provisioned yet." %}
- </div>
- {% endif %}
- </div>
- </div>
- </div>
-{% endif %}
-<div class="info row-fluid detail">
- <div class="span4">
- <h4>{% trans "About" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "IP Subnet" %}</dt>
- <dd>{{ rack.subnet|default:_("None") }}</dd>
- <dt>{% trans "Switch IPs" %}</dt>
- <dd>{{ rack.switch_ips|default:_("None") }}</dd>
- <dt>{% trans "Location" %}</dt>
- <dd>{{ rack.location|default:_("None") }}</dd>
- <dt>{% trans "State" %}</dt>
- <dd>{{ rack.state|default:_("None") }}</dd>
- </dl>
- </div>
- <div class="span4">
- <h4>{% trans "Resource Assignment" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Nodes" %}</dt>
- <dd>
- <a href="{% url 'horizon:infrastructure:resource_management:racks:detail' rack.id %}?tab=rack_detail_tabs__nodes">
- {{ rack.nodes_count|default:_("None") }}
- </a>
- </dd>
- <dt>{% trans "Class" %}</dt>
- <dd>
- {% if rack.resource_class %}
- <a href="{% url 'horizon:infrastructure:resource_management:resource_classes:detail' rack.resource_class_id %}">
- {{ rack.resource_class.name }}
- </a>
- {% else %}
- {% trans "None" %}
- {% endif %}
- </dd>
- <dt>{% trans "Class Image" %}</dt>
- <dd>overcloud-compute</dd> {# FIXME It will eventually have to be not-hardcoded later #}
- </dl>
- </div>
- <div class="span4">
- <h4>{% trans "Capacities" %}</h4>
- <hr class="header_rule">
- {% if rack.capacities %}
- <table class="capacities">
- {% for capacity in rack.capacities %}
- <tr>
- <td class="capacity_label">{{ capacity.name }}:</td>
- {% if rack.is_provisioned %}
- <td>
- <div id="{{ capacity.name }}_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart"
- data-capacity-limit="{{ capacity.value }}"
- data-capacity-used="{{ capacity.usage }}"
- data-average-capacity-used="{{ capacity.average }}">
- </div>
- </td>
- <td>
- <a href="#" data-chart-type="modal_line_chart" data-url="/infrastructure/resource_management/racks/usage_data">{{ capacity.usage|default:_(" - ") }}/{{ capacity.value|default:_(" - ") }} {{ capacity.unit }}</a>
- </td>
- {% else %}
- <td>
- <div id="{{ capacity.name }}_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart">
- </div>
- </td>
- <td></td>
- {% endif %}
- </tr>
- {% endfor %}
- </table>
- {% else %}
- <p>No data available yet.</p>
- {% endif %}
- </div>
-</div>
-
-<div class="info row-fluid detail">
- <div class="span6">
- <h4>{% trans "Summary of instances and Usage" %}</h4>
- <hr class="header_rule">
- {% if rack.is_provisioned %}
- <div>
- <strong>{{ rack.total_instances }}</strong> instances
- <strong>{{ rack.remaining_capacity }}%</strong> capacity remaining
- </div>
-
- <div class="flavor_usage_bar"
- data-popup-free='{{ rack|remaining_capacity_by_flavors }}'
- data-single-bar-orientation="horizontal"
- data-single-bar-height="35"
- data-single-bar-width="100%"
- data-single-bar-used="{{ rack|all_used_instances }}"
- data-single-bar-auto-scale-selector=".flavors_scale_selector"
- data-single-bar-color-scale-range='["#000060", "#99FFFF"]'>
- </div>
-
- <table class="flavor_usages">
- <tr>
- {% for flavor in rack.list_flavors %}
- <td class="flavor_usage_label">
- <a href="{% url 'horizon:infrastructure:resource_management:resource_classes:flavors:detail' rack.resource_class.id flavor.id %}">{{ flavor.name }}</a>
- </td>
- {% endfor %}
- </tr>
- <tr>
- {% for flavor in rack.list_flavors %}
- <td>
- <div class="flavor_usage_bar flavors_scale_selector"
- data-popup-average='<p>Average capacity consumed by instances of {{flavor.name}} flavor in {{rack.name}} class.</p>
- <p>{{ flavor.used_instances }}%, <strong>{{ flavor.used_instances }} instances</strong></p>'
- data-single-bar-orientation="vertical"
- data-single-bar-height="100%"
- data-single-bar-width="30"
- data-single-bar-used="{{ flavor.used_instances }}"
- data-single-bar-average-used="{{ 50 }}"
- data-single-bar-auto-scale-selector=".flavors_scale_selector"
- data-single-bar-color-scale-range='["#000060", "#99FFFF"]'>
- </div>
- </td>
- {% endfor %}
- </tr>
- <tr>
- {% for flavor in rack.list_flavors %}
- <td class="modal_chart flavor_usage_text"><a href="{{ "#" }}">{{ flavor.used_instances }}%</a></td>
- {% endfor %}
- </tr>
- <tr>
- {% for flavor in rack.list_flavors %}
- <td class="flavor_usage_text">{{ flavor.used_instances }} inst.</td>
- {% endfor %}
- </tr>
- </table>
- {% else %}
- <p>{% trans "No data available yet." %}</p>
- {% endif %}
- </div>
-
- <div class="span6 alerts">
- <h4>{% trans "Active Alerts" %}</h4>
- <hr class="header_rule">
- {% if rack.is_provisioned %}
- <ul>
- {% for alert in rack.alerts %}
- <li><i class="icon-warning-sign"></i>{{ alert.message }}</li>
- {% endfor %}
- {% for tuskar_node in rack.aggregated_alerts %}
- <li>
- <i class="icon-warning-sign"></i>
- Node <a href="{% url 'horizon:infrastructure:resource_management:nodes:detail' tuskar_node.nova_baremetal_node_id %}">{{ tuskar_node.name }}</a> has some problems
- </li>
- {% endfor %}
- </ul>
- {% else %}
- <p>{% trans "No data available yet." %}</p>
- {% endif %}
- </div>
-</div>
-
-<div class="row-fluid">
- <div class="span6">
- <!-- FIXME Will be added later
- <div class="circles_chart_time_picker">
- <select data-circles-chart-command="change_time"
- data-receiver="#most_contacting_racks, #most_contacted_racks">
- <option value="now">Now</option>
- <option value="yesterday">Yesterday</option>
- <option value="last_week">Last Week</option>
- <option value="last_month">Last Month</option>
- </select>
- </div>
- -->
-
- <h4>Top Communicating Racks</h4>
- <hr class="header_rule">
- <div class="clear"></div>
- {% if rack.nodes_count and rack.is_provisioned %}
- <div class="communication_charts_wrapper">
- <div class="communication_chart_wrapper">
- <h5>The most contacting</h5>
- <div id="most_contacting_racks"
- class="communication_chart"
- data-chart-type="circles_chart"
- data-url="{% url 'horizon:infrastructure:resource_management:racks:top_communicating' rack.id %}?cond=from"
- data-time="now"
- data-size="22">
- </div>
- </div>
- <div class="communication_chart_connection"></div>
- <div class="communication_chart_wrapper">
- <h5>The most contacted</h5>
- <div id="most_contacted_racks"
- class="communication_chart"
- data-chart-type="circles_chart"
- data-url="{% url 'horizon:infrastructure:resource_management:racks:top_communicating' rack.id %}?cond=to"
- data-time="now"
- data-size="22">
- </div>
- </div>
- </div>
- {% else %}
- <p>No data available yet.</p>
- {% endif %}
- </div>
- <div class="span6">
- <!-- FIXME Will be added later
- <div class="circles_chart_time_picker">
- <select data-circles-chart-command="change_time"
- data-receiver="#rack_health_chart">
- <option value="now">Now</option>
- <option value="yesterday">Yesterday</option>
- <option value="last_week">Last Week</option>
- <option value="last_month">Last Month</option>
- </select>
- </div>
- -->
-
- <h4>Node health</h4>
- {% if rack.nodes_count and rack.is_provisioned %}
-
- <ul class="nav nav-tabs"
- data-circles-chart-command="change_url"
- data-receiver="#rack_health_chart">
- <li class="active">
- <a data-url="{% url 'horizon:infrastructure:resource_management:racks:node_health' rack.id %}?type=overall_health" href="#">
- Overall Health</a>
- </li>
- <li>
- <a data-url="{% url 'horizon:infrastructure:resource_management:racks:node_health' rack.id %}?type=alerts" href="#">
- Alerts</a>
- </li>
- <li>
- <a data-url="{% url 'horizon:infrastructure:resource_management:racks:node_health' rack.id %}?type=capacities" href="#">
- Capacities</a>
- </li>
- <li>
- <a data-url="{% url 'horizon:infrastructure:resource_management:racks:node_health' rack.id %}?type=status" href="#">
- Status</a>
- </li>
- </ul>
- <div id ="rack_health_chart"
- class="health_chart"
- data-chart-type="circles_chart"
- data-url="{% url 'horizon:infrastructure:resource_management:racks:node_health' rack.id %}"
- data-time="now"
- data-size="22">
- </div>
- {% else %}
- <hr class="header_rule">
- <div class="clear"></div>
-
- <p>No data available yet.</p>
- {% endif %}
- </div>
-</div>
-
-
-<script type="text/javascript">
-/* polling of status. */
-horizon.detail_overview = {
- update: function () {
- var state_obj = $('.overall-state').first();
- var state = state_obj.data('state');
- var interval = state_obj.data('interval');
- var url = state_obj.data('url');
- if (state == 'provisioning') {
- // Wait and try to update again in next interval instead
- setTimeout(horizon.detail_overview.update, interval);
-
- this.jqxhr = $.getJSON( url, function() {
- state_obj.html('{% filter escapejs %}{% include "infrastructure/resource_management/_provision_progress.html" %}{% endfilter %}');
- })
- .done(function(data) {
- // FIXME find a way how to only update graph with new data
- // not delete and create
- if (data['state'] != 'provisioning'){
- window.location.reload();
- }
- })
- .fail(function() {
- // FIXME add proper fail message
- console.log( "error" );
- })
- .always(function() {
- // FIXME add behaviour that should be always done
- });
- }
- }
-};
-
-
-horizon.addInitFunction(function () {
- horizon.detail_overview.update();
-});
-
-</script>
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_edit.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_edit.html
deleted file mode 100644
index 87ccb864..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_edit.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}edit_rack_form{% endblock %}
-{% block form_action %}{% url 'horizon:infrastructure:resource_management:racks:edit' rack_id %}{% endblock %}
-
-{% block modal_id %}edit_rack_modal{% endblock %}
-{% block modal-header %}{% trans "Edit Rack" %}{% endblock %}
-
-{% block modal-body %}
-<div>
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save" %}" />
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_edit_status.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_edit_status.html
deleted file mode 100644
index f2a81170..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_edit_status.html
+++ /dev/null
@@ -1,23 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}edit_rack_status_form{% endblock %}
-{% block form_action %}{% url 'horizon:infrastructure:resource_management:racks:edit_status' rack_id %}?action={{ action }}{% endblock %}
-
-{% block modal_id %}edit_rack_status_modal{% endblock %}
-{% block modal-header %}{% trans "Rack Action Confirmation" %}{% endblock %}
-
-{% block modal-body %}
-<div>
- {% trans "Are you sure?" %}
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary" type="submit" value="{% trans "Yes" %}" />
- <a href="{% url 'horizon:infrastructure:resource_management:racks:detail' rack_id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_index_table.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_index_table.html
deleted file mode 100644
index 66f5116c..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_index_table.html
+++ /dev/null
@@ -1,4 +0,0 @@
-{% load i18n %}
-{% include "infrastructure/resource_management/_provision_info.html" with provisioning_state=provisioning_state %}
-{{ racks_table.render }}
-<a href="{% url 'horizon:infrastructure:resource_management:nodes:unracked' %}">{% trans "View Unracked Nodes"%} ({{baremetal_nodes|length}})</a>
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_rack_nodes_step.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_rack_nodes_step.html
deleted file mode 100644
index 3e0cbf1b..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_rack_nodes_step.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<noscript><h3>{{ step }}</h3></noscript>
-<table class="table-fixed">
- <tbody>
- <tr>
- <td class="actions">
- {% include "horizon/common/_form_fields.html" %}
- </td>
- <td class="help_text">
- {{ step.get_help_text }}
- </td>
- </tr>
- </tbody>
-</table>
-
-<div id="nodes-formset-datatable">
- {{ nodes_table.render }}
-</div>
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_upload.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_upload.html
deleted file mode 100644
index 44097d3d..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/_upload.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}upload_rack_form{% endblock %}
-{% block form_action %}{% url 'horizon:infrastructure:resource_management:racks:upload' %}{% endblock %}
-{% block form_attrs %}enctype="multipart/form-data"{% endblock %}
-
-{% block modal_id %}upload_rack_modal{% endblock %}
-{% block modal-header %}{% trans "Upload Rack" %}{% endblock %}
-
-{% block modal-body %}
- <div>
- <fieldset>
- <span class="control-group clearfix error">
- {% if form.csv_file.errors %}
- <div class="error help-inline">{{ form.csv_file.errors }}</div>
- {% endif %}
- </span>
- {{ form.csv_file }}
- <input class="btn btn-primary pull-right always-enabled" type="submit" name=upload value="{% trans "Upload File" %}" />
- <div class="help-block">
- CSV file format:<br>rack name,resource class name,subnet,region,list of mac addresses separated by space
- </div>
- {{ form.uploaded_data }}
- </fieldset>
- </div>
- <div class="csv_rack_table">
- {% trans "Uploaded racks, which you are going to add to the system:" %}
- {{ racks_table.render }}
- </div>
-{% endblock %}
-
-{% block modal-footer %}
-<input class="btn btn-primary pull-right always-enabled" type="submit" name=add_racks value="{% trans "Add Racks" %}" {% if not form.uploaded_data.value %}disabled{% endif %}/>
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/create.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/create.html
deleted file mode 100644
index 9ad42b2d..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Rack" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create Rack") %}
-{% endblock page_header %}
-
-{% block infrastructure_main %}
- {% include "infrastructure/resource_management/racks/_create.html" %}
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/detail.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/detail.html
deleted file mode 100644
index 8ac1cfa4..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/detail.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{% extends 'infrastructure/base_detail.html' %}
-{% load i18n %}
-{% load url from future %}
-{% block title %}{% trans "Rack Detail"%}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Rack Detail") %}
-{% endblock page_header %}
-
-{% block breadcrumbs %}
- <div class="breadcrumbs">
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__resource_classes_tab" >Home</a>
- <span class="separator"></span>
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__racks_tab" >Racks</a>
- <span class="separator"></span>
- </div>
-{% endblock breadcrumbs %}
-
-{% block name %}{{ rack.name }}{% endblock %}
-
-{% block actions %}
- <div class="btn-group">
- {% if rack.is_provisioned %}
- <a class="btn ajax-modal" href="{% url 'horizon:infrastructure:resource_management:racks:edit_status' rack.id %}?action=unprovision">{% trans "Unprovision Rack" %}</a>
- {% endif %}
- </div>
- {# <div class="btn-group"> #}
- {# <a class="btn ajax-modal" href="{% url 'horizon:infrastructure:resource_management:racks:edit_status' rack.id %}?action=start">{% trans "Start" %}</a> #}
- {# <a class="btn ajax-modal" href="{% url 'horizon:infrastructure:resource_management:racks:edit_status' rack.id %}?action=reboot">{% trans "Reboot" %}</a> #}
- {# <a class="btn ajax-modal" href="{% url 'horizon:infrastructure:resource_management:racks:edit_status' rack.id %}?action=shutdown">{% trans "Shutdown" %}</a> #}
- {# </div> #}
- <div class="btn-group">
- <a class="btn ajax-modal" href="{% url 'horizon:infrastructure:resource_management:racks:detail_edit' rack.id %}">{% trans "Edit" %}</a>
- </div>
-{% endblock %}
-
-{% block overall_usage %}
- <table class="capacities overall_usage">
- <tr>
- <td class="capacity_label">{% trans "Usage" %}:</td>
- <td>
- {% if rack.is_provisioned %}
- <div id="rack_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart"
- data-capacity-limit="{{ rack.vm_capacity.value }}"
- data-capacity-used="{{ rack.vm_capacity.usage }}"
- data-average-capacity-used="{{ rack.vm_capacity.average }}">
- </div>
- {% else %}
- <div id="rack_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart">
- </div>
- {% endif %}
- </td>
- </tr>
- </table>
-{% endblock %}
-
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/edit.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/edit.html
deleted file mode 100644
index 76a8e439..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/edit.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Edit Rack" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Edit Rack") %}
-{% endblock page_header %}
-
-{% block infrastructure_main %}
- {% include "infrastructure/resource_management/racks/_edit.html" %}
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/edit_status.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/edit_status.html
deleted file mode 100644
index 99789380..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/edit_status.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Rack Action Confirmation" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Edit Rack Status") %}
-{% endblock page_header %}
-
-{% block infrastructure_main %}
- {% include "infrastructure/resource_management/racks/_edit_status.html" %}
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/upload.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/upload.html
deleted file mode 100644
index 1df9454d..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/racks/upload.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Upload Rack" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Upload Rack") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "infrastructure/resource_management/racks/_upload.html" %}
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_action.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_action.html
deleted file mode 100644
index 5f7108ea..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_action.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-{% block form_id %}resource_class_action_form{% endblock %}
-{% block form_action %}
- {% url 'horizon:infrastructure:resource_management:resource_classes:detail_action' resource_class_id %}?action={{ action }}
-{% endblock %}
-{% block modal_id %}resource_class_action_modal{% endblock %}
-{% block modal-header %}{{header}}{% endblock %}
-{% block modal-body %}
-<div>
- {% trans "Are you sure?" %}
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-{% endblock %}
-{% block modal-footer %}
- <input class="btn btn-primary" type="submit" value="{% trans "Yes" %}" />
- <a href="{% url 'horizon:infrastructure:resource_management:resource_classes:detail' resource_class_id %}"
- class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_flavors.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_flavors.html
deleted file mode 100644
index 34226ea9..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_flavors.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ flavors_table_table.render }}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_overview.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_overview.html
deleted file mode 100644
index 6eec6751..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_overview.html
+++ /dev/null
@@ -1,239 +0,0 @@
-{% load i18n sizeformat %}
-{% load url from future %}
-{% load chart_helpers %}
-
-<div class="status row-fluid detail">
- <div class="span4">
- <h4>{% trans "About" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Racks" %}</dt>
- <dd><a href="?tab=resource_class_details__racks" >{{ resource_class.list_racks|length }} {% trans "racks" %}</a></dd>
- <dt>{% trans "Nodes" %}</dt>
- <dd>{{ resource_class.tuskar_nodes|length }} {% trans "nodes" %}</dd>
- </dl>
- </div>
-
- <div class="span4">
- <h4>{% trans "Provided Service" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Type" %}</dt>
- <dd>{{ resource_class.service_type }}</dd>
- <dt>{% trans "Flavors" %}</dt>
- <dd><a href="?tab=resource_class_details__flavors" >{{ resource_class.list_flavors|length }} {% trans "flavors" %}</a></dd>
- <dd></dd>
- <dt>{% trans "Active Instances" %}</dt>
- <dd>{{ resource_class.running_virtual_machines|length }} {% trans "instances" %}</dd>
- </dl>
- </dl>
- </div>
-
- <div class="span4">
- <h4>{% trans "Capacities" %}</h4>
- <hr class="header_rule">
- {% if resource_class.capacities %}
- <table class="capacities">
- {% for capacity in resource_class.capacities %}
- <tr>
- {% if resource_class.has_provisioned_rack %}
- <td class="capacity_label">{{ capacity.name }}:</td>
- <td>
- <div id="{{ capacity.name }}_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart"
- data-capacity-limit="{{ capacity.value }}"
- data-capacity-used="{{ capacity.usage }}"
- data-average-capacity-used="{{ capacity.average }}">
- </div>
- </td>
- <td>
- <a href="#" data-chart-type="modal_line_chart" data-url="/infrastructure/resource_management/racks/usage_data" data-series="{{ capacity.name }}">{{ capacity.usage|default:_(" - ") }}/{{ capacity.value|default:_(" - ") }} {{ capacity.unit }}</a>
- </td>
- {% else %}
- <td>
- <div id="{{ capacity.name }}_capacity_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart">
- </div>
- </td>
- <td></td>
- {% endif %}
- </tr>
- {% endfor %}
- </table>
- {% else %}
- <p>No data available yet.</p>
- {% endif %}
- </div>
-</div>
-
-<div class="status row-fluid detail">
- <div class="span6">
- <h4>{% trans "Capacity Usage" %}</h4>
- <hr class="header_rule">
- {% if resource_class.has_provisioned_rack %}
- <div data-chart-type="line_chart" data-url="/infrastructure/resource_management/racks/usage_data" data-series="cpu,ram,storage,network"></div>
- {% else %}
- <p>{% trans "No data available yet." %}</p>
- {% endif %}
- </div>
-
- <div class="span6 alerts">
- <h4>{% trans "Active Alerts" %}</h4>
- <hr class="header_rule">
- {% if resource_class.has_provisioned_rack %}
- <ul>
- {% for rack in resource_class.aggregated_alerts %}
- <li>
- <i class="icon-warning-sign"></i>
- Rack <a href="{% url 'horizon:infrastructure:resource_management:racks:detail' rack.id %}">{{ rack.name }}</a> has some problems
- </li>
- {% endfor %}
- </ul>
- {% else %}
- <p>{% trans "No data available yet." %}</p>
- {% endif %}
- </div>
-</div>
-
-<div class="row-fluid detail">
- <div class="span6">
- <h4>{% trans "Summary of Instances and Usage" %}</h4>
- <hr class="header_rule">
- {% if resource_class.has_provisioned_rack %}
- <!--
- <dl>
- {% for flavor in resource_class.running_virtual_machines %}
- <dt>{{ flavor.name }}</dt>
- <dd>{{ flavor.max_vms|default:_(" - ") }}</dd>
- {% endfor %}
- </dl>
- -->
-
- <div class="clear"></div>
- <div>
- <strong>{{ resource_class.total_instances }}</strong> instances
- <strong>{{resource_class.remaining_capacity}}%</strong> capacity remaining
- </div>
- <div class="flavor_usage_bar"
- data-popup-free='{{resource_class|remaining_capacity_by_flavors}}'
- data-single-bar-orientation="horizontal"
- data-single-bar-height="35"
- data-single-bar-width="100%"
- data-single-bar-used="{{ resource_class|all_used_instances }}"
- data-single-bar-auto-scale-selector=".flavors_scale_selector"
- data-single-bar-color-scale-range='["#000060", "#99FFFF"]'
- >
- </div>
-
- <table class="flavor_usages">
- <tr>
- {% for flavor in resource_class.list_flavors %}
- <td class="flavor_usage_label">
- {{ flavor.name }}
- </td>
- {% endfor %}
- </tr>
- <tr>
- {% for flavor in resource_class.list_flavors %}
- <td>
- <div
- class="flavor_usage_bar flavors_scale_selector"
- data-popup-average='
- <p>Average capacity consumed by instances of {{flavor.name}} flavor in {{resource_class.name}} class.</p>
- <p>{{ flavor.used_instances }}%, <strong>{{ flavor.used_instances }} instances</strong></p>
- '
- data-single-bar-orientation="vertical"
- data-single-bar-height="100%"
- data-single-bar-width="30"
- data-single-bar-used="{{ flavor.used_instances }}"
- data-single-bar-average-used="{{ 50 }}"
- data-single-bar-auto-scale-selector=".flavors_scale_selector"
- data-single-bar-color-scale-range='["#000060", "#99FFFF"]'
- >
- </div>
- </td>
- {% endfor %}
- </tr>
- <tr>
- {% for flavor in resource_class.list_flavors %}
- <td class="modal_chart flavor_usage_text"><a href="{{ "#" }}">{{ flavor.used_instances }}%</a></td>
- {% endfor %}
- </tr>
- <tr>
- {% for flavor in resource_class.list_flavors %}
- <td class="flavor_usage_text">{{ flavor.used_instances }} inst.</td>
- {% endfor %}
- </tr>
- </table>
- {% else %}
- <p>{% trans "No data available yet." %}</p>
- {% endif %}
- </div>
-
- <div class="span6">
- <!-- FIXME Will be added later
- <div class="circles_chart_time_picker">
- <select data-circles-chart-command="change_time"
- data-receiver=".rack_health_chart">
- <option value="now">Now</option>
- <option value="yesterday">Yesterday</option>
- <option value="last_week">Last Week</option>
- <option value="last_month">Last Month</option>
- </select>
- </div>
- -->
-
- <h4>Rack health</h4>
-
- {% if resource_class.has_provisioned_rack %}
- <ul class="nav nav-tabs"
- data-circles-chart-command="change_url"
- data-receiver=".rack_health_chart">
- <li class="active">
- <a data-url="{% url 'horizon:infrastructure:resource_management:resource_classes:rack_health' resource_class.id %}?type=overall_health" href="#">
- Overall Health</a>
- </li>
- <li>
- <a data-url="{% url 'horizon:infrastructure:resource_management:resource_classes:rack_health' resource_class.id %}?type=alerts" href="#">
- Alerts</a>
- </li>
- <li>
- <a data-url="{% url 'horizon:infrastructure:resource_management:resource_classes:rack_health' resource_class.id %}?type=capacities" href="#">
- Capacities</a>
- </li>
- <li>
- <a data-url="{% url 'horizon:infrastructure:resource_management:resource_classes:rack_health' resource_class.id %}?type=status" href="#">
- Status</a>
- </li>
- </ul>
- <!--<h5>Region 1<h5>
- <div class="rack_health_chart"
- data-chart-type="circles_chart"
- data-url="/infrastructure/racks/1/top_communicating.json?region=1"
- data-region=1 //// implement region parameter
- data-time="now"
- data-size="10">
- </div>
- <h5>Region 2<h5>
- <div class="rack_health_chart"
- data-chart-type="circles_chart"
- data-url="/infrastructure/racks/1/top_communicating.json?region=2"
- data-region=1 //// implement region parameter
- data-time="now"
- data-size="10">
- </div>
- <h5>Region 3<h5>-->
- <div class="rack_health_chart"
- data-chart-type="circles_chart"
- data-url="{% url 'horizon:infrastructure:resource_management:resource_classes:rack_health' resource_class.id %}"
- data-time="now"
- data-size="22">
- </div>
- {% else %}
- <hr class="header_rule">
- <p>{% trans "No data available yet." %}</p>
- {% endif %}
- </div>
-</div>
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_racks.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_racks.html
deleted file mode 100644
index b5d73097..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_detail_racks.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ racks_table_table.render }}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_flavors_step.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_flavors_step.html
deleted file mode 100644
index a75c6d9f..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_flavors_step.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "infrastructure/resource_management/resource_classes/_table_step.html" %}
-{% block table_step %}
- <div id="flavors-table-block">
- {{ block.super }}
- </div>
- <script>
- (window.$ || window.addHorizonLoadEvent)(function () {
- 'use strict';
-
- var $select = $('select#id_service_type'),
- $table_block = $('#flavors-table-block'),
- $tab = $(
- 'a[data-target="#create_resource_class__' +
- 'resourceclassflavorsaction"], ' +
- 'a[data-target="#update_resource_class__' +
- 'resourceclassflavorsaction"]'
- ).parent('li');
-
- $select.change(function () {
- if ($select.val() === 'compute') {
- $table_block.show();
- $tab.show(300);
- } else {
- $table_block.hide();
- $tab.hide(300);
- };
- });
-
- if ($select.val() !== 'compute') {
- $table_block.hide();
- $tab.hide();
- };
- });
- </script>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_index_table.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_index_table.html
deleted file mode 100644
index e60ecb26..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_index_table.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{% load i18n %}
-{% include "infrastructure/resource_management/_provision_info.html" with provisioning_state=provisioning_state %}
-{{ table.render }}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_table_step.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_table_step.html
deleted file mode 100644
index 55bfb116..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/_table_step.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% block table_step %}
-<noscript><h3>{{ step }}</h3></noscript>
-
-{{ table.render }}
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/action.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/action.html
deleted file mode 100644
index c2b03cf1..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/action.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Resource Class Action Confirmation" %}{% endblock %}
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Resource Class Action") %}
-{% endblock page_header %}
-{% block infrastructure_main %}
- {% include "infrastructure/resource_management/resource_classes/_edit_status.html" %}
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/detail.html b/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/detail.html
deleted file mode 100644
index 4a1047d1..00000000
--- a/tuskar_ui/infrastructure/resource_management/templates/resource_management/resource_classes/detail.html
+++ /dev/null
@@ -1,63 +0,0 @@
-{% extends 'infrastructure/base_detail.html' %}
-{% load i18n sizeformat %}
-{% load url from future %}
-{% block title %}{% trans "Resource Class Detail" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title="Resource Class Detail" %}
-{% endblock page_header %}
-
-{% block breadcrumbs %}
- <div class="breadcrumbs">
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__resource_classes_tab" >Home</a>
- <span class="separator"></span>
- <a href="{% url 'horizon:infrastructure:resource_management:index' %}?tab=resource_management_tabs__resource_classes_tab" >Classes</a>
- <span class="separator"></span>
- </div>
-{% endblock breadcrumbs %}
-
-{% block name %}{{ resource_class.name }}{% endblock %}
-
-{% block actions %}
- <div class="btn-group">
- <a class="btn ajax-modal"
- href="{% url 'horizon:infrastructure:resource_management:resource_classes:detail_update' resource_class.id %}">
- {% trans "Edit" %}
- </a>
- <a {% if resource_class.deletable %}
- class="btn ajax-modal"
- href="{% url 'horizon:infrastructure:resource_management:resource_classes:detail_action' resource_class.id %}?action=delete"
- {% else %}
- title="{% trans "Resource Class contains racks and can't be deleted." %}"
- class="btn disabled"
- href="#"
- {% endif %}
- >
- {% trans "Delete" %}
- </a>
- </div>
-{% endblock %}
-
-
-{% block overall_usage %}
- <table class="capacities overall_usage">
- <tr>
- <td class="capacity_label">{% trans "Usage" %}:</td>
- <td>
- {% if resource_class.has_provisioned_rack %}
- <div id="resource_class_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart"
- data-capacity-limit="{{ resource_class.vm_capacity.value }}"
- data-capacity-used="{{ resource_class.vm_capacity.usage }}">
- </div>
- {% else %}
- <div id="resource_class_usage"
- class="capacity_bar"
- data-chart-type="capacity_bar_chart">
- </div>
- {% endif %}
- </td>
- </tr>
- </table>
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/resource_management/tests.py b/tuskar_ui/infrastructure/resource_management/tests.py
deleted file mode 100644
index ef876124..00000000
--- a/tuskar_ui/infrastructure/resource_management/tests.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django import http
-
-import mox
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.test import helpers as test
-
-
-class ResourceManagementTests(test.BaseAdminViewTests):
- index_page = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
-
- def setUp(self):
- super(ResourceManagementTests, self).setUp()
-
- @test.create_stubs({
- tuskar.ResourceClass: ('get', 'list', 'list_racks', 'tuskar_nodes'),
- tuskar.TuskarNode: ('list',),
- tuskar.Rack: ('list',),
- })
- def test_index(self):
-
- # ResourceClass stubs
- resource_classes = self.tuskar_resource_classes.list()
- resource_class = self.tuskar_resource_classes.first()
- tuskar_nodes = []
- racks = []
-
- tuskar.ResourceClass.tuskar_nodes = tuskar_nodes
- tuskar.ResourceClass.list_racks = racks
-
- tuskar.Rack.list(mox.IsA(http.HttpRequest)).AndReturn(racks)
- tuskar.ResourceClass.list(
- mox.IsA(http.HttpRequest)).AndReturn(resource_classes)
-
- tuskar.ResourceClass.get(
- mox.IsA(http.HttpRequest),
- resource_class.id).AndReturn(resource_class)
- # ResourceClass stubs end
-
- # Rack stubs
- racks = self.tuskar_racks.list()
-
- tuskar.Rack.list(mox.IsA(http.HttpRequest)).AndReturn(racks)
- tuskar.Rack.list(mox.IsA(http.HttpRequest)).AndReturn(racks)
- tuskar.TuskarNode.list(
- mox.IsA(http.HttpRequest)).AndReturn(tuskar_nodes)
- # Rack stubs end
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- res = self.client.get(url)
- self.assertTemplateUsed(
- res, 'infrastructure/resource_management/index.html')
-
- # ResourceClass asserts
- self.assertItemsEqual(res.context['resource_classes_table'].data,
- resource_classes)
- # ResourceClass asserts end
-
- # Rack asserts
- self.assertItemsEqual(res.context['racks_table'].data, racks)
- # Rack asserts end
-
- @test.create_stubs({tuskar.Rack: ('provision_all',)})
- def test_provision_post(self):
- tuskar.Rack.provision_all(mox.IsA(http.HttpRequest))
-
- self.mox.ReplayAll()
-
- url = urlresolvers.reverse('horizon:infrastructure:'
- 'resource_management:provision',
- args=[])
- response = self.client.post(url)
-
- self.assertNoFormErrors(response)
- self.assertMessageCount(success=1)
- self.assertRedirectsNoFollow(response, self.index_page)
diff --git a/tuskar_ui/infrastructure/resource_management/urls.py b/tuskar_ui/infrastructure/resource_management/urls.py
deleted file mode 100644
index 9a5c7621..00000000
--- a/tuskar_ui/infrastructure/resource_management/urls.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django import conf
-from django.conf.urls import defaults
-
-from tuskar_ui.infrastructure.resource_management.nodes\
- import urls as node_urls
-from tuskar_ui.infrastructure.resource_management.racks\
- import urls as rack_urls
-from tuskar_ui.infrastructure.resource_management.resource_classes\
- import urls as resource_classes_urls
-from tuskar_ui.infrastructure.resource_management import views
-from tuskar_ui.test import urls as test_urls
-
-
-urlpatterns = defaults.patterns(
- '',
- defaults.url(r'^$', views.IndexView.as_view(), name='index'),
- defaults.url(r'^provision$', views.ProvisionView.as_view(),
- name='provision'),
- defaults.url(r'^provisioning_state.json$', views.provisioning_state,
- name='provisioning_state'),
- defaults.url(r'^racks/', defaults.include(rack_urls, namespace='racks')),
- defaults.url(r'^resource_classes/',
- defaults.include(resource_classes_urls,
- namespace='resource_classes')),
- defaults.url(r'^nodes/', defaults.include(node_urls, namespace='nodes')),
-)
-
-if conf.settings.DEBUG:
- urlpatterns += defaults.patterns(
- '', defaults.url(r'^qunit$',
- defaults.include(test_urls, namespace='tests')))
diff --git a/tuskar_ui/infrastructure/resource_management/views.py b/tuskar_ui/infrastructure/resource_management/views.py
deleted file mode 100644
index acc5a141..00000000
--- a/tuskar_ui/infrastructure/resource_management/views.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for Resource Management.
-"""
-
-from django.core import urlresolvers
-from django import http
-from django.utils import simplejson
-
-from horizon import forms as horizon_forms
-from horizon import tabs as horizon_tabs
-
-from tuskar_ui import api as tuskar
-from tuskar_ui.infrastructure.resource_management import forms
-from tuskar_ui.infrastructure.resource_management import tabs
-
-
-class IndexView(horizon_tabs.TabbedTableView):
- tab_group_class = tabs.ResourceManagementTabs
- template_name = 'infrastructure/resource_management/index.html'
-
-
-class ProvisionView(tabs.ProvisioningInfoMixin, horizon_forms.ModalFormView):
- form_class = forms.Provision
- template_name = 'infrastructure/resource_management/provision.html'
-
- def get_success_url(self):
- # Redirect to previous URL
- default_url = urlresolvers.reverse(
- 'horizon:infrastructure:resource_management:index')
- return self.request.META.get('HTTP_REFERER', default_url)
-
-
-def provisioning_state(request, rack_id=None):
- racks = tuskar.Rack.list(request)
- (unprovisioned_racks, provisioning_racks,
- state) = tabs.get_provision_racks_and_state(racks)
- return http.HttpResponse(simplejson.dumps({'state': state}),
- mimetype="application/json")
diff --git a/tuskar_ui/infrastructure/resources_archived/__init__.py b/tuskar_ui/infrastructure/resources_archived/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_archived/__init__.py
diff --git a/tuskar_ui/infrastructure/resources_archived/panel.py b/tuskar_ui/infrastructure/resources_archived/panel.py
new file mode 100644
index 00000000..1b0477f9
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_archived/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class ResourcesArchived(horizon.Panel):
+ name = _("Archived")
+ slug = "resources_archived"
+
+
+dashboard.Infrastructure.register(ResourcesArchived)
diff --git a/tuskar_ui/infrastructure/resources_archived/urls.py b/tuskar_ui/infrastructure/resources_archived/urls.py
new file mode 100644
index 00000000..d4258572
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_archived/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import defaults
+
+from tuskar_ui.infrastructure.resources_archived import views
+
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/resources_archived/views.py b/tuskar_ui/infrastructure/resources_archived/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_archived/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/resources_management/__init__.py b/tuskar_ui/infrastructure/resources_management/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_management/__init__.py
diff --git a/tuskar_ui/infrastructure/resources_management/panel.py b/tuskar_ui/infrastructure/resources_management/panel.py
new file mode 100644
index 00000000..d69a6c99
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_management/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class ResourcesManagement(horizon.Panel):
+ name = _("Management Nodes")
+ slug = "resources_management"
+
+
+dashboard.Infrastructure.register(ResourcesManagement)
diff --git a/tuskar_ui/infrastructure/resources_management/urls.py b/tuskar_ui/infrastructure/resources_management/urls.py
new file mode 100644
index 00000000..5ecf4c3a
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_management/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import defaults
+
+from tuskar_ui.infrastructure.resources_management import views
+
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/resources_management/views.py b/tuskar_ui/infrastructure/resources_management/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_management/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/resources_overview/__init__.py b/tuskar_ui/infrastructure/resources_overview/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_overview/__init__.py
diff --git a/tuskar_ui/infrastructure/resources_overview/panel.py b/tuskar_ui/infrastructure/resources_overview/panel.py
new file mode 100644
index 00000000..746a81b8
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_overview/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class ResourcesOverview(horizon.Panel):
+ name = _("Overview")
+ slug = "resources_overview"
+
+
+dashboard.Infrastructure.register(ResourcesOverview)
diff --git a/tuskar_ui/infrastructure/resources_overview/urls.py b/tuskar_ui/infrastructure/resources_overview/urls.py
new file mode 100644
index 00000000..5638adfc
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_overview/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import defaults
+
+from tuskar_ui.infrastructure.resources_overview import views
+
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/resources_overview/views.py b/tuskar_ui/infrastructure/resources_overview/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_overview/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/resources_resource/__init__.py b/tuskar_ui/infrastructure/resources_resource/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_resource/__init__.py
diff --git a/tuskar_ui/infrastructure/service_management/panel.py b/tuskar_ui/infrastructure/resources_resource/panel.py
index f6d31b49..54286120 100644
--- a/tuskar_ui/infrastructure/service_management/panel.py
+++ b/tuskar_ui/infrastructure/resources_resource/panel.py
@@ -16,12 +16,12 @@ from django.utils.translation import ugettext_lazy as _ # noqa
import horizon
-#from tuskar_ui.infrastructure import dashboard
+from tuskar_ui.infrastructure import dashboard
-class Service_Management(horizon.Panel):
- name = _("Service Management")
- slug = "service_management"
+class ResourcesResource(horizon.Panel):
+ name = _("Resource Nodes")
+ slug = "resources_resource"
-#dashboard.Infrastructure.register(Service_Management)
+dashboard.Infrastructure.register(ResourcesResource)
diff --git a/tuskar_ui/infrastructure/resources_resource/urls.py b/tuskar_ui/infrastructure/resources_resource/urls.py
new file mode 100644
index 00000000..b06e8c69
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_resource/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import defaults
+
+from tuskar_ui.infrastructure.resources_resource import views
+
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/resources_resource/views.py b/tuskar_ui/infrastructure/resources_resource/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_resource/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/resources_unallocated/__init__.py b/tuskar_ui/infrastructure/resources_unallocated/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_unallocated/__init__.py
diff --git a/tuskar_ui/infrastructure/resources_unallocated/panel.py b/tuskar_ui/infrastructure/resources_unallocated/panel.py
new file mode 100644
index 00000000..b78b679d
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_unallocated/panel.py
@@ -0,0 +1,27 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _ # noqa
+
+import horizon
+
+from tuskar_ui.infrastructure import dashboard
+
+
+class ResourcesUnallocated(horizon.Panel):
+ name = _("Unallocated")
+ slug = "resources_unallocated"
+
+
+dashboard.Infrastructure.register(ResourcesUnallocated)
diff --git a/tuskar_ui/infrastructure/resources_unallocated/urls.py b/tuskar_ui/infrastructure/resources_unallocated/urls.py
new file mode 100644
index 00000000..b96f8861
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_unallocated/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import defaults
+
+from tuskar_ui.infrastructure.resources_unallocated import views
+
+
+urlpatterns = defaults.patterns(
+ '',
+ defaults.url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/tuskar_ui/infrastructure/resources_unallocated/views.py b/tuskar_ui/infrastructure/resources_unallocated/views.py
new file mode 100644
index 00000000..f046b626
--- /dev/null
+++ b/tuskar_ui/infrastructure/resources_unallocated/views.py
@@ -0,0 +1,18 @@
+# -*- coding: utf8 -*-
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+from django.views import generic
+
+
+class IndexView(generic.TemplateView):
+ template_name = 'infrastructure/base.html'
diff --git a/tuskar_ui/infrastructure/service_management/templates/service_management/index.html b/tuskar_ui/infrastructure/service_management/templates/service_management/index.html
deleted file mode 100644
index 7de2a028..00000000
--- a/tuskar_ui/infrastructure/service_management/templates/service_management/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Service Management" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Service Management") %}
-{% endblock page_header %}
-
-{% block infrastructure_main %}
-{% endblock %}
-
-