diff --git a/gbpui/client.py b/gbpui/client.py
index e064c91..835b13c 100644
--- a/gbpui/client.py
+++ b/gbpui/client.py
@@ -58,6 +58,26 @@ class PTG(neutron.NeutronAPIDictWrapper):
return epg_dict
+class ExternalPTG(neutron.NeutronAPIDictWrapper):
+
+ """Wrapper for neutron external endpoint group."""
+
+ def get_dict(self):
+ eepg_dict = self._apidict
+ eepg_dict['eepg_id'] = eepg_dict['id']
+ return eepg_dict
+
+
+class ExternalConnectivity(neutron.NeutronAPIDictWrapper):
+
+ """Wrapper for neutron external segment."""
+
+ def get_dict(self):
+ ec_dict = self._apidict
+ ec_dict['ec_id'] = ec_dict['id']
+ return ec_dict
+
+
class Contract(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron policy_rule_set."""
@@ -204,6 +224,38 @@ def policy_target_update(request, policy_target_id, **kwargs):
return PTG(policy_target)
+def ext_policy_target_create(request, **kwargs):
+ body = {'external_policy': kwargs}
+ policy_target = gbpclient(request).create_external_policy(
+ body).get('endpoint_group')
+ return ExternalPTG(policy_target)
+
+
+def ext_policy_target_list(request, tenant_id, **kwargs):
+ policy_targets = gbpclient(request).list_external_policies(
+ tenant_id=tenant_id, shared=False, **kwargs).get('external_policies')
+ policy_targets.extend(gbpclient(request).list_external_policies(
+ shared=True, **kwargs).get('external_policies'))
+ return [ExternalPTG(policy_target) for policy_target in policy_targets]
+
+
+def ext_policy_target_get(request, ext_policy_target_id):
+ policy_target = gbpclient(request).show_external_policy(
+ ext_policy_target_id).get('external_policy')
+ return ExternalPTG(policy_target)
+
+
+def ext_policy_target_delete(request, ext_policy_target_id):
+ gbpclient(request).delete_external_policy(ext_policy_target_id)
+
+
+def ext_policy_target_update(request, ext_policy_target_id, **kwargs):
+ body = {'external_policy': kwargs}
+ policy_target = gbpclient(request).update_external_policy(
+ ext_policy_target_id, body).get('external_policy')
+ return ExternalPTG(policy_target)
+
+
def policy_rule_set_create(request, **kwargs):
body = {'policy_rule_set': kwargs}
policy_rule_set = gbpclient(request).create_policy_rule_set(
@@ -357,6 +409,39 @@ def networkservicepolicy_list(request, tenant_id, **kwargs):
return [NetworkServicePolicy(item) for item in policies]
+def externalconnectivity_list(request, tenant_id, **kwargs):
+ external_connectivities = gbpclient(request).list_external_segments(
+ tenant_id=tenant_id, shared=False, **kwargs).get('external_segments')
+ external_connectivities.extend(gbpclient(request).list_external_segments(
+ shared=True, **kwargs).get('external_segments'))
+ return [ExternalConnectivity(external_connectivity)
+ for external_connectivity in external_connectivities]
+
+
+def create_externalconnectivity(request, **kwargs):
+ body = {'external_segment': kwargs}
+ es = gbpclient(request).create_external_segment(
+ body).get('external_segment')
+ return ExternalConnectivity(es)
+
+
+def get_externalconnectivity(request, external_connectivity_id):
+ es = gbpclient(request).show_external_segment(
+ external_connectivity_id).get('external_segment')
+ return ExternalConnectivity(es)
+
+
+def delete_externalconnectivity(request, external_connectivity_id, **kwargs):
+ gbpclient(request).delete_external_segment(external_connectivity_id)
+
+
+def update_externalconnectivity(request, external_connectivity_id, **kwargs):
+ body = {'external_segment': kwargs}
+ ec = gbpclient(request).update_external_segment(
+ external_connectivity_id, body).get('external_segment')
+ return NetworkServicePolicy(ec)
+
+
def create_networkservice_policy(request, **kwargs):
body = {'network_service_policy': kwargs}
spolicy = gbpclient(request).create_network_service_policy(
diff --git a/gbpui/column_filters.py b/gbpui/column_filters.py
index 2765c96..b02c8f8 100644
--- a/gbpui/column_filters.py
+++ b/gbpui/column_filters.py
@@ -82,12 +82,20 @@ def update_policy_target_attributes(request, pt):
setattr(pt, 'provided_policy_rule_sets', mark_safe(p))
setattr(pt, 'consumed_policy_rule_sets', mark_safe(c))
l2url = "horizon:project:network_policy:l2policy_details"
- if pt.l2_policy_id is not None:
+ if hasattr(pt, 'l2_policy_id') and pt.l2_policy_id is not None:
policy = client.l2policy_get(request, pt.l2_policy_id)
u = reverse(l2url, kwargs={'l2policy_id': policy.id})
atag = mark_safe(
"" + policy.name + "")
setattr(pt, 'l2_policy_id', atag)
+ if hasattr(pt, 'external_segments'):
+ exturl = "horizon:project:network_policy:external_connectivity_details"
+ ext_policy = client.get_externalconnectivity(request,
+ pt.external_segments[0])
+ u = reverse(exturl, kwargs={'external_connectivity_id': ext_policy.id})
+ exttag = mark_safe(
+ "" + ext_policy.name + "")
+ setattr(pt, 'external_segments', exttag)
return pt
@@ -234,3 +242,23 @@ def update_classifier_attributes(classifiers):
in port_protocol_map:
classifiers.protocol = port_protocol_map[classifiers.port_range]
return classifiers
+
+
+def update_l3_policy_attributes(request, l3_policy):
+ url = "horizon:project:network_policy:external_connectivity_details"
+ if bool(l3_policy.external_segments):
+ external_connectivity_id = l3_policy.external_segments.keys()[0]
+ try:
+ external_connectivity = client.get_externalconnectivity(request,
+ external_connectivity_id)
+ segment_name = external_connectivity.name
+ except Exception:
+ segment_name = external_connectivity_id
+ u = reverse(url,
+ kwargs={'external_connectivity_id': external_connectivity_id})
+ tag = mark_safe("" + segment_name + ""
+ + " : " + l3_policy.external_segments.values()[0][0])
+ else:
+ tag = '-'
+ setattr(l3_policy, 'external_segments', tag)
+ return l3_policy
diff --git a/gbpui/panels/network_policy/forms.py b/gbpui/panels/network_policy/forms.py
index ce2f9f6..43abce6 100644
--- a/gbpui/panels/network_policy/forms.py
+++ b/gbpui/panels/network_policy/forms.py
@@ -21,6 +21,7 @@ from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import messages
+from openstack_dashboard import api
from gbpui import client
from gbpui import fields
@@ -28,6 +29,7 @@ from gbpui import fields
LOG = logging.getLogger(__name__)
NETWORK_PARAM_URL = "horizon:project:network_policy:add_network_service_param"
+ROUTE_URL = "horizon:project:network_policy:add_external_route_param"
class BaseUpdateForm(forms.SelfHandlingForm):
@@ -60,11 +62,21 @@ class AddL3PolicyForm(forms.SelfHandlingForm):
label=_("Subnet Prefix Length"),
help_text=_("Between 2 - 30 for IP4"
"and 2-127 for IP6."),)
+ external_segments = forms.ChoiceField(label=_("External Segment"),
+ required=False)
+ segment_ip = forms.IPField(label=_("External Segment IP"), initial="",
+ required=False)
shared = forms.BooleanField(label=_("Shared"),
- initial=False, required=False)
+ initial=False,
+ required=False)
def __init__(self, request, *args, **kwargs):
super(AddL3PolicyForm, 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]
+ external_segments_options.insert(0, (None, "Select"))
+ self.fields['external_segments'].choices = external_segments_options
def clean(self):
cleaned_data = super(AddL3PolicyForm, self).clean()
@@ -76,11 +88,23 @@ class AddL3PolicyForm(forms.SelfHandlingForm):
raise forms.ValidationError(msg)
if ipversion == 6 and subnet_prefix_length not in range(2, 128):
raise forms.ValidationError(msg)
+ if cleaned_data['external_segments'] != '':
+ if cleaned_data['segment_ip'] == '':
+ self.add_error('segment_ip', 'This field is required')
return cleaned_data
def handle(self, request, context):
url = reverse("horizon:project:network_policy:index")
+ external_segment_dic = {}
+ l = []
try:
+ if context['external_segments'] != '':
+ l.append(context['segment_ip'])
+ external_segment_dic[context['external_segments']] = l
+ context['external_segments'] = external_segment_dic
+ else:
+ del context['external_segments']
+ del context['segment_ip']
if context.get('name'):
context['name'] = html.escape(context['name'])
if context.get('description'):
@@ -97,18 +121,34 @@ class UpdateL3PolicyForm(AddL3PolicyForm):
def __init__(self, request, *args, **kwargs):
super(UpdateL3PolicyForm, self).__init__(request, *args, **kwargs)
try:
+ ec_list = client.externalconnectivity_list(request,
+ tenant_id=request.user.tenant_id)
+ external_segments_options = [(ec.id, ec.name) for ec in ec_list]
+ external_segments_options.insert(0, (None, "Select"))
+ self.fields['external_segments'].choices = \
+ external_segments_options
l3policy_id = self.initial['l3policy_id']
l3 = client.l3policy_get(request, l3policy_id)
for item in ['name', 'description', 'ip_version',
'ip_pool', 'subnet_prefix_length']:
self.fields[item].initial = str(l3[item])
self.fields['shared'].initial = l3['shared']
+ if bool(l3['external_segments']):
+ self.fields['external_segments'].initial = \
+ l3['external_segments'].keys()[0]
+ self.fields['segment_ip'].initial = \
+ l3['external_segments'].values()[0][0]
+ else:
+ self.fields['external_segments'].initial = None
+ self.fields['segment_ip'].initial = ''
except Exception:
msg = _("Failed to get L3 policy")
LOG.error(msg)
exceptions.handle(request, msg, redirect=shortcuts.redirect)
def clean(self):
+ external_segment_dict = {}
+ l = []
cleaned_data = super(UpdateL3PolicyForm, self).clean()
if self.is_valid():
ipversion = int(cleaned_data['ip_version'])
@@ -118,6 +158,20 @@ class UpdateL3PolicyForm(AddL3PolicyForm):
raise forms.ValidationError(msg)
if ipversion == 6 and subnet_prefix_length not in range(2, 128):
raise forms.ValidationError(msg)
+ if cleaned_data['external_segments'] != '':
+ if cleaned_data['segment_ip'] == '':
+ self.add_error('segment_ip', 'This field is required')
+ if 'external_segments' in self.changed_data or \
+ 'segment_ip' in self.changed_data:
+ if cleaned_data['external_segments'] != '':
+ l.append(cleaned_data['segment_ip'])
+ external_segment_dict[cleaned_data['external_segments']] = \
+ l
+ cleaned_data['external_segments'] = external_segment_dict
+ else:
+ cleaned_data['external_segments'] = {}
+ del cleaned_data['segment_ip']
+ self.changed_data.append('external_segments')
updated_data = {d: cleaned_data[d] for d in cleaned_data
if d in self.changed_data}
cleaned_data = updated_data
@@ -324,3 +378,129 @@ class UpdateServicePolicyForm(BaseUpdateForm):
msg = _("Failed to update service policy")
LOG.error(msg)
exceptions.handle(request, msg, redirect=shortcuts.redirect)
+
+
+class UpdateExternalConnectivityForm(forms.SelfHandlingForm):
+ name = forms.CharField(max_length=80, label=_("Name"))
+ description = forms.CharField(
+ max_length=80, label=_("Description"), required=False)
+ shared = forms.BooleanField(label=_("Shared"), required=False)
+
+ def __init__(self, request, *args, **kwargs):
+ super(UpdateExternalConnectivityForm, self).__init__(request,
+ *args, **kwargs)
+ try:
+ external_connectivity_id = \
+ self.initial['external_connectivity_id']
+ external_connectivity = client.get_externalconnectivity(request,
+ external_connectivity_id)
+ self.fields['name'].initial = external_connectivity.name
+ self.fields['description'].initial = \
+ external_connectivity.description
+ self.fields['shared'].initial = external_connectivity.shared
+ except Exception as e:
+ msg = _("Failed to retrive external connectivity details. %s") % \
+ (str(e))
+ LOG.debug(msg)
+
+ def handle(self, request, context):
+ url = reverse("horizon:project:network_policy:index")
+ try:
+ external_connectivity_id = self.initial['external_connectivity_id']
+ client.update_externalconnectivity(
+ request, external_connectivity_id, **context)
+ msg = _("External Connectivity updated successfully!")
+ LOG.debug(msg)
+ return http.HttpResponseRedirect(url)
+ except Exception:
+ msg = _("Failed to update External Connectivity")
+ LOG.error(msg)
+ exceptions.handle(request, msg, redirect=shortcuts.redirect)
+
+
+class CreateExternalConnectivityForm(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"))
+ cidr = forms.IPField(label=_("CIDR"),
+ initial="",
+ 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_routes = fields.CustomMultiChoiceField(
+ label=_("External Routes"), add_item_link=ROUTE_URL,
+ required=False)
+ subnet_id = forms.ChoiceField(label=_("Subnet ID"), required=False)
+ port_address_translation = forms.BooleanField(
+ label=_("Port Address Translation"),
+ initial=False, required=False)
+ shared = forms.BooleanField(label=_("Shared"),
+ initial=False, required=False)
+
+ def __init__(self, request, *args, **kwargs):
+ super(CreateExternalConnectivityForm, self).__init__(request,
+ *args, **kwargs)
+ net_id_list = []
+ dic = {"router:external": True}
+ try:
+ net_list = api.neutron.network_list(request, **dic)
+ subnet_list = api.neutron.subnet_list(request)
+ net_id_list = [net.id for net in net_list]
+ self.fields['subnet_id'].choices = [(subnet.id, subnet.name)
+ for subnet in subnet_list if subnet.network_id in net_id_list]
+ except Exception:
+ msg = _("Failed to get Subnet ID list.")
+ exceptions.handle(request, msg)
+
+ def handle(self, request, context):
+ url = reverse("horizon:project:network_policy:index")
+ try:
+ routes = context['external_routes']
+ p = []
+ if len(routes) > 0:
+ for item in routes:
+ values = [i.split(":")[1] for i in item.split(",")]
+ values = {'destination': values[0],
+ 'nexthop': values[1]}
+ p.append(values)
+ context['external_routes'] = p
+ client.create_externalconnectivity(
+ request, **context)
+ msg = _("External Connectivity updatedsuccessfully!")
+ LOG.debug(msg)
+ return http.HttpResponseRedirect(url)
+ except Exception as e:
+ msg = str(e)
+ LOG.error(msg)
+ exceptions.handle(request, msg, redirect=shortcuts.redirect)
+
+
+class ExternalRouteParam(object):
+
+ def __init__(self, context):
+ self.destination = context['destination']
+ self.next_hop = context['next_hop']
+ self.name = 'destination:%s,next_hop:%s' % (
+ self.destination, self.next_hop)
+ self.id = self.name
+
+
+class CreateExternalRouteParamForm(forms.SelfHandlingForm):
+ destination = forms.IPField(label=_("Destination"),
+ initial="",
+ help_text=_(
+ "(e.g. 192.168.0.0/24,"
+ "2001:DB8::/48)"),
+ version=forms.IPv4 | forms.IPv6,
+ mask=True)
+ next_hop = forms.IPField(label=_("Next hop"))
+
+ def handle(self, request, context):
+ return ExternalRouteParam(context)
diff --git a/gbpui/panels/network_policy/tables.py b/gbpui/panels/network_policy/tables.py
index a7699a2..e9de49e 100644
--- a/gbpui/panels/network_policy/tables.py
+++ b/gbpui/panels/network_policy/tables.py
@@ -94,6 +94,8 @@ class L3PolicyTable(tables.DataTable):
ip_pool = tables.Column("ip_pool", verbose_name=_("IP Pool"))
subnet_prefix_length = tables.Column(
"subnet_prefix_length", verbose_name=_("Subnet Prefix Length"))
+ external_segments = tables.Column("external_segments",
+ verbose_name=_("External Segment"))
class Meta(object):
name = "l3policy_table"
@@ -140,3 +142,47 @@ class ServicePolicyTable(tables.DataTable):
verbose_name = _("Service Policies")
table_actions = (CreateServicePolicyLink, DeleteServicePolicyLink,)
row_actions = (EditServicePolicyLink, DeleteServicePolicyLink,)
+
+
+class CreateExternalConnectivityLink(tables.LinkAction):
+ name = "create_external_connectivity"
+ verbose_name = _("Create External Connectivity")
+ url = "horizon:project:network_policy:create_external_connectivity"
+ classes = ("ajax-modal", "btn-addexternalconnectivity")
+
+
+class EditExternalConnectivityLink(tables.LinkAction):
+ name = "update_external_connectivity"
+ verbose_name = _("Edit")
+ classes = ("ajax-modal", "btn-update",)
+
+ def get_link_url(self, external_connectivity):
+ urlstring = \
+ "horizon:project:network_policy:update_externalconnectivity"
+ base_url = reverse(urlstring,
+ kwargs={'external_connectivity_id': external_connectivity.id})
+ return base_url
+
+
+class DeleteExternalConnectivityLink(tables.DeleteAction):
+ name = "deleteexternalconnectivity"
+ action_present = _("Delete")
+ action_past = _("Scheduled deletion of %(data_type)s")
+ data_type_singular = _("ExternalConnectivity")
+ data_type_plural = _("ExternalConnectivities")
+
+
+class ExternalConnectivityTable(tables.DataTable):
+ name = tables.Column("name", verbose_name=_("Name"),
+ link="horizon:project:network_policy:external_connectivity_details")
+ description = tables.Column("description", verbose_name=_("Description"))
+ ip_version = tables.Column("ip_version", verbose_name=_("IP Version"))
+ cidr = tables.Column("cidr", verbose_name=_("CIDR"))
+
+ class Meta(object):
+ name = "external_connectivity_table"
+ verbose_name = _("External Connectivity")
+ table_actions = (CreateExternalConnectivityLink,
+ DeleteExternalConnectivityLink,)
+ row_actions = (EditExternalConnectivityLink,
+ DeleteExternalConnectivityLink,)
diff --git a/gbpui/panels/network_policy/tabs.py b/gbpui/panels/network_policy/tabs.py
index 3ee67c0..3db81d7 100644
--- a/gbpui/panels/network_policy/tabs.py
+++ b/gbpui/panels/network_policy/tabs.py
@@ -50,6 +50,9 @@ class L3PolicyTab(tabs.TableTab):
try:
policies = client.l3policy_list(self.request,
tenant_id=self.request.user.tenant_id)
+ update = lambda x: gfilters.update_l3_policy_attributes(
+ self.request, x)
+ policies = [update(item) for item in policies]
except Exception:
policies = []
exceptions.handle(self.tab_group.request,
@@ -111,15 +114,59 @@ class ServicePolicyDetailsTab(tabs.Tab):
return {'policy': policy}
+class ExternalConnectivityTab(tabs.TableTab):
+ table_classes = (tables.ExternalConnectivityTable,)
+ name = _("External Connectivity")
+ slug = "external_connectivity"
+ template_name = "horizon/common/_detail_table.html"
+
+ def get_external_connectivity_table_data(self):
+ external_segment_list = []
+ try:
+ external_segment_list = \
+ client.externalconnectivity_list(self.request,
+ self.request.user.tenant_id)
+ except Exception:
+ exceptions.handle(self.tab_group.request,
+ _('Unable to retrieve network service policy list.'))
+ return external_segment_list
+
+
+class ExternalConnectivityDetailsTab(tabs.Tab):
+ name = _("External Connectivity Details")
+ slug = "external_connectivity_details"
+ template_name = \
+ "project/network_policy/_external_connectivity_details.html"
+ failure_url = reverse_lazy('horizon:project:network_policy:index')
+
+ def get_context_data(self, request):
+ external_connectivity_id = \
+ self.tab_group.kwargs['external_connectivity_id']
+ try:
+ external_connectivity = client.get_externalconnectivity(request,
+ external_connectivity_id)
+ except Exception:
+ exceptions.handle(
+ request, _('Unable to retrieve service policy details.'),
+ redirect=self.failure_url)
+ return {'external_connectivity': external_connectivity}
+
+
class ServicePolicyDetailsTabs(tabs.TabGroup):
slug = "service_policy_details_tab"
tabs = (ServicePolicyDetailsTab,)
sticky = True
+class ExternalConnectivityDetailsTabs(tabs.TabGroup):
+ slug = "external_connectivity_details_tab"
+ tabs = (ExternalConnectivityDetailsTab,)
+ sticky = True
+
+
class L3PolicyTabs(tabs.TabGroup):
slug = "l3policy_tab"
- tabs = (L3PolicyTab, ServicePolicyTab,)
+ tabs = (L3PolicyTab, ServicePolicyTab, ExternalConnectivityTab,)
sticky = True
diff --git a/gbpui/panels/network_policy/templates/network_policy/_add_l3policy.html b/gbpui/panels/network_policy/templates/network_policy/_add_l3policy.html
index 8f4aea0..7a08de4 100644
--- a/gbpui/panels/network_policy/templates/network_policy/_add_l3policy.html
+++ b/gbpui/panels/network_policy/templates/network_policy/_add_l3policy.html
@@ -19,6 +19,26 @@
{% endblock %}
+
+{% block modal-js %}
+
+{% endblock %}
+
+
+
{% block modal-footer %}
{% trans "Cancel" %}
diff --git a/gbpui/panels/network_policy/templates/network_policy/_create_external_connectivity.html b/gbpui/panels/network_policy/templates/network_policy/_create_external_connectivity.html
new file mode 100644
index 0000000..f36e8d7
--- /dev/null
+++ b/gbpui/panels/network_policy/templates/network_policy/_create_external_connectivity.html
@@ -0,0 +1,24 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}create_external_connectivity{% endblock %}
+{% block form_action %}{% url 'horizon:project:network_policy:create_external_connectivity' %}{% endblock %}
+
+{% block modal-header %}{% trans "Create External Connectivity" %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/gbpui/panels/network_policy/templates/network_policy/_create_external_route_param.html b/gbpui/panels/network_policy/templates/network_policy/_create_external_route_param.html
new file mode 100644
index 0000000..5704638
--- /dev/null
+++ b/gbpui/panels/network_policy/templates/network_policy/_create_external_route_param.html
@@ -0,0 +1,24 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}add_external_route_param_form{% endblock %}
+{% block form_action %}{% url 'horizon:project:network_policy:add_external_route_param' %}{% endblock %}
+
+{% block modal-header %}{% trans "Add External Route Parameter" %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/gbpui/panels/network_policy/templates/network_policy/_external_connectivity_details.html b/gbpui/panels/network_policy/templates/network_policy/_external_connectivity_details.html
new file mode 100644
index 0000000..f648e3f
--- /dev/null
+++ b/gbpui/panels/network_policy/templates/network_policy/_external_connectivity_details.html
@@ -0,0 +1,32 @@
+{% load i18n sizeformat parse_date %}
+{% load url from future %}
+
+
+
+
+ - {% trans "Name" %}
+ - {{ external_connectivity.name|default:_("-") }}
+
+ - {% trans "Description" %}
+ - {{ external_connectivity.description|default:_("-") }}
+
+ - {% trans "ID" %}
+ - {{ external_connectivity.id }}
+
+ - {% trans "Ip Version" %}
+ - {{ external_connectivity.ip_version }}
+
+ - {% trans "CIDR" %}
+ - {{ external_connectivity.cidr }}
+
+ - {% trans "External Routes" %}
+ - {{ external_connectivity.external_routes|default:_("-") }}
+
+
+ - {% trans "Port Address Translation" %}
+ - {{ external_connectivity.port_address_translation }}
+
+ - {% trans "Shared" %}
+ - {{ external_connectivity.shared }}
+
+
diff --git a/gbpui/panels/network_policy/templates/network_policy/_update_external_connectivity.html b/gbpui/panels/network_policy/templates/network_policy/_update_external_connectivity.html
new file mode 100644
index 0000000..cca6285
--- /dev/null
+++ b/gbpui/panels/network_policy/templates/network_policy/_update_external_connectivity.html
@@ -0,0 +1,25 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}update_external_connectivity_form{% endblock %}
+{% block form_action %}{% url 'horizon:project:network_policy:update_externalconnectivity' external_connectivity_id %}{% endblock %}
+
+{% block modal-header %}{% trans "Update External Connectivity" %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
{% trans "Update Service Policy." %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/gbpui/panels/network_policy/templates/network_policy/_update_l3policy.html b/gbpui/panels/network_policy/templates/network_policy/_update_l3policy.html
index 5a1297a..927464c 100644
--- a/gbpui/panels/network_policy/templates/network_policy/_update_l3policy.html
+++ b/gbpui/panels/network_policy/templates/network_policy/_update_l3policy.html
@@ -19,6 +19,25 @@
{% endblock %}
+
+{% block modal-js %}
+
+{% endblock %}
+
+
{% block modal-footer %}
{% trans "Cancel" %}
diff --git a/gbpui/panels/network_policy/urls.py b/gbpui/panels/network_policy/urls.py
index e1233a8..1e32b8e 100644
--- a/gbpui/panels/network_policy/urls.py
+++ b/gbpui/panels/network_policy/urls.py
@@ -21,18 +21,32 @@ urlpatterns = patterns('',
url(r'^addl3policy$',
views.AddL3policyView.as_view(),
name='addl3policy'),
- url(r'^addserviceolicy$',
+ url(r'^addservicepolicy$',
views.CreateServicePolicyView.as_view(),
name='create_servicepolicy'),
url(r'^addnetworkserviceparam$',
views.AddNetworkServiceParamView.as_view(),
name='add_network_service_param'),
+ url(r'^addexternalrouteparam$',
+ views.AddExternalRouteParamView.as_view(),
+ name='add_external_route_param'),
+ url(r'^createexternalconnectivity$',
+ views.CreateExternalConnectivityView.as_view(),
+ name='create_external_connectivity'),
url(r'^update_servicepolicy/(?P[^/]+)/$',
views.UpdateServicePolicyView.as_view(),
name='update_service_policy'),
+ url(r'^update_externalconnectivity/'
+ '(?P[^/]+)/$',
+ views.UpdateExternalConnectivityView.as_view(),
+ name='update_externalconnectivity'),
url(r'^servicepolicy/(?P[^/]+)/$',
views.ServicePolicyDetailsView.as_view(),
name='service_policy_details'),
+ url(r'^externalconnectivity/'
+ '(?P[^/]+)/$',
+ views.ExternalConnectivityDetailsView.as_view(),
+ name='external_connectivity_details'),
url(r'^addl2policy$',
views.AddL2policyView.as_view(),
name='addl2policy'),
diff --git a/gbpui/panels/network_policy/views.py b/gbpui/panels/network_policy/views.py
index edcf707..b246e4e 100644
--- a/gbpui/panels/network_policy/views.py
+++ b/gbpui/panels/network_policy/views.py
@@ -55,6 +55,15 @@ class IndexView(tabs.TabView):
except Exception as e:
msg = _('Unable to delete action. %s') % (str(e))
exceptions.handle(request, msg)
+ if obj_type == 'externalconnectivity':
+ for obj_id in obj_ids:
+ try:
+ client.delete_externalconnectivity(request, obj_id)
+ messages.success(request,
+ _('Deleted External Connectivity %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)
@@ -170,6 +179,29 @@ class AddNetworkServiceParamView(forms.ModalFormView):
return params.name
+class AddExternalRouteParamView(forms.ModalFormView):
+ form_class = np_forms.CreateExternalRouteParamForm
+ template_name = "project/network_policy/create_external_route_param.html"
+
+ def get_object_id(self, params):
+ return params.name
+
+
+class UpdateExternalConnectivityView(forms.ModalFormView):
+ form_class = np_forms.UpdateExternalConnectivityForm
+ template_name = "project/network_policy/update_external_connectivity.html"
+
+ def get_context_data(self, **kwargs):
+ context = super(
+ UpdateExternalConnectivityView, self).get_context_data(**kwargs)
+ context['external_connectivity_id'] = \
+ self.kwargs['external_connectivity_id']
+ return context
+
+ def get_initial(self):
+ return self.kwargs
+
+
class UpdateServicePolicyView(forms.ModalFormView):
form_class = np_forms.UpdateServicePolicyForm
template_name = "project/network_policy/update_service_policy.html"
@@ -187,3 +219,18 @@ class UpdateServicePolicyView(forms.ModalFormView):
class ServicePolicyDetailsView(tabs.TabView):
tab_group_class = (np_tabs.ServicePolicyDetailsTabs)
template_name = 'project/network_policy/details_tabs.html'
+
+
+class CreateExternalConnectivityView(forms.ModalFormView):
+ form_class = np_forms.CreateExternalConnectivityForm
+ template_name = "project/network_policy/create_external_connectivity.html"
+
+ def get_context_data(self, **kwargs):
+ context = super(
+ CreateExternalConnectivityView, self).get_context_data(**kwargs)
+ return context
+
+
+class ExternalConnectivityDetailsView(tabs.TabView):
+ tab_group_class = (np_tabs.ExternalConnectivityDetailsTabs)
+ template_name = 'project/network_policy/details_tabs.html'
diff --git a/gbpui/panels/policytargets/forms.py b/gbpui/panels/policytargets/forms.py
index 3937218..bfa904c 100644
--- a/gbpui/panels/policytargets/forms.py
+++ b/gbpui/panels/policytargets/forms.py
@@ -134,6 +134,103 @@ class UpdatePolicyTargetForm(forms.SelfHandlingForm):
exceptions.handle(request, msg, redirect=redirect)
+class UpdateExternalPolicyTargetForm(forms.SelfHandlingForm):
+ name = forms.CharField(max_length=80,
+ label=_("Name"), required=False)
+ description = forms.CharField(max_length=80,
+ label=_("Description"), required=False)
+ provided_policy_rule_sets = forms.MultipleChoiceField(
+ label=_("Provided Policy Rule Set"), required=False)
+ consumed_policy_rule_sets = forms.MultipleChoiceField(
+ label=_("Consumed Policy Rule Set"), required=False)
+ external_segments = forms.ChoiceField(
+ label=_("External Connectivity"),
+ help_text=_("Select external segment for Group."))
+ shared = forms.BooleanField(label=_("Shared"), required=False)
+ failure_url = 'horizon:project:policytargets:index'
+
+ def __init__(self, request, *args, **kwargs):
+ super(UpdateExternalPolicyTargetForm, self).__init__(request,
+ *args, **kwargs)
+ try:
+ ext_policy_target_id = self.initial['ext_policy_target_id']
+ ext_policy_target = client.ext_policy_target_get(request,
+ ext_policy_target_id)
+ policy_rule_sets = client.policy_rule_set_list(
+ request, tenant_id=request.user.tenant_id)
+ external_connectivities = client.externalconnectivity_list(
+ request, tenant_id=request.user.tenant_id)
+ for c in policy_rule_sets:
+ c.set_id_as_name_if_empty()
+ ext_conn_list = [(e.id, e.name)for e in external_connectivities]
+ policy_rule_sets = sorted(
+ policy_rule_sets, key=lambda rule: rule.name)
+ policy_rule_set_list = [(c.id, c.name) for c in policy_rule_sets]
+ self.fields[
+ 'provided_policy_rule_sets'].choices = policy_rule_set_list
+ self.fields[
+ 'consumed_policy_rule_sets'].choices = policy_rule_set_list
+ self.fields[
+ 'external_segments'].choices = ext_conn_list
+ provided_init = []
+ consumed_init = []
+ for item in policy_rule_set_list:
+ if item[0] in ext_policy_target.provided_policy_rule_sets:
+ provided_init.append(item[0])
+ if item[0] in ext_policy_target.consumed_policy_rule_sets:
+ consumed_init.append(item[0])
+ self.fields['provided_policy_rule_sets'].initial = provided_init
+ self.fields['consumed_policy_rule_sets'].initial = consumed_init
+ for attr in ['name', 'description', 'shared']:
+ self.fields[attr].initial = getattr(ext_policy_target, attr)
+ self.fields['external_segments'].initial = \
+ ext_policy_target.external_segments[0]
+ except Exception as e:
+ msg = _('Unable to retrieve policy_rule_set details. %s') % (
+ str(e))
+ exceptions.handle(request, msg)
+ pass
+
+ def clean(self):
+ cleaned_data = super(UpdateExternalPolicyTargetForm, self).clean()
+ updated_data = {d: cleaned_data[d] for d in cleaned_data
+ if d in self.changed_data}
+ return updated_data
+
+ def handle(self, request, context):
+ ext_policy_target_id = self.initial['ext_policy_target_id']
+ name_or_id = context.get('name') or ext_policy_target_id
+ external_segment_list = []
+ try:
+ if context.get('provided_policy_rule_sets'):
+ context['provided_policy_rule_sets'] = dict(
+ [(i, 'string')
+ for i in context['provided_policy_rule_sets']])
+ if context.get('consumed_policy_rule_sets'):
+ context['consumed_policy_rule_sets'] = dict(
+ [(i, 'string')
+ for i in context['consumed_policy_rule_sets']])
+ if 'external_segments' in context:
+ external_segment_list.append(context['external_segments'])
+ context['external_segments'] = external_segment_list
+ if context.get('name'):
+ context['name'] = html.escape(context['name'])
+ if context.get('description'):
+ context['description'] = html.escape(context['description'])
+ ext_policy_target = client.ext_policy_target_update(
+ request, ext_policy_target_id, **context)
+ msg = _('External Group %s was successfully updated.') % name_or_id
+ LOG.debug(msg)
+ messages.success(request, msg)
+ return ext_policy_target
+ except Exception as e:
+ msg = _('Failed to update Group %(name)s. %(reason)s') % {'name':
+ name_or_id, 'reason': str(e)}
+ LOG.error(msg)
+ redirect = reverse(self.failure_url)
+ exceptions.handle(request, msg, redirect=redirect)
+
+
class AddProvidedPRSForm(forms.SelfHandlingForm):
policy_rule_set = forms.MultipleChoiceField(
label=_("Provided Policy Rule Sets"),)
@@ -184,6 +281,57 @@ class AddProvidedPRSForm(forms.SelfHandlingForm):
exceptions.handle(request, msg, redirect=redirect)
+class ExtAddProvidedPRSForm(forms.SelfHandlingForm):
+ policy_rule_set = forms.MultipleChoiceField(
+ label=_("Provided Policy Rule Sets"),)
+
+ def __init__(self, request, *args, **kwargs):
+ super(ExtAddProvidedPRSForm, self).__init__(request, *args, **kwargs)
+ policy_rule_sets = []
+ try:
+ ext_policy_target_id = kwargs['initial']['ext_policy_target_id']
+ ext_policy_target = client.ext_policy_target_get(request,
+ ext_policy_target_id)
+ providedpolicy_rule_sets = ext_policy_target.get(
+ "provided_policy_rule_sets")
+ items = client.policy_rule_set_list(request,
+ tenant_id=request.user.tenant_id)
+ policy_rule_sets = [
+ (p.id, p.name) for p in items
+ if p.id not in providedpolicy_rule_sets]
+ except Exception as e:
+ msg = _('Unable to retrieve policy rule set list.') % (str(e))
+ LOG.debug(msg)
+ self.fields['policy_rule_set'].choices = policy_rule_sets
+
+ def handle(self, request, context):
+ ext_policy_target_id = self.initial['ext_policy_target_id']
+ ext_policy_target = client.ext_policy_target_get(request,
+ ext_policy_target_id)
+ url = reverse("horizon:project:policytargets:ext_policy_targetdetails",
+ kwargs={'ext_policy_target_id': ext_policy_target_id})
+ try:
+ for policy_rule_set in ext_policy_target.get(
+ "provided_policy_rule_sets"):
+ context['policy_rule_set'].append(policy_rule_set)
+ policy_rule_sets = dict([(item, 'string')
+ for item in context['policy_rule_set']])
+ client.ext_policy_target_update(
+ request, ext_policy_target_id,
+ provided_policy_rule_sets=policy_rule_sets)
+ msg = _('Policy Rule Set added successfully!')
+ messages.success(request, msg)
+ LOG.debug(msg)
+ return http.HttpResponseRedirect(url)
+ except Exception:
+ u = "horizon:project:policytargets:ext_policy_targetdetails"
+ msg = _('Failed to add policy_rule_set!')
+ redirect = reverse(u, kwargs={'ext_policy_target_id':
+ ext_policy_target_id})
+ LOG.error(msg)
+ exceptions.handle(request, msg, redirect=redirect)
+
+
class RemoveProvidedPRSForm(forms.SelfHandlingForm):
policy_rule_set = forms.MultipleChoiceField(
label=_("Provided Policy Rule Sets"),)
@@ -235,6 +383,60 @@ class RemoveProvidedPRSForm(forms.SelfHandlingForm):
exceptions.handle(request, msg, redirect=redirect)
+class ExtRemoveProvidedPRSForm(forms.SelfHandlingForm):
+ policy_rule_set = forms.MultipleChoiceField(
+ label=_("Provided Policy Rule Sets"),)
+
+ def __init__(self, request, *args, **kwargs):
+ super(ExtRemoveProvidedPRSForm, self).__init__(request,
+ *args, **kwargs)
+ policy_rule_sets = []
+ try:
+ ext_policy_target_id = kwargs['initial']['ext_policy_target_id']
+ ext_policy_target = client.ext_policy_target_get(request,
+ ext_policy_target_id)
+ providedpolicy_rule_sets = ext_policy_target.get(
+ "provided_policy_rule_sets")
+ items = client.policy_rule_set_list(request,
+ tenant_id=request.user.tenant_id)
+ policy_rule_sets = [(p.id, p.name)
+ for p in items if p.id in
+ providedpolicy_rule_sets]
+ except Exception as e:
+ msg = _('Unable to retrieve policy rule set list.') % (str(e))
+ LOG.debug(msg)
+ self.fields['policy_rule_set'].choices = policy_rule_sets
+
+ def handle(self, request, context):
+ ext_policy_target_id = self.initial['ext_policy_target_id']
+ url = reverse(
+ "horizon:project:policytargets:ext_policy_targetdetails",
+ kwargs={'ext_policy_target_id': ext_policy_target_id})
+ try:
+ ext_policy_target = client.ext_policy_target_get(request,
+ ext_policy_target_id)
+ old_policy_rule_sets = ext_policy_target.get(
+ "provided_policy_rule_sets")
+ for policy_rule_set in context['policy_rule_set']:
+ old_policy_rule_sets.remove(policy_rule_set)
+ policy_rule_sets = dict([(item, 'string')
+ for item in old_policy_rule_sets])
+ client.ext_policy_target_update(
+ request, ext_policy_target_id,
+ provided_policy_rule_sets=policy_rule_sets)
+ msg = _('Policy Rule Set removed successfully!')
+ messages.success(request, msg)
+ LOG.debug(msg)
+ return http.HttpResponseRedirect(url)
+ except Exception:
+ msg = _('Failed to remove policy_rule_set!')
+ u = "horizon:project:policytargets:ext_policy_targetdetails"
+ redirect = reverse(u,
+ kwargs={'ext_policy_target_id': ext_policy_target_id})
+ LOG.error(msg)
+ exceptions.handle(request, msg, redirect=redirect)
+
+
class AddConsumedPRSForm(forms.SelfHandlingForm):
policy_rule_set = forms.MultipleChoiceField(
label=_("Consumed Policy Rule Sets"),)
@@ -283,6 +485,56 @@ class AddConsumedPRSForm(forms.SelfHandlingForm):
exceptions.handle(request, msg, redirect=redirect)
+class ExtAddConsumedPRSForm(forms.SelfHandlingForm):
+ policy_rule_set = forms.MultipleChoiceField(
+ label=_("Consumed Policy Rule Sets"),)
+
+ def __init__(self, request, *args, **kwargs):
+ super(ExtAddConsumedPRSForm, self).__init__(request, *args, **kwargs)
+ policy_rule_sets = []
+ try:
+ ext_policy_target_id = kwargs['initial']['ext_policy_target_id']
+ ext_policy_target = client.ext_policy_target_get(request,
+ ext_policy_target_id)
+ consumedpolicy_rule_sets = ext_policy_target.get(
+ "consumed_policy_rule_sets")
+ items = items = client.policy_rule_set_list(request,
+ tenant_id=request.user.tenant_id)
+ policy_rule_sets = [
+ (p.id, p.name) for p in items
+ if p.id not in consumedpolicy_rule_sets]
+ except Exception:
+ pass
+ self.fields['policy_rule_set'].choices = policy_rule_sets
+
+ def handle(self, request, context):
+ ext_policy_target_id = self.initial['ext_policy_target_id']
+ url = reverse("horizon:project:policytargets:ext_policy_targetdetails",
+ kwargs={'ext_policy_target_id': ext_policy_target_id})
+ try:
+ ext_policy_target = client.ext_policy_target_get(request,
+ ext_policy_target_id)
+ for policy_rule_set in ext_policy_target.get(
+ "consumed_policy_rule_sets"):
+ context['policy_rule_set'].append(policy_rule_set)
+ consumed = dict([(item, 'string')
+ for item in context['policy_rule_set']])
+ client.ext_policy_target_update(
+ request,
+ ext_policy_target_id, consumed_policy_rule_sets=consumed)
+ msg = _('Policy Rule Set Added successfully!')
+ messages.success(request, msg)
+ LOG.debug(msg)
+ return http.HttpResponseRedirect(url)
+ except Exception:
+ msg = _('Failed to add policy_rule_set!')
+ u = "horizon:project:policytargets:ext_policy_targetdetails"
+ redirect = reverse(u,
+ kwargs={'ext_policy_target_id': ext_policy_target_id})
+ LOG.error(msg)
+ exceptions.handle(request, msg, redirect=redirect)
+
+
class RemoveConsumedPRSForm(forms.SelfHandlingForm):
policy_rule_set = forms.MultipleChoiceField(
label=_("Consumed Policy Rule Sets"),)
@@ -327,3 +579,53 @@ class RemoveConsumedPRSForm(forms.SelfHandlingForm):
redirect = url
LOG.error(msg)
exceptions.handle(request, msg, redirect=redirect)
+
+
+class ExtRemoveConsumedPRSForm(forms.SelfHandlingForm):
+ policy_rule_set = forms.MultipleChoiceField(
+ label=_("Consumed Policy Rule Sets"),)
+
+ def __init__(self, request, *args, **kwargs):
+ super(ExtRemoveConsumedPRSForm, self).__init__(request,
+ *args, **kwargs)
+ policy_rule_sets = []
+ try:
+ ext_policy_target_id = kwargs['initial']['ext_policy_target_id']
+ ext_policy_target = client.ext_policy_target_get(request,
+ ext_policy_target_id)
+ consumedpolicy_rule_sets = ext_policy_target.get(
+ "consumed_policy_rule_sets")
+ items = client.policy_rule_set_list(request,
+ tenant_id=request.user.tenant_id)
+ policy_rule_sets = [(p.id, p.name)
+ for p in items if p.id
+ in consumedpolicy_rule_sets]
+ except Exception:
+ pass
+ self.fields['policy_rule_set'].choices = policy_rule_sets
+
+ def handle(self, request, context):
+ ext_policy_target_id = self.initial['ext_policy_target_id']
+ url = reverse("horizon:project:policytargets:ext_policy_targetdetails",
+ kwargs={'ext_policy_target_id': ext_policy_target_id})
+ try:
+ ext_policy_target = client.ext_policy_target_get(request,
+ ext_policy_target_id)
+ old_policy_rule_sets = ext_policy_target.get(
+ "consumed_policy_rule_sets")
+ for policy_rule_set in context['policy_rule_set']:
+ old_policy_rule_sets.remove(policy_rule_set)
+ consumed = dict([(item, 'string')
+ for item in old_policy_rule_sets])
+ client.ext_policy_target_update(
+ request, ext_policy_target_id,
+ consumed_policy_rule_sets=consumed)
+ msg = _('Policy Rule Set removed successfully!')
+ messages.success(request, msg)
+ LOG.debug(msg)
+ return http.HttpResponseRedirect(url)
+ except Exception:
+ msg = _('Failed to remove policy_rule_set!')
+ redirect = url
+ LOG.error(msg)
+ exceptions.handle(request, msg, redirect=redirect)
diff --git a/gbpui/panels/policytargets/tables.py b/gbpui/panels/policytargets/tables.py
index 84c48f4..dc6ec33 100644
--- a/gbpui/panels/policytargets/tables.py
+++ b/gbpui/panels/policytargets/tables.py
@@ -40,7 +40,7 @@ class UpdatePTGLink(tables.LinkAction):
class DeletePTGLink(tables.DeleteAction):
- name = "deletepolicy_target"
+ name = "deletepolicytarget"
action_present = _("Delete")
action_past = _("Scheduled deletion of %(data_type)s")
data_type_singular = _("Group")
@@ -49,7 +49,7 @@ class DeletePTGLink(tables.DeleteAction):
class AddPTGLink(tables.LinkAction):
name = "addpolicy_target"
- verbose_name = _("Create Group")
+ verbose_name = _("Create Internal Group")
url = "horizon:project:policytargets:addpolicy_target"
classes = ("ajax-modal", "btn-addpolicy_target",)
@@ -70,11 +70,59 @@ class PTGsTable(tables.DataTable):
class Meta(object):
name = "policy_targetstable"
- verbose_name = _("Groups")
+ verbose_name = _("Internal Groups")
table_actions = (AddPTGLink, DeletePTGLink)
row_actions = (UpdatePTGLink, DeletePTGLink)
+class UpdateExternalPTGLink(tables.LinkAction):
+ name = "updateexternal_policy_target"
+ verbose_name = _("Edit")
+ classes = ("ajax-modal", "btn-update",)
+
+ def get_link_url(self, ext_policy_target):
+ u = "horizon:project:policytargets:update_ext_policy_target"
+ base_url = reverse(u, kwargs={'ext_policy_target_id':
+ ext_policy_target.id})
+ return base_url
+
+
+class AddExternalPTGLink(tables.LinkAction):
+ name = "addexternal_policy_target"
+ verbose_name = _("Create External Group")
+ url = "horizon:project:policytargets:addexternal_policy_target"
+ classes = ("ajax-modal", "btn-addexternal_policy_target",)
+
+
+class DeleteExternalPTGLink(tables.DeleteAction):
+ name = "deleteexternalpolicytarget"
+ action_present = _("Delete")
+ action_past = _("Scheduled deletion of %(data_type)s")
+ data_type_singular = _("Group")
+ data_type_plural = _("Groups")
+
+
+class ExternalPTGsTable(tables.DataTable):
+ name = tables.Column("name",
+ verbose_name=_("Name"),
+ link="horizon:project:policytargets:ext_policy_targetdetails")
+ description = tables.Column("description", verbose_name=_("Description"))
+ provided_policy_rule_sets = tables.Column("provided_policy_rule_sets",
+ sortable=False,
+ verbose_name=_("Provided Rule Sets"))
+ consumed_policy_rule_sets = tables.Column("consumed_policy_rule_sets",
+ sortable=False,
+ verbose_name=_("Consumed Rule Sets"))
+ external_segments = tables.Column("external_segments",
+ verbose_name=_("External Connectivity"))
+
+ class Meta(object):
+ name = "external_policy_targetstable"
+ verbose_name = _("External Group")
+ table_actions = (AddExternalPTGLink, DeleteExternalPTGLink)
+ row_actions = (UpdateExternalPTGLink, DeleteExternalPTGLink,)
+
+
class LaunchVMLink(tables.LinkAction):
name = "launch_vm"
verbose_name = _("Create Member")
@@ -166,8 +214,8 @@ class AddProvidedLink(tables.LinkAction):
def get_link_url(self):
return reverse("horizon:project:policytargets:add_provided_prs",
- kwargs={'policy_target_id':
- self.table.kwargs['policy_target_id']})
+ kwargs={'policy_target_id':
+ self.table.kwargs['policy_target_id']})
class RemoveProvidedLink(tables.LinkAction):
@@ -196,6 +244,28 @@ class ProvidedContractsTable(tables.DataTable):
table_actions = (AddProvidedLink, RemoveProvidedLink,)
+class ExtAddProvidedLink(AddProvidedLink):
+
+ def get_link_url(self):
+ return reverse("horizon:project:policytargets:ext_add_provided_prs",
+ kwargs={'ext_policy_target_id':
+ self.table.kwargs['ext_policy_target_id']})
+
+
+class ExtRemoveProvidedLink(RemoveProvidedLink):
+
+ def get_link_url(self):
+ return reverse("horizon:project:policytargets:ext_remove_provided_prs",
+ kwargs={'ext_policy_target_id':
+ self.table.kwargs['ext_policy_target_id']})
+
+
+class ExtProvidedContractsTable(ProvidedContractsTable):
+
+ class Meta(ProvidedContractsTable.Meta):
+ table_actions = (ExtAddProvidedLink, ExtRemoveProvidedLink,)
+
+
class AddConsumedLink(tables.LinkAction):
name = "add_consumed"
verbose_name = _("Add Consumed Policy Rule Set")
@@ -232,3 +302,25 @@ class ConsumedContractsTable(tables.DataTable):
name = 'consumed_policy_rule_sets'
verbose_name = _("Consumed Policy Rule Set")
table_actions = (AddConsumedLink, RemoveConsumedLink,)
+
+
+class ExtAddConsumedLink(AddConsumedLink):
+
+ def get_link_url(self):
+ return reverse("horizon:project:policytargets:ext_add_consumed_prs",
+ kwargs={'ext_policy_target_id':
+ self.table.kwargs['ext_policy_target_id']})
+
+
+class ExtRemoveConsumedLink(RemoveConsumedLink):
+
+ def get_link_url(self):
+ return reverse("horizon:project:policytargets:ext_remove_consumed_prs",
+ kwargs={'ext_policy_target_id':
+ self.table.kwargs['ext_policy_target_id']})
+
+
+class ExtConsumedContractsTable(ConsumedContractsTable):
+
+ class Meta(ConsumedContractsTable.Meta):
+ table_actions = (ExtAddConsumedLink, ExtRemoveConsumedLink,)
diff --git a/gbpui/panels/policytargets/tabs.py b/gbpui/panels/policytargets/tabs.py
index 1485779..4f81292 100644
--- a/gbpui/panels/policytargets/tabs.py
+++ b/gbpui/panels/policytargets/tabs.py
@@ -25,11 +25,12 @@ from gbpui import column_filters as gfilters
import tables
PTGsTable = tables.PTGsTable
+External_PTGsTable = tables.ExternalPTGsTable
class PTGsTab(tabs.TableTab):
table_classes = (PTGsTable,)
- name = _("Groups")
+ name = _("Internal")
slug = "policytargets"
template_name = "horizon/common/_detail_table.html"
@@ -48,9 +49,32 @@ class PTGsTab(tabs.TableTab):
return policy_targets
+class ExternalPTGsTab(tabs.TableTab):
+ table_classes = (External_PTGsTable,)
+ name = _("External")
+ slug = "externalpolicytargets"
+ template_name = "horizon/common/_detail_table.html"
+
+ def get_external_policy_targetstable_data(self):
+ external_policy_targets = []
+ try:
+ external_policy_targets = client.ext_policy_target_list(
+ self.tab_group.request,
+ tenant_id=self.tab_group.request.user.tenant_id)
+ a = lambda x, y: gfilters.update_policy_target_attributes(x, y)
+ external_policy_targets = [a(self.request, item)
+ for item in external_policy_targets]
+ except Exception as e:
+ msg = _('Unable to retrieve policy_target list. %s') % (str(e))
+ exceptions.handle(self.tab_group.request, msg)
+ for policy_target in external_policy_targets:
+ policy_target.set_id_as_name_if_empty()
+ return external_policy_targets
+
+
class PTGTabs(tabs.TabGroup):
slug = "policy_targettabs"
- tabs = (PTGsTab,)
+ tabs = (PTGsTab, ExternalPTGsTab)
sticky = True
@@ -186,3 +210,55 @@ class PTGMemberTabs(tabs.TabGroup):
slug = 'member_tabs'
tabs = (InstancesTab, ProvidedTab, ConsumedTab, PTGDetailsTab,)
stiky = True
+
+
+class ExtProvidedTab(ProvidedTab):
+ table_classes = (tables.ExtProvidedContractsTable,)
+
+ def get_provided_policy_rule_sets_data(self):
+ try:
+ ext_policy_targetid = self.tab_group.kwargs['ext_policy_target_id']
+ ext_policy_target = client.ext_policy_target_get(
+ self.request, ext_policy_targetid)
+ provided_policy_rule_set_ids = ext_policy_target.get(
+ 'provided_policy_rule_sets')
+ provided_policy_rule_sets = []
+ for _id in provided_policy_rule_set_ids:
+ provided_policy_rule_sets.append(
+ client.policy_rule_set_get(self.request, _id))
+ provided_policy_rule_sets = [gfilters.update_pruleset_attributes(
+ self.request, item) for item in provided_policy_rule_sets]
+ return provided_policy_rule_sets
+ except Exception:
+ error_message = _('Unable to get provided rule sets')
+ exceptions.handle(self.request, error_message)
+ return []
+
+
+class ExtConsumedTab(ConsumedTab):
+ table_classes = (tables.ExtConsumedContractsTable,)
+
+ def get_consumed_policy_rule_sets_data(self):
+ try:
+ ext_policy_targetid = self.tab_group.kwargs['ext_policy_target_id']
+ ext_policy_target = client.ext_policy_target_get(
+ self.request, ext_policy_targetid)
+ consumed_policy_rule_set_ids = ext_policy_target.get(
+ 'consumed_policy_rule_sets')
+ consumed_policy_rule_sets = []
+ for _id in consumed_policy_rule_set_ids:
+ consumed_policy_rule_sets.append(
+ client.policy_rule_set_get(self.request, _id))
+ consumed_policy_rule_sets = [gfilters.update_pruleset_attributes(
+ self.request, item) for item in consumed_policy_rule_sets]
+ return consumed_policy_rule_sets
+ except Exception:
+ error_message = _('Unable to get consumed rule sets')
+ exceptions.handle(self.request, error_message)
+ return []
+
+
+class ExternalPTGMemberTabs(tabs.TabGroup):
+ slug = 'members'
+ tabs = (ExtProvidedTab, ExtConsumedTab)
+ sticky = True
diff --git a/gbpui/panels/policytargets/templates/policytargets/_ext_add_consumed_prs.html b/gbpui/panels/policytargets/templates/policytargets/_ext_add_consumed_prs.html
new file mode 100644
index 0000000..14aa82f
--- /dev/null
+++ b/gbpui/panels/policytargets/templates/policytargets/_ext_add_consumed_prs.html
@@ -0,0 +1,25 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}add_consumed_form{% endblock %}
+{% block form_action %}{% url 'horizon:project:policytargets:ext_add_consumed_prs' ext_policy_target_id %}{% endblock %}
+
+{% block modal-header %}{% trans "Add " %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
{% trans "Add Consumed Policy Rule Set. Press Ctrl to select multiple items." %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/gbpui/panels/policytargets/templates/policytargets/_ext_add_provided_prs.html b/gbpui/panels/policytargets/templates/policytargets/_ext_add_provided_prs.html
new file mode 100644
index 0000000..2686d72
--- /dev/null
+++ b/gbpui/panels/policytargets/templates/policytargets/_ext_add_provided_prs.html
@@ -0,0 +1,25 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}ext_add_provider_form{% endblock %}
+{% block form_action %}{% url 'horizon:project:policytargets:ext_add_provided_prs' ext_policy_target_id %}{% endblock %}
+
+{% block modal-header %}{% trans "Add Provided PRS" %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
{% trans "Add Consumed Policy Rule Set. Press Ctrl to select multiple items." %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/gbpui/panels/policytargets/templates/policytargets/_ext_remove_consumed_prs.html b/gbpui/panels/policytargets/templates/policytargets/_ext_remove_consumed_prs.html
new file mode 100644
index 0000000..1f78cfd
--- /dev/null
+++ b/gbpui/panels/policytargets/templates/policytargets/_ext_remove_consumed_prs.html
@@ -0,0 +1,25 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}remove_contract_form{% endblock %}
+{% block form_action %}{% url 'horizon:project:policytargets:ext_remove_consumed_prs' ext_policy_target_id %}{% endblock %}
+
+{% block modal-header %}{% trans "Remove Policy Rule Set" %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
{% trans "Remove Consumed Policy Rule Set. Press Ctrl to select multiple items." %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/gbpui/panels/policytargets/templates/policytargets/_ext_remove_provided_prs.html b/gbpui/panels/policytargets/templates/policytargets/_ext_remove_provided_prs.html
new file mode 100644
index 0000000..84ab3ea
--- /dev/null
+++ b/gbpui/panels/policytargets/templates/policytargets/_ext_remove_provided_prs.html
@@ -0,0 +1,25 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}add_consumed_form{% endblock %}
+{% block form_action %}{% url 'horizon:project:policytargets:ext_remove_provided_prs' ext_policy_target_id %}{% endblock %}
+
+{% block modal-header %}{% trans "Remove Provided PRS" %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
{% trans "Remove Consumed Policy Rule Set. Press Ctrl to select multiple items." %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/gbpui/panels/policytargets/templates/policytargets/_update_external_policy_target.html b/gbpui/panels/policytargets/templates/policytargets/_update_external_policy_target.html
new file mode 100644
index 0000000..809a7ed
--- /dev/null
+++ b/gbpui/panels/policytargets/templates/policytargets/_update_external_policy_target.html
@@ -0,0 +1,25 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}update_external_policy_target_form{% endblock %}
+{% block form_action %}{% url 'horizon:project:policytargets:update_ext_policy_target' ext_policy_target_id %}{% endblock %}
+
+{% block modal-header %}{% trans "Edit Group" %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
{% trans "You may update External Policy details here." %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/gbpui/panels/policytargets/urls.py b/gbpui/panels/policytargets/urls.py
index 4f0693e..21cf3ac 100644
--- a/gbpui/panels/policytargets/urls.py
+++ b/gbpui/panels/policytargets/urls.py
@@ -23,19 +23,38 @@ urlpatterns = patterns('',
url(r'^addpolicy_target$',
views.AddPTGView.as_view(),
name='addpolicy_target'),
+ url(r'^addexternal_policy_target$',
+ views.AddExternalPTGView.as_view(),
+ name='addexternal_policy_target'),
url(r'^updatepolicy_target/'
'(?P[^/]+)/$',
views.UpdatePTGView.as_view(),
name='updatepolicy_target'),
+ url(r'^update_ext_policy_target/'
+ '(?P[^/]+)/$',
+ views.UpdateExternalPTGView.as_view(),
+ name='update_ext_policy_target'),
url(r'^policy_target/(?P[^/]+)/$',
views.PTGDetailsView.as_view(),
name='policy_targetdetails'),
+ url(r'^ext_policy_target/'
+ '(?P[^/]+)/$',
+ views.ExternalPTGDetailsView.as_view(),
+ name='ext_policy_targetdetails'),
url(r'^addvm/(?P[^/]+)/$',
views.LaunchVMView.as_view(), name='addvm'),
+ url(r'^ext_add_policy_rule_set/'
+ '(?P[^/]+)/$',
+ views.ExtAddProvidedPRSView.as_view(),
+ name='ext_add_provided_prs'),
url(r'^add_policy_rule_set/'
'(?P[^/]+)/$',
views.AddProvidedPRSView.as_view(),
name='add_provided_prs'),
+ url(r'^ext_remove_policy_rule_set/'
+ '(?P[^/]+)/$',
+ views.ExtRemoveProvidedPRSView.as_view(),
+ name='ext_remove_provided_prs'),
url(r'^remove_policy_rule_set/'
'(?P[^/]+)/$',
views.RemoveProvidedPRSView.as_view(),
@@ -43,7 +62,15 @@ urlpatterns = patterns('',
url(r'^add_consumed/(?P[^/]+)/$',
views.AddConsumedPRSView.as_view(),
name='add_consumed_prs'),
+ url(r'^ext_add_consumed/'
+ '(?P[^/]+)/$',
+ views.ExtAddConsumedPRSView.as_view(),
+ name='ext_add_consumed_prs'),
url(r'^remove_consumed/(?P[^/]+)/$',
views.RemoveConsumedPRSView.as_view(),
name='remove_consumed_prs'),
+ url(r'^ext_remove_consumed/'
+ '(?P[^/]+)/$',
+ views.ExtRemoveConsumedPRSView.as_view(),
+ name='ext_remove_consumed_prs'),
)
diff --git a/gbpui/panels/policytargets/views.py b/gbpui/panels/policytargets/views.py
index a931f88..8cd3093 100644
--- a/gbpui/panels/policytargets/views.py
+++ b/gbpui/panels/policytargets/views.py
@@ -32,6 +32,7 @@ PTGTabs = policy_target_tabs.PTGTabs
PTGDetailsTabs = policy_target_tabs.PTGDetailsTabs
AddPTG = policy_target_workflows.AddPTG
+AddExternalPTG = policy_target_workflows.AddExternalPTG
class IndexView(tabs.TabView):
@@ -41,16 +42,27 @@ class IndexView(tabs.TabView):
def post(self, request, *args, **kwargs):
obj_ids = request.POST.getlist('object_ids')
action = request.POST['action']
+ obj_type = re.search('delete([a-z]+)', action).group(1)
if not obj_ids:
obj_ids.append(re.search('([0-9a-z-]+)$', action).group(1))
- for obj_id in obj_ids:
- try:
- client.policy_target_delete(request, obj_id)
- messages.success(request,
+ if obj_type == 'policytarget':
+ for obj_id in obj_ids:
+ try:
+ client.policy_target_delete(request, obj_id)
+ messages.success(request,
_('Deleted Group %s') % obj_id)
- except Exception as e:
- exceptions.handle(request,
+ except Exception as e:
+ exceptions.handle(request,
_('Unable to delete Group. %s') % e)
+ if obj_type == 'externalpolicytarget':
+ for obj_id in obj_ids:
+ try:
+ client.ext_policy_target_delete(request, obj_id)
+ messages.success(request,
+ _('Deleted External Group %s') % obj_id)
+ except Exception as e:
+ exceptions.handle(request,
+ _('Unable to delete External Group. %s') % e)
return self.get(request, *args, **kwargs)
@@ -59,6 +71,10 @@ class AddPTGView(workflows.WorkflowView):
template_name = "project/policytargets/addpolicy_target.html"
+class AddExternalPTGView(workflows.WorkflowView):
+ workflow_class = AddExternalPTG
+
+
class PTGDetailsView(tabs.TabbedTableView):
tab_group_class = (policy_target_tabs.PTGMemberTabs)
template_name = 'project/policytargets/group_details.html'
@@ -74,6 +90,22 @@ class PTGDetailsView(tabs.TabbedTableView):
return context
+class ExternalPTGDetailsView(tabs.TabbedTableView):
+ tab_group_class = (policy_target_tabs.ExternalPTGMemberTabs)
+ template_name = 'project/policytargets/group_details.html'
+
+ def get_context_data(self, **kwargs):
+ context = super(ExternalPTGDetailsView, self).get_context_data(
+ **kwargs)
+ try:
+ ext_policy_target = client.ext_policy_target_get(
+ self.request, context['ext_policy_target_id'])
+ context['policy_target'] = ext_policy_target
+ except Exception:
+ pass
+ return context
+
+
class LaunchVMView(workflows.WorkflowView):
workflow_class = policy_target_workflows.LaunchInstance
template_name = "project/policytargets/add_vm.html"
@@ -116,6 +148,65 @@ class UpdatePTGView(forms.ModalFormView):
return self.kwargs
+class UpdateExternalPTGView(forms.ModalFormView):
+ form_class = policy_target_forms.UpdateExternalPolicyTargetForm
+ template_name = "project/policytargets/update_external_policy_target.html"
+ context_object_name = 'external_policy_target'
+ success_url = reverse_lazy("horizon:project:policytargets:index")
+
+ def get_context_data(self, **kwargs):
+ context = super(UpdateExternalPTGView, self).get_context_data(**kwargs)
+ context["ext_policy_target_id"] = self.kwargs['ext_policy_target_id']
+ obj = self._get_object()
+ if obj:
+ context['name'] = obj.name
+ return context
+
+ @memoized.memoized_method
+ def _get_object(self, *args, **kwargs):
+ ext_policy_target_id = self.kwargs['ext_policy_target_id']
+ try:
+ ext_policy_target = client.ext_policy_target_get(
+ self.request, ext_policy_target_id)
+ ext_policy_target.set_id_as_name_if_empty()
+ return ext_policy_target
+ except Exception:
+ redirect = self.success_url
+ msg = _('Unable to retrieve policy_target details.')
+ exceptions.handle(self.request, msg, redirect=redirect)
+
+ def get_initial(self):
+ return self.kwargs
+
+
+class ExtAddProvidedPRSView(forms.ModalFormView):
+ form_class = policy_target_forms.ExtAddProvidedPRSForm
+ template_name = "project/policytargets/ext_add_provided_prs.html"
+
+ def get_context_data(self, **kwargs):
+ context = super(ExtAddProvidedPRSView, self).get_context_data(**kwargs)
+ context["ext_policy_target_id"] = self.kwargs['ext_policy_target_id']
+ return context
+
+ def get_initial(self):
+ return self.kwargs
+
+
+class ExtRemoveProvidedPRSView(forms.ModalFormView):
+ form_class = policy_target_forms.ExtRemoveProvidedPRSForm
+ template_name = \
+ "project/policytargets/ext_remove_provided_prs.html"
+
+ def get_context_data(self, **kwargs):
+ context = super(ExtRemoveProvidedPRSView, self).get_context_data(
+ **kwargs)
+ context["ext_policy_target_id"] = self.kwargs['ext_policy_target_id']
+ return context
+
+ def get_initial(self):
+ return self.kwargs
+
+
class AddProvidedPRSView(forms.ModalFormView):
form_class = policy_target_forms.AddProvidedPRSForm
template_name = "project/policytargets/add_provided_prs.html"
@@ -142,6 +233,34 @@ class RemoveProvidedPRSView(forms.ModalFormView):
return self.kwargs
+class ExtAddConsumedPRSView(forms.ModalFormView):
+ form_class = policy_target_forms.ExtAddConsumedPRSForm
+ template_name = "project/policytargets/ext_add_consumed_prs.html"
+
+ def get_context_data(self, **kwargs):
+ context = super(ExtAddConsumedPRSView, self).get_context_data(**kwargs)
+ context["ext_policy_target_id"] = self.kwargs['ext_policy_target_id']
+ return context
+
+ def get_initial(self):
+ return self.kwargs
+
+
+class ExtRemoveConsumedPRSView(forms.ModalFormView):
+ form_class = policy_target_forms.ExtRemoveConsumedPRSForm
+ template_name = \
+ "project/policytargets/ext_remove_consumed_prs.html"
+
+ def get_context_data(self, **kwargs):
+ context = super(ExtRemoveConsumedPRSView, self).get_context_data(
+ **kwargs)
+ context["ext_policy_target_id"] = self.kwargs['ext_policy_target_id']
+ return context
+
+ def get_initial(self):
+ return self.kwargs
+
+
class AddConsumedPRSView(forms.ModalFormView):
form_class = policy_target_forms.AddConsumedPRSForm
template_name = "project/policytargets/add_consumed_prs.html"
diff --git a/gbpui/panels/policytargets/workflows.py b/gbpui/panels/policytargets/workflows.py
index 89f4ccc..3e09c8a 100644
--- a/gbpui/panels/policytargets/workflows.py
+++ b/gbpui/panels/policytargets/workflows.py
@@ -187,8 +187,8 @@ class AddPTGAction(workflows.Action):
super(AddPTGAction, self).__init__(request, *args, **kwargs)
class Meta(object):
- name = _("Create Group")
- help_text = _("Create a new Group")
+ name = _("Group")
+ help_text = _("Create Internal Group")
class AddPTGStep(workflows.Step):
@@ -202,7 +202,7 @@ class AddPTGStep(workflows.Step):
class AddPTG(workflows.Workflow):
slug = "addpolicy_target"
- name = _("Create Group")
+ name = _("Create Internal Group")
finalize_button_name = _("Create")
success_message = _('Create Group "%s".')
failure_message = _('Unable to create Group "%s".')
@@ -229,6 +229,101 @@ class AddPTG(workflows.Workflow):
return False
+class ExternalConnectivityAction(workflows.Action):
+ external_segments = forms.ChoiceField(
+ label=_("External Connectivity"),
+ help_text=_("Select external segment for Group."))
+
+ class Meta(object):
+ name = _("External Connectivity")
+ help_text = _(
+ "Select External Connectivity for Group.")
+
+ def populate_external_segments_choices(self, request, context):
+ external_connectivities = []
+ try:
+ external_connectivities = client.externalconnectivity_list(
+ request, tenant_id=request.user.tenant_id)
+ for p in external_connectivities:
+ p.set_id_as_name_if_empty()
+ ext_conn_list = sorted(external_connectivities,
+ key=lambda segment: segment.name)
+ ext_conn_list = \
+ [(p.id, p.name + ":" + p.id) for p in ext_conn_list]
+ except Exception as e:
+ exceptions.handle(request,
+ _("Unable to retrieve policies (%(error)s).")
+ % {'error': str(e)})
+ return ext_conn_list
+
+
+class ExternalConnectivityStep(workflows.Step):
+ action_class = ExternalConnectivityAction
+ name = _("External Connectivity")
+ contributes = ("external_segments",)
+
+ def contribute(self, data, context):
+ ext_seg_list = []
+ ext_seg_list.append(data['external_segments'])
+ context['external_segments'] = ext_seg_list
+ return context
+
+
+class ExtAddPTGAction(workflows.Action):
+ name = forms.CharField(max_length=80,
+ label=_("Name"))
+ description = forms.CharField(max_length=80,
+ label=_("Description"),
+ required=False)
+ shared = forms.BooleanField(label=_("Shared"),
+ initial=False, required=False)
+
+ def __init__(self, request, *args, **kwargs):
+ super(ExtAddPTGAction, self).__init__(request, *args, **kwargs)
+
+ class Meta(object):
+ name = _("Group")
+ help_text = _("Create External Group")
+
+
+class ExtAddPTGStep(workflows.Step):
+ action_class = ExtAddPTGAction
+ contributes = ("name", "description", "shared")
+
+ def contribute(self, data, context):
+ context = super(ExtAddPTGStep, self).contribute(data, context)
+ return context
+
+
+class AddExternalPTG(workflows.Workflow):
+ slug = "addexternal_policy_target"
+ name = _("Create External Group")
+ finalize_button_name = _("Create")
+ success_message = _('Create External Group "%s".')
+ failure_message = _('Unable to create External Group "%s".')
+ success_url = "horizon:project:policytargets:index"
+ default_steps = (ExtAddPTGStep,
+ SelectPolicyRuleSetStep,
+ ExternalConnectivityStep,)
+ wizard = True
+
+ def format_status_message(self, message):
+ return message % self.context.get('name')
+
+ def handle(self, request, context):
+ try:
+ if context.get('name'):
+ context['name'] = html.escape(context['name'])
+ if context.get('description'):
+ context['description'] = html.escape(context['description'])
+ group = client.ext_policy_target_create(request, **context)
+ return group
+ except Exception as e:
+ msg = self.format_status_message(self.failure_message) + str(e)
+ exceptions.handle(request, msg)
+ return False
+
+
KEYPAIR_IMPORT_URL = "horizon:project:access_and_security:keypairs:import"