No option to CRUD NAT Pool

Added support for "NAT Pool" CRUD in
network policy page.

Change-Id: I0f226c77c6cde426de5fa4c8628eb173281fc518
Closes-Bug: #1497781
This commit is contained in:
sriharshabarkuru 2015-11-13 12:27:39 +05:30
parent 7271ee2722
commit 3d53287284
10 changed files with 383 additions and 1 deletions

View File

@ -78,6 +78,16 @@ class ExternalConnectivity(neutron.NeutronAPIDictWrapper):
return ec_dict
class NATPool(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron nat pool."""
def get_dict(self):
natpool_dict = self._apidict
natpool_dict['natpool_id'] = natpool_dict['id']
return natpool_dict
class Contract(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron policy_rule_set."""
@ -418,6 +428,38 @@ def externalconnectivity_list(request, tenant_id, **kwargs):
for external_connectivity in external_connectivities]
def natpool_list(request, tenant_id, **kwargs):
nat_pools = gbpclient(request).list_nat_pools(
tenant_id=tenant_id, shared=False, **kwargs).get('nat_pools')
nat_pools.extend(gbpclient(request).list_nat_pools(
shared=True, **kwargs).get('nat_pools'))
return [NATPool(nat_pool) for nat_pool in nat_pools]
def create_natpool(request, **kwargs):
body = {'nat_pool': kwargs}
np = gbpclient(request).create_nat_pool(
body).get('nat_pool')
return NATPool(np)
def get_natpool(request, nat_pool_id):
np = gbpclient(request).show_nat_pool(
nat_pool_id).get('nat_pool')
return NATPool(np)
def delete_natpool(request, nat_pool_id, **kwargs):
gbpclient(request).delete_nat_pool(nat_pool_id)
def update_natpool(request, nat_pool_id, **kwargs):
body = {'nat_pool': kwargs}
np = gbpclient(request).update_nat_pool(
nat_pool_id, body).get('nat_pool')
return NATPool(np)
def create_externalconnectivity(request, **kwargs):
body = {'external_segment': kwargs}
es = gbpclient(request).create_external_segment(

View File

@ -268,3 +268,20 @@ def update_l3_policy_attributes(request, l3_policy):
tag = '-'
setattr(l3_policy, 'external_segments', tag)
return l3_policy
def update_nat_pool_attributes(request, nat_pool):
url = "horizon:project:network_policy:external_connectivity_details"
id = nat_pool.external_segment_id
value = ["<ul>"]
li = \
lambda x: "<li><a href='" + \
reverse(url, kwargs={'external_connectivity_id': x.id}) + \
"'>" + x.name + "</a>" + "</li>"
external_connectivity = client.get_externalconnectivity(request,
id)
value.append(li(external_connectivity))
value.append("</ul>")
tag = mark_safe("".join(value))
setattr(nat_pool, 'external_segment_id', tag)
return nat_pool

View File

@ -394,6 +394,112 @@ class UpdateServicePolicyForm(BaseUpdateForm):
exceptions.handle(request, msg, redirect=shortcuts.redirect)
class CreateNATPoolForm(forms.SelfHandlingForm):
name = forms.CharField(max_length=80, label=_("Name"))
description = forms.CharField(
max_length=80, label=_("Description"), required=False)
ip_version = forms.ChoiceField(choices=[(4, 'IPv4'), (6, 'IPv6')],
widget=forms.Select(attrs={
'class': 'switchable',
'data-slug': 'ipversion',
}),
label=_("IP Version"))
ip_pool = forms.IPField(label=_("CIDR"),
initial="", required=True,
help_text=_("Network address in CIDR format "
"(e.g. 192.168.0.0/24,"
"2001:DB8::/48)"),
version=forms.IPv4 | forms.IPv6, mask=True)
external_segment_id = forms.ChoiceField(label=_("External Segment"),
required=True)
shared = forms.BooleanField(label=_("Shared"),
initial=False, required=False)
def __init__(self, request, *args, **kwargs):
super(CreateNATPoolForm, self).__init__(request,
*args,
**kwargs)
ec_list = client.externalconnectivity_list(request,
tenant_id=request.user.tenant_id)
external_segments_options = [(ec.id, ec.name) for ec in ec_list]
self.fields['external_segment_id'].choices = external_segments_options
def handle(self, request, context):
url = reverse("horizon:project:network_policy:index")
try:
if context.get('name'):
context['name'] = html.escape(context['name'])
if context.get('description'):
context['description'] = html.escape(context['description'])
client.create_natpool(request, **context)
msg = _("NAT Pool created successfully!")
LOG.debug(msg)
messages.success(request, msg)
return http.HttpResponseRedirect(url)
except Exception as e:
msg = _("Failed to NAT Pool. %s") % (str(e))
LOG.error(msg)
exceptions.handle(request, msg, redirect=url)
class UpdateNATPoolForm(BaseUpdateForm):
name = forms.CharField(max_length=80, label=_("Name"))
description = forms.CharField(
max_length=80, label=_("Description"), required=False)
ip_version = forms.ChoiceField(choices=[(4, 'IPv4'), (6, 'IPv6')],
widget=forms.Select(attrs={
'class': 'switchable',
'data-slug': 'ipversion',
}),
label=_("IP Version"))
ip_pool = forms.IPField(label=_("CIDR"),
initial="", required=True,
help_text=_("Network address in CIDR format "
"(e.g. 192.168.0.0/24,"
"2001:DB8::/48)"),
version=forms.IPv4 | forms.IPv6, mask=True)
external_segment_id = forms.ChoiceField(label=_("External Segment"),
required=True)
shared = forms.BooleanField(label=_("Shared"),
initial=False, required=False)
def __init__(self, request, *args, **kwargs):
super(UpdateNATPoolForm, self).__init__(request,
*args,
**kwargs)
nat_pool_id = self.initial['nat_pool_id']
ec_list = client.externalconnectivity_list(request,
tenant_id=request.user.tenant_id)
external_segments_options = [(ec.id, ec.name) for ec in ec_list]
self.fields['external_segment_id'].choices = external_segments_options
nat_pool = client.get_natpool(request, nat_pool_id)
attributes = ['name', 'description',
'ip_version', 'ip_pool', 'external_segment_id']
for attr in attributes:
self.fields[attr].initial = str(nat_pool[attr])
self.fields['shared'].initial = nat_pool['shared']
def handle(self, request, context):
url = reverse("horizon:project:network_policy:index")
try:
if context.get('name'):
context['name'] = html.escape(context['name'])
if context.get('description'):
context['description'] = html.escape(context['description'])
nat_pool_id = self.initial['nat_pool_id']
client.update_natpool(
request, nat_pool_id, **context)
msg = _("NAT Pool updated successfully!")
LOG.debug(msg)
messages.success(request, msg)
return http.HttpResponseRedirect(url)
except Exception as e:
msg = _("Failed to update NAT Pool.%s") % \
(str(e))
LOG.error(msg)
exceptions.handle(request, msg, redirect=url)
class UpdateExternalConnectivityForm(forms.SelfHandlingForm):
name = forms.CharField(max_length=80, label=_("Name"))
description = forms.CharField(

View File

@ -186,3 +186,47 @@ class ExternalConnectivityTable(tables.DataTable):
DeleteExternalConnectivityLink,)
row_actions = (EditExternalConnectivityLink,
DeleteExternalConnectivityLink,)
class CreateNATPoolLink(tables.LinkAction):
name = "create_nat_pool"
verbose_name = _("Create NAT Pool")
url = "horizon:project:network_policy:create_nat_pool"
classes = ("ajax-modal", "btn-addnatpool")
class DeleteNATPoolLink(tables.DeleteAction):
name = "deletenatpool"
action_present = _("Delete")
action_past = _("Scheduled deletion of %(data_type)s")
data_type_singular = _("NAT Pool")
data_type_plural = _("NAT Pools")
class EditNATPoolLink(tables.LinkAction):
name = "update_nat_pool"
verbose_name = _("Edit")
classes = ("ajax-modal", "btn-update",)
def get_link_url(self, nat_pool):
urlstring = \
"horizon:project:network_policy:update_natpool"
base_url = reverse(urlstring,
kwargs={'nat_pool_id': nat_pool.id})
return base_url
class NATPoolTable(tables.DataTable):
name = tables.Column("name", verbose_name=_("Name"),
link="horizon:project:network_policy:nat_pool_details")
description = tables.Column("description", verbose_name=_("Description"))
ip_version = tables.Column("ip_version", verbose_name=_("IP Version"))
cidr = tables.Column("ip_pool", verbose_name=_("IP Pool"))
external_segment = tables.Column("external_segment_id",
verbose_name=_("External Segment"))
class Meta(object):
name = "nat_pool_table"
verbose_name = _("NAT Pool")
table_actions = (CreateNATPoolLink, DeleteNATPoolLink,)
row_actions = (EditNATPoolLink, DeleteNATPoolLink,)

View File

@ -152,6 +152,47 @@ class ExternalConnectivityDetailsTab(tabs.Tab):
return {'external_connectivity': external_connectivity}
class NATPoolTab(tabs.TableTab):
table_classes = (tables.NATPoolTable,)
name = _("NAT Pool")
slug = "nat_pool"
template_name = "horizon/common/_detail_table.html"
def get_nat_pool_table_data(self):
nat_pool_list = []
try:
nat_pools = \
client.natpool_list(self.request,
self.request.user.tenant_id)
update = lambda x: gfilters.update_nat_pool_attributes(
self.request, x)
nat_pool_list = [update(nat_pool) for nat_pool in nat_pools]
except Exception:
exceptions.handle(self.tab_group.request,
_('Unable to retrieve nat pool list.'))
return nat_pool_list
class NATPoolDetailsTab(tabs.Tab):
name = _("NAT Pool Details")
slug = "nat_pool_details"
template_name = \
"project/network_policy/_nat_pool_details.html"
failure_url = reverse_lazy('horizon:project:network_policy:index')
def get_context_data(self, request):
nat_pool_id = \
self.tab_group.kwargs['nat_pool_id']
try:
nat_pool = client.get_natpool(request,
nat_pool_id)
except Exception:
exceptions.handle(
request, _('Unable to retrieve nat pool details.'),
redirect=self.failure_url)
return {'nat_pool': nat_pool}
class ServicePolicyDetailsTabs(tabs.TabGroup):
slug = "service_policy_details_tab"
tabs = (ServicePolicyDetailsTab,)
@ -164,9 +205,15 @@ class ExternalConnectivityDetailsTabs(tabs.TabGroup):
sticky = True
class NATPoolDetailsTabs(tabs.TabGroup):
slug = "nat_pool_details_tab"
tabs = (NATPoolDetailsTab,)
sticky = True
class L3PolicyTabs(tabs.TabGroup):
slug = "l3policy_tab"
tabs = (L3PolicyTab, ServicePolicyTab, ExternalConnectivityTab,)
tabs = (L3PolicyTab, ServicePolicyTab, ExternalConnectivityTab, NATPoolTab)
sticky = True

View File

@ -0,0 +1,24 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load url from future %}
{% block form_id %}create_nat_pool{% endblock %}
{% block form_action %}{% url 'horizon:project:network_policy:create_nat_pool' %}{% endblock %}
{% block modal-header %}{% trans "Create NAT Pool" %}{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description:" %}</h3>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Create" %}" />
<a href="{% url 'horizon:project:network_policy:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -0,0 +1,28 @@
{% load i18n sizeformat parse_date %}
{% load url from future %}
<div class="info row detail">
<hr class="header_rule">
<dl>
<dt>{% trans "Name" %}</dt>
<dd>{{ nat_pool.name|default:_("-") }}</dd>
<dt>{% trans "Description" %}</dt>
<dd>{{ nat_pool.description|default:_("-") }}</dd>
<dt>{% trans "ID" %}</dt>
<dd>{{ nat_pool.id }} </dd>
<dt>{% trans "IP Version" %}</dt>
<dd>{{ nat_pool.ip_version }} </dd>
<dt>{% trans "IP Pool" %}</dt>
<dd>{{ nat_pool.ip_pool }} </dd>
<dt>{% trans "External Segment ID" %}</dt>
<dd>{{ nat_pool.external_segment_id }} </dd>
<dt>{% trans "Shared" %}</dt>
<dd>{{ nat_pool.shared }} </dd>
</dl>
</div>

View File

@ -0,0 +1,25 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load url from future %}
{% block form_id %}update_nat_pool_form{% endblock %}
{% block form_action %}{% url 'horizon:project:network_policy:update_natpool' nat_pool_id %}{% endblock %}
{% block modal-header %}{% trans "Update NAT Pool" %}{% 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 "Update NAT Pool." %}</p>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Update" %}" />
<a href="{% url 'horizon:project:network_policy:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -36,6 +36,9 @@ urlpatterns = patterns('',
url(r'^createexternalconnectivity$',
views.CreateExternalConnectivityView.as_view(),
name='create_external_connectivity'),
url(r'^createnatpool$',
views.CreateNATPoolView.as_view(),
name='create_nat_pool'),
url(r'^update_servicepolicy/(?P<service_policy_id>[^/]+)/$',
views.UpdateServicePolicyView.as_view(),
name='update_service_policy'),
@ -43,6 +46,14 @@ urlpatterns = patterns('',
'(?P<external_connectivity_id>[^/]+)/$',
views.UpdateExternalConnectivityView.as_view(),
name='update_externalconnectivity'),
url(r'^update_natpool/'
'(?P<nat_pool_id>[^/]+)/$',
views.UpdateNATPoolView.as_view(),
name='update_natpool'),
url(r'^natpool/'
'(?P<nat_pool_id>[^/]+)/$',
views.NATPoolDetailsView.as_view(),
name='nat_pool_details'),
url(r'^servicepolicy/(?P<service_policy_id>[^/]+)/$',
views.ServicePolicyDetailsView.as_view(),
name='service_policy_details'),

View File

@ -65,6 +65,15 @@ class IndexView(tabs.TabView):
except Exception as e:
msg = _('Unable to delete action. %s') % (str(e))
exceptions.handle(request, msg)
if obj_type == 'natpool':
for obj_id in obj_ids:
try:
client.delete_natpool(request, obj_id)
messages.success(request,
_('Deleted NAT Pool %s') % obj_id)
except Exception as e:
msg = _('Unable to delete action. %s') % (str(e))
exceptions.handle(request, msg)
return self.get(request, *args, **kwargs)
@ -196,6 +205,20 @@ class AddExternalRouteParamView(forms.ModalFormView):
return params.name
class UpdateNATPoolView(forms.ModalFormView):
form_class = np_forms.UpdateNATPoolForm
template_name = "project/network_policy/update_nat_pool.html"
def get_context_data(self, **kwargs):
context = super(
UpdateNATPoolView, self).get_context_data(**kwargs)
context['nat_pool_id'] = self.kwargs['nat_pool_id']
return context
def get_initial(self):
return self.kwargs
class UpdateExternalConnectivityView(forms.ModalFormView):
form_class = np_forms.UpdateExternalConnectivityForm
template_name = "project/network_policy/update_external_connectivity.html"
@ -249,3 +272,18 @@ class CreateExternalConnectivityView(forms.ModalFormView):
class ExternalConnectivityDetailsView(tabs.TabView):
tab_group_class = (np_tabs.ExternalConnectivityDetailsTabs)
template_name = 'project/network_policy/details_tabs.html'
class CreateNATPoolView(forms.ModalFormView):
form_class = np_forms.CreateNATPoolForm
template_name = "project/network_policy/create_nat_pool.html"
def get_context_data(self, **kwargs):
context = super(
CreateNATPoolView, self).get_context_data(**kwargs)
return context
class NATPoolDetailsView(tabs.TabView):
tab_group_class = (np_tabs.NATPoolDetailsTabs)
template_name = 'project/network_policy/details_tabs.html'