summaryrefslogtreecommitdiff
path: root/tuskar_ui/infrastructure/roles
diff options
context:
space:
mode:
Diffstat (limited to 'tuskar_ui/infrastructure/roles')
-rw-r--r--tuskar_ui/infrastructure/roles/__init__.py0
-rw-r--r--tuskar_ui/infrastructure/roles/panel.py26
-rw-r--r--tuskar_ui/infrastructure/roles/tables.py66
-rw-r--r--tuskar_ui/infrastructure/roles/templates/roles/config.html24
-rw-r--r--tuskar_ui/infrastructure/roles/templates/roles/detail.html39
-rw-r--r--tuskar_ui/infrastructure/roles/templates/roles/index.html16
-rw-r--r--tuskar_ui/infrastructure/roles/templates/roles/info.html11
-rw-r--r--tuskar_ui/infrastructure/roles/tests.py166
-rw-r--r--tuskar_ui/infrastructure/roles/urls.py29
-rw-r--r--tuskar_ui/infrastructure/roles/views.py191
-rw-r--r--tuskar_ui/infrastructure/roles/workflows.py180
11 files changed, 0 insertions, 748 deletions
diff --git a/tuskar_ui/infrastructure/roles/__init__.py b/tuskar_ui/infrastructure/roles/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/tuskar_ui/infrastructure/roles/__init__.py
+++ /dev/null
diff --git a/tuskar_ui/infrastructure/roles/panel.py b/tuskar_ui/infrastructure/roles/panel.py
deleted file mode 100644
index 3a2041f6..00000000
--- a/tuskar_ui/infrastructure/roles/panel.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- 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 _
-import horizon
-
-from tuskar_ui.infrastructure import dashboard
-
-
-class Roles(horizon.Panel):
- name = _("Deployment Roles")
- slug = "roles"
-
-
-dashboard.Infrastructure.register(Roles)
diff --git a/tuskar_ui/infrastructure/roles/tables.py b/tuskar_ui/infrastructure/roles/tables.py
deleted file mode 100644
index 8da446ca..00000000
--- a/tuskar_ui/infrastructure/roles/tables.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- 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 _
-from horizon import tables
-
-from tuskar_ui import api
-from tuskar_ui.infrastructure.nodes import tables as nodes_tables
-
-
-class UpdateRole(tables.LinkAction):
- name = "update"
- verbose_name = _("Edit Role")
- url = "horizon:infrastructure:roles:update"
- classes = ("ajax-modal",)
- icon = "pencil"
-
- def allowed(self, request, datum):
- plan = api.tuskar.Plan.get_the_plan(request)
-
- if datum.id in [role.id for role in plan.role_list]:
- return True
- return False
-
-
-class RolesTable(tables.DataTable):
-
- name = tables.Column('name',
- link="horizon:infrastructure:roles:detail",
- verbose_name=_("Role"))
- flavor = tables.Column('flavor',
- verbose_name=_("Flavor"))
- image = tables.Column('image',
- verbose_name=_("Image"))
-
- def get_object_id(self, datum):
- return datum.uuid
-
- class Meta(object):
- name = "roles"
- verbose_name = _("Deployment Roles")
- table_actions = ()
- row_actions = (UpdateRole,)
- template = "horizon/common/_enhanced_data_table.html"
-
-
-class NodeTable(nodes_tables.ProvisionedNodesTable):
-
- class Meta(object):
- name = "nodetable"
- verbose_name = _("Nodes")
- hidden_title = False
- table_actions = ()
- row_actions = ()
- template = "horizon/common/_enhanced_data_table.html"
diff --git a/tuskar_ui/infrastructure/roles/templates/roles/config.html b/tuskar_ui/infrastructure/roles/templates/roles/config.html
deleted file mode 100644
index 854871b4..00000000
--- a/tuskar_ui/infrastructure/roles/templates/roles/config.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<noscript><h3>{{ step }}</h3></noscript>
-<div class="row">
- <div class="col-sm-12">
- <div class="form form-horizontal" id="role-config-form">
- {% include "horizon/common/_horizontal_fields.html" %}
- </div>
- </div>
-</div>
-<script type="text/javascript">
- (window.$ || window.addHorizonLoadEvent)(function () {
- $(document).tooltip('hide'); // Prevent Horizon from adding tooltip.
- $('#role-config-form a.help-icon').click(function () {
- return false;
- }).popover({
- trigger: 'focus',
- placement: 'right',
- container: '#role-config-form'
- });
- $('#role-config-form a.password-button').popover({
- trigger: 'click',
- placement: 'right'
- });
- });
-</script>
diff --git a/tuskar_ui/infrastructure/roles/templates/roles/detail.html b/tuskar_ui/infrastructure/roles/templates/roles/detail.html
deleted file mode 100644
index 0839ca0d..00000000
--- a/tuskar_ui/infrastructure/roles/templates/roles/detail.html
+++ /dev/null
@@ -1,39 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% load url from future %}
-{% block title %}{% trans 'Role' %}: {{ role.name }}{% endblock %}
-
-{% block page_header %}
- {% include 'horizon/common/_domain_page_header.html' with title=_('Deployment Role: ')|add:role.name %}
-{% endblock page_header %}
-
-{% block main %}
-
-<div class="row">
- <div class="col-md-4">
- <h3>{% trans "Properties" %}</h3>
- <h4 class="info">{% blocktrans count counter=nodes|length %}{{ counter }} instance{% plural %}{{ counter }} instances{% endblocktrans %}</h4>
- <dl class="dl-horizontal dl-horizontal-left">
- <dt>{% trans 'Flavor' %}</dt>
- {% if flavor %}
- <dd><em>{{ flavor.name }}</em> {{ flavor.get_keys.cpu_arch }} | {{ flavor.vcpus }} {% trans "CPU" %} | {{ flavor.ram }} {% trans "MB RAM" %} | {{ flavor.disk }} {% trans "GB HDD" %}</dd>
- {% else %}
- <dd>{% trans 'No flavor associated' %}</dd>
- {% endif %}
- <dt>{% trans 'Image' %}</dt>
- {% if image %}
- <dd>{{ image.name }}</dd>
- {% else %}
- <dd>{% trans 'No image associated' %}</dd>
- {% endif %}
- </dl>
- </div>
- <div class="col-md-8">
- <h3>{% trans "Performance & Metrics" %}</h3>
- {% url 'horizon:infrastructure:roles:performance' role.uuid as node_perf_url %}
- {% include "infrastructure/_performance_chart_box.html" with meter_conf=meter_conf node_perf_url=node_perf_url col_size=4 %}
- </div>
-</div>
-
-{{ table.render }}
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/roles/templates/roles/index.html b/tuskar_ui/infrastructure/roles/templates/roles/index.html
deleted file mode 100644
index b17ae230..00000000
--- a/tuskar_ui/infrastructure/roles/templates/roles/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends 'infrastructure/base.html' %}
-{% load i18n %}
-{% block title %}{% trans 'Deployment Roles' %}{% endblock %}
-
-{% block page_header %}
- {% include 'horizon/common/_items_count_domain_page_header.html' with title=_('Deployment Roles') %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row">
- <div class="col-xs-12">
- {{ table.render }}
- </div>
-</div>
-
-{% endblock %}
diff --git a/tuskar_ui/infrastructure/roles/templates/roles/info.html b/tuskar_ui/infrastructure/roles/templates/roles/info.html
deleted file mode 100644
index 2909bd1c..00000000
--- a/tuskar_ui/infrastructure/roles/templates/roles/info.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<noscript><h3>{{ step }}</h3></noscript>
-<div class="row">
- <div class="col-sm-8">
- <div class="form form-horizontal">
- {% include "horizon/common/_horizontal_fields.html" %}
- </div>
- </div>
- <div class="col-sm-4">
- {{ step.get_help_text }}
- </div>
-</div>
diff --git a/tuskar_ui/infrastructure/roles/tests.py b/tuskar_ui/infrastructure/roles/tests.py
deleted file mode 100644
index d9ee2057..00000000
--- a/tuskar_ui/infrastructure/roles/tests.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# -*- 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.
-
-import contextlib
-
-from django.core import urlresolvers
-from openstack_dashboard.test.test_data import utils
-from mock import patch, call # noqa
-
-from tuskar_ui import api
-from tuskar_ui.test import helpers as test
-from tuskar_ui.test.test_data import flavor_data
-from tuskar_ui.test.test_data import heat_data
-from tuskar_ui.test.test_data import node_data
-from tuskar_ui.test.test_data import tuskar_data
-
-
-INDEX_URL = urlresolvers.reverse(
- 'horizon:infrastructure:roles:index')
-DETAIL_URL = urlresolvers.reverse(
- 'horizon:infrastructure:roles:detail', args=('role-1',))
-UPDATE_URL = urlresolvers.reverse(
- 'horizon:infrastructure:roles:update', args=('role-1',))
-
-TEST_DATA = utils.TestDataContainer()
-flavor_data.data(TEST_DATA)
-node_data.data(TEST_DATA)
-heat_data.data(TEST_DATA)
-tuskar_data.data(TEST_DATA)
-
-
-class RolesTest(test.BaseAdminViewTests):
-
- def test_index_get(self):
- roles = [api.tuskar.Role(role)
- for role in self.tuskarclient_roles.list()]
- plans = [api.tuskar.Plan(plan)
- for plan in self.tuskarclient_plans.list()]
- flavor = self.novaclient_flavors.first()
- images = self.glanceclient_images.list()
-
- with contextlib.nested(
- patch('tuskar_ui.api.tuskar.Plan.list',
- return_value=plans),
- patch('tuskar_ui.api.tuskar.Role.list',
- return_value=roles),
- patch('openstack_dashboard.api.glance.image_list_detailed',
- return_value=[images]),
- patch('tuskar_ui.api.flavor.Flavor.get_by_name',
- return_value=flavor)):
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res, 'infrastructure/roles/index.html')
-
- def test_detail_get(self):
- roles = [api.tuskar.Role(role)
- for role in self.tuskarclient_roles.list()]
- plans = [api.tuskar.Plan(plan)
- for plan in self.tuskarclient_plans.list()]
- flavor = self.novaclient_flavors.first()
- images = self.glanceclient_images.list()
- stack = api.heat.Stack(TEST_DATA.heatclient_stacks.first())
-
- with contextlib.nested(
- patch('tuskar_ui.api.tuskar.Role.list',
- return_value=roles),
- patch('tuskar_ui.api.heat.Stack.get_by_plan',
- return_value=stack),
- patch('tuskar_ui.api.heat.Stack.events',
- return_value=[]),
- patch('tuskar_ui.api.heat.Stack.resources',
- return_value=[]),
- patch('tuskar_ui.api.tuskar.Plan.list',
- return_value=plans),
- patch('openstack_dashboard.api.glance.image_list_detailed',
- return_value=[images]),
- patch('tuskar_ui.api.flavor.Flavor.get_by_name',
- return_value=flavor)):
- res = self.client.get(DETAIL_URL)
-
- self.assertTemplateUsed(
- res, 'infrastructure/roles/detail.html')
-
- def test_update_get(self):
- roles = [api.tuskar.Role(role)
- for role in self.tuskarclient_roles.list()]
- plans = [api.tuskar.Plan(plan)
- for plan in self.tuskarclient_plans.list()]
- flavors = self.novaclient_flavors.list()
- images = self.glanceclient_images.list()
- stack = api.heat.Stack(TEST_DATA.heatclient_stacks.first())
-
- with contextlib.nested(
- patch('tuskar_ui.api.tuskar.Role.list',
- return_value=roles),
- patch('tuskar_ui.api.heat.Stack.get_by_plan',
- return_value=stack),
- patch('tuskar_ui.api.heat.Stack.events',
- return_value=[]),
- patch('tuskar_ui.api.heat.Stack.resources',
- return_value=[]),
- patch('tuskar_ui.api.tuskar.Plan.list',
- return_value=plans),
- patch('openstack_dashboard.api.glance.image_get',
- return_value=images[0]),
- patch('tuskar_ui.api.flavor.Flavor.list',
- return_value=flavors),
- patch('openstack_dashboard.api.glance.image_list_detailed',
- return_value=[images])):
-
- res = self.client.get(UPDATE_URL)
-
- # Check that the expected fields are in the form:
- self.assertIn('id="id_flavor" name="flavor"', res.content)
- self.assertIn('id="id_image" name="image"', res.content)
- self.assertIn('flavor-1', res.content)
- self.assertIn('flavor-2', res.content)
-
- def test_update_post(self):
- plan = api.tuskar.Plan(self.tuskarclient_plans.first())
- role = api.tuskar.Role(self.tuskarclient_roles.first())
- flavors = self.novaclient_flavors.list()
- images = self.glanceclient_images.list()
-
- data = {
- 'name': 'controller',
- 'description': 'The controller node role.',
- 'flavor': self.novaclient_flavors.first().name,
- 'image': self.glanceclient_images.first().name,
- 'nodes': '0',
- }
-
- with contextlib.nested(
- patch('tuskar_ui.api.flavor.Flavor.list',
- return_value=flavors),
- patch('openstack_dashboard.api.glance.image_list_detailed',
- return_value=[images]),
- patch('openstack_dashboard.api.glance.image_get',
- return_value=images[0]),
- patch('tuskar_ui.api.tuskar.Role.get',
- return_value=role),
- patch('tuskar_ui.api.tuskar.Plan.patch',
- return_value=plan),
- patch('tuskar_ui.api.tuskar.Plan.get_the_plan',
- return_value=plan)) as mocks:
-
- mock_patch = mocks[4]
- res = self.client.post(UPDATE_URL, data)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- self.assertEqual(len(mock_patch.call_args_list), 1)
- args = mock_patch.call_args_list[0][0]
- self.assertEqual(args[1], plan.id)
- self.assertEqual(args[2]['Controller-1::Flavor'], u'flavor-1')
- self.assertEqual(args[2]['Controller-1::Image'], u'overcloud-full')
diff --git a/tuskar_ui/infrastructure/roles/urls.py b/tuskar_ui/infrastructure/roles/urls.py
deleted file mode 100644
index 9dfdb778..00000000
--- a/tuskar_ui/infrastructure/roles/urls.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- 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 import urls
-
-from tuskar_ui.infrastructure.roles import views
-
-
-urlpatterns = urls.patterns(
- '',
- urls.url(r'^$', views.IndexView.as_view(), name='index'),
- urls.url(r'^(?P<role_id>[^/]+)/$', views.DetailView.as_view(),
- name='detail'),
- urls.url(r'^(?P<role_id>[^/]+)/edit$', views.UpdateView.as_view(),
- name='update'),
- urls.url(r'^(?P<role_id>[^/]+)/performance/$',
- views.PerformanceView.as_view(), name='performance'),
-)
diff --git a/tuskar_ui/infrastructure/roles/views.py b/tuskar_ui/infrastructure/roles/views.py
deleted file mode 100644
index b5cb5801..00000000
--- a/tuskar_ui/infrastructure/roles/views.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# -*- 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.
-import json
-
-from django.core.urlresolvers import reverse
-from django import http
-from django.utils.translation import ugettext_lazy as _
-from django.views.generic import base
-from glanceclient import exc as glance_exc
-from horizon import tables as horizon_tables
-from horizon import utils
-from horizon import workflows
-from openstack_dashboard.api import base as api_base
-
-from tuskar_ui import api
-from tuskar_ui.infrastructure.roles import tables
-from tuskar_ui.infrastructure.roles import workflows as role_workflows
-from tuskar_ui.infrastructure import views
-from tuskar_ui.utils import metering as metering_utils
-
-
-INDEX_URL = 'horizon:infrastructure:roles:index'
-
-
-class IndexView(views.ItemCountMixin, horizon_tables.DataTableView):
- table_class = tables.RolesTable
- template_name = "infrastructure/roles/index.html"
-
- @utils.memoized.memoized
- def get_data(self):
- roles = api.tuskar.Role.list(self.request)
- plan = api.tuskar.Plan.get_the_plan(self.request)
- for role in roles:
- role_flavor = role.flavor(plan)
- try:
- role_image = role.image(plan)
- except glance_exc.HTTPNotFound:
- # Glance returns a 404 if the image doesn't exist
- role_image = None
- if role_flavor:
- role.flavor = role_flavor.name
- else:
- role.flavor = _('Unknown')
- if role_image:
- role.image = role_image.name
- else:
- role.image = _('Unknown')
-
- return roles
-
-
-class DetailView(horizon_tables.DataTableView, views.RoleMixin,
- views.StackMixin):
- table_class = tables.NodeTable
- template_name = 'infrastructure/roles/detail.html'
-
- @utils.memoized.memoized
- def _get_nodes(self, stack, role):
- resources = stack.resources(role=role, with_joins=True)
- nodes = [r.node for r in resources]
- for node in nodes:
- try:
- resource = api.heat.Resource.get_by_node(self.request, node)
- except LookupError:
- node.role_name = '-'
- else:
- node.role_name = resource.role.name
- node.role_id = resource.role.id
- node.stack_id = resource.stack.id
-
- return nodes
-
- def get_data(self):
- redirect = reverse(INDEX_URL)
- stack = self.get_stack()
- if stack:
- role = self.get_role(redirect)
- return self._get_nodes(stack, role)
- return []
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- redirect = reverse(INDEX_URL)
-
- plan = api.tuskar.Plan.get_the_plan(self.request)
- stack = self.get_stack()
- role = self.get_role(redirect)
-
- context['role'] = role
- if stack:
- context['nodes'] = self._get_nodes(stack, role)
- else:
- context['nodes'] = []
- context['flavor'] = role.flavor(plan)
- context['image'] = role.image(plan)
-
- if stack:
- if api_base.is_service_enabled(self.request, 'metering'):
- # Meter configuration in the following format:
- # (meter label, url part, barchart (True/False))
- context['meter_conf'] = (
- (_('System Load'),
- metering_utils.url_part('hardware.cpu.load.1min', False),
- None),
- (_('CPU Utilization'),
- metering_utils.url_part('hardware.system_stats.cpu.util',
- True),
- '100'),
- (_('Swap Utilization'),
- metering_utils.url_part('hardware.memory.swap.util',
- True),
- '100'),
- )
- return context
-
-
-class UpdateView(workflows.WorkflowView, views.StackMixin, views.RoleMixin):
- workflow_class = role_workflows.UpdateRole
-
- def get_initial(self):
- plan = self.get_plan()
- role = self.get_role()
-
- stack = self.get_stack()
- if stack:
- resources = stack.resources(role=role, with_joins=True)
- role_nodes = len(resources)
- else:
- role_nodes = 0
-
- role_flavor = role.flavor(plan)
- role_flavor = '' if role_flavor is None else role_flavor.name
-
- role_image = role.image(plan)
- role_image = '' if role_image is None else role_image.name
-
- free_nodes = len(api.node.Node.list(self.request, associated=False,
- maintenance=False))
- available_nodes = role_nodes + free_nodes
-
- return {
- 'role_id': role.id,
- 'name': role.name,
- 'flavor': role_flavor,
- 'image': role_image,
- 'nodes': role_nodes,
- 'available_nodes': available_nodes,
- }
-
-
-class PerformanceView(base.TemplateView, views.RoleMixin, views.StackMixin):
- def get(self, request, *args, **kwargs):
- meter = request.GET.get('meter')
- date_options = request.GET.get('date_options')
- date_from = request.GET.get('date_from')
- date_to = request.GET.get('date_to')
- stats_attr = request.GET.get('stats_attr', 'avg')
- barchart = bool(request.GET.get('barchart'))
-
- role = self.get_role()
- stack = self.get_stack()
- instances = stack.resources(role=role, with_joins=True)
-
- if instances:
- instance_uuids = [i.physical_resource_id for i in instances]
- json_output = metering_utils.get_nodes_stats(
- request=request,
- node_uuid=None,
- instance_uuids=instance_uuids,
- meter=meter,
- date_options=date_options,
- date_from=date_from,
- date_to=date_to,
- stats_attr=stats_attr,
- barchart=barchart)
- else:
- json_output = None
-
- return http.HttpResponse(json.dumps(json_output),
- content_type='application/json')
diff --git a/tuskar_ui/infrastructure/roles/workflows.py b/tuskar_ui/infrastructure/roles/workflows.py
deleted file mode 100644
index b9786112..00000000
--- a/tuskar_ui/infrastructure/roles/workflows.py
+++ /dev/null
@@ -1,180 +0,0 @@
-# -*- 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.core.urlresolvers import reverse_lazy
-import django.forms
-from django.utils.translation import ugettext_lazy as _
-from horizon import exceptions
-from horizon import forms
-from horizon import workflows
-from openstack_dashboard.api import glance
-
-from tuskar_ui import api
-import tuskar_ui.forms
-from tuskar_ui.infrastructure.flavors import utils
-from tuskar_ui.infrastructure.parameters import forms as parameters_forms
-from tuskar_ui.utils import utils as tuskar_utils
-
-
-class UpdateRoleInfoAction(workflows.Action):
- # TODO(rdopiera) Make the name and description editable.
- name = forms.CharField(
- label=_("Name"),
- required=False,
- widget=tuskar_ui.forms.StaticTextWidget
- )
- description = forms.CharField(
- label=_("Description"),
- required=False,
- widget=tuskar_ui.forms.StaticTextWidget
- )
- flavor = forms.ChoiceField(
- label=_("Flavor"),
- )
- image = forms.ChoiceField(
- label=_("Image"),
- )
- nodes = forms.IntegerField(
- label=_("Number of Nodes"),
- required=False,
- initial=0,
- )
-
- class Meta(object):
- name = _("Overall Settings")
- slug = 'update_role_info'
- help_text = _("Edit the role details.")
-
- def __init__(self, request, context, *args, **kwargs):
- super(UpdateRoleInfoAction, self).__init__(request, context, *args,
- **kwargs)
- self.available_nodes = context['available_nodes']
- self.fields['nodes'].widget = tuskar_ui.forms.NumberInput(attrs={
- 'min': 0,
- 'max': self.available_nodes,
- })
- self.fields['nodes'].help_text = _(
- "{0} nodes available").format(self.available_nodes)
- if not utils.matching_deployment_mode():
- del self.fields['flavor']
-
- def populate_flavor_choices(self, request, context):
- flavors = api.flavor.Flavor.list(self.request)
- choices = [(f.name, f.name) for f in flavors]
- return [('', _('Unknown'))] + choices
-
- def populate_image_choices(self, request, context):
- images = glance.image_list_detailed(self.request)[0]
- images = [image for image in images
- if tuskar_utils.check_image_type(image,
- 'overcloud provisioning')]
- choices = [(i.name, i.name) for i in images]
- return [('', _('Unknown'))] + choices
-
- def clean_nodes(self):
- new_count = int(self.cleaned_data['nodes'] or 0)
- if new_count > self.available_nodes:
- raise django.forms.ValidationError(_(
- "There are only {0} nodes available "
- "for the selected flavor."
- ).format(self.available_nodes))
- return str(new_count)
-
- def handle(self, request, context):
- return {
- 'name': self.cleaned_data['name'],
- 'description': self.cleaned_data['description'],
- 'flavor': self.cleaned_data.get('flavor'),
- 'image': self.cleaned_data['image'],
- 'nodes': self.cleaned_data['nodes'],
- }
-
-
-class UpdateRoleConfigAction(workflows.Action):
- class Meta(object):
- name = _("Service Configuration")
- slug = 'update_role_config'
- help_text = _("Edit the role's services configuration.")
-
- def __init__(self, request, context, *args, **kwargs):
- super(UpdateRoleConfigAction, self).__init__(request, context,
- *args, **kwargs)
- self.fields.update(
- parameters_forms.parameter_fields(
- request,
- prefix='%s-1::' % context['name']),
- )
-
- def handle(self, request, context):
- return {'parameters': self.cleaned_data}
-
-
-class UpdateRoleInfo(workflows.Step):
- action_class = UpdateRoleInfoAction
- depends_on = ("role_id", "available_nodes")
- contributes = ("name", "description", "flavor", "image", "nodes")
- template_name = 'infrastructure/roles/info.html'
-
-
-class UpdateRoleConfig(workflows.Step):
- action_class = UpdateRoleConfigAction
- depends_on = ("role_id", "name")
- contributes = ("parameters",)
- template_name = 'infrastructure/roles/config.html'
-
-
-class UpdateRole(workflows.Workflow):
- slug = "update_role"
- finalize_button_name = _("Save")
- success_message = _('Modified role "%s".')
- failure_message = _('Unable to modify role "%s".')
- index_url = "horizon:infrastructure:roles:index"
- default_steps = (
- UpdateRoleInfo,
- UpdateRoleConfig,
- )
- success_url = reverse_lazy(
- 'horizon:infrastructure:roles:index')
-
- def name(self):
- # Use context_seed here, as context['name'] returns empty
- # as it's one of the fields.
- return _('Edit Role "%s"') % self.context_seed['name']
-
- def format_status_message(self, message):
- # Use context_seed here, as context['name'] returns empty
- # as it's one of the fields.
- return message % self.context_seed['name']
-
- def handle(self, request, data):
- # save it!
- role_id = data['role_id']
- try:
- # Get initial role information
- plan = api.tuskar.Plan.get_the_plan(self.request)
- role = api.tuskar.Role.get(self.request, role_id)
- except Exception:
- exceptions.handle(
- self.request,
- _('Unable to retrieve role details.'),
- redirect=reverse_lazy(self.index_url))
-
- parameters = data['parameters']
- parameters[role.image_parameter_name] = data['image']
- parameters[role.node_count_parameter_name] = data['nodes']
- if utils.matching_deployment_mode():
- parameters[role.flavor_parameter_name] = data['flavor']
-
- plan.patch(request, plan.uuid, parameters)
- # TODO(rdopiera) Find out how to update role's name and description.
- return True