Merge "Added service profile UI support."
This commit is contained in:
commit
360e81b4df
|
@ -144,6 +144,15 @@ class ServiceChainInstance(neutron.NeutronAPIDictWrapper):
|
|||
return sc_instance_dict
|
||||
|
||||
|
||||
class ServiceProfile(neutron.NeutronAPIDictWrapper):
|
||||
|
||||
"""Wrapper for neutron service profile."""
|
||||
|
||||
def get_dict(self):
|
||||
sc_profile_dict = self._apidict
|
||||
return sc_profile_dict
|
||||
|
||||
|
||||
def policy_target_create(request, **kwargs):
|
||||
body = {'policy_target_group': kwargs}
|
||||
policy_target = gbpclient(request).create_policy_target_group(
|
||||
|
@ -505,3 +514,26 @@ def update_servicechain_instance(request, scinstance_id, **kwargs):
|
|||
|
||||
def delete_servicechain_instance(request, scinstance_id):
|
||||
gbpclient(request).delete_servicechain_instance(scinstance_id)
|
||||
|
||||
|
||||
def serviceprofile_list(request, **kwargs):
|
||||
sc_profile = gbpclient(request).list_service_profiles(True,
|
||||
**kwargs).get('service_profiles')
|
||||
return [ServiceProfile(item) for item in sc_profile]
|
||||
|
||||
|
||||
def get_service_profile(request, service_profile_id):
|
||||
service_profile = gbpclient(request).show_service_profile(
|
||||
service_profile_id).get('service_profile')
|
||||
return ServiceProfile(service_profile)
|
||||
|
||||
|
||||
def create_service_profile(request, **kwargs):
|
||||
body = {'service_profile': kwargs}
|
||||
service_profile = gbpclient(request).create_service_profile(
|
||||
body).get('service_profile')
|
||||
return ServiceProfile(service_profile)
|
||||
|
||||
|
||||
def delete_service_profile(request, service_profile_id):
|
||||
gbpclient(request).delete_service_profile(service_profile_id)
|
||||
|
|
|
@ -154,17 +154,41 @@ def update_sc_spec_attributes(request, scspec):
|
|||
scn_url = "horizon:project:network_services:sc_node_details"
|
||||
for n in nodes:
|
||||
url = reverse(scn_url, kwargs={'scnode_id': n.id})
|
||||
service_profile_id = n.service_profile_id
|
||||
try:
|
||||
service_profile = client.get_service_profile(request,
|
||||
service_profile_id)
|
||||
service_type = service_profile.service_type
|
||||
except Exception:
|
||||
pass
|
||||
val.append(
|
||||
"<td><span class='glyphicon glyphicon-arrow-right'></span></td>")
|
||||
scnode = "<td><a href='" + url + "' style='font-size: 9px;' >" \
|
||||
+ "<img src='" + img_src + n.service_type + ".png'>" \
|
||||
+ "<br>" + n.name + " (" + n.service_type + ")</a></td>"
|
||||
+ "<img src='" + img_src + service_type + ".png'>" \
|
||||
+ "<br>" + n.name + " (" + service_type + ")</a></td>"
|
||||
val.append(scnode)
|
||||
val.append("</tr></table>")
|
||||
setattr(scspec, 'nodes', mark_safe("".join(val)))
|
||||
return scspec
|
||||
|
||||
|
||||
def update_sc_node_attributes(request, scnode):
|
||||
t = "<p style='margin-bottom:0px'>"
|
||||
val = [t]
|
||||
sp_url = "horizon:project:network_services:service_profile_details"
|
||||
url = reverse(sp_url, kwargs={'sp_id': scnode.service_profile_id})
|
||||
try:
|
||||
service_profile = client.get_service_profile(request,
|
||||
scnode.service_profile_id)
|
||||
sp = "<a href='" + url + "'>" + service_profile.name + ' : ' + \
|
||||
service_profile.service_type + '</a></p>'
|
||||
val.append(sp)
|
||||
except Exception:
|
||||
return scnode
|
||||
setattr(scnode, 'service_profile', mark_safe("".join(val)))
|
||||
return scnode
|
||||
|
||||
|
||||
def update_sc_instance_attributes(request, scinstance):
|
||||
ptg_url = "horizon:project:policytargets:policy_targetdetails"
|
||||
clsurl = "horizon:project:application_policy:policyclassifierdetails"
|
||||
|
|
|
@ -42,12 +42,49 @@ class BaseUpdateForm(forms.SelfHandlingForm):
|
|||
return updated_data
|
||||
|
||||
|
||||
class CreateServiceProfileForm(forms.SelfHandlingForm):
|
||||
name = forms.CharField(max_length=80, label=_("Name"))
|
||||
description = forms.CharField(
|
||||
max_length=80, label=_("Description"), required=False)
|
||||
vendor = forms.CharField(
|
||||
max_length=80, label=_("Vendor"), required=True)
|
||||
service_flavor = forms.CharField(
|
||||
max_length=80, label=_("Service Flavor"), required=False)
|
||||
service_type = forms.ChoiceField(
|
||||
label=_("Service Type"), choices=SERVICE_TYPES)
|
||||
insertion_mode = forms.ChoiceField(
|
||||
label=_("Insertion Mode"), choices=[('l3', 'L3'), ('l2', 'L2')])
|
||||
shared = forms.BooleanField(label=_("Shared"),
|
||||
initial=False, required=False)
|
||||
|
||||
def handle(self, request, context):
|
||||
url = reverse("horizon:project:network_services:index")
|
||||
try:
|
||||
if context.get('name'):
|
||||
context['name'] = html.escape(context['name'])
|
||||
if context.get('description'):
|
||||
context['description'] = html.escape(context['description'])
|
||||
if context.get('vendor'):
|
||||
context['vendor'] = html.escape(context['vendor'])
|
||||
if context.get('service_flavor'):
|
||||
context['service_flavor'] = html.escape(
|
||||
context['service_flavor'])
|
||||
client.create_service_profile(request, **context)
|
||||
msg = _("Service Profile Created Successfully")
|
||||
messages.success(request, msg)
|
||||
return http.HttpResponseRedirect(url)
|
||||
except Exception as e:
|
||||
msg = _("Failed to create Service Profile. %s") % (str(e))
|
||||
LOG.error(msg)
|
||||
exceptions.handle(request, msg, redirect=shortcuts.redirect)
|
||||
|
||||
|
||||
class CreateServiceChainNodeForm(forms.SelfHandlingForm):
|
||||
name = forms.CharField(max_length=80, label=_("Name"))
|
||||
description = forms.CharField(
|
||||
max_length=80, label=_("Description"), required=False)
|
||||
service_type = forms.ChoiceField(
|
||||
label=_("Service Type"), choices=SERVICE_TYPES)
|
||||
service_profile_id = forms.ChoiceField(
|
||||
label=_("Service Profile"))
|
||||
config_type = forms.ChoiceField(label=_("Config Type"),
|
||||
choices=[('file', 'Heat Template'),
|
||||
('string', 'Config String')],
|
||||
|
@ -70,6 +107,21 @@ class CreateServiceChainNodeForm(forms.SelfHandlingForm):
|
|||
shared = forms.BooleanField(label=_("Shared"),
|
||||
initial=False, required=False)
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(CreateServiceChainNodeForm, self).__init__(
|
||||
request, *args, **kwargs)
|
||||
try:
|
||||
service_profile_tuples = []
|
||||
service_profile_list = client.serviceprofile_list(self.request)
|
||||
for service_profile in service_profile_list:
|
||||
sp = (service_profile.id,
|
||||
service_profile.name + ' : ' + service_profile.service_type)
|
||||
service_profile_tuples.append(sp)
|
||||
self.fields['service_profile_id'].choices = service_profile_tuples
|
||||
except Exception:
|
||||
msg = _("Failed to retrive Service profile details.")
|
||||
LOG.error(msg)
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(CreateServiceChainNodeForm, self).clean()
|
||||
files = self.request.FILES
|
||||
|
|
|
@ -91,8 +91,8 @@ class ServiceChainNodeTable(tables.DataTable):
|
|||
link="horizon:project:network_services:sc_node_details")
|
||||
description = tables.Column("description",
|
||||
verbose_name=_("Description"))
|
||||
service_type = tables.Column("service_type",
|
||||
verbose_name=_("Service Type"))
|
||||
service_profile = tables.Column("service_profile",
|
||||
verbose_name=_("Service Profile"))
|
||||
|
||||
class Meta(object):
|
||||
name = "service_chain_node_table"
|
||||
|
@ -149,3 +149,37 @@ class ServiceChainInstanceTable(tables.DataTable):
|
|||
table_actions = (CreateServiceChainInstanceLink,)
|
||||
row_actions = (
|
||||
EditServiceChainInstanceLink, DeleteServiceChainInstanceLink,)
|
||||
|
||||
|
||||
class CreateServiceProfileLink(tables.LinkAction):
|
||||
name = "create_service_profile_link"
|
||||
verbose_name = _("Create Service Profile")
|
||||
url = "horizon:project:network_services:create_service_profile"
|
||||
classes = ("ajax-modal", "btn-create_service_profile")
|
||||
|
||||
|
||||
class DeleteServiceProfileLink(tables.DeleteAction):
|
||||
name = "deleteserviceprofile"
|
||||
action_present = _("Delete")
|
||||
action_past = _("Scheduled deletion of %(data_type)s")
|
||||
data_type_singular = _("ServiceProfile")
|
||||
data_type_plural = _("ServiceProfiles")
|
||||
|
||||
|
||||
class ServiceProfileTable(tables.DataTable):
|
||||
name = tables.Column("name", verbose_name=_("Name"),
|
||||
link="horizon:project:network_services:service_profile_details")
|
||||
description = tables.Column("description",
|
||||
verbose_name=_("Description"))
|
||||
service_type = tables.Column("service_type",
|
||||
verbose_name=_("Service Type"))
|
||||
insertion_mode = tables.Column("insertion_mode",
|
||||
verbose_name=_("Insertion Mode"))
|
||||
vendor = tables.Column("vendor", verbose_name=_("Vendor"))
|
||||
|
||||
class Meta(object):
|
||||
name = "service_profile_table"
|
||||
verbose_name = _("Service Profile")
|
||||
table_actions = (CreateServiceProfileLink,
|
||||
DeleteServiceProfileLink,)
|
||||
row_actions = (DeleteServiceProfileLink,)
|
||||
|
|
|
@ -55,6 +55,8 @@ class ServiceChainNodeTab(tabs.TableTab):
|
|||
try:
|
||||
nodes = client.servicechainnode_list(self.request,
|
||||
tenant_id=self.request.user.tenant_id)
|
||||
nodes = [gfilters.update_sc_node_attributes(
|
||||
self.request, item) for item in nodes]
|
||||
except Exception:
|
||||
pass
|
||||
return nodes
|
||||
|
@ -78,12 +80,50 @@ class ServiceChainInstanceTab(tabs.TableTab):
|
|||
return instances
|
||||
|
||||
|
||||
class ServiceProfileTab(tabs.TableTab):
|
||||
name = _("Service Profiles")
|
||||
table_classes = (ns_tables.ServiceProfileTable,)
|
||||
slug = "service_profile"
|
||||
template_name = "horizon/common/_detail_table.html"
|
||||
|
||||
def get_service_profile_table_data(self):
|
||||
service_profiles = []
|
||||
try:
|
||||
service_profiles = client.serviceprofile_list(self.request)
|
||||
except Exception:
|
||||
pass
|
||||
return service_profiles
|
||||
|
||||
|
||||
class ServiceChainTabs(tabs.TabGroup):
|
||||
slug = "service_chain_spec_tabs"
|
||||
tabs = (ServiceChainSpecTab, ServiceChainNodeTab,)
|
||||
tabs = (ServiceChainSpecTab, ServiceChainNodeTab, ServiceProfileTab,)
|
||||
sticky = True
|
||||
|
||||
|
||||
class ServiceProfileDetailsTab(tabs.Tab):
|
||||
name = _("Service Profile Details")
|
||||
slug = "serviceprofile_details"
|
||||
template_name = "project/network_services/_serviceprofile_details.html"
|
||||
failure_url = reverse_lazy('horizon:project:network_services:index')
|
||||
|
||||
def get_context_data(self, request):
|
||||
service_profile_id = self.tab_group.kwargs['sp_id']
|
||||
try:
|
||||
service_profile = client.get_service_profile(
|
||||
request, service_profile_id)
|
||||
except Exception:
|
||||
exceptions.handle(request, _(
|
||||
'Unable to retrieve service profile details.'),
|
||||
redirect=self.failure_url)
|
||||
return {'service_profile': service_profile}
|
||||
|
||||
|
||||
class ServiceProfileDetailsTabGroup(tabs.TabGroup):
|
||||
slug = 'scnode_details'
|
||||
tabs = (ServiceProfileDetailsTab,)
|
||||
|
||||
|
||||
class ServiceChainNodeDetailsTab(tabs.Tab):
|
||||
name = _("Service Chain Node Details")
|
||||
slug = "scnode_details"
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
{% load url from future %}
|
||||
|
||||
{% block form_id %}create_service_profile_form{% endblock %}
|
||||
{% block form_action %}{% url "horizon:project:network_services:create_service_profile" %}{% endblock %}
|
||||
|
||||
{% block modal_id %}create_service_profile_modal{% endblock %}
|
||||
{% block modal-header %}{% trans "Create Service Profile" %}{% endblock %}
|
||||
|
||||
{% block modal-body %}
|
||||
<div class="left">
|
||||
<fieldset>
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="right">
|
||||
<h3>{% trans "Description" %}:</h3>
|
||||
<p>{% trans "Create Service Profile." %}</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block modal-footer %}
|
||||
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Save changes" %}" />
|
||||
<a href="{% url "horizon:project:network_services:index" %}" class="btn btn-default secondary cancel close">{% trans "Cancel" %}</a>
|
||||
{% endblock %}
|
|
@ -16,8 +16,8 @@
|
|||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ scnode.id }} </dd>
|
||||
|
||||
<dt>{% trans "Service Type" %}</dt>
|
||||
<dd>{{ scnode.service_type }} </dd>
|
||||
<dt>{% trans "Service Profile" %}</dt>
|
||||
<dd><a href="{% url 'horizon:project:network_services:service_profile_details' sp_id=scnode.service_profile_id %}">{{ scnode.service_profile_id }}</a></dd>
|
||||
|
||||
<dt>{% trans "Shared" %}</dt>
|
||||
<dd>{{ scnode.shared }}</dd>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Service Type</th>
|
||||
<th>Service Profile</th>
|
||||
<th>Config</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -34,7 +34,10 @@
|
|||
<a href="{% url 'horizon:project:network_services:sc_node_details' scnode_id=node.id %}">
|
||||
{{node.name}}</a>
|
||||
</td>
|
||||
<td>{{node.service_type}}</td>
|
||||
<td>
|
||||
<a href="{% url 'horizon:project:network_services:service_profile_details' sp_id=node.service_profile_id %}">
|
||||
{{ node.service_profile_id }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<div style ="white-space:pre;overflow-y: scroll;height:300px;background-color:#EEEEEE">{{node.config}}</div>
|
||||
</td>
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
{% load i18n sizeformat parse_date %}
|
||||
{% load url from future %}
|
||||
|
||||
<div class="info row detail">
|
||||
<hr class="header_rule">
|
||||
<dl style="font-size:14px">
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ service_profile.name|default:_("-") }}</dd>
|
||||
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ service_profile.description|default:_("-") }}</dd>
|
||||
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ service_profile.id }} </dd>
|
||||
|
||||
<dt>{% trans "Service Type" %}</dt>
|
||||
<dd>{{ service_profile.service_type }} </dd>
|
||||
|
||||
<dt>{% trans "Insertion Mode" %}</dt>
|
||||
<dd>{{ service_profile.insertion_mode }}</dd>
|
||||
|
||||
<dt>{% trans "Vendor" %}</dt>
|
||||
<dd>{{ service_profile.vendor }}</dd>
|
||||
|
||||
<dt>{% trans "Service Flavor" %}</dt>
|
||||
<dd>{{ service_profile.service_flavor|default:_("-") }}</dd>
|
||||
|
||||
<dt>{% trans "Shared" %}</dt>
|
||||
<dd>{{ service_profile.shared }}</dd>
|
||||
|
||||
</dl>
|
||||
</div>
|
|
@ -18,6 +18,12 @@ import views
|
|||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^create_service_profile$',
|
||||
views.CreateServiceProfileView.as_view(),
|
||||
name='create_service_profile'),
|
||||
url(r'^serviceprofile/(?P<sp_id>[^/]+)/$',
|
||||
views.ServiceProfileDetailsView.as_view(),
|
||||
name='service_profile_details'),
|
||||
url(r'^create_sc_node$',
|
||||
views.CreateServiceChainNodeView.as_view(),
|
||||
name='create_sc_node'),
|
||||
|
|
|
@ -60,9 +60,33 @@ class IndexView(tabs.TabView):
|
|||
except Exception as e:
|
||||
exceptions.handle(request,
|
||||
_('Unable to delete . %s') % e)
|
||||
if obj_type == 'serviceprofile':
|
||||
for obj_id in obj_ids:
|
||||
try:
|
||||
client.delete_service_profile(request, obj_id)
|
||||
messages.success(request,
|
||||
_('Deleted %s') % obj_id)
|
||||
except Exception as e:
|
||||
exceptions.handle(request,
|
||||
_('Unable to delete . %s') % e)
|
||||
return self.get(request, *args, **kwargs)
|
||||
|
||||
|
||||
class ServiceProfileDetailsView(tabs.TabView):
|
||||
tab_group_class = (ns_tabs.ServiceProfileDetailsTabGroup)
|
||||
template_name = 'project/network_services/details_tabs.html'
|
||||
|
||||
|
||||
class CreateServiceProfileView(forms.ModalFormView):
|
||||
form_class = ns_forms.CreateServiceProfileForm
|
||||
template_name = "project/network_services/create_service_profile.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(
|
||||
CreateServiceProfileView, self).get_context_data(**kwargs)
|
||||
return context
|
||||
|
||||
|
||||
class CreateServiceChainNodeView(forms.ModalFormView):
|
||||
form_class = ns_forms.CreateServiceChainNodeForm
|
||||
template_name = "project/network_services/create_service_chain_node.html"
|
||||
|
|
Loading…
Reference in New Issue