Add "Service Configuration" tab to the Role Edit dialog

Change-Id: Ibebc1c796b414bdd2315df5e1aaaad1f10454ada
This commit is contained in:
Radomir Dopieralski 2015-02-19 14:49:07 +01:00
parent b353f7a8c6
commit 18e2c8b394
5 changed files with 109 additions and 51 deletions

View File

@ -22,6 +22,19 @@ import netaddr
SEPARATOR_RE = re.compile('[\s,;|]+', re.UNICODE)
def label_with_tooltip(label, tooltip=None, title=None):
if not tooltip:
return label
return html.format_html(
u'{0}&nbsp;<a class="help-icon fa fa-question-circle" '
u'data-content="{1}" tabindex="0" href="#" '
u'data-title="{2}"></a>',
html.escape(label),
html.escape(tooltip),
html.escape(title or label)
)
def fieldset(form, *args, **kwargs):
"""A helper function for grouping fields based on their names."""

View File

@ -16,7 +16,7 @@ import json
import logging
import django.forms
from django.utils import html
from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext_lazy as _
import horizon.exceptions
import horizon.forms
@ -46,38 +46,42 @@ CINDER_ISCSI_HELPER_CHOICES = [
]
def name_with_tooltip(parameter):
humanized_name = utils.de_camel_case(parameter.stripped_name)
if not parameter.description:
return humanized_name
return html.format_html(
u'{0}&nbsp;<a class="help-icon fa fa-question-circle" '
u'data-content="{1}" tabindex="0" href="#" '
u'title="{2}"></a>',
html.escape(humanized_name),
html.escape(parameter.description),
html.escape(humanized_name)
)
def parameter_fields(request, prefix=None, read_only=False):
fields = SortedDict()
plan = api.tuskar.Plan.get_the_plan(request)
parameters = plan.parameter_list(include_key_parameters=False)
for p in parameters:
if prefix and not p.name.startswith(prefix):
continue
if read_only:
if p.hidden:
widget = tuskar_ui.forms.StaticTextPasswordWidget
else:
widget = tuskar_ui.forms.StaticTextWidget
else:
if p.hidden:
widget = django.forms.PasswordInput(render_value=True)
elif 'Certificate' in p.name:
widget = django.forms.Textarea
else:
widget = None
fields[p.name] = django.forms.CharField(
required=False,
widget=widget,
label=tuskar_ui.forms.label_with_tooltip(
utils.de_camel_case(p.stripped_name),
p.description,
),
initial=p.value,
)
return fields
class ServiceConfig(horizon.forms.SelfHandlingForm):
def __init__(self, *args, **kwargs):
super(ServiceConfig, self).__init__(*args, **kwargs)
plan = api.tuskar.Plan.get_the_plan(self.request)
parameters = plan.parameter_list(include_key_parameters=False)
for p in parameters:
if p.hidden:
self.fields[p.name] = django.forms.CharField(
required=False,
widget=tuskar_ui.forms.StaticTextPasswordWidget(),
label=name_with_tooltip(p))
else:
self.fields[p.name] = django.forms.CharField(
required=False,
widget=tuskar_ui.forms.StaticTextWidget(),
label=name_with_tooltip(p))
self.fields.update(parameter_fields(self.request, read_only=True))
def global_fieldset(self):
return tuskar_ui.forms.fieldset(self, prefix='^(?!.*::)')
@ -101,20 +105,7 @@ class ServiceConfig(horizon.forms.SelfHandlingForm):
class AdvancedEditServiceConfig(ServiceConfig):
def __init__(self, *args, **kwargs):
super(AdvancedEditServiceConfig, self).__init__(*args, **kwargs)
plan = api.tuskar.Plan.get_the_plan(self.request)
parameters = plan.parameter_list(include_key_parameters=False)
for p in parameters:
if p.hidden:
self.fields[p.name] = django.forms.CharField(
required=False,
widget=django.forms.PasswordInput(render_value=True),
label=name_with_tooltip(p))
else:
self.fields[p.name] = django.forms.CharField(
required=False,
label=name_with_tooltip(p))
self.fields.update(parameter_fields(self.request))
def handle(self, request, data):
plan = api.tuskar.Plan.get_the_plan(self.request)

View File

@ -0,0 +1,24 @@
<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>

View File

@ -159,5 +159,5 @@ class RolesTest(test.BaseAdminViewTests):
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',
'Controller-1::Image': u'2'})
self.assertEqual(args[2]['Controller-1::Flavor'], u'flavor-1')
self.assertEqual(args[2]['Controller-1::Image'], u'2')

View File

@ -19,21 +19,22 @@ from horizon import workflows
from openstack_dashboard.api import glance
from tuskar_ui import api
from tuskar_ui import forms as tuskar_forms
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):
name = forms.CharField(
label=_("Name"),
widget=tuskar_forms.LabelWidget(),
widget=tuskar_ui.forms.LabelWidget(),
required=False,
)
description = forms.CharField(
label=_("Description"),
widget=tuskar_forms.LabelWidget(),
widget=tuskar_ui.forms.LabelWidget(),
required=False,
)
@ -46,8 +47,7 @@ class UpdateRoleInfoAction(workflows.Action):
)
class Meta(object):
name = _("Role Information")
help_text = _("helptext here")
name = _("Overall Settings")
slug = 'update_role_info'
help_text = _("Edit the role details.")
@ -71,19 +71,48 @@ class UpdateRoleInfoAction(workflows.Action):
return [('', _('Unknown'))] + choices
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",)
contributes = ("name", "flavor", "image",)
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,)
default_steps = (
UpdateRoleInfo,
UpdateRoleConfig,
)
success_url = reverse_lazy(
'horizon:infrastructure:roles:index')
@ -110,7 +139,8 @@ class UpdateRole(workflows.Workflow):
_('Unable to retrieve role details.'),
redirect=reverse_lazy(self.index_url))
parameters = {role.image_id_parameter_name: data['image']}
parameters = data['parameters']
parameters[role.image_id_parameter_name] = data['image']
if utils.matching_deployment_mode():
parameters[role.flavor_parameter_name] = data['flavor']