Add support for Endpoint Group
Current VPNaaS is lacking of endpoint group interaction and new way of IPsec Site Connection creating with endpoint group. This patch filed the gap. Co-Authored-By: Akihiro Motoki <amotoki@gmail.com> Change-Id: Ibdeabd667e00617c7c4d3cee611fa75ac2877d9b Closes-Bug: 1704066
This commit is contained in:
parent
5092245c5a
commit
9f9adbb83f
@ -40,6 +40,10 @@ class VPNService(neutron.NeutronAPIDictWrapper):
|
|||||||
"""Wrapper for neutron VPNService."""
|
"""Wrapper for neutron VPNService."""
|
||||||
|
|
||||||
|
|
||||||
|
class EndpointGroup(neutron.NeutronAPIDictWrapper):
|
||||||
|
"""Wrapper for neutron Endpoint Group."""
|
||||||
|
|
||||||
|
|
||||||
@profiler.trace
|
@profiler.trace
|
||||||
def vpnservice_create(request, **kwargs):
|
def vpnservice_create(request, **kwargs):
|
||||||
"""Create VPNService
|
"""Create VPNService
|
||||||
@ -55,9 +59,11 @@ def vpnservice_create(request, **kwargs):
|
|||||||
{'admin_state_up': kwargs['admin_state_up'],
|
{'admin_state_up': kwargs['admin_state_up'],
|
||||||
'name': kwargs['name'],
|
'name': kwargs['name'],
|
||||||
'description': kwargs['description'],
|
'description': kwargs['description'],
|
||||||
'router_id': kwargs['router_id'],
|
'router_id': kwargs['router_id']
|
||||||
'subnet_id': kwargs['subnet_id']}
|
}
|
||||||
}
|
}
|
||||||
|
if kwargs.get('subnet_id'):
|
||||||
|
body['vpnservice']['subnet_id'] = kwargs['subnet_id']
|
||||||
vpnservice = neutronclient(request).create_vpnservice(body).get(
|
vpnservice = neutronclient(request).create_vpnservice(body).get(
|
||||||
'vpnservice')
|
'vpnservice')
|
||||||
return VPNService(vpnservice)
|
return VPNService(vpnservice)
|
||||||
@ -65,7 +71,8 @@ def vpnservice_create(request, **kwargs):
|
|||||||
|
|
||||||
@profiler.trace
|
@profiler.trace
|
||||||
def vpnservice_list(request, **kwargs):
|
def vpnservice_list(request, **kwargs):
|
||||||
return _vpnservice_list(request, expand_subnet=True, expand_router=True,
|
return _vpnservice_list(request, expand_subnet=True,
|
||||||
|
expand_router=True,
|
||||||
expand_conns=True, **kwargs)
|
expand_conns=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@ -77,7 +84,8 @@ def _vpnservice_list(request, expand_subnet=False, expand_router=False,
|
|||||||
subnets = neutron.subnet_list(request)
|
subnets = neutron.subnet_list(request)
|
||||||
subnet_dict = OrderedDict((s.id, s) for s in subnets)
|
subnet_dict = OrderedDict((s.id, s) for s in subnets)
|
||||||
for s in vpnservices:
|
for s in vpnservices:
|
||||||
s['subnet_name'] = subnet_dict.get(s['subnet_id']).cidr
|
if s.get('subnet_id'):
|
||||||
|
s['subnet_name'] = subnet_dict.get(s['subnet_id']).cidr
|
||||||
if expand_router:
|
if expand_router:
|
||||||
routers = neutron.router_list(request)
|
routers = neutron.router_list(request)
|
||||||
router_dict = OrderedDict((r.id, r) for r in routers)
|
router_dict = OrderedDict((r.id, r) for r in routers)
|
||||||
@ -101,9 +109,10 @@ def _vpnservice_get(request, vpnservice_id, expand_subnet=False,
|
|||||||
expand_router=False, expand_conns=False):
|
expand_router=False, expand_conns=False):
|
||||||
vpnservice = neutronclient(request).show_vpnservice(vpnservice_id).get(
|
vpnservice = neutronclient(request).show_vpnservice(vpnservice_id).get(
|
||||||
'vpnservice')
|
'vpnservice')
|
||||||
if expand_subnet:
|
if expand_subnet and ('subnet_id' in vpnservice):
|
||||||
vpnservice['subnet'] = neutron.subnet_get(
|
if vpnservice['subnet_id'] is not None:
|
||||||
request, vpnservice['subnet_id'])
|
vpnservice['subnet'] = neutron.subnet_get(
|
||||||
|
request, vpnservice['subnet_id'])
|
||||||
if expand_router:
|
if expand_router:
|
||||||
vpnservice['router'] = neutron.router_get(
|
vpnservice['router'] = neutron.router_get(
|
||||||
request, vpnservice['router_id'])
|
request, vpnservice['router_id'])
|
||||||
@ -126,6 +135,74 @@ def vpnservice_delete(request, vpnservice_id):
|
|||||||
neutronclient(request).delete_vpnservice(vpnservice_id)
|
neutronclient(request).delete_vpnservice(vpnservice_id)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def endpointgroup_create(request, **kwargs):
|
||||||
|
"""Create Endpoint Group
|
||||||
|
|
||||||
|
:param request: request context
|
||||||
|
:param name: name for Endpoint Group
|
||||||
|
:param description: description for Endpoint Group
|
||||||
|
:param type: type of Endpoint Group
|
||||||
|
:param endpoints: endpoint(s) of Endpoint Group
|
||||||
|
"""
|
||||||
|
body = {'endpoint_group':
|
||||||
|
{'name': kwargs['name'],
|
||||||
|
'description': kwargs['description'],
|
||||||
|
'type': kwargs['type'],
|
||||||
|
'endpoints': kwargs['endpoints']}
|
||||||
|
}
|
||||||
|
endpointgroup = neutronclient(request).create_endpoint_group(body).get(
|
||||||
|
'endpoint_group')
|
||||||
|
return EndpointGroup(endpointgroup)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def endpointgroup_list(request, **kwargs):
|
||||||
|
return _endpointgroup_list(request, expand_conns=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def _endpointgroup_list(request, expand_conns=False, **kwargs):
|
||||||
|
endpointgroups = neutronclient(request).list_endpoint_groups(
|
||||||
|
**kwargs).get('endpoint_groups')
|
||||||
|
if expand_conns:
|
||||||
|
ipsecsiteconns = _ipsecsiteconnection_list(request)
|
||||||
|
for g in endpointgroups:
|
||||||
|
g['ipsecsiteconns'] = [
|
||||||
|
c.id for c in ipsecsiteconns
|
||||||
|
if (c.get('local_ep_group_id') == g['id'] or
|
||||||
|
c.get('peer_ep_group_id') == g['id'])]
|
||||||
|
return [EndpointGroup(v) for v in endpointgroups]
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def endpointgroup_get(request, endpoint_group_id):
|
||||||
|
return _endpointgroup_get(request, endpoint_group_id, expand_conns=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _endpointgroup_get(request, endpoint_group_id, expand_conns=False):
|
||||||
|
endpointgroup = neutronclient(request).show_endpoint_group(
|
||||||
|
endpoint_group_id).get('endpoint_group')
|
||||||
|
if expand_conns:
|
||||||
|
ipsecsiteconns = _ipsecsiteconnection_list(request)
|
||||||
|
endpointgroup['ipsecsiteconns'] = [
|
||||||
|
c for c in ipsecsiteconns
|
||||||
|
if (c.get('local_ep_group_id') == endpointgroup['id'] or
|
||||||
|
c.get('peer_ep_group_id') == endpointgroup['id'])]
|
||||||
|
return EndpointGroup(endpointgroup)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def endpointgroup_update(request, endpoint_group_id, **kwargs):
|
||||||
|
endpointgroup = neutronclient(request).update_endpoint_group(
|
||||||
|
endpoint_group_id, kwargs).get('endpoint_group')
|
||||||
|
return EndpointGroup(endpointgroup)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def endpointgroup_delete(request, endpoint_group_id):
|
||||||
|
neutronclient(request).delete_endpoint_group(endpoint_group_id)
|
||||||
|
|
||||||
|
|
||||||
@profiler.trace
|
@profiler.trace
|
||||||
def ikepolicy_create(request, **kwargs):
|
def ikepolicy_create(request, **kwargs):
|
||||||
"""Create IKEPolicy
|
"""Create IKEPolicy
|
||||||
@ -290,23 +367,28 @@ def ipsecsiteconnection_create(request, **kwargs):
|
|||||||
:param vpnservice_id: VPNService associated with this connection
|
:param vpnservice_id: VPNService associated with this connection
|
||||||
:param admin_state_up: admin state (default on)
|
:param admin_state_up: admin state (default on)
|
||||||
"""
|
"""
|
||||||
body = {'ipsec_site_connection':
|
body = {
|
||||||
{'name': kwargs['name'],
|
'name': kwargs['name'],
|
||||||
'description': kwargs['description'],
|
'description': kwargs['description'],
|
||||||
'dpd': kwargs['dpd'],
|
'dpd': kwargs['dpd'],
|
||||||
'ikepolicy_id': kwargs['ikepolicy_id'],
|
'ikepolicy_id': kwargs['ikepolicy_id'],
|
||||||
'initiator': kwargs['initiator'],
|
'initiator': kwargs['initiator'],
|
||||||
'ipsecpolicy_id': kwargs['ipsecpolicy_id'],
|
'ipsecpolicy_id': kwargs['ipsecpolicy_id'],
|
||||||
'mtu': kwargs['mtu'],
|
'mtu': kwargs['mtu'],
|
||||||
'peer_address': kwargs['peer_address'],
|
'peer_address': kwargs['peer_address'],
|
||||||
'peer_cidrs': kwargs['peer_cidrs'],
|
'peer_id': kwargs['peer_id'],
|
||||||
'peer_id': kwargs['peer_id'],
|
'psk': kwargs['psk'],
|
||||||
'psk': kwargs['psk'],
|
'vpnservice_id': kwargs['vpnservice_id'],
|
||||||
'vpnservice_id': kwargs['vpnservice_id'],
|
'admin_state_up': kwargs['admin_state_up']
|
||||||
'admin_state_up': kwargs['admin_state_up']}
|
}
|
||||||
}
|
cidrs = kwargs.get('peer_cidrs', [])
|
||||||
|
if not cidrs:
|
||||||
|
body['local_ep_group_id'] = kwargs['local_ep_group_id']
|
||||||
|
body['peer_ep_group_id'] = kwargs['peer_ep_group_id']
|
||||||
|
else:
|
||||||
|
body['peer_cidrs'] = kwargs['peer_cidrs']
|
||||||
ipsecsiteconnection = neutronclient(request).create_ipsec_site_connection(
|
ipsecsiteconnection = neutronclient(request).create_ipsec_site_connection(
|
||||||
body).get('ipsec_site_connection')
|
{'ipsec_site_connection': body}).get('ipsec_site_connection')
|
||||||
return IPSecSiteConnection(ipsecsiteconnection)
|
return IPSecSiteConnection(ipsecsiteconnection)
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +59,41 @@ class UpdateVPNService(forms.SelfHandlingForm):
|
|||||||
exceptions.handle(request, msg, redirect=redirect)
|
exceptions.handle(request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateEndpointGroup(forms.SelfHandlingForm):
|
||||||
|
name = forms.CharField(
|
||||||
|
max_length=80,
|
||||||
|
label=_("Name"),
|
||||||
|
required=False)
|
||||||
|
endpoint_group_id = forms.CharField(
|
||||||
|
label=_("ID"),
|
||||||
|
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
||||||
|
description = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
max_length=80,
|
||||||
|
label=_("Description"))
|
||||||
|
|
||||||
|
failure_url = 'horizon:project:vpn:index'
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
data = {'endpoint_group':
|
||||||
|
{'name': context['name'],
|
||||||
|
'description': context['description']}
|
||||||
|
}
|
||||||
|
endpointgroup = api_vpn.endpointgroup_update(
|
||||||
|
request, context['endpoint_group_id'], **data)
|
||||||
|
msg = (_('Endpoint Group %s was successfully updated.')
|
||||||
|
% context['name'])
|
||||||
|
messages.success(request, msg)
|
||||||
|
return endpointgroup
|
||||||
|
except Exception as e:
|
||||||
|
LOG.info('Failed to update Endpint Group %(id)s: %(exc)s',
|
||||||
|
{'id': context['endpoint_group_id'], 'exc': e})
|
||||||
|
msg = _('Failed to update Endpint Group %s') % context['name']
|
||||||
|
redirect = reverse(self.failure_url)
|
||||||
|
exceptions.handle(request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
|
||||||
class UpdateIKEPolicy(forms.SelfHandlingForm):
|
class UpdateIKEPolicy(forms.SelfHandlingForm):
|
||||||
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
ikepolicy_id = forms.CharField(
|
ikepolicy_id = forms.CharField(
|
||||||
@ -236,6 +271,7 @@ class UpdateIPSecSiteConnection(forms.SelfHandlingForm):
|
|||||||
version=forms.IPv4 | forms.IPv6,
|
version=forms.IPv4 | forms.IPv6,
|
||||||
mask=False)
|
mask=False)
|
||||||
peer_cidrs = forms.MultiIPField(
|
peer_cidrs = forms.MultiIPField(
|
||||||
|
required=False,
|
||||||
label=_("Remote peer subnet(s)"),
|
label=_("Remote peer subnet(s)"),
|
||||||
help_text=_("Remote peer subnet(s) address(es) "
|
help_text=_("Remote peer subnet(s) address(es) "
|
||||||
"with mask(s) in CIDR format "
|
"with mask(s) in CIDR format "
|
||||||
@ -243,6 +279,16 @@ class UpdateIPSecSiteConnection(forms.SelfHandlingForm):
|
|||||||
"(e.g. 20.1.0.0/24, 21.1.0.0/24)"),
|
"(e.g. 20.1.0.0/24, 21.1.0.0/24)"),
|
||||||
version=forms.IPv4 | forms.IPv6,
|
version=forms.IPv4 | forms.IPv6,
|
||||||
mask=True)
|
mask=True)
|
||||||
|
local_ep_group_id = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
label=_("Local Endpoint Group(s)"),
|
||||||
|
help_text=_("IPsec connection validation requires "
|
||||||
|
"that local endpoints are subnets"))
|
||||||
|
peer_ep_group_id = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
label=_("Peer Endpoint Group(s)"),
|
||||||
|
help_text=_("IPSec connection validation requires "
|
||||||
|
"that peer endpoints are CIDRs"))
|
||||||
psk = forms.CharField(
|
psk = forms.CharField(
|
||||||
widget=forms.PasswordInput(render_value=True),
|
widget=forms.PasswordInput(render_value=True),
|
||||||
max_length=80, label=_("Pre-Shared Key (PSK) string"))
|
max_length=80, label=_("Pre-Shared Key (PSK) string"))
|
||||||
@ -293,23 +339,29 @@ class UpdateIPSecSiteConnection(forms.SelfHandlingForm):
|
|||||||
|
|
||||||
def handle(self, request, context):
|
def handle(self, request, context):
|
||||||
try:
|
try:
|
||||||
data = {'ipsec_site_connection':
|
data = {
|
||||||
{'name': context['name'],
|
'name': context['name'],
|
||||||
'description': context['description'],
|
'description': context['description'],
|
||||||
'peer_address': context['peer_address'],
|
'peer_address': context['peer_address'],
|
||||||
'peer_id': context['peer_id'],
|
'peer_id': context['peer_id'],
|
||||||
'peer_cidrs': context[
|
'psk': context['psk'],
|
||||||
'peer_cidrs'].replace(" ", "").split(","),
|
'mtu': context['mtu'],
|
||||||
'psk': context['psk'],
|
'dpd': {'action': context['dpd_action'],
|
||||||
'mtu': context['mtu'],
|
'interval': context['dpd_interval'],
|
||||||
'dpd': {'action': context['dpd_action'],
|
'timeout': context['dpd_timeout']},
|
||||||
'interval': context['dpd_interval'],
|
'initiator': context['initiator'],
|
||||||
'timeout': context['dpd_timeout']},
|
'admin_state_up': context['admin_state_up']
|
||||||
'initiator': context['initiator'],
|
}
|
||||||
'admin_state_up': context['admin_state_up'],
|
if not context['peer_cidrs']:
|
||||||
}}
|
data['local_ep_group_id'] = context['local_ep_group_id']
|
||||||
|
data['peer_ep_group_id'] = context['peer_ep_group_id']
|
||||||
|
else:
|
||||||
|
cidrs = context['peer_cidrs']
|
||||||
|
data['peer_cidrs'] = [cidr.strip() for cidr in cidrs.split(',')
|
||||||
|
if cidr.strip()]
|
||||||
ipsecsiteconnection = api_vpn.ipsecsiteconnection_update(
|
ipsecsiteconnection = api_vpn.ipsecsiteconnection_update(
|
||||||
request, context['ipsecsiteconnection_id'], **data)
|
request, context['ipsecsiteconnection_id'],
|
||||||
|
ipsec_site_connection=data)
|
||||||
msg = (_('IPSec Site Connection %s was successfully updated.')
|
msg = (_('IPSec Site Connection %s was successfully updated.')
|
||||||
% context['name'])
|
% context['name'])
|
||||||
messages.success(request, msg)
|
messages.success(request, msg)
|
||||||
|
@ -57,6 +57,15 @@ class AddVPNServiceLink(tables.LinkAction):
|
|||||||
policy_rules = (("network", "create_vpnservice"),)
|
policy_rules = (("network", "create_vpnservice"),)
|
||||||
|
|
||||||
|
|
||||||
|
class AddEndpointGroupLink(tables.LinkAction):
|
||||||
|
name = "addendpointgroup"
|
||||||
|
verbose_name = _("Add Endpoint Group")
|
||||||
|
url = "horizon:project:vpn:addendpointgroup"
|
||||||
|
classes = ("ajax-modal",)
|
||||||
|
icon = "plus"
|
||||||
|
policy_rules = (("network", "create_endpointgroup"),)
|
||||||
|
|
||||||
|
|
||||||
class AddIPSecSiteConnectionLink(tables.LinkAction):
|
class AddIPSecSiteConnectionLink(tables.LinkAction):
|
||||||
name = "addipsecsiteconnection"
|
name = "addipsecsiteconnection"
|
||||||
verbose_name = _("Add IPSec Site Connection")
|
verbose_name = _("Add IPSec Site Connection")
|
||||||
@ -99,6 +108,34 @@ class DeleteVPNServiceLink(policy.PolicyTargetMixin, tables.DeleteAction):
|
|||||||
request, _('Unable to delete VPN Service. %s') % e)
|
request, _('Unable to delete VPN Service. %s') % e)
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteEndpointGroupLink(policy.PolicyTargetMixin, tables.DeleteAction):
|
||||||
|
name = "deleteendpointgroup"
|
||||||
|
policy_rules = (("network", "delete_endpointgroup"),)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_present(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Delete Endpoint Group",
|
||||||
|
u"Delete Endpoint Groups",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_past(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Scheduled deletion of Endpoint Group",
|
||||||
|
u"Scheduled deletion of Endpoint Groups",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self, request, obj_id):
|
||||||
|
try:
|
||||||
|
api_vpn.endpointgroup_delete(request, obj_id)
|
||||||
|
except Exception as e:
|
||||||
|
exceptions.handle(
|
||||||
|
request, _('Unable to delete Endpoint Group. %s') % e)
|
||||||
|
|
||||||
|
|
||||||
class DeleteIKEPolicyLink(policy.PolicyTargetMixin, tables.DeleteAction):
|
class DeleteIKEPolicyLink(policy.PolicyTargetMixin, tables.DeleteAction):
|
||||||
name = "deleteikepolicy"
|
name = "deleteikepolicy"
|
||||||
policy_rules = (("network", "delete_ikepolicy"),)
|
policy_rules = (("network", "delete_ikepolicy"),)
|
||||||
@ -210,6 +247,17 @@ class UpdateVPNServiceLink(tables.LinkAction):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateEndpointGroupLink(tables.LinkAction):
|
||||||
|
name = "updateendpointgroup"
|
||||||
|
verbose_name = _("Edit Endpoint Group")
|
||||||
|
classes = ("ajax-modal", "btn-update",)
|
||||||
|
policy_rules = (("network", "update_endpointgroup"),)
|
||||||
|
|
||||||
|
def get_link_url(self, endpoint_group):
|
||||||
|
return reverse("horizon:project:vpn:update_endpointgroup",
|
||||||
|
kwargs={'endpoint_group_id': endpoint_group.id})
|
||||||
|
|
||||||
|
|
||||||
class UpdateIKEPolicyLink(tables.LinkAction):
|
class UpdateIKEPolicyLink(tables.LinkAction):
|
||||||
name = "updateikepolicy"
|
name = "updateikepolicy"
|
||||||
verbose_name = _("Edit IKE Policy")
|
verbose_name = _("Edit IKE Policy")
|
||||||
@ -355,13 +403,21 @@ def get_local_ips(vpn):
|
|||||||
return template.loader.render_to_string(template_name, context)
|
return template.loader.render_to_string(template_name, context)
|
||||||
|
|
||||||
|
|
||||||
|
def get_subnet_name(vpn):
|
||||||
|
try:
|
||||||
|
return vpn.subnet_name
|
||||||
|
except AttributeError:
|
||||||
|
return _("-")
|
||||||
|
|
||||||
|
|
||||||
class UpdateVPNServiceRow(tables.Row):
|
class UpdateVPNServiceRow(tables.Row):
|
||||||
ajax = True
|
ajax = True
|
||||||
|
|
||||||
def get_data(self, request, vpn_id):
|
def get_data(self, request, vpn_id):
|
||||||
vpn = api_vpn.vpnservice_get(request, vpn_id)
|
vpn = api_vpn.vpnservice_get(request, vpn_id)
|
||||||
vpn.router_name = vpn['router'].get('name', vpn['router_id'])
|
vpn.router_name = vpn['router'].get('name', vpn['router_id'])
|
||||||
vpn.subnet_name = vpn['subnet'].get('cidr', vpn['subnet_id'])
|
if 'subnet' in vpn:
|
||||||
|
vpn.subnet_name = vpn['subnet'].get('cidr', vpn['subnet_id'])
|
||||||
return vpn
|
return vpn
|
||||||
|
|
||||||
|
|
||||||
@ -384,7 +440,7 @@ class VPNServicesTable(tables.DataTable):
|
|||||||
description = tables.Column('description', verbose_name=_('Description'))
|
description = tables.Column('description', verbose_name=_('Description'))
|
||||||
local_ips = tables.Column(get_local_ips,
|
local_ips = tables.Column(get_local_ips,
|
||||||
verbose_name=_("Local Side Public IPs"))
|
verbose_name=_("Local Side Public IPs"))
|
||||||
subnet_name = tables.Column('subnet_name', verbose_name=_('Subnet'))
|
subnet_name = tables.Column(get_subnet_name, verbose_name=_('Subnet'))
|
||||||
router_name = tables.Column('router_name', verbose_name=_('Router'))
|
router_name = tables.Column('router_name', verbose_name=_('Router'))
|
||||||
status = tables.Column("status",
|
status = tables.Column("status",
|
||||||
verbose_name=_("Status"),
|
verbose_name=_("Status"),
|
||||||
@ -406,6 +462,40 @@ class VPNServicesTable(tables.DataTable):
|
|||||||
row_actions = (UpdateVPNServiceLink, DeleteVPNServiceLink)
|
row_actions = (UpdateVPNServiceLink, DeleteVPNServiceLink)
|
||||||
|
|
||||||
|
|
||||||
|
class EndpointGroupFilterAction(tables.FilterAction):
|
||||||
|
name = 'endpointgroups_project'
|
||||||
|
filter_type = 'server'
|
||||||
|
filter_choices = (
|
||||||
|
('name', _("Name ="), True),
|
||||||
|
('type', _("Type ="), True),
|
||||||
|
('endpoints', _("Endpoints ="), True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_endpoints(epg):
|
||||||
|
return ', '.join(epg.endpoints)
|
||||||
|
|
||||||
|
|
||||||
|
class EndpointGroupTable(tables.DataTable):
|
||||||
|
id = tables.Column('id', hidden=True)
|
||||||
|
name = tables.Column("name_or_id", verbose_name=_('Name'),
|
||||||
|
link="horizon:project:vpn:endpointgroupdetails")
|
||||||
|
description = tables.Column('description', verbose_name=_('Description'))
|
||||||
|
type = tables.Column('type', verbose_name=_('Type'))
|
||||||
|
endpoints = tables.Column(_get_endpoints, verbose_name=_('Endpoints'))
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = "endpointgroupstable"
|
||||||
|
verbose_name = _("Endpoint Groups")
|
||||||
|
table_actions = (AddEndpointGroupLink,
|
||||||
|
DeleteEndpointGroupLink,
|
||||||
|
EndpointGroupFilterAction)
|
||||||
|
row_actions = (UpdateEndpointGroupLink, DeleteEndpointGroupLink)
|
||||||
|
|
||||||
|
def get_object_display(self, endpoitgroup):
|
||||||
|
return endpoitgroup.name_or_id
|
||||||
|
|
||||||
|
|
||||||
class PoliciesFilterAction(tables.FilterAction):
|
class PoliciesFilterAction(tables.FilterAction):
|
||||||
name = 'filter_project_IKEPolicies'
|
name = 'filter_project_IKEPolicies'
|
||||||
filter_type = 'server'
|
filter_type = 'server'
|
||||||
|
@ -114,6 +114,32 @@ class VPNServicesTab(tabs.TableTab, htables.DataTableView):
|
|||||||
return super(VPNServicesTab, self).get_filters()
|
return super(VPNServicesTab, self).get_filters()
|
||||||
|
|
||||||
|
|
||||||
|
class EndpointGroupTab(tabs.TableTab, htables.DataTableView):
|
||||||
|
table_classes = (tables.EndpointGroupTable,)
|
||||||
|
name = _("Endpoint Groups")
|
||||||
|
slug = "endpointgroups"
|
||||||
|
template_name = ("horizon/common/_detail_table.html")
|
||||||
|
|
||||||
|
def get_endpointgroupstable_data(self):
|
||||||
|
try:
|
||||||
|
filters = self.get_filters()
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
endpointgroups = api_vpn.endpointgroup_list(
|
||||||
|
self.tab_group.request, tenant_id=tenant_id, **filters)
|
||||||
|
except Exception:
|
||||||
|
endpointgroups = []
|
||||||
|
exceptions.handle(self.tab_group.request,
|
||||||
|
_('Unable to retrieve endpoint group list.'))
|
||||||
|
return endpointgroups
|
||||||
|
|
||||||
|
def get_filters(self):
|
||||||
|
self.table = self._tables['endpointgroupstable']
|
||||||
|
self.handle_server_filter(self.request, table=self.table)
|
||||||
|
self.update_server_filter_action(self.request, table=self.table)
|
||||||
|
|
||||||
|
return super(EndpointGroupTab, self).get_filters()
|
||||||
|
|
||||||
|
|
||||||
class IKEPoliciesTab(tabs.TableTab, htables.DataTableView):
|
class IKEPoliciesTab(tabs.TableTab, htables.DataTableView):
|
||||||
table_classes = (tables.IKEPoliciesTable,)
|
table_classes = (tables.IKEPoliciesTable,)
|
||||||
name = _("IKE Policies")
|
name = _("IKE Policies")
|
||||||
@ -169,7 +195,8 @@ class IPSecPoliciesTab(tabs.TableTab, htables.DataTableView):
|
|||||||
class VPNTabs(tabs.TabGroup):
|
class VPNTabs(tabs.TabGroup):
|
||||||
slug = "vpntabs"
|
slug = "vpntabs"
|
||||||
tabs = (IKEPoliciesTab, IPSecPoliciesTab,
|
tabs = (IKEPoliciesTab, IPSecPoliciesTab,
|
||||||
VPNServicesTab, IPSecSiteConnectionsTab,)
|
VPNServicesTab, EndpointGroupTab,
|
||||||
|
IPSecSiteConnectionsTab,)
|
||||||
sticky = True
|
sticky = True
|
||||||
|
|
||||||
|
|
||||||
@ -218,6 +245,21 @@ class VPNServiceDetailsTabs(tabs.TabGroup):
|
|||||||
tabs = (VPNServiceDetailsTab,)
|
tabs = (VPNServiceDetailsTab,)
|
||||||
|
|
||||||
|
|
||||||
|
class EndpointGroupDetailsTab(tabs.Tab):
|
||||||
|
name = _("Endpoint Groups Details")
|
||||||
|
slug = "endpointgroupdetails"
|
||||||
|
template_name = "project/vpn/_endpointgroup_details.html"
|
||||||
|
|
||||||
|
def get_context_data(self, request):
|
||||||
|
endpointgroup = self.tab_group.kwargs['endpointgroup']
|
||||||
|
return {'endpointgroup': endpointgroup}
|
||||||
|
|
||||||
|
|
||||||
|
class EndpointGroupDetailsTabs(tabs.TabGroup):
|
||||||
|
slug = "endpointgrouptabs"
|
||||||
|
tabs = (EndpointGroupDetailsTab,)
|
||||||
|
|
||||||
|
|
||||||
class IPSecSiteConnectionDetailsTab(tabs.Tab):
|
class IPSecSiteConnectionDetailsTab(tabs.Tab):
|
||||||
name = _("IPSec Site Connection Details")
|
name = _("IPSec Site Connection Details")
|
||||||
slug = "ipsecsiteconnectiondetails"
|
slug = "ipsecsiteconnectiondetails"
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
<p>{% trans "Create endpoint group for current project." %}</p>
|
@ -1,7 +1,15 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<p>{% trans "Create VPN service for current project." %}</p>
|
<p>{% trans "Create VPN service for current project." %}</p>
|
||||||
<p>{% trans "The VPN service is attached to a router and references to a single subnet to push to a remote site." %}</p>
|
<p>{% blocktrans trimmed %}
|
||||||
<p>{% trans "Specify a name, description, router, and subnet for the VPN Service." %}</p>
|
The VPN service is attached to a router and references to endpoint group
|
||||||
|
or a single subnet to push to a remote site.
|
||||||
|
{% endblocktrans %}</p>
|
||||||
|
<p>{% trans "Specify a name, description, router, and subnet (optional) for the VPN Service." %}</p>
|
||||||
<p>{% trans "Admin State is enabled by default." %}</p>
|
<p>{% trans "Admin State is enabled by default." %}</p>
|
||||||
<p>{% trans "The router, subnet and admin state fields require to be enabled. All others are optional." %} </p>
|
<p>{% trans "The router and admin state fields require to be enabled. All others are optional." %} </p>
|
||||||
|
<p>{% blocktrans trimmed %}
|
||||||
|
Note: The recommended way to specify local subnets is to use endpoint groups
|
||||||
|
in IPsec site connection. It is deprecated to specify subnet in VPN service.
|
||||||
|
For a new VPN service or IPsec site connection, using endpoint group is recommended.
|
||||||
|
{% endblocktrans %}</p>
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
{% load i18n sizeformat parse_date %}
|
||||||
|
|
||||||
|
<div class="detail">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>{% trans "Name" %}</dt>
|
||||||
|
<dd>{{ endpointgroup.name|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Description" %}</dt>
|
||||||
|
<dd>{{ endpointgroup.description|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "ID" %}</dt>
|
||||||
|
<dd>{{ endpointgroup.id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Project ID" %}</dt>
|
||||||
|
<dd>{{ endpointgroup.tenant_id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Type" %}</dt>
|
||||||
|
<dd>{{ endpointgroup.type }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Endpoints" %}</dt>
|
||||||
|
{% if endpointgroup.type == 'subnet' %}
|
||||||
|
{% for ep in endpointgroup.endpoints %}
|
||||||
|
{% url 'horizon:project:networks:subnets:detail' ep as subnet_url %}
|
||||||
|
<dd><a href="{{ subnet_url }}">{{ ep }}</a></dd>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% for cidr in endpointgroup.endpoints %}
|
||||||
|
<dd>{{ cidr }}</dd>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</dl>
|
||||||
|
</div>
|
@ -18,6 +18,10 @@
|
|||||||
{% url 'horizon:project:vpn:vpnservicedetails' ipsecsiteconnection.vpnservice_id as vpnservice_url %}
|
{% url 'horizon:project:vpn:vpnservicedetails' ipsecsiteconnection.vpnservice_id as vpnservice_url %}
|
||||||
<dd><a href="{{ vpnservice_url }}">{{ ipsecsiteconnection.vpnservice.name_or_id }}</a></dd>
|
<dd><a href="{{ vpnservice_url }}">{{ ipsecsiteconnection.vpnservice.name_or_id }}</a></dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Local Endpoint Group" %}</dt>
|
||||||
|
{% url 'horizon:project:vpn:endpointgroupdetails' ipsecsiteconnection.local_ep_group_id as local_epg_url %}
|
||||||
|
<dd><a href="{{ local_epg_url }}">{{ ipsecsiteconnection.local_ep_group_id }}</a></dd>
|
||||||
|
|
||||||
<dt>{% trans "IKE Policy" %}</dt>
|
<dt>{% trans "IKE Policy" %}</dt>
|
||||||
{% url 'horizon:project:vpn:ikepolicydetails' ipsecsiteconnection.ikepolicy_id as ikepolicy_url %}
|
{% url 'horizon:project:vpn:ikepolicydetails' ipsecsiteconnection.ikepolicy_id as ikepolicy_url %}
|
||||||
<dd><a href="{{ ikepolicy_url }}">{{ ipsecsiteconnection.ikepolicy.name_or_id }}</a></dd>
|
<dd><a href="{{ ikepolicy_url }}">{{ ipsecsiteconnection.ikepolicy.name_or_id }}</a></dd>
|
||||||
@ -39,6 +43,10 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Peer Endpoint Group" %}</dt>
|
||||||
|
{% url 'horizon:project:vpn:endpointgroupdetails' ipsecsiteconnection.peer_ep_group_id as peer_epg_url %}
|
||||||
|
<dd><a href="{{ peer_epg_url }}">{{ ipsecsiteconnection.peer_ep_group_id }}</a></dd>
|
||||||
|
|
||||||
<dt>{% trans "MTU" %}</dt>
|
<dt>{% trans "MTU" %}</dt>
|
||||||
<dd>{{ ipsecsiteconnection.mtu }}</dd>
|
<dd>{{ ipsecsiteconnection.mtu }}</dd>
|
||||||
|
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
{% extends "horizon/common/_modal_form.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block modal-body-right %}
|
||||||
|
<h3>{% trans "Description:" %}</h3>
|
||||||
|
<p>{% trans "You may update endpoint group details here." %}</p>
|
||||||
|
{% endblock %}
|
@ -19,8 +19,12 @@
|
|||||||
<dd><a href="{{ router_url }}">{{ vpnservice.router.name_or_id }}</a></dd>
|
<dd><a href="{{ router_url }}">{{ vpnservice.router.name_or_id }}</a></dd>
|
||||||
|
|
||||||
<dt>{% trans "Subnet ID" %}</dt>
|
<dt>{% trans "Subnet ID" %}</dt>
|
||||||
{% url 'horizon:project:networks:subnets:detail' vpnservice.subnet_id as subnet_url %}
|
{% if vpnservice.subnet_id %}
|
||||||
<dd><a href="{{ subnet_url }}">{{ vpnservice.subnet.name_or_id }} {{ vpnservice.subnet.cidr }}</a></dd>
|
{% url 'horizon:project:networks:subnets:detail' vpnservice.subnet_id as subnet_url %}
|
||||||
|
<dd><a href="{{ subnet_url }}">{{ vpnservice.subnet.name_or_id }} {{ vpnservice.subnet.cidr }}</a></dd>
|
||||||
|
{% else %}
|
||||||
|
<dd>{% trans "None" %}</dd>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<dt>{% trans "VPN Connections" %}</dt>
|
<dt>{% trans "VPN Connections" %}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Edit Endpoint Group" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% include 'project/vpn/_update_endpointgroup.html' %}
|
||||||
|
{% endblock %}
|
@ -40,17 +40,22 @@ class VPNTests(test.TestCase):
|
|||||||
ADDIKEPOLICY_PATH = 'horizon:%s:vpn:addikepolicy' % DASHBOARD
|
ADDIKEPOLICY_PATH = 'horizon:%s:vpn:addikepolicy' % DASHBOARD
|
||||||
ADDIPSECPOLICY_PATH = 'horizon:%s:vpn:addipsecpolicy' % DASHBOARD
|
ADDIPSECPOLICY_PATH = 'horizon:%s:vpn:addipsecpolicy' % DASHBOARD
|
||||||
ADDVPNSERVICE_PATH = 'horizon:%s:vpn:addvpnservice' % DASHBOARD
|
ADDVPNSERVICE_PATH = 'horizon:%s:vpn:addvpnservice' % DASHBOARD
|
||||||
|
ADDENDPOINTGROUP_PATH = 'horizon:%s:vpn:addendpointgroup' % DASHBOARD
|
||||||
ADDVPNCONNECTION_PATH = 'horizon:%s:vpn:addipsecsiteconnection' % DASHBOARD
|
ADDVPNCONNECTION_PATH = 'horizon:%s:vpn:addipsecsiteconnection' % DASHBOARD
|
||||||
|
|
||||||
IKEPOLICY_DETAIL_PATH = 'horizon:%s:vpn:ikepolicydetails' % DASHBOARD
|
IKEPOLICY_DETAIL_PATH = 'horizon:%s:vpn:ikepolicydetails' % DASHBOARD
|
||||||
IPSECPOLICY_DETAIL_PATH = 'horizon:%s:vpn:ipsecpolicydetails' % DASHBOARD
|
IPSECPOLICY_DETAIL_PATH = 'horizon:%s:vpn:ipsecpolicydetails' % DASHBOARD
|
||||||
VPNSERVICE_DETAIL_PATH = 'horizon:%s:vpn:vpnservicedetails' % DASHBOARD
|
VPNSERVICE_DETAIL_PATH = 'horizon:%s:vpn:vpnservicedetails' % DASHBOARD
|
||||||
|
ENDPOINTGROUP_DETAIL_PATH = 'horizon:%s:vpn:endpointgroupdetails' %\
|
||||||
|
DASHBOARD
|
||||||
VPNCONNECTION_DETAIL_PATH = 'horizon:%s:vpn:ipsecsiteconnectiondetails' %\
|
VPNCONNECTION_DETAIL_PATH = 'horizon:%s:vpn:ipsecsiteconnectiondetails' %\
|
||||||
DASHBOARD
|
DASHBOARD
|
||||||
|
|
||||||
UPDATEIKEPOLICY_PATH = 'horizon:%s:vpn:update_ikepolicy' % DASHBOARD
|
UPDATEIKEPOLICY_PATH = 'horizon:%s:vpn:update_ikepolicy' % DASHBOARD
|
||||||
UPDATEIPSECPOLICY_PATH = 'horizon:%s:vpn:update_ipsecpolicy' % DASHBOARD
|
UPDATEIPSECPOLICY_PATH = 'horizon:%s:vpn:update_ipsecpolicy' % DASHBOARD
|
||||||
UPDATEVPNSERVICE_PATH = 'horizon:%s:vpn:update_vpnservice' % DASHBOARD
|
UPDATEVPNSERVICE_PATH = 'horizon:%s:vpn:update_vpnservice' % DASHBOARD
|
||||||
|
UPDATEENDPOINTGROUP_PATH = 'horizon:%s:vpn:update_endpointgroup' %\
|
||||||
|
DASHBOARD
|
||||||
UPDATEVPNCONNECTION_PATH = 'horizon:%s:vpn:update_ipsecsiteconnection' %\
|
UPDATEVPNCONNECTION_PATH = 'horizon:%s:vpn:update_ipsecsiteconnection' %\
|
||||||
DASHBOARD
|
DASHBOARD
|
||||||
|
|
||||||
@ -60,6 +65,11 @@ class VPNTests(test.TestCase):
|
|||||||
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
.AndReturn(self.vpnservices.list())
|
.AndReturn(self.vpnservices.list())
|
||||||
|
|
||||||
|
# retrieves endpoint groups
|
||||||
|
api_vpn.endpointgroup_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.endpointgroups.list())
|
||||||
|
|
||||||
# retrieves ikepolicies
|
# retrieves ikepolicies
|
||||||
api_vpn.ikepolicy_list(
|
api_vpn.ikepolicy_list(
|
||||||
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
@ -79,6 +89,9 @@ class VPNTests(test.TestCase):
|
|||||||
api_vpn.vpnservice_list(
|
api_vpn.vpnservice_list(
|
||||||
IsA(http.HttpRequest),
|
IsA(http.HttpRequest),
|
||||||
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
||||||
|
api_vpn.endpointgroup_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
||||||
api_vpn.ikepolicy_list(
|
api_vpn.ikepolicy_list(
|
||||||
IsA(http.HttpRequest),
|
IsA(http.HttpRequest),
|
||||||
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
||||||
@ -90,7 +103,7 @@ class VPNTests(test.TestCase):
|
|||||||
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_list')})
|
'ipsecsiteconnection_list')})
|
||||||
def test_index_vpnservices(self):
|
def test_index_vpnservices(self):
|
||||||
self.set_up_expect()
|
self.set_up_expect()
|
||||||
@ -106,7 +119,23 @@ class VPNTests(test.TestCase):
|
|||||||
len(self.vpnservices.list()))
|
len(self.vpnservices.list()))
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_endpointgroups(self):
|
||||||
|
self.set_up_expect()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(self.INDEX_URL + '?tab=vpntabs__endpointgroups')
|
||||||
|
|
||||||
|
self.assertTemplateUsed(res, '%s/vpn/index.html'
|
||||||
|
% self.DASHBOARD)
|
||||||
|
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||||
|
self.assertEqual(len(res.context['endpointgroupstable_table'].data),
|
||||||
|
len(self.endpointgroups.list()))
|
||||||
|
|
||||||
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_list')})
|
'ipsecsiteconnection_list')})
|
||||||
def test_index_ikepolicies(self):
|
def test_index_ikepolicies(self):
|
||||||
self.set_up_expect()
|
self.set_up_expect()
|
||||||
@ -122,7 +151,7 @@ class VPNTests(test.TestCase):
|
|||||||
len(self.ikepolicies.list()))
|
len(self.ikepolicies.list()))
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_list')})
|
'ipsecsiteconnection_list')})
|
||||||
def test_index_ipsecpolicies(self):
|
def test_index_ipsecpolicies(self):
|
||||||
self.set_up_expect()
|
self.set_up_expect()
|
||||||
@ -138,7 +167,7 @@ class VPNTests(test.TestCase):
|
|||||||
len(self.ipsecpolicies.list()))
|
len(self.ipsecpolicies.list()))
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_list')})
|
'ipsecsiteconnection_list')})
|
||||||
def test_index_ipsecsiteconnections(self):
|
def test_index_ipsecsiteconnections(self):
|
||||||
self.set_up_expect()
|
self.set_up_expect()
|
||||||
@ -156,7 +185,7 @@ class VPNTests(test.TestCase):
|
|||||||
len(self.ipsecsiteconnections.list()))
|
len(self.ipsecsiteconnections.list()))
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_list')})
|
'ipsecsiteconnection_list')})
|
||||||
def test_index_exception_vpnservices(self):
|
def test_index_exception_vpnservices(self):
|
||||||
self.set_up_expect_with_exception()
|
self.set_up_expect_with_exception()
|
||||||
@ -172,7 +201,23 @@ class VPNTests(test.TestCase):
|
|||||||
self.assertEqual(len(res.context['table'].data), 0)
|
self.assertEqual(len(res.context['table'].data), 0)
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_exception_endpointgroups(self):
|
||||||
|
self.set_up_expect_with_exception()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(self.INDEX_URL + '?tab=vpntabs__endpointgroups')
|
||||||
|
|
||||||
|
self.assertTemplateUsed(res, '%s/vpn/index.html'
|
||||||
|
% self.DASHBOARD)
|
||||||
|
self.assertTemplateUsed(res,
|
||||||
|
'horizon/common/_detail_table.html')
|
||||||
|
self.assertEqual(len(res.context['table'].data), 0)
|
||||||
|
|
||||||
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_list')})
|
'ipsecsiteconnection_list')})
|
||||||
def test_index_exception_ikepolicies(self):
|
def test_index_exception_ikepolicies(self):
|
||||||
self.set_up_expect_with_exception()
|
self.set_up_expect_with_exception()
|
||||||
@ -188,7 +233,7 @@ class VPNTests(test.TestCase):
|
|||||||
self.assertEqual(len(res.context['table'].data), 0)
|
self.assertEqual(len(res.context['table'].data), 0)
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_list')})
|
'ipsecsiteconnection_list')})
|
||||||
def test_index_exception_ipsecpolicies(self):
|
def test_index_exception_ipsecpolicies(self):
|
||||||
self.set_up_expect_with_exception()
|
self.set_up_expect_with_exception()
|
||||||
@ -204,7 +249,7 @@ class VPNTests(test.TestCase):
|
|||||||
self.assertEqual(len(res.context['table'].data), 0)
|
self.assertEqual(len(res.context['table'].data), 0)
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_list')})
|
'ipsecsiteconnection_list')})
|
||||||
def test_index_exception_ipsecsiteconnections(self):
|
def test_index_exception_ipsecsiteconnections(self):
|
||||||
self.set_up_expect_with_exception()
|
self.set_up_expect_with_exception()
|
||||||
@ -293,7 +338,68 @@ class VPNTests(test.TestCase):
|
|||||||
|
|
||||||
res = self.client.post(reverse(self.ADDVPNSERVICE_PATH), form_data)
|
res = self.client.post(reverse(self.ADDVPNSERVICE_PATH), form_data)
|
||||||
|
|
||||||
self.assertFormErrors(res, 2)
|
self.assertFormErrors(res, 1)
|
||||||
|
|
||||||
|
@test.create_stubs({api.neutron: ('network_list_for_tenant', )})
|
||||||
|
def test_add_endpointgroup_get(self):
|
||||||
|
networks = [{'subnets': [self.subnets.first(), ]}, ]
|
||||||
|
|
||||||
|
api.neutron.network_list_for_tenant(
|
||||||
|
IsA(http.HttpRequest), self.tenant.id).AndReturn(networks)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(reverse(self.ADDENDPOINTGROUP_PATH))
|
||||||
|
|
||||||
|
workflow = res.context['workflow']
|
||||||
|
self.assertTemplateUsed(res, views.WorkflowView.template_name)
|
||||||
|
self.assertEqual(workflow.name, workflows.AddEndpointGroup.name)
|
||||||
|
|
||||||
|
expected_objs = ['<AddEndpointGroupStep: addendpointgroupaction>', ]
|
||||||
|
self.assertQuerysetEqual(workflow.steps, expected_objs)
|
||||||
|
|
||||||
|
@test.create_stubs({api.neutron: ('network_list_for_tenant', ),
|
||||||
|
api_vpn: ('endpointgroup_create', )})
|
||||||
|
def test_add_endpointgroup_post(self):
|
||||||
|
endpointgroup = self.endpointgroups.first()
|
||||||
|
networks = [{'subnets': [self.subnets.first(), ]}, ]
|
||||||
|
|
||||||
|
api.neutron.network_list_for_tenant(
|
||||||
|
IsA(http.HttpRequest), self.tenant.id).AndReturn(networks)
|
||||||
|
|
||||||
|
form_data = {'name': endpointgroup['name'],
|
||||||
|
'description': endpointgroup['description'],
|
||||||
|
'endpoints': endpointgroup['endpoints'],
|
||||||
|
'type': endpointgroup['type']}
|
||||||
|
|
||||||
|
api_vpn.endpointgroup_create(
|
||||||
|
IsA(http.HttpRequest), **form_data).AndReturn(endpointgroup)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDENDPOINTGROUP_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
@test.create_stubs({api.neutron: ('network_list_for_tenant', )})
|
||||||
|
def test_add_endpointgroup_post_error(self):
|
||||||
|
endpointgroup = self.endpointgroups.first()
|
||||||
|
networks = [{'subnets': [self.subnets.first(), ]}, ]
|
||||||
|
|
||||||
|
api.neutron.network_list_for_tenant(
|
||||||
|
IsA(http.HttpRequest), self.tenant.id).AndReturn(networks)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = {'name': endpointgroup['name'],
|
||||||
|
'description': endpointgroup['description'],
|
||||||
|
'endpoints': endpointgroup['endpoints'],
|
||||||
|
'type': ''}
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDENDPOINTGROUP_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertFormErrors(res, 1)
|
||||||
|
|
||||||
def test_add_ikepolicy_get(self):
|
def test_add_ikepolicy_get(self):
|
||||||
res = self.client.get(reverse(self.ADDIKEPOLICY_PATH))
|
res = self.client.get(reverse(self.ADDIKEPOLICY_PATH))
|
||||||
@ -408,7 +514,7 @@ class VPNTests(test.TestCase):
|
|||||||
self.assertFormErrors(res, 1)
|
self.assertFormErrors(res, 1)
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list')})
|
'vpnservice_list', 'endpointgroup_list',)})
|
||||||
def test_add_ipsecsiteconnection_get(self):
|
def test_add_ipsecsiteconnection_get(self):
|
||||||
ikepolicies = self.ikepolicies.list()
|
ikepolicies = self.ikepolicies.list()
|
||||||
ipsecpolicies = self.ipsecpolicies.list()
|
ipsecpolicies = self.ipsecpolicies.list()
|
||||||
@ -439,13 +545,13 @@ class VPNTests(test.TestCase):
|
|||||||
self.assertQuerysetEqual(workflow.steps, expected_objs)
|
self.assertQuerysetEqual(workflow.steps, expected_objs)
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_create')})
|
'ipsecsiteconnection_create')})
|
||||||
def test_add_ipsecsiteconnection_post(self):
|
def test_add_ipsecsiteconnection_post(self):
|
||||||
self._test_add_ipsecsiteconnection_post()
|
self._test_add_ipsecsiteconnection_post()
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_create')})
|
'ipsecsiteconnection_create')})
|
||||||
def test_add_ipsecsiteconnection_post_single_subnet(self):
|
def test_add_ipsecsiteconnection_post_single_subnet(self):
|
||||||
self._test_add_ipsecsiteconnection_post(subnet_list=False)
|
self._test_add_ipsecsiteconnection_post(subnet_list=False)
|
||||||
@ -498,13 +604,13 @@ class VPNTests(test.TestCase):
|
|||||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_create')})
|
'ipsecsiteconnection_create')})
|
||||||
def test_add_ipsecsiteconnection_post_required_fields_error(self):
|
def test_add_ipsecsiteconnection_post_required_fields_error(self):
|
||||||
self._test_add_ipsecsiteconnection_post_error()
|
self._test_add_ipsecsiteconnection_post_error()
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
'vpnservice_list',
|
'vpnservice_list', 'endpointgroup_list',
|
||||||
'ipsecsiteconnection_create')})
|
'ipsecsiteconnection_create')})
|
||||||
def test_add_ipsecsiteconnection_post_peer_cidrs_error(self):
|
def test_add_ipsecsiteconnection_post_peer_cidrs_error(self):
|
||||||
self._test_add_ipsecsiteconnection_post_error(subnets=True)
|
self._test_add_ipsecsiteconnection_post_error(subnets=True)
|
||||||
@ -548,7 +654,10 @@ class VPNTests(test.TestCase):
|
|||||||
|
|
||||||
res = self.client.post(reverse(self.ADDVPNCONNECTION_PATH), form_data)
|
res = self.client.post(reverse(self.ADDVPNCONNECTION_PATH), form_data)
|
||||||
|
|
||||||
self.assertFormErrors(res, 7)
|
if subnets:
|
||||||
|
self.assertFormErrors(res, 7)
|
||||||
|
else:
|
||||||
|
self.assertFormErrors(res, 6)
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('vpnservice_get', )})
|
@test.create_stubs({api_vpn: ('vpnservice_get', )})
|
||||||
def test_update_vpnservice_get(self):
|
def test_update_vpnservice_get(self):
|
||||||
@ -590,6 +699,48 @@ class VPNTests(test.TestCase):
|
|||||||
self.assertNoFormErrors(res)
|
self.assertNoFormErrors(res)
|
||||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
@test.create_stubs({api_vpn: ('endpointgroup_get', )})
|
||||||
|
def test_update_endpointgroup_get(self):
|
||||||
|
endpointgroup = self.endpointgroups.first()
|
||||||
|
|
||||||
|
api_vpn.endpointgroup_get(IsA(http.HttpRequest), endpointgroup.id)\
|
||||||
|
.AndReturn(endpointgroup)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(
|
||||||
|
reverse(self.UPDATEENDPOINTGROUP_PATH, args=(endpointgroup.id,)))
|
||||||
|
|
||||||
|
self.assertTemplateUsed(
|
||||||
|
res, 'project/vpn/update_endpointgroup.html')
|
||||||
|
|
||||||
|
@test.create_stubs({api_vpn: ('endpointgroup_get',
|
||||||
|
'endpointgroup_update')})
|
||||||
|
def test_update_endpointgroup_post(self):
|
||||||
|
endpointgroup = self.endpointgroups.first()
|
||||||
|
|
||||||
|
api_vpn.endpointgroup_get(IsA(http.HttpRequest), endpointgroup.id)\
|
||||||
|
.AndReturn(endpointgroup)
|
||||||
|
|
||||||
|
data = {'name': endpointgroup.name,
|
||||||
|
'description': endpointgroup.description}
|
||||||
|
|
||||||
|
api_vpn.endpointgroup_update(IsA(http.HttpRequest), endpointgroup.id,
|
||||||
|
endpointgroup=data
|
||||||
|
).AndReturn(endpointgroup)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = data.copy()
|
||||||
|
form_data['endpoint_group_id'] = endpointgroup.id
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.UPDATEENDPOINTGROUP_PATH,
|
||||||
|
args=(endpointgroup.id, )
|
||||||
|
), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_get', )})
|
@test.create_stubs({api_vpn: ('ikepolicy_get', )})
|
||||||
def test_update_ikepolicy_get(self):
|
def test_update_ikepolicy_get(self):
|
||||||
ikepolicy = self.ikepolicies.first()
|
ikepolicy = self.ikepolicies.first()
|
||||||
@ -764,6 +915,23 @@ class VPNTests(test.TestCase):
|
|||||||
|
|
||||||
self.assertNoFormErrors(res)
|
self.assertNoFormErrors(res)
|
||||||
|
|
||||||
|
@test.create_stubs({api_vpn: ('endpointgroup_list',
|
||||||
|
'endpointgroup_delete',)})
|
||||||
|
def test_delete_endpointgroup(self):
|
||||||
|
endpointgroup = self.endpointgroups.list()[0]
|
||||||
|
api_vpn.endpointgroup_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.endpointgroups.list())
|
||||||
|
api_vpn.endpointgroup_delete(IsA(http.HttpRequest), endpointgroup.id)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = {"action":
|
||||||
|
"endpointgroupstable__deleteendpointgroup__%s"
|
||||||
|
% endpointgroup.id}
|
||||||
|
res = self.client.post(self.INDEX_URL, form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
|
||||||
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ikepolicy_delete',)})
|
@test.create_stubs({api_vpn: ('ikepolicy_list', 'ikepolicy_delete',)})
|
||||||
def test_delete_ikepolicy(self):
|
def test_delete_ikepolicy(self):
|
||||||
ikepolicy = self.ikepolicies.list()[1]
|
ikepolicy = self.ikepolicies.list()[1]
|
||||||
|
@ -36,12 +36,18 @@ urlpatterns = [
|
|||||||
views.AddVPNServiceView.as_view(), name='addvpnservice'),
|
views.AddVPNServiceView.as_view(), name='addvpnservice'),
|
||||||
url(r'^update_vpnservice/(?P<vpnservice_id>[^/]+)/$',
|
url(r'^update_vpnservice/(?P<vpnservice_id>[^/]+)/$',
|
||||||
views.UpdateVPNServiceView.as_view(), name='update_vpnservice'),
|
views.UpdateVPNServiceView.as_view(), name='update_vpnservice'),
|
||||||
|
url(r'^addendpointgroup$',
|
||||||
|
views.AddEndpointGroupView.as_view(), name='addendpointgroup'),
|
||||||
|
url(r'^update_endpointgroup/(?P<endpoint_group_id>[^/]+)/$',
|
||||||
|
views.UpdateEndpointGroupView.as_view(), name='update_endpointgroup'),
|
||||||
url(r'^ikepolicy/(?P<ikepolicy_id>[^/]+)/$',
|
url(r'^ikepolicy/(?P<ikepolicy_id>[^/]+)/$',
|
||||||
views.IKEPolicyDetailsView.as_view(), name='ikepolicydetails'),
|
views.IKEPolicyDetailsView.as_view(), name='ikepolicydetails'),
|
||||||
url(r'^ipsecpolicy/(?P<ipsecpolicy_id>[^/]+)/$',
|
url(r'^ipsecpolicy/(?P<ipsecpolicy_id>[^/]+)/$',
|
||||||
views.IPSecPolicyDetailsView.as_view(), name='ipsecpolicydetails'),
|
views.IPSecPolicyDetailsView.as_view(), name='ipsecpolicydetails'),
|
||||||
url(r'^vpnservice/(?P<vpnservice_id>[^/]+)/$',
|
url(r'^vpnservice/(?P<vpnservice_id>[^/]+)/$',
|
||||||
views.VPNServiceDetailsView.as_view(), name='vpnservicedetails'),
|
views.VPNServiceDetailsView.as_view(), name='vpnservicedetails'),
|
||||||
|
url(r'^endpointgroup/(?P<endpoint_group_id>[^/]+)/$',
|
||||||
|
views.EndpointGroupDetailsView.as_view(), name='endpointgroupdetails'),
|
||||||
url(r'^ipsecsiteconnection/(?P<ipsecsiteconnection_id>[^/]+)/$',
|
url(r'^ipsecsiteconnection/(?P<ipsecsiteconnection_id>[^/]+)/$',
|
||||||
views.IPSecSiteConnectionDetailsView.as_view(),
|
views.IPSecSiteConnectionDetailsView.as_view(),
|
||||||
name='ipsecsiteconnectiondetails'),
|
name='ipsecsiteconnectiondetails'),
|
||||||
|
@ -39,6 +39,10 @@ class AddVPNServiceView(horizon_workflows.WorkflowView):
|
|||||||
workflow_class = workflows.AddVPNService
|
workflow_class = workflows.AddVPNService
|
||||||
|
|
||||||
|
|
||||||
|
class AddEndpointGroupView(horizon_workflows.WorkflowView):
|
||||||
|
workflow_class = workflows.AddEndpointGroup
|
||||||
|
|
||||||
|
|
||||||
class AddIPSecSiteConnectionView(horizon_workflows.WorkflowView):
|
class AddIPSecSiteConnectionView(horizon_workflows.WorkflowView):
|
||||||
workflow_class = workflows.AddIPSecSiteConnection
|
workflow_class = workflows.AddIPSecSiteConnection
|
||||||
|
|
||||||
@ -161,6 +165,50 @@ class VPNServiceDetailsView(horizon_tabs.TabView):
|
|||||||
return reverse_lazy('horizon:project:vpn:index')
|
return reverse_lazy('horizon:project:vpn:index')
|
||||||
|
|
||||||
|
|
||||||
|
class EndpointGroupDetailsView(horizon_tabs.TabView):
|
||||||
|
tab_group_class = tabs.EndpointGroupDetailsTabs
|
||||||
|
template_name = 'horizon/common/_detail.html'
|
||||||
|
page_title = "{{ endpointgroup.name|default:endpointgroup.id }}"
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def get_data(self):
|
||||||
|
gid = self.kwargs['endpoint_group_id']
|
||||||
|
|
||||||
|
try:
|
||||||
|
endpointgroup = api_vpn.endpointgroup_get(self.request, gid)
|
||||||
|
except Exception:
|
||||||
|
msg = _('Unable to retrieve endpoint group details.')
|
||||||
|
exceptions.handle(self.request, msg,
|
||||||
|
redirect=self.get_redirect_url())
|
||||||
|
try:
|
||||||
|
connections = api_vpn.ipsecsiteconnection_list(
|
||||||
|
self.request, endpoint_group_id=gid)
|
||||||
|
endpointgroup.vpnconnections = connections
|
||||||
|
except Exception:
|
||||||
|
endpointgroup.vpnconnections = []
|
||||||
|
|
||||||
|
return endpointgroup
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(EndpointGroupDetailsView, self).get_context_data(
|
||||||
|
**kwargs)
|
||||||
|
endpointgroup = self.get_data()
|
||||||
|
table = tables.EndpointGroupTable(self.request)
|
||||||
|
context["endpointgroup"] = endpointgroup
|
||||||
|
context["url"] = self.get_redirect_url()
|
||||||
|
context["actions"] = table.render_row_actions(endpointgroup)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_tabs(self, request, *args, **kwargs):
|
||||||
|
endpointgroup = self.get_data()
|
||||||
|
return self.tab_group_class(request, endpointgroup=endpointgroup,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_redirect_url():
|
||||||
|
return reverse('horizon:project:vpn:index')
|
||||||
|
|
||||||
|
|
||||||
class IPSecSiteConnectionDetailsView(horizon_tabs.TabView):
|
class IPSecSiteConnectionDetailsView(horizon_tabs.TabView):
|
||||||
tab_group_class = tabs.IPSecSiteConnectionDetailsTabs
|
tab_group_class = tabs.IPSecSiteConnectionDetailsTabs
|
||||||
template_name = 'horizon/common/_detail.html'
|
template_name = 'horizon/common/_detail.html'
|
||||||
@ -232,6 +280,41 @@ class UpdateVPNServiceView(horizon_forms.ModalFormView):
|
|||||||
'admin_state_up': vpnservice['admin_state_up']}
|
'admin_state_up': vpnservice['admin_state_up']}
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateEndpointGroupView(horizon_forms.ModalFormView):
|
||||||
|
form_class = forms.UpdateEndpointGroup
|
||||||
|
form_id = "update_endpointgroup_form"
|
||||||
|
template_name = "project/vpn/update_endpointgroup.html"
|
||||||
|
context_object_name = 'endpointgroup'
|
||||||
|
submit_label = _("Save Changes")
|
||||||
|
submit_url = "horizon:project:vpn:update_endpointgroup"
|
||||||
|
success_url = reverse_lazy("horizon:project:vpn:index")
|
||||||
|
page_title = _("Edit Endpoint Group")
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(UpdateEndpointGroupView, self).get_context_data(
|
||||||
|
**kwargs)
|
||||||
|
context["endpoint_group_id"] = self.kwargs['endpoint_group_id']
|
||||||
|
args = (self.kwargs['endpoint_group_id'],)
|
||||||
|
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||||
|
return context
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def _get_object(self, *args, **kwargs):
|
||||||
|
endpoint_group_id = self.kwargs['endpoint_group_id']
|
||||||
|
try:
|
||||||
|
return api_vpn.endpointgroup_get(self.request, endpoint_group_id)
|
||||||
|
except Exception as e:
|
||||||
|
redirect = self.success_url
|
||||||
|
msg = _('Unable to retrieve Endpoint Group details. %s') % e
|
||||||
|
exceptions.handle(self.request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
endpointgroup = self._get_object()
|
||||||
|
return {'name': endpointgroup['name'],
|
||||||
|
'endpoint_group_id': endpointgroup['id'],
|
||||||
|
'description': endpointgroup['description']}
|
||||||
|
|
||||||
|
|
||||||
class UpdateIKEPolicyView(horizon_forms.ModalFormView):
|
class UpdateIKEPolicyView(horizon_forms.ModalFormView):
|
||||||
form_class = forms.UpdateIKEPolicy
|
form_class = forms.UpdateIKEPolicy
|
||||||
form_id = "update_ikepolicy_form"
|
form_id = "update_ikepolicy_form"
|
||||||
@ -346,16 +429,25 @@ class UpdateIPSecSiteConnectionView(horizon_forms.ModalFormView):
|
|||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
ipsecsiteconnection = self._get_object()
|
ipsecsiteconnection = self._get_object()
|
||||||
return {'name': ipsecsiteconnection['name'],
|
data = {
|
||||||
'ipsecsiteconnection_id': ipsecsiteconnection['id'],
|
'name': ipsecsiteconnection['name'],
|
||||||
'description': ipsecsiteconnection['description'],
|
'ipsecsiteconnection_id': ipsecsiteconnection['id'],
|
||||||
'peer_address': ipsecsiteconnection['peer_address'],
|
'description': ipsecsiteconnection['description'],
|
||||||
'peer_id': ipsecsiteconnection['peer_id'],
|
'peer_address': ipsecsiteconnection['peer_address'],
|
||||||
'peer_cidrs': ", ".join(ipsecsiteconnection['peer_cidrs']),
|
'peer_id': ipsecsiteconnection['peer_id'],
|
||||||
'psk': ipsecsiteconnection['psk'],
|
'psk': ipsecsiteconnection['psk'],
|
||||||
'mtu': ipsecsiteconnection['mtu'],
|
'mtu': ipsecsiteconnection['mtu'],
|
||||||
'dpd_action': ipsecsiteconnection['dpd']['action'],
|
'dpd_action': ipsecsiteconnection['dpd']['action'],
|
||||||
'dpd_interval': ipsecsiteconnection['dpd']['interval'],
|
'dpd_interval': ipsecsiteconnection['dpd']['interval'],
|
||||||
'dpd_timeout': ipsecsiteconnection['dpd']['timeout'],
|
'dpd_timeout': ipsecsiteconnection['dpd']['timeout'],
|
||||||
'initiator': ipsecsiteconnection['initiator'],
|
'initiator': ipsecsiteconnection['initiator'],
|
||||||
'admin_state_up': ipsecsiteconnection['admin_state_up']}
|
'admin_state_up': ipsecsiteconnection['admin_state_up']
|
||||||
|
}
|
||||||
|
if 'local_ep_group_id' in ipsecsiteconnection:
|
||||||
|
data['local_ep_group_id'] = \
|
||||||
|
ipsecsiteconnection['local_ep_group_id']
|
||||||
|
data['peer_ep_group_id'] = ipsecsiteconnection['peer_ep_group_id']
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
data['peer_cidrs'] = ", ".join(ipsecsiteconnection['peer_cidrs'])
|
||||||
|
return data
|
||||||
|
@ -29,7 +29,11 @@ class AddVPNServiceAction(workflows.Action):
|
|||||||
initial="", required=False,
|
initial="", required=False,
|
||||||
max_length=80, label=_("Description"))
|
max_length=80, label=_("Description"))
|
||||||
router_id = forms.ChoiceField(label=_("Router"))
|
router_id = forms.ChoiceField(label=_("Router"))
|
||||||
subnet_id = forms.ChoiceField(label=_("Subnet"))
|
subnet_id = forms.ChoiceField(
|
||||||
|
label=_("Subnet"),
|
||||||
|
help_text=_("Optional. No need to be specified "
|
||||||
|
"when you use endpoint groups."),
|
||||||
|
required=False)
|
||||||
admin_state_up = forms.BooleanField(
|
admin_state_up = forms.BooleanField(
|
||||||
label=_("Enable Admin State"),
|
label=_("Enable Admin State"),
|
||||||
help_text=_("The state of VPN service to start in. If disabled "
|
help_text=_("The state of VPN service to start in. If disabled "
|
||||||
@ -106,6 +110,109 @@ class AddVPNService(workflows.Workflow):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class AddEndpointGroupAction(workflows.Action):
|
||||||
|
name = forms.CharField(
|
||||||
|
max_length=80,
|
||||||
|
label=_("Name"),
|
||||||
|
required=False)
|
||||||
|
description = forms.CharField(
|
||||||
|
initial="",
|
||||||
|
required=False,
|
||||||
|
max_length=80,
|
||||||
|
label=_("Description"))
|
||||||
|
type = forms.ThemableChoiceField(
|
||||||
|
label=_("Type"),
|
||||||
|
help_text=_("IPSec connection validation requires that local "
|
||||||
|
"endpoints are subnets, and peer endpoints are CIDRs."),
|
||||||
|
choices=[('cidr', _('CIDR (for external systems)')),
|
||||||
|
('subnet', _('Subnet (for local systems)'))],
|
||||||
|
widget=forms.ThemableSelectWidget(attrs={
|
||||||
|
'class': 'switchable',
|
||||||
|
'data-slug': 'type', }))
|
||||||
|
cidrs = forms.MultiIPField(
|
||||||
|
required=False,
|
||||||
|
label=_("External System CIDRs"),
|
||||||
|
widget=forms.TextInput(attrs={
|
||||||
|
'class': 'switched',
|
||||||
|
'data-switch-on': 'type',
|
||||||
|
'data-type-cidr': _("External System CIDRs"),
|
||||||
|
}),
|
||||||
|
help_text=_("Remote peer subnet(s) address(es) "
|
||||||
|
"with mask(s) in CIDR format "
|
||||||
|
"separated with commas if needed "
|
||||||
|
"(e.g. 20.1.0.0/24, 21.1.0.0/24). "
|
||||||
|
"This field is valid if type is CIDR"),
|
||||||
|
version=forms.IPv4 | forms.IPv6,
|
||||||
|
mask=True)
|
||||||
|
subnets = forms.MultipleChoiceField(
|
||||||
|
required=False,
|
||||||
|
label=_("Local System Subnets"),
|
||||||
|
widget=forms.ThemableCheckboxSelectMultiple(attrs={
|
||||||
|
'class': 'switched',
|
||||||
|
'data-switch-on': 'type',
|
||||||
|
'data-type-subnet': _("External System Subnets"),
|
||||||
|
}),
|
||||||
|
help_text=_("Local subnet(s). "
|
||||||
|
"This field is valid if type is Subnet"),)
|
||||||
|
|
||||||
|
def populate_subnets_choices(self, request, context):
|
||||||
|
subnets_choices = []
|
||||||
|
try:
|
||||||
|
tenant_id = request.user.tenant_id
|
||||||
|
networks = api.neutron.network_list_for_tenant(request, tenant_id)
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request,
|
||||||
|
_('Unable to retrieve networks list.'))
|
||||||
|
networks = []
|
||||||
|
for n in networks:
|
||||||
|
for s in n['subnets']:
|
||||||
|
subnets_choices.append((s.id, s.cidr))
|
||||||
|
self.fields['subnets'].choices = subnets_choices
|
||||||
|
return subnets_choices
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = _("Add New Endpoint Groups")
|
||||||
|
permissions = ('openstack.services.network',)
|
||||||
|
help_text_template = "project/vpn/_add_endpoint_group_help.html"
|
||||||
|
|
||||||
|
|
||||||
|
class AddEndpointGroupStep(workflows.Step):
|
||||||
|
action_class = AddEndpointGroupAction
|
||||||
|
contributes = ("name", "description", "type",
|
||||||
|
"cidrs", "subnets", "endpoints")
|
||||||
|
|
||||||
|
def contribute(self, data, context):
|
||||||
|
context = super(AddEndpointGroupStep, self).contribute(data, context)
|
||||||
|
if context['type'] == 'cidr':
|
||||||
|
cidrs = context['cidrs']
|
||||||
|
context['endpoints'] = [
|
||||||
|
cidr.strip() for cidr in cidrs.split(',') if cidr.strip()]
|
||||||
|
else:
|
||||||
|
context['endpoints'] = context['subnets']
|
||||||
|
if data:
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class AddEndpointGroup(workflows.Workflow):
|
||||||
|
slug = "addendpointgroup"
|
||||||
|
name = _("Add Endpoint Group")
|
||||||
|
finalize_button_name = _("Add")
|
||||||
|
success_message = _('Added Endpoint Group "%s".')
|
||||||
|
failure_message = _('Unable to add Endpoint Group "%s".')
|
||||||
|
success_url = "horizon:project:vpn:index"
|
||||||
|
default_steps = (AddEndpointGroupStep,)
|
||||||
|
|
||||||
|
def format_status_message(self, message):
|
||||||
|
return message % self.context.get('name')
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
api_vpn.endpointgroup_create(request, **context)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class AddIKEPolicyAction(workflows.Action):
|
class AddIKEPolicyAction(workflows.Action):
|
||||||
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
description = forms.CharField(
|
description = forms.CharField(
|
||||||
@ -315,6 +422,12 @@ class AddIPSecSiteConnectionAction(workflows.Action):
|
|||||||
max_length=80, label=_("Description"))
|
max_length=80, label=_("Description"))
|
||||||
vpnservice_id = forms.ChoiceField(
|
vpnservice_id = forms.ChoiceField(
|
||||||
label=_("VPN Service associated with this connection"))
|
label=_("VPN Service associated with this connection"))
|
||||||
|
local_ep_group_id = forms.ChoiceField(
|
||||||
|
required=False,
|
||||||
|
label=_("Endpoint Group for local subnet(s)"),
|
||||||
|
help_text=_("Local subnets which the new IPsec connection is "
|
||||||
|
"connected to. Required if no subnet is specified "
|
||||||
|
"in a VPN service selected."))
|
||||||
ikepolicy_id = forms.ChoiceField(
|
ikepolicy_id = forms.ChoiceField(
|
||||||
label=_("IKE Policy associated with this connection"))
|
label=_("IKE Policy associated with this connection"))
|
||||||
ipsecpolicy_id = forms.ChoiceField(
|
ipsecpolicy_id = forms.ChoiceField(
|
||||||
@ -331,9 +444,15 @@ class AddIPSecSiteConnectionAction(workflows.Action):
|
|||||||
"Can be IPv4/IPv6 address, e-mail, key ID, or FQDN"),
|
"Can be IPv4/IPv6 address, e-mail, key ID, or FQDN"),
|
||||||
version=forms.IPv4 | forms.IPv6,
|
version=forms.IPv4 | forms.IPv6,
|
||||||
mask=False)
|
mask=False)
|
||||||
|
peer_ep_group_id = forms.ChoiceField(
|
||||||
|
required=False,
|
||||||
|
label=_("Endpoint Group for remote peer CIDR(s)"),
|
||||||
|
help_text=_("Remove peer CIDR(s) connected to the new IPSec "
|
||||||
|
"connection."))
|
||||||
peer_cidrs = forms.MultiIPField(
|
peer_cidrs = forms.MultiIPField(
|
||||||
|
required=False,
|
||||||
label=_("Remote peer subnet(s)"),
|
label=_("Remote peer subnet(s)"),
|
||||||
help_text=_("Remote peer subnet(s) address(es) "
|
help_text=_("(Deprecated) Remote peer subnet(s) address(es) "
|
||||||
"with mask(s) in CIDR format "
|
"with mask(s) in CIDR format "
|
||||||
"separated with commas if needed "
|
"separated with commas if needed "
|
||||||
"(e.g. 20.1.0.0/24, 21.1.0.0/24)"),
|
"(e.g. 20.1.0.0/24, 21.1.0.0/24)"),
|
||||||
@ -389,6 +508,36 @@ class AddIPSecSiteConnectionAction(workflows.Action):
|
|||||||
self.fields['vpnservice_id'].choices = vpnservice_id_choices
|
self.fields['vpnservice_id'].choices = vpnservice_id_choices
|
||||||
return vpnservice_id_choices
|
return vpnservice_id_choices
|
||||||
|
|
||||||
|
def populate_local_ep_group_id_choices(self, request, context):
|
||||||
|
try:
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
endpointgroups = api_vpn.endpointgroup_list(request,
|
||||||
|
tenant_id=tenant_id)
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request,
|
||||||
|
_('Unable to retrieve endpoint group list.'))
|
||||||
|
endpointgroups = []
|
||||||
|
local_ep_group_ids = [(s.id, s.name) for s in endpointgroups
|
||||||
|
if s.type == 'subnet']
|
||||||
|
local_ep_group_ids.insert(0, ('', _("Select local endpoint group")))
|
||||||
|
self.fields['local_ep_group_id'].choices = local_ep_group_ids
|
||||||
|
return local_ep_group_ids
|
||||||
|
|
||||||
|
def populate_peer_ep_group_id_choices(self, request, context):
|
||||||
|
try:
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
endpointgroups = api_vpn.endpointgroup_list(request,
|
||||||
|
tenant_id=tenant_id)
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request,
|
||||||
|
_('Unable to retrieve endpoint group list.'))
|
||||||
|
endpointgroups = []
|
||||||
|
peer_ep_group_ids = [(s.id, s.name) for s in endpointgroups
|
||||||
|
if s.type == 'cidr']
|
||||||
|
peer_ep_group_ids.insert(0, ('', _("Select peer endpoint group")))
|
||||||
|
self.fields['peer_ep_group_id'].choices = peer_ep_group_ids
|
||||||
|
return peer_ep_group_ids
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
name = _("Add New IPSec Site Connection")
|
name = _("Add New IPSec Site Connection")
|
||||||
permissions = ('openstack.services.network',)
|
permissions = ('openstack.services.network',)
|
||||||
@ -403,7 +552,8 @@ class AddIPSecSiteConnectionStep(workflows.Step):
|
|||||||
action_class = AddIPSecSiteConnectionAction
|
action_class = AddIPSecSiteConnectionAction
|
||||||
contributes = ("name", "description",
|
contributes = ("name", "description",
|
||||||
"vpnservice_id", "ikepolicy_id", "ipsecpolicy_id",
|
"vpnservice_id", "ikepolicy_id", "ipsecpolicy_id",
|
||||||
"peer_address", "peer_id", "peer_cidrs", "psk")
|
"peer_address", "peer_id", "peer_cidrs", "psk",
|
||||||
|
"local_ep_group_id", "peer_ep_group_id")
|
||||||
|
|
||||||
|
|
||||||
class AddIPSecSiteConnectionOptionalAction(workflows.Action):
|
class AddIPSecSiteConnectionOptionalAction(workflows.Action):
|
||||||
@ -489,7 +639,8 @@ class AddIPSecSiteConnectionOptionalStep(workflows.Step):
|
|||||||
context.pop('dpd_timeout')
|
context.pop('dpd_timeout')
|
||||||
|
|
||||||
cidrs = context['peer_cidrs']
|
cidrs = context['peer_cidrs']
|
||||||
context['peer_cidrs'] = cidrs.replace(" ", "").split(",")
|
context['peer_cidrs'] = [cidr.strip() for cidr in cidrs.split(',')
|
||||||
|
if cidr.strip()]
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
return context
|
return context
|
||||||
|
@ -88,6 +88,64 @@ class VPNaasApiTests(test.APITestCase):
|
|||||||
ret_val = api_vpn.vpnservice_get(self.request, vpnservice.id)
|
ret_val = api_vpn.vpnservice_get(self.request, vpnservice.id)
|
||||||
self.assertIsInstance(ret_val, api_vpn.VPNService)
|
self.assertIsInstance(ret_val, api_vpn.VPNService)
|
||||||
|
|
||||||
|
@test.create_stubs({neutronclient: ('create_endpoint_group',)})
|
||||||
|
def test_endpointgroup_create(self):
|
||||||
|
endpointgroup = self.api_endpointgroups.first()
|
||||||
|
form_data = {
|
||||||
|
'name': endpointgroup['name'],
|
||||||
|
'description': endpointgroup['description'],
|
||||||
|
'type': endpointgroup['type'],
|
||||||
|
'endpoints': endpointgroup['endpoints']
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint_group = {'endpoint_group': self.api_endpointgroups.first()}
|
||||||
|
neutronclient.create_endpoint_group(
|
||||||
|
{'endpoint_group': form_data}).AndReturn(endpoint_group)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
ret_val = api_vpn.endpointgroup_create(self.request, **form_data)
|
||||||
|
self.assertIsInstance(ret_val, api_vpn.EndpointGroup)
|
||||||
|
|
||||||
|
@test.create_stubs({neutronclient: ('list_endpoint_groups',
|
||||||
|
'list_ipsec_site_connections')})
|
||||||
|
def test_endpointgroup_list(self):
|
||||||
|
endpointgroups = {'endpoint_groups': self.endpointgroups.list()}
|
||||||
|
endpointgroups_dict = {
|
||||||
|
'endpoint_groups': self.api_endpointgroups.list()}
|
||||||
|
ipsecsiteconnections_dict = {
|
||||||
|
'ipsec_site_connections': self.api_ipsecsiteconnections.list()}
|
||||||
|
|
||||||
|
neutronclient.list_endpoint_groups().AndReturn(endpointgroups_dict)
|
||||||
|
neutronclient.list_ipsec_site_connections().AndReturn(
|
||||||
|
ipsecsiteconnections_dict)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
ret_val = api_vpn.endpointgroup_list(self.request)
|
||||||
|
for (v, d) in zip(ret_val, endpointgroups['endpoint_groups']):
|
||||||
|
self.assertIsInstance(v, api_vpn.EndpointGroup)
|
||||||
|
self.assertTrue(v.name, d.name)
|
||||||
|
self.assertTrue(v.id)
|
||||||
|
|
||||||
|
@test.create_stubs({neutronclient: ('show_endpoint_group',
|
||||||
|
'list_ipsec_site_connections')})
|
||||||
|
def test_endpointgroup_get(self):
|
||||||
|
endpoint_group = self.endpointgroups.first()
|
||||||
|
endpoint_group_dict = {
|
||||||
|
'endpoint_group': self.api_endpointgroups.first()}
|
||||||
|
ipsecsiteconnections_dict = {
|
||||||
|
'ipsec_site_connections': self.api_ipsecsiteconnections.list()}
|
||||||
|
|
||||||
|
neutronclient.show_endpoint_group(
|
||||||
|
endpoint_group.id).AndReturn(endpoint_group_dict)
|
||||||
|
neutronclient.list_ipsec_site_connections().AndReturn(
|
||||||
|
ipsecsiteconnections_dict)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
ret_val = api_vpn.endpointgroup_get(self.request, endpoint_group.id)
|
||||||
|
self.assertIsInstance(ret_val, api_vpn.EndpointGroup)
|
||||||
|
|
||||||
@test.create_stubs({neutronclient: ('create_ikepolicy',)})
|
@test.create_stubs({neutronclient: ('create_ikepolicy',)})
|
||||||
def test_ikepolicy_create(self):
|
def test_ikepolicy_create(self):
|
||||||
ikepolicy1 = self.api_ikepolicies.first()
|
ikepolicy1 = self.api_ikepolicies.first()
|
||||||
|
@ -23,12 +23,14 @@ def data(TEST):
|
|||||||
TEST.ikepolicies = utils.TestDataContainer()
|
TEST.ikepolicies = utils.TestDataContainer()
|
||||||
TEST.ipsecpolicies = utils.TestDataContainer()
|
TEST.ipsecpolicies = utils.TestDataContainer()
|
||||||
TEST.ipsecsiteconnections = utils.TestDataContainer()
|
TEST.ipsecsiteconnections = utils.TestDataContainer()
|
||||||
|
TEST.endpointgroups = utils.TestDataContainer()
|
||||||
|
|
||||||
# Data return by neutronclient.
|
# Data return by neutronclient.
|
||||||
TEST.api_vpnservices = utils.TestDataContainer()
|
TEST.api_vpnservices = utils.TestDataContainer()
|
||||||
TEST.api_ikepolicies = utils.TestDataContainer()
|
TEST.api_ikepolicies = utils.TestDataContainer()
|
||||||
TEST.api_ipsecpolicies = utils.TestDataContainer()
|
TEST.api_ipsecpolicies = utils.TestDataContainer()
|
||||||
TEST.api_ipsecsiteconnections = utils.TestDataContainer()
|
TEST.api_ipsecsiteconnections = utils.TestDataContainer()
|
||||||
|
TEST.api_endpointgroups = utils.TestDataContainer()
|
||||||
|
|
||||||
# 1st VPNService.
|
# 1st VPNService.
|
||||||
vpnservice_dict = {'id': '09a26949-6231-4f72-942a-0c8c0ddd4d61',
|
vpnservice_dict = {'id': '09a26949-6231-4f72-942a-0c8c0ddd4d61',
|
||||||
@ -64,6 +66,17 @@ def data(TEST):
|
|||||||
TEST.api_vpnservices.add(vpnservice_dict)
|
TEST.api_vpnservices.add(vpnservice_dict)
|
||||||
TEST.vpnservices.add(vpn.VPNService(vpnservice_dict))
|
TEST.vpnservices.add(vpn.VPNService(vpnservice_dict))
|
||||||
|
|
||||||
|
# 1st Endpoint Group
|
||||||
|
endpointgroup_dict = {'id': 'baa588ff-e1b9-4256-8687-9f06315f64b7',
|
||||||
|
'tenant_id': '1',
|
||||||
|
'name': 'endpoint_group_one',
|
||||||
|
'description': 'the first test endpoint group',
|
||||||
|
'type': 'subnet',
|
||||||
|
'endpoints': [TEST.subnets.first().id]
|
||||||
|
}
|
||||||
|
TEST.api_endpointgroups.add(endpointgroup_dict)
|
||||||
|
TEST.endpointgroups.add(vpn.EndpointGroup(endpointgroup_dict))
|
||||||
|
|
||||||
# 1st IKEPolicy
|
# 1st IKEPolicy
|
||||||
ikepolicy_dict = {'id': 'a1f009b7-0ffa-43a7-ba19-dcabb0b4c981',
|
ikepolicy_dict = {'id': 'a1f009b7-0ffa-43a7-ba19-dcabb0b4c981',
|
||||||
'tenant_id': '1',
|
'tenant_id': '1',
|
||||||
|
4
releasenotes/notes/endpoint-group-3bb4083130952d17.yaml
Normal file
4
releasenotes/notes/endpoint-group-3bb4083130952d17.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add support for Endpoint Group feature.
|
Loading…
Reference in New Issue
Block a user