Initial commit
This commit is contained in:
commit
7fada8ebbf
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.pyc
|
||||||
|
*.swp
|
17
CONTRIBUTING.rst
Normal file
17
CONTRIBUTING.rst
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
If you would like to contribute to the development of OpenStack, you must
|
||||||
|
follow the steps in this page:
|
||||||
|
|
||||||
|
http://docs.openstack.org/infra/manual/developers.html
|
||||||
|
|
||||||
|
If you already have a good understanding of how the system works and your
|
||||||
|
OpenStack accounts are set up, you can skip to the development workflow
|
||||||
|
section of this documentation to learn how changes to OpenStack should be
|
||||||
|
submitted for review via the Gerrit tool:
|
||||||
|
|
||||||
|
http://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||||
|
|
||||||
|
Pull requests submitted through GitHub will be ignored.
|
||||||
|
|
||||||
|
Bugs should be filed on Launchpad, not GitHub:
|
||||||
|
|
||||||
|
https://bugs.launchpad.net/neutron-vpnaas-dashbaard
|
13
HACKING.rst
Normal file
13
HACKING.rst
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
===========================================
|
||||||
|
Neutron VPNaaS Dashboard Style Commandments
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
Read the OpenStack Style Commandments
|
||||||
|
http://docs.openstack.org/developer/hacking/
|
||||||
|
|
||||||
|
Project Specific Commandments
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
- Read the Horizon contributing documentation at
|
||||||
|
http://docs.openstack.org/developer/horizon/contributing.html
|
||||||
|
- [M322] Method's default argument shouldn't be mutable.
|
176
LICENSE
Normal file
176
LICENSE
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
9
README.rst
Normal file
9
README.rst
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
========================
|
||||||
|
Neutron VPNaaS Dashboard
|
||||||
|
========================
|
||||||
|
|
||||||
|
OpenStack Dashboard panels for Neutron VPNaaS
|
||||||
|
|
||||||
|
* Documentation: http://docs.openstack.org/developer/neutron-vpnaas-dashboard
|
||||||
|
* Source: http://git.openstack.org/cgit/openstack/neutron-vpnaas-dashboard
|
||||||
|
* Bugs: http://bugs.launchpad.net/neutron-vpnaas-dashboard
|
381
neutron_vpnaas_dashboard/api/vpn.py
Normal file
381
neutron_vpnaas_dashboard/api/vpn.py
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
# Copyright 2013, Mirantis Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
from horizon.utils.memoized import memoized
|
||||||
|
|
||||||
|
from openstack_dashboard.api import neutron
|
||||||
|
from openstack_dashboard.contrib.developer.profiler import api as profiler
|
||||||
|
|
||||||
|
neutronclient = neutron.neutronclient
|
||||||
|
|
||||||
|
|
||||||
|
class IKEPolicy(neutron.NeutronAPIDictWrapper):
|
||||||
|
"""Wrapper for neutron VPN IKEPolicy."""
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecPolicy(neutron.NeutronAPIDictWrapper):
|
||||||
|
"""Wrapper for neutron VPN IPSecPolicy."""
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecSiteConnection(neutron.NeutronAPIDictWrapper):
|
||||||
|
"""Wrapper for neutron IPSecSiteConnection."""
|
||||||
|
|
||||||
|
|
||||||
|
class VPNService(neutron.NeutronAPIDictWrapper):
|
||||||
|
"""Wrapper for neutron VPNService."""
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def vpnservice_create(request, **kwargs):
|
||||||
|
"""Create VPNService
|
||||||
|
|
||||||
|
:param request: request context
|
||||||
|
:param admin_state_up: admin state (default on)
|
||||||
|
:param name: name for VPNService
|
||||||
|
:param description: description for VPNService
|
||||||
|
:param router_id: router id for router of VPNService
|
||||||
|
:param subnet_id: subnet id for subnet of VPNService
|
||||||
|
"""
|
||||||
|
body = {'vpnservice':
|
||||||
|
{'admin_state_up': kwargs['admin_state_up'],
|
||||||
|
'name': kwargs['name'],
|
||||||
|
'description': kwargs['description'],
|
||||||
|
'router_id': kwargs['router_id'],
|
||||||
|
'subnet_id': kwargs['subnet_id']}
|
||||||
|
}
|
||||||
|
vpnservice = neutronclient(request).create_vpnservice(body).get(
|
||||||
|
'vpnservice')
|
||||||
|
return VPNService(vpnservice)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def vpnservice_list(request, **kwargs):
|
||||||
|
return _vpnservice_list(request, expand_subnet=True, expand_router=True,
|
||||||
|
expand_conns=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def _vpnservice_list(request, expand_subnet=False, expand_router=False,
|
||||||
|
expand_conns=False, **kwargs):
|
||||||
|
vpnservices = neutronclient(request).list_vpnservices(
|
||||||
|
**kwargs).get('vpnservices')
|
||||||
|
if expand_subnet:
|
||||||
|
subnets = neutron.subnet_list(request)
|
||||||
|
subnet_dict = OrderedDict((s.id, s) for s in subnets)
|
||||||
|
for s in vpnservices:
|
||||||
|
s['subnet_name'] = subnet_dict.get(s['subnet_id']).cidr
|
||||||
|
if expand_router:
|
||||||
|
routers = neutron.router_list(request)
|
||||||
|
router_dict = OrderedDict((r.id, r) for r in routers)
|
||||||
|
for s in vpnservices:
|
||||||
|
s['router_name'] = router_dict.get(s['router_id']).name_or_id
|
||||||
|
if expand_conns:
|
||||||
|
ipsecsiteconns = _ipsecsiteconnection_list(request, **kwargs)
|
||||||
|
for s in vpnservices:
|
||||||
|
s['ipsecsiteconns'] = [c.id for c in ipsecsiteconns
|
||||||
|
if c.vpnservice_id == s['id']]
|
||||||
|
return [VPNService(v) for v in vpnservices]
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def vpnservice_get(request, vpnservice_id):
|
||||||
|
return _vpnservice_get(request, vpnservice_id, expand_subnet=True,
|
||||||
|
expand_router=True, expand_conns=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _vpnservice_get(request, vpnservice_id, expand_subnet=False,
|
||||||
|
expand_router=False, expand_conns=False):
|
||||||
|
vpnservice = neutronclient(request).show_vpnservice(vpnservice_id).get(
|
||||||
|
'vpnservice')
|
||||||
|
if expand_subnet:
|
||||||
|
vpnservice['subnet'] = neutron.subnet_get(
|
||||||
|
request, vpnservice['subnet_id'])
|
||||||
|
if expand_router:
|
||||||
|
vpnservice['router'] = neutron.router_get(
|
||||||
|
request, vpnservice['router_id'])
|
||||||
|
if expand_conns:
|
||||||
|
ipsecsiteconns = _ipsecsiteconnection_list(request)
|
||||||
|
vpnservice['ipsecsiteconns'] = [c for c in ipsecsiteconns
|
||||||
|
if c.vpnservice_id == vpnservice['id']]
|
||||||
|
return VPNService(vpnservice)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def vpnservice_update(request, vpnservice_id, **kwargs):
|
||||||
|
vpnservice = neutronclient(request).update_vpnservice(
|
||||||
|
vpnservice_id, kwargs).get('vpnservice')
|
||||||
|
return VPNService(vpnservice)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def vpnservice_delete(request, vpnservice_id):
|
||||||
|
neutronclient(request).delete_vpnservice(vpnservice_id)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ikepolicy_create(request, **kwargs):
|
||||||
|
"""Create IKEPolicy
|
||||||
|
|
||||||
|
:param request: request context
|
||||||
|
:param name: name for IKEPolicy
|
||||||
|
:param description: description for IKEPolicy
|
||||||
|
:param auth_algorithm: authorization algorithm for IKEPolicy
|
||||||
|
:param encryption_algorithm: encryption algorithm for IKEPolicy
|
||||||
|
:param ike_version: IKE version for IKEPolicy
|
||||||
|
:param lifetime: Lifetime Units and Value for IKEPolicy
|
||||||
|
:param pfs: Perfect Forward Secrecy for IKEPolicy
|
||||||
|
:param phase1_negotiation_mode: IKE Phase1 negotiation mode for IKEPolicy
|
||||||
|
"""
|
||||||
|
body = {'ikepolicy':
|
||||||
|
{'name': kwargs['name'],
|
||||||
|
'description': kwargs['description'],
|
||||||
|
'auth_algorithm': kwargs['auth_algorithm'],
|
||||||
|
'encryption_algorithm': kwargs['encryption_algorithm'],
|
||||||
|
'ike_version': kwargs['ike_version'],
|
||||||
|
'lifetime': kwargs['lifetime'],
|
||||||
|
'pfs': kwargs['pfs'],
|
||||||
|
'phase1_negotiation_mode': kwargs['phase1_negotiation_mode']}
|
||||||
|
}
|
||||||
|
ikepolicy = neutronclient(request).create_ikepolicy(body).get(
|
||||||
|
'ikepolicy')
|
||||||
|
return IKEPolicy(ikepolicy)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ikepolicy_list(request, **kwargs):
|
||||||
|
return _ikepolicy_list(request, expand_conns=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def _ikepolicy_list(request, expand_conns=False, **kwargs):
|
||||||
|
ikepolicies = neutronclient(request).list_ikepolicies(
|
||||||
|
**kwargs).get('ikepolicies')
|
||||||
|
if expand_conns:
|
||||||
|
ipsecsiteconns = _ipsecsiteconnection_list(request, **kwargs)
|
||||||
|
for p in ikepolicies:
|
||||||
|
p['ipsecsiteconns'] = [c.id for c in ipsecsiteconns
|
||||||
|
if c.ikepolicy_id == p['id']]
|
||||||
|
return [IKEPolicy(v) for v in ikepolicies]
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ikepolicy_get(request, ikepolicy_id):
|
||||||
|
return _ikepolicy_get(request, ikepolicy_id, expand_conns=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _ikepolicy_get(request, ikepolicy_id, expand_conns=False):
|
||||||
|
ikepolicy = neutronclient(request).show_ikepolicy(
|
||||||
|
ikepolicy_id).get('ikepolicy')
|
||||||
|
if expand_conns:
|
||||||
|
ipsecsiteconns = _ipsecsiteconnection_list(request)
|
||||||
|
ikepolicy['ipsecsiteconns'] = [c for c in ipsecsiteconns
|
||||||
|
if c.ikepolicy_id == ikepolicy['id']]
|
||||||
|
return IKEPolicy(ikepolicy)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ikepolicy_update(request, ikepolicy_id, **kwargs):
|
||||||
|
ikepolicy = neutronclient(request).update_ikepolicy(
|
||||||
|
ikepolicy_id, kwargs).get('ikepolicy')
|
||||||
|
return IKEPolicy(ikepolicy)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ikepolicy_delete(request, ikepolicy_id):
|
||||||
|
neutronclient(request).delete_ikepolicy(ikepolicy_id)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ipsecpolicy_create(request, **kwargs):
|
||||||
|
"""Create IPSecPolicy
|
||||||
|
|
||||||
|
:param request: request context
|
||||||
|
:param name: name for IPSecPolicy
|
||||||
|
:param description: description for IPSecPolicy
|
||||||
|
:param auth_algorithm: authorization algorithm for IPSecPolicy
|
||||||
|
:param encapsulation_mode: encapsulation mode for IPSecPolicy
|
||||||
|
:param encryption_algorithm: encryption algorithm for IPSecPolicy
|
||||||
|
:param lifetime: Lifetime Units and Value for IPSecPolicy
|
||||||
|
:param pfs: Perfect Forward Secrecy for IPSecPolicy
|
||||||
|
:param transform_protocol: Transform Protocol for IPSecPolicy
|
||||||
|
"""
|
||||||
|
body = {'ipsecpolicy':
|
||||||
|
{'name': kwargs['name'],
|
||||||
|
'description': kwargs['description'],
|
||||||
|
'auth_algorithm': kwargs['auth_algorithm'],
|
||||||
|
'encapsulation_mode': kwargs['encapsulation_mode'],
|
||||||
|
'encryption_algorithm': kwargs['encryption_algorithm'],
|
||||||
|
'lifetime': kwargs['lifetime'],
|
||||||
|
'pfs': kwargs['pfs'],
|
||||||
|
'transform_protocol': kwargs['transform_protocol']}
|
||||||
|
}
|
||||||
|
ipsecpolicy = neutronclient(request).create_ipsecpolicy(body).get(
|
||||||
|
'ipsecpolicy')
|
||||||
|
return IPSecPolicy(ipsecpolicy)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ipsecpolicy_list(request, **kwargs):
|
||||||
|
return _ipsecpolicy_list(request, expand_conns=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def _ipsecpolicy_list(request, expand_conns=False, **kwargs):
|
||||||
|
ipsecpolicies = neutronclient(request).list_ipsecpolicies(
|
||||||
|
**kwargs).get('ipsecpolicies')
|
||||||
|
if expand_conns:
|
||||||
|
ipsecsiteconns = _ipsecsiteconnection_list(request, **kwargs)
|
||||||
|
for p in ipsecpolicies:
|
||||||
|
p['ipsecsiteconns'] = [c.id for c in ipsecsiteconns
|
||||||
|
if c.ipsecpolicy_id == p['id']]
|
||||||
|
return [IPSecPolicy(v) for v in ipsecpolicies]
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ipsecpolicy_get(request, ipsecpolicy_id):
|
||||||
|
return _ipsecpolicy_get(request, ipsecpolicy_id, expand_conns=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _ipsecpolicy_get(request, ipsecpolicy_id, expand_conns=False):
|
||||||
|
ipsecpolicy = neutronclient(request).show_ipsecpolicy(
|
||||||
|
ipsecpolicy_id).get('ipsecpolicy')
|
||||||
|
if expand_conns:
|
||||||
|
ipsecsiteconns = _ipsecsiteconnection_list(request)
|
||||||
|
ipsecpolicy['ipsecsiteconns'] = [c for c in ipsecsiteconns
|
||||||
|
if (c.ipsecpolicy_id ==
|
||||||
|
ipsecpolicy['id'])]
|
||||||
|
return IPSecPolicy(ipsecpolicy)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ipsecpolicy_update(request, ipsecpolicy_id, **kwargs):
|
||||||
|
ipsecpolicy = neutronclient(request).update_ipsecpolicy(
|
||||||
|
ipsecpolicy_id, kwargs).get('ipsecpolicy')
|
||||||
|
return IPSecPolicy(ipsecpolicy)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ipsecpolicy_delete(request, ipsecpolicy_id):
|
||||||
|
neutronclient(request).delete_ipsecpolicy(ipsecpolicy_id)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ipsecsiteconnection_create(request, **kwargs):
|
||||||
|
"""Create IPSecSiteConnection
|
||||||
|
|
||||||
|
:param request: request context
|
||||||
|
:param name: name for IPSecSiteConnection
|
||||||
|
:param description: description for IPSecSiteConnection
|
||||||
|
:param dpd: dead peer detection action, interval and timeout
|
||||||
|
:param ikepolicy_id: IKEPolicy associated with this connection
|
||||||
|
:param initiator: initiator state
|
||||||
|
:param ipsecpolicy_id: IPsecPolicy associated with this connection
|
||||||
|
:param mtu: MTU size for the connection
|
||||||
|
:param peer_address: Peer gateway public address
|
||||||
|
:param peer_cidrs: remote subnet(s) in CIDR format
|
||||||
|
:param peer_id: Peer router identity for authentication"
|
||||||
|
:param psk: Pre-Shared Key string
|
||||||
|
:param vpnservice_id: VPNService associated with this connection
|
||||||
|
:param admin_state_up: admin state (default on)
|
||||||
|
"""
|
||||||
|
body = {'ipsec_site_connection':
|
||||||
|
{'name': kwargs['name'],
|
||||||
|
'description': kwargs['description'],
|
||||||
|
'dpd': kwargs['dpd'],
|
||||||
|
'ikepolicy_id': kwargs['ikepolicy_id'],
|
||||||
|
'initiator': kwargs['initiator'],
|
||||||
|
'ipsecpolicy_id': kwargs['ipsecpolicy_id'],
|
||||||
|
'mtu': kwargs['mtu'],
|
||||||
|
'peer_address': kwargs['peer_address'],
|
||||||
|
'peer_cidrs': kwargs['peer_cidrs'],
|
||||||
|
'peer_id': kwargs['peer_id'],
|
||||||
|
'psk': kwargs['psk'],
|
||||||
|
'vpnservice_id': kwargs['vpnservice_id'],
|
||||||
|
'admin_state_up': kwargs['admin_state_up']}
|
||||||
|
}
|
||||||
|
ipsecsiteconnection = neutronclient(request).create_ipsec_site_connection(
|
||||||
|
body).get('ipsec_site_connection')
|
||||||
|
return IPSecSiteConnection(ipsecsiteconnection)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
@memoized
|
||||||
|
def ipsecsiteconnection_list(request, **kwargs):
|
||||||
|
return _ipsecsiteconnection_list(request, expand_ikepolicies=True,
|
||||||
|
expand_ipsecpolicies=True,
|
||||||
|
expand_vpnservices=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@memoized
|
||||||
|
def _ipsecsiteconnection_list(request, expand_ikepolicies=False,
|
||||||
|
expand_ipsecpolicies=False,
|
||||||
|
expand_vpnservices=False, **kwargs):
|
||||||
|
ipsecsiteconnections = neutronclient(request).list_ipsec_site_connections(
|
||||||
|
**kwargs).get('ipsec_site_connections')
|
||||||
|
if expand_ikepolicies:
|
||||||
|
ikepolicies = _ikepolicy_list(request)
|
||||||
|
policy_dict = OrderedDict((p.id, p) for p in ikepolicies)
|
||||||
|
for c in ipsecsiteconnections:
|
||||||
|
c['ikepolicy_name'] = policy_dict.get(c['ikepolicy_id']).name_or_id
|
||||||
|
if expand_ipsecpolicies:
|
||||||
|
ipsecpolicies = _ipsecpolicy_list(request)
|
||||||
|
policy_dict = OrderedDict((p.id, p) for p in ipsecpolicies)
|
||||||
|
for c in ipsecsiteconnections:
|
||||||
|
c['ipsecpolicy_name'] = policy_dict.get(c['ipsecpolicy_id']
|
||||||
|
).name_or_id
|
||||||
|
if expand_vpnservices:
|
||||||
|
vpnservices = _vpnservice_list(request)
|
||||||
|
service_dict = OrderedDict((s.id, s) for s in vpnservices)
|
||||||
|
for c in ipsecsiteconnections:
|
||||||
|
c['vpnservice_name'] = service_dict.get(c['vpnservice_id']
|
||||||
|
).name_or_id
|
||||||
|
return [IPSecSiteConnection(v) for v in ipsecsiteconnections]
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ipsecsiteconnection_get(request, ipsecsiteconnection_id):
|
||||||
|
return _ipsecsiteconnection_get(request, ipsecsiteconnection_id,
|
||||||
|
expand_ikepolicies=True,
|
||||||
|
expand_ipsecpolicies=True,
|
||||||
|
expand_vpnservices=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _ipsecsiteconnection_get(request, ipsecsiteconnection_id,
|
||||||
|
expand_ikepolicies, expand_ipsecpolicies,
|
||||||
|
expand_vpnservices):
|
||||||
|
ipsecsiteconnection = neutronclient(request).show_ipsec_site_connection(
|
||||||
|
ipsecsiteconnection_id).get('ipsec_site_connection')
|
||||||
|
if expand_ikepolicies:
|
||||||
|
ipsecsiteconnection['ikepolicy'] = _ikepolicy_get(
|
||||||
|
request, ipsecsiteconnection['ikepolicy_id'])
|
||||||
|
if expand_ipsecpolicies:
|
||||||
|
ipsecsiteconnection['ipsecpolicy'] = _ipsecpolicy_get(
|
||||||
|
request, ipsecsiteconnection['ipsecpolicy_id'])
|
||||||
|
if expand_vpnservices:
|
||||||
|
ipsecsiteconnection['vpnservice'] = _vpnservice_get(
|
||||||
|
request, ipsecsiteconnection['vpnservice_id'])
|
||||||
|
return IPSecSiteConnection(ipsecsiteconnection)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ipsecsiteconnection_update(request, ipsecsiteconnection_id, **kwargs):
|
||||||
|
ipsecsiteconnection = neutronclient(request).update_ipsec_site_connection(
|
||||||
|
ipsecsiteconnection_id, kwargs).get('ipsec_site_connection')
|
||||||
|
return IPSecSiteConnection(ipsecsiteconnection)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def ipsecsiteconnection_delete(request, ipsecsiteconnection_id):
|
||||||
|
neutronclient(request).delete_ipsec_site_connection(ipsecsiteconnection_id)
|
323
neutron_vpnaas_dashboard/dashboards/project/forms.py
Normal file
323
neutron_vpnaas_dashboard/dashboards/project/forms.py
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
# Copyright 2013, Mirantis Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import forms
|
||||||
|
from horizon import messages
|
||||||
|
|
||||||
|
from neutron_vpnaas_dashboard import api as api_vpn
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateVPNService(forms.SelfHandlingForm):
|
||||||
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
|
vpnservice_id = forms.CharField(
|
||||||
|
label=_("ID"),
|
||||||
|
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
||||||
|
description = forms.CharField(
|
||||||
|
required=False, max_length=80, label=_("Description"))
|
||||||
|
admin_state_up = forms.BooleanField(label=_("Enable Admin State"),
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
failure_url = 'horizon:project:vpn:index'
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
data = {'vpnservice': {'name': context['name'],
|
||||||
|
'description': context['description'],
|
||||||
|
'admin_state_up': context['admin_state_up'],
|
||||||
|
}}
|
||||||
|
vpnservice = api_vpn.vpnservice_update(
|
||||||
|
request, context['vpnservice_id'], **data)
|
||||||
|
msg = (_('VPN Service %s was successfully updated.')
|
||||||
|
% context['name'])
|
||||||
|
LOG.debug(msg)
|
||||||
|
messages.success(request, msg)
|
||||||
|
return vpnservice
|
||||||
|
except Exception as e:
|
||||||
|
msg = _('Failed to update VPN Service %s') % context['name']
|
||||||
|
LOG.info('%(msg)s: %(exception)s', {'msg': msg, 'exception': e})
|
||||||
|
redirect = reverse(self.failure_url)
|
||||||
|
exceptions.handle(request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIKEPolicy(forms.SelfHandlingForm):
|
||||||
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
|
ikepolicy_id = forms.CharField(
|
||||||
|
label=_("ID"),
|
||||||
|
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
||||||
|
description = forms.CharField(
|
||||||
|
required=False, max_length=80, label=_("Description"))
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
auth_algorithm = forms.ChoiceField(
|
||||||
|
label=_("Authorization algorithm"),
|
||||||
|
choices=[('sha1', _('sha1'))],
|
||||||
|
widget=forms.ThemableSelectWidget(attrs={'readonly': 'readonly'}),
|
||||||
|
required=False)
|
||||||
|
encryption_algorithm = forms.ChoiceField(
|
||||||
|
label=_("Encryption algorithm"),
|
||||||
|
choices=[('3des', _('3des')),
|
||||||
|
('aes-128', _('aes-128')),
|
||||||
|
('aes-192', _('aes-192')),
|
||||||
|
('aes-256', _('aes-256'))],
|
||||||
|
required=False)
|
||||||
|
ike_version = forms.ChoiceField(
|
||||||
|
label=_("IKE version"),
|
||||||
|
choices=[('v1', _('v1')),
|
||||||
|
('v2', _('v2'))],
|
||||||
|
required=False)
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
lifetime_units = forms.ChoiceField(
|
||||||
|
label=_("Lifetime units for IKE keys"),
|
||||||
|
choices=[('seconds', _('seconds'))],
|
||||||
|
widget=forms.ThemableSelectWidget(attrs={'readonly': 'readonly'}),
|
||||||
|
required=False)
|
||||||
|
lifetime_value = forms.IntegerField(
|
||||||
|
min_value=60,
|
||||||
|
label=_("Lifetime value for IKE keys"),
|
||||||
|
help_text=_("Equal to or greater than 60"),
|
||||||
|
required=False)
|
||||||
|
pfs = forms.ChoiceField(
|
||||||
|
label=_("Perfect Forward Secrecy"),
|
||||||
|
choices=[('group2', _('group2')),
|
||||||
|
('group5', _('group5')),
|
||||||
|
('group14', _('group14'))],
|
||||||
|
required=False)
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
phase1_negotiation_mode = forms.ChoiceField(
|
||||||
|
label=_("IKE Phase1 negotiation mode"),
|
||||||
|
choices=[('main', 'main')],
|
||||||
|
widget=forms.ThemableSelectWidget(attrs={'readonly': 'readonly'}),
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
failure_url = 'horizon:project:vpn:index'
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
data = {'ikepolicy':
|
||||||
|
{'name': context['name'],
|
||||||
|
'description': context['description'],
|
||||||
|
'auth_algorithm': context['auth_algorithm'],
|
||||||
|
'encryption_algorithm': context['encryption_algorithm'],
|
||||||
|
'ike_version': context['ike_version'],
|
||||||
|
'lifetime': {'units': context['lifetime_units'],
|
||||||
|
'value': context['lifetime_value']},
|
||||||
|
'pfs': context['pfs'],
|
||||||
|
'phase1_negotiation_mode':
|
||||||
|
context['phase1_negotiation_mode'],
|
||||||
|
}}
|
||||||
|
ikepolicy = api_vpn.ikepolicy_update(
|
||||||
|
request, context['ikepolicy_id'], **data)
|
||||||
|
msg = (_('IKE Policy %s was successfully updated.')
|
||||||
|
% context['name'])
|
||||||
|
LOG.debug(msg)
|
||||||
|
messages.success(request, msg)
|
||||||
|
return ikepolicy
|
||||||
|
except Exception as e:
|
||||||
|
msg = _('Failed to update IKE Policy %s') % context['name']
|
||||||
|
LOG.info('%(msg)s: %(exception)s', {'msg': msg, 'exception': e})
|
||||||
|
redirect = reverse(self.failure_url)
|
||||||
|
exceptions.handle(request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIPSecPolicy(forms.SelfHandlingForm):
|
||||||
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
|
ipsecpolicy_id = forms.CharField(
|
||||||
|
label=_("ID"),
|
||||||
|
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
||||||
|
description = forms.CharField(
|
||||||
|
required=False, max_length=80, label=_("Description"))
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
auth_algorithm = forms.ChoiceField(
|
||||||
|
label=_("Authorization algorithm"),
|
||||||
|
choices=[('sha1', _('sha1'))],
|
||||||
|
widget=forms.TextInput(attrs={'readonly': 'readonly'}),
|
||||||
|
required=False)
|
||||||
|
encapsulation_mode = forms.ChoiceField(
|
||||||
|
label=_("Encapsulation mode"),
|
||||||
|
choices=[('tunnel', _('tunnel')),
|
||||||
|
('transport', _('transport'))],
|
||||||
|
required=False)
|
||||||
|
encryption_algorithm = forms.ChoiceField(
|
||||||
|
label=_("Encryption algorithm"),
|
||||||
|
choices=[('3des', _('3des')),
|
||||||
|
('aes-128', _('aes-128')),
|
||||||
|
('aes-192', _('aes-192')),
|
||||||
|
('aes-256', _('aes-256'))],
|
||||||
|
required=False)
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
lifetime_units = forms.ChoiceField(
|
||||||
|
label=_("Lifetime units"),
|
||||||
|
choices=[('seconds', _('seconds'))],
|
||||||
|
widget=forms.ThemableSelectWidget(attrs={'readonly': 'readonly'}),
|
||||||
|
required=False)
|
||||||
|
lifetime_value = forms.IntegerField(
|
||||||
|
min_value=60,
|
||||||
|
label=_("Lifetime value"),
|
||||||
|
help_text=_("Equal to or greater than 60"),
|
||||||
|
required=False)
|
||||||
|
pfs = forms.ChoiceField(
|
||||||
|
label=_("Perfect Forward Secrecy"),
|
||||||
|
choices=[('group2', _('group2')),
|
||||||
|
('group5', _('group5')),
|
||||||
|
('group14', _('group14'))],
|
||||||
|
required=False)
|
||||||
|
transform_protocol = forms.ChoiceField(
|
||||||
|
label=_("Transform Protocol"),
|
||||||
|
choices=[('esp', _('esp')),
|
||||||
|
('ah', _('ah')),
|
||||||
|
('ah-esp', _('ah-esp'))],
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
failure_url = 'horizon:project:vpn:index'
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
data = {'ipsecpolicy':
|
||||||
|
{'name': context['name'],
|
||||||
|
'description': context['description'],
|
||||||
|
'auth_algorithm': context['auth_algorithm'],
|
||||||
|
'encapsulation_mode': context['encapsulation_mode'],
|
||||||
|
'encryption_algorithm': context['encryption_algorithm'],
|
||||||
|
'lifetime': {'units': context['lifetime_units'],
|
||||||
|
'value': context['lifetime_value']},
|
||||||
|
'pfs': context['pfs'],
|
||||||
|
'transform_protocol': context['transform_protocol'],
|
||||||
|
}}
|
||||||
|
ipsecpolicy = api_vpn.ipsecpolicy_update(
|
||||||
|
request, context['ipsecpolicy_id'], **data)
|
||||||
|
msg = (_('IPSec Policy %s was successfully updated.')
|
||||||
|
% context['name'])
|
||||||
|
LOG.debug(msg)
|
||||||
|
messages.success(request, msg)
|
||||||
|
return ipsecpolicy
|
||||||
|
except Exception as e:
|
||||||
|
msg = _('Failed to update IPSec Policy %s') % context['name']
|
||||||
|
LOG.info('%(msg)s: %(exception)s', {'msg': msg, 'exception': e})
|
||||||
|
redirect = reverse(self.failure_url)
|
||||||
|
exceptions.handle(request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIPSecSiteConnection(forms.SelfHandlingForm):
|
||||||
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
|
ipsecsiteconnection_id = forms.CharField(
|
||||||
|
label=_("ID"),
|
||||||
|
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
||||||
|
description = forms.CharField(
|
||||||
|
required=False, max_length=80, label=_("Description"))
|
||||||
|
peer_address = forms.IPField(
|
||||||
|
label=_("Peer gateway public IPv4/IPv6 Address or FQDN"),
|
||||||
|
help_text=_("Peer gateway public IPv4/IPv6 address or FQDN for "
|
||||||
|
"the VPN Connection"),
|
||||||
|
version=forms.IPv4 | forms.IPv6,
|
||||||
|
mask=False)
|
||||||
|
peer_id = forms.IPField(
|
||||||
|
label=_("Peer router identity for authentication (Peer ID)"),
|
||||||
|
help_text=_("Peer router identity for authentication. "
|
||||||
|
"Can be IPv4/IPv6 address, e-mail, key ID, or FQDN"),
|
||||||
|
version=forms.IPv4 | forms.IPv6,
|
||||||
|
mask=False)
|
||||||
|
peer_cidrs = forms.MultiIPField(
|
||||||
|
label=_("Remote peer subnet(s)"),
|
||||||
|
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)"),
|
||||||
|
version=forms.IPv4 | forms.IPv6,
|
||||||
|
mask=True)
|
||||||
|
psk = forms.CharField(
|
||||||
|
widget=forms.PasswordInput(render_value=True),
|
||||||
|
max_length=80, label=_("Pre-Shared Key (PSK) string"))
|
||||||
|
mtu = forms.IntegerField(
|
||||||
|
min_value=68,
|
||||||
|
required=False,
|
||||||
|
label=_("Maximum Transmission Unit size for the connection"),
|
||||||
|
help_text=_("Equal to or greater than 68 if the local subnet is IPv4. "
|
||||||
|
"Equal to or greater than 1280 if the local subnet "
|
||||||
|
"is IPv6."))
|
||||||
|
dpd_action = forms.ChoiceField(
|
||||||
|
label=_("Dead peer detection actions"),
|
||||||
|
required=False,
|
||||||
|
choices=[('hold', _('hold')),
|
||||||
|
('clear', _('clear')),
|
||||||
|
('disabled', _('disabled')),
|
||||||
|
('restart', _('restart')),
|
||||||
|
('restart-by-peer', _('restart-by-peer'))])
|
||||||
|
dpd_interval = forms.IntegerField(
|
||||||
|
min_value=1,
|
||||||
|
required=False,
|
||||||
|
label=_("Dead peer detection interval"),
|
||||||
|
help_text=_("Valid integer lesser than the DPD timeout"))
|
||||||
|
dpd_timeout = forms.IntegerField(
|
||||||
|
min_value=1,
|
||||||
|
required=False,
|
||||||
|
label=_("Dead peer detection timeout"),
|
||||||
|
help_text=_("Valid integer greater than the DPD interval"))
|
||||||
|
initiator = forms.ChoiceField(
|
||||||
|
label=_("Initiator state"),
|
||||||
|
required=False,
|
||||||
|
choices=[('bi-directional', _('bi-directional')),
|
||||||
|
('response-only', _('response-only'))])
|
||||||
|
admin_state_up = forms.BooleanField(label=_("Enable Admin State"),
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
failure_url = 'horizon:project:vpn:index'
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super(UpdateIPSecSiteConnection, self).clean()
|
||||||
|
interval = cleaned_data.get('dpd_interval')
|
||||||
|
timeout = cleaned_data.get('dpd_timeout')
|
||||||
|
|
||||||
|
if not interval < timeout:
|
||||||
|
msg = _("DPD Timeout must be greater than DPD Interval")
|
||||||
|
self._errors['dpd_timeout'] = self.error_class([msg])
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
data = {'ipsec_site_connection':
|
||||||
|
{'name': context['name'],
|
||||||
|
'description': context['description'],
|
||||||
|
'peer_address': context['peer_address'],
|
||||||
|
'peer_id': context['peer_id'],
|
||||||
|
'peer_cidrs': context[
|
||||||
|
'peer_cidrs'].replace(" ", "").split(","),
|
||||||
|
'psk': context['psk'],
|
||||||
|
'mtu': context['mtu'],
|
||||||
|
'dpd': {'action': context['dpd_action'],
|
||||||
|
'interval': context['dpd_interval'],
|
||||||
|
'timeout': context['dpd_timeout']},
|
||||||
|
'initiator': context['initiator'],
|
||||||
|
'admin_state_up': context['admin_state_up'],
|
||||||
|
}}
|
||||||
|
ipsecsiteconnection = api_vpn.ipsecsiteconnection_update(
|
||||||
|
request, context['ipsecsiteconnection_id'], **data)
|
||||||
|
msg = (_('IPSec Site Connection %s was successfully updated.')
|
||||||
|
% context['name'])
|
||||||
|
LOG.debug(msg)
|
||||||
|
messages.success(request, msg)
|
||||||
|
return ipsecsiteconnection
|
||||||
|
except Exception as e:
|
||||||
|
msg = (_('Failed to update IPSec Site Connection %s')
|
||||||
|
% context['name'])
|
||||||
|
LOG.info('%(msg)s: %(exception)s', {'msg': msg, 'exception': e})
|
||||||
|
redirect = reverse(self.failure_url)
|
||||||
|
exceptions.handle(request, msg, redirect=redirect)
|
47
neutron_vpnaas_dashboard/dashboards/project/panel.py
Normal file
47
neutron_vpnaas_dashboard/dashboards/project/panel.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Copyright 2013, Mirantis Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
import horizon
|
||||||
|
|
||||||
|
from openstack_dashboard.api import neutron
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class VPN(horizon.Panel):
|
||||||
|
name = _("VPN")
|
||||||
|
slug = 'vpn'
|
||||||
|
permissions = ('openstack.services.network',)
|
||||||
|
|
||||||
|
def allowed(self, context):
|
||||||
|
request = context['request']
|
||||||
|
if not request.user.has_perms(self.permissions):
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
if not neutron.is_service_enabled(request,
|
||||||
|
config_name='enable_vpn',
|
||||||
|
ext_name='vpnaas'):
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
LOG.error("Call to list enabled services failed. This is likely "
|
||||||
|
"due to a problem communicating with the Neutron "
|
||||||
|
"endpoint. VPN panel will not be displayed.")
|
||||||
|
return False
|
||||||
|
if not super(VPN, self).allowed(context):
|
||||||
|
return False
|
||||||
|
return True
|
465
neutron_vpnaas_dashboard/dashboards/project/tables.py
Normal file
465
neutron_vpnaas_dashboard/dashboards/project/tables.py
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
# Copyright 2013, Mirantis Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django import template
|
||||||
|
from django.utils.translation import pgettext_lazy
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.utils.translation import ungettext_lazy
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import tables
|
||||||
|
|
||||||
|
from openstack_dashboard import policy
|
||||||
|
|
||||||
|
from neutron_vpnaas_dashboard import api
|
||||||
|
|
||||||
|
|
||||||
|
forbid_updates = set(["PENDING_CREATE", "PENDING_UPDATE", "PENDING_DELETE"])
|
||||||
|
|
||||||
|
|
||||||
|
class AddIKEPolicyLink(tables.LinkAction):
|
||||||
|
name = "addikepolicy"
|
||||||
|
verbose_name = _("Add IKE Policy")
|
||||||
|
url = "horizon:project:vpn:addikepolicy"
|
||||||
|
classes = ("ajax-modal",)
|
||||||
|
icon = "plus"
|
||||||
|
policy_rules = (("network", "create_ikepolicy"),)
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecPolicyLink(tables.LinkAction):
|
||||||
|
name = "addipsecpolicy"
|
||||||
|
verbose_name = _("Add IPSec Policy")
|
||||||
|
url = "horizon:project:vpn:addipsecpolicy"
|
||||||
|
classes = ("ajax-modal",)
|
||||||
|
icon = "plus"
|
||||||
|
policy_rules = (("network", "create_ipsecpolicy"),)
|
||||||
|
|
||||||
|
|
||||||
|
class AddVPNServiceLink(tables.LinkAction):
|
||||||
|
name = "addvpnservice"
|
||||||
|
verbose_name = _("Add VPN Service")
|
||||||
|
url = "horizon:project:vpn:addvpnservice"
|
||||||
|
classes = ("ajax-modal",)
|
||||||
|
icon = "plus"
|
||||||
|
policy_rules = (("network", "create_vpnservice"),)
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecSiteConnectionLink(tables.LinkAction):
|
||||||
|
name = "addipsecsiteconnection"
|
||||||
|
verbose_name = _("Add IPSec Site Connection")
|
||||||
|
url = "horizon:project:vpn:addipsecsiteconnection"
|
||||||
|
classes = ("ajax-modal",)
|
||||||
|
icon = "plus"
|
||||||
|
policy_rules = (("network", "create_ipsec_site_connection"),)
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteVPNServiceLink(policy.PolicyTargetMixin, tables.DeleteAction):
|
||||||
|
name = "deletevpnservice"
|
||||||
|
policy_rules = (("network", "delete_vpnservice"),)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_present(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Delete VPN Service",
|
||||||
|
u"Delete VPN Services",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_past(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Scheduled deletion of VPN Service",
|
||||||
|
u"Scheduled deletion of VPN Services",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
def allowed(self, request, datum=None):
|
||||||
|
if datum and datum.ipsecsiteconns:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def delete(self, request, obj_id):
|
||||||
|
try:
|
||||||
|
api.vpn.vpnservice_delete(request, obj_id)
|
||||||
|
except Exception as e:
|
||||||
|
exceptions.handle(
|
||||||
|
request, _('Unable to delete VPN Service. %s') % e)
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteIKEPolicyLink(policy.PolicyTargetMixin, tables.DeleteAction):
|
||||||
|
name = "deleteikepolicy"
|
||||||
|
policy_rules = (("network", "delete_ikepolicy"),)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_present(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Delete IKE Policy",
|
||||||
|
u"Delete IKE Policies",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_past(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Scheduled deletion of IKE Policy",
|
||||||
|
u"Scheduled deletion of IKE Policies",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
def allowed(self, request, datum=None):
|
||||||
|
if datum and datum.ipsecsiteconns:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def delete(self, request, obj_id):
|
||||||
|
try:
|
||||||
|
api.vpn.ikepolicy_delete(request, obj_id)
|
||||||
|
except Exception as e:
|
||||||
|
exceptions.handle(
|
||||||
|
request, _('Unable to delete IKE Policy. %s') % e)
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteIPSecPolicyLink(policy.PolicyTargetMixin, tables.DeleteAction):
|
||||||
|
name = "deleteipsecpolicy"
|
||||||
|
policy_rules = (("network", "delete_ipsecpolicy"),)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_present(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Delete IPSec Policy",
|
||||||
|
u"Delete IPSec Policies",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_past(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Scheduled deletion of IPSec Policy",
|
||||||
|
u"Scheduled deletion of IPSec Policies",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
def allowed(self, request, datum=None):
|
||||||
|
if datum and datum.ipsecsiteconns:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def delete(self, request, obj_id):
|
||||||
|
try:
|
||||||
|
api.vpn.ipsecpolicy_delete(request, obj_id)
|
||||||
|
except Exception as e:
|
||||||
|
exceptions.handle(
|
||||||
|
request, _('Unable to delete IPSec Policy. %s') % e)
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteIPSecSiteConnectionLink(policy.PolicyTargetMixin,
|
||||||
|
tables.DeleteAction):
|
||||||
|
name = "deleteipsecsiteconnection"
|
||||||
|
policy_rules = (("network", "delete_ipsec_site_connection"),)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_present(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Delete IPSec Site Connection",
|
||||||
|
u"Delete IPSec Site Connections",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_past(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Scheduled deletion of IPSec Site Connection",
|
||||||
|
u"Scheduled deletion of IPSec Site Connections",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self, request, obj_id):
|
||||||
|
try:
|
||||||
|
api.vpn.ipsecsiteconnection_delete(request, obj_id)
|
||||||
|
except Exception as e:
|
||||||
|
exceptions.handle(
|
||||||
|
request, _('Unable to delete IPSec Site Connection. %s') % e)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateVPNServiceLink(tables.LinkAction):
|
||||||
|
name = "update_vpnservice"
|
||||||
|
verbose_name = _("Edit VPN Service")
|
||||||
|
classes = ("ajax-modal", "btn-update",)
|
||||||
|
policy_rules = (("network", "update_vpnservice"),)
|
||||||
|
|
||||||
|
def get_link_url(self, vpnservice):
|
||||||
|
return reverse("horizon:project:vpn:update_vpnservice",
|
||||||
|
kwargs={'vpnservice_id': vpnservice.id})
|
||||||
|
|
||||||
|
def allowed(self, request, datum=None):
|
||||||
|
if datum and datum.status not in forbid_updates:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIKEPolicyLink(tables.LinkAction):
|
||||||
|
name = "updateikepolicy"
|
||||||
|
verbose_name = _("Edit IKE Policy")
|
||||||
|
classes = ("ajax-modal", "btn-update",)
|
||||||
|
policy_rules = (("network", "update_ikepolicy"),)
|
||||||
|
|
||||||
|
def get_link_url(self, ikepolicy):
|
||||||
|
return reverse("horizon:project:vpn:update_ikepolicy",
|
||||||
|
kwargs={'ikepolicy_id': ikepolicy.id})
|
||||||
|
|
||||||
|
def allowed(self, request, datum=None):
|
||||||
|
return not datum['ipsecsiteconns']
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIPSecPolicyLink(tables.LinkAction):
|
||||||
|
name = "updateipsecpolicy"
|
||||||
|
verbose_name = _("Edit IPSec Policy")
|
||||||
|
classes = ("ajax-modal", "btn-update",)
|
||||||
|
policy_rules = (("network", "update_ipsecpolicy"),)
|
||||||
|
|
||||||
|
def get_link_url(self, ipsecpolicy):
|
||||||
|
return reverse("horizon:project:vpn:update_ipsecpolicy",
|
||||||
|
kwargs={'ipsecpolicy_id': ipsecpolicy.id})
|
||||||
|
|
||||||
|
def allowed(self, request, datum=None):
|
||||||
|
return not datum['ipsecsiteconns']
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIPSecSiteConnectionLink(tables.LinkAction):
|
||||||
|
name = "updateipsecsiteconnection"
|
||||||
|
verbose_name = _("Edit Connection")
|
||||||
|
classes = ("ajax-modal", "btn-update",)
|
||||||
|
policy_rules = (("network", "update_ipsec_site_connection"),)
|
||||||
|
|
||||||
|
def get_link_url(self, ipsecsiteconnection):
|
||||||
|
return reverse("horizon:project:vpn:update_ipsecsiteconnection",
|
||||||
|
kwargs={'ipsecsiteconnection_id':
|
||||||
|
ipsecsiteconnection.id})
|
||||||
|
|
||||||
|
def allowed(self, request, datum=None):
|
||||||
|
if datum and datum.status not in forbid_updates:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
STATUS_CHOICES = (
|
||||||
|
("active", True),
|
||||||
|
("down", True),
|
||||||
|
("created", True),
|
||||||
|
("error", False),
|
||||||
|
("inactive", False),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
STATUS_DISPLAY_CHOICES = (
|
||||||
|
("active", pgettext_lazy("Current status of an IPSec Site Connection"
|
||||||
|
" and VPN Service", u"Active")),
|
||||||
|
("down", pgettext_lazy("Current status of an IPSec Site Connection"
|
||||||
|
" and VPN Service", u"Down")),
|
||||||
|
("error", pgettext_lazy("Current status of an IPSec Site Connection"
|
||||||
|
" and VPN Service", u"Error")),
|
||||||
|
("created", pgettext_lazy("Current status of an IPSec Site Connection"
|
||||||
|
" and VPN Service", u"Created")),
|
||||||
|
("pending_create", pgettext_lazy("Current status of an"
|
||||||
|
" IPSec Site Connection and VPN Service",
|
||||||
|
u"Pending Create")),
|
||||||
|
("pending_update", pgettext_lazy("Current status of an"
|
||||||
|
" IPSec Site Connection and VPN Service",
|
||||||
|
u"Pending Update")),
|
||||||
|
("pending_delete", pgettext_lazy("Current status of an"
|
||||||
|
" IPSec Site Connection and VPN Service",
|
||||||
|
u"Pending Delete")),
|
||||||
|
("inactive", pgettext_lazy("Current status of an IPSec Site Connection"
|
||||||
|
" and VPN Service", u"Inactive")),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIPSecSiteConnectionRow(tables.Row):
|
||||||
|
ajax = True
|
||||||
|
|
||||||
|
def get_data(self, request, conn_id):
|
||||||
|
conn = api.vpn.ipsecsiteconnection_get(request, conn_id)
|
||||||
|
conn.ikepolicy_name = conn['ikepolicy'].get('name',
|
||||||
|
conn['ikepolicy_id'])
|
||||||
|
conn.ipsecpolicy_name = conn['ipsecpolicy'].get('name',
|
||||||
|
conn['ipsecpolicy_id'])
|
||||||
|
conn.vpnservice_name = conn['vpnservice'].get('name',
|
||||||
|
conn['vpnservice_id'])
|
||||||
|
return conn
|
||||||
|
|
||||||
|
|
||||||
|
class IPSSCFilterAction(tables.FilterAction):
|
||||||
|
name = 'IPSSC_project_IKEPolicies'
|
||||||
|
filter_type = 'server'
|
||||||
|
filter_choices = (
|
||||||
|
('name', _("Name ="), True),
|
||||||
|
('vpnservice', _("VPN Service ="), True),
|
||||||
|
('vpnservice_id', _("VPN Service ID ="), True),
|
||||||
|
('ikepolicy', _("IKE Policy ="), True),
|
||||||
|
('ikepolicy_id', _("IKE Policy ID ="), True),
|
||||||
|
('ipsecpolicy', _("IPSec Policy ="), True),
|
||||||
|
('ipsecpolicy_id', _("IPSec Policy ID ="), True),
|
||||||
|
('status', _("Status ="), True)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecSiteConnectionsTable(tables.DataTable):
|
||||||
|
id = tables.Column('id', hidden=True)
|
||||||
|
name = tables.Column('name_or_id', verbose_name=_('Name'),
|
||||||
|
link="horizon:project:vpn:ipsecsiteconnectiondetails")
|
||||||
|
description = tables.Column('description', verbose_name=_('Description'))
|
||||||
|
vpnservice_name = tables.Column('vpnservice_name',
|
||||||
|
verbose_name=_('VPN Service'))
|
||||||
|
ikepolicy_name = tables.Column('ikepolicy_name',
|
||||||
|
verbose_name=_('IKE Policy'))
|
||||||
|
ipsecpolicy_name = tables.Column('ipsecpolicy_name',
|
||||||
|
verbose_name=_('IPSec Policy'))
|
||||||
|
status = tables.Column("status",
|
||||||
|
verbose_name=_("Status"),
|
||||||
|
status=True,
|
||||||
|
status_choices=STATUS_CHOICES,
|
||||||
|
display_choices=STATUS_DISPLAY_CHOICES)
|
||||||
|
|
||||||
|
def get_object_display(self, ipsecsiteconnection):
|
||||||
|
return ipsecsiteconnection.name_or_id
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = "ipsecsiteconnectionstable"
|
||||||
|
verbose_name = _("IPSec Site Connections")
|
||||||
|
status_columns = ['status']
|
||||||
|
row_class = UpdateIPSecSiteConnectionRow
|
||||||
|
table_actions = (AddIPSecSiteConnectionLink,
|
||||||
|
DeleteIPSecSiteConnectionLink,
|
||||||
|
IPSSCFilterAction)
|
||||||
|
row_actions = (UpdateIPSecSiteConnectionLink,
|
||||||
|
DeleteIPSecSiteConnectionLink)
|
||||||
|
|
||||||
|
|
||||||
|
def get_local_ips(vpn):
|
||||||
|
template_name = 'project/vpn/_vpn_ips.html'
|
||||||
|
context = {"external_v4_ip": vpn.get('external_v4_ip'),
|
||||||
|
"external_v6_ip": vpn.get('external_v6_ip')}
|
||||||
|
return template.loader.render_to_string(template_name, context)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateVPNServiceRow(tables.Row):
|
||||||
|
ajax = True
|
||||||
|
|
||||||
|
def get_data(self, request, vpn_id):
|
||||||
|
vpn = api.vpn.vpnservice_get(request, vpn_id)
|
||||||
|
vpn.router_name = vpn['router'].get('name', vpn['router_id'])
|
||||||
|
vpn.subnet_name = vpn['subnet'].get('cidr', vpn['subnet_id'])
|
||||||
|
return vpn
|
||||||
|
|
||||||
|
|
||||||
|
class VPNServicesFilterAction(tables.FilterAction):
|
||||||
|
name = 'vpnservices_project_IKEPolicies'
|
||||||
|
filter_type = 'server'
|
||||||
|
filter_choices = (
|
||||||
|
('name', _("Name ="), True),
|
||||||
|
('subnet_id', _("Subnet ID ="), True),
|
||||||
|
('subnet_name', _("Subnet ="), True),
|
||||||
|
('router_id', _("Router ID ="), True),
|
||||||
|
('router_name', _("Router ="), True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VPNServicesTable(tables.DataTable):
|
||||||
|
id = tables.Column('id', hidden=True)
|
||||||
|
name = tables.Column("name_or_id", verbose_name=_('Name'),
|
||||||
|
link="horizon:project:vpn:vpnservicedetails")
|
||||||
|
description = tables.Column('description', verbose_name=_('Description'))
|
||||||
|
local_ips = tables.Column(get_local_ips,
|
||||||
|
verbose_name=_("Local Side Public IPs"))
|
||||||
|
subnet_name = tables.Column('subnet_name', verbose_name=_('Subnet'))
|
||||||
|
router_name = tables.Column('router_name', verbose_name=_('Router'))
|
||||||
|
status = tables.Column("status",
|
||||||
|
verbose_name=_("Status"),
|
||||||
|
status=True,
|
||||||
|
status_choices=STATUS_CHOICES,
|
||||||
|
display_choices=STATUS_DISPLAY_CHOICES)
|
||||||
|
|
||||||
|
def get_object_display(self, vpnservice):
|
||||||
|
return vpnservice.name_or_id
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = "vpnservicestable"
|
||||||
|
verbose_name = _("VPN Services")
|
||||||
|
status_columns = ['status']
|
||||||
|
row_class = UpdateVPNServiceRow
|
||||||
|
table_actions = (AddVPNServiceLink,
|
||||||
|
DeleteVPNServiceLink,
|
||||||
|
VPNServicesFilterAction)
|
||||||
|
row_actions = (UpdateVPNServiceLink, DeleteVPNServiceLink)
|
||||||
|
|
||||||
|
|
||||||
|
class PoliciesFilterAction(tables.FilterAction):
|
||||||
|
name = 'filter_project_IKEPolicies'
|
||||||
|
filter_type = 'server'
|
||||||
|
filter_choices = (
|
||||||
|
('name', _("Name ="), True),
|
||||||
|
('auth_algorithm', _("Authorization algorithm ="), True),
|
||||||
|
('encryption_algorithm', _("Encryption algorithm ="), True),
|
||||||
|
('pfs', _("PFS ="), True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class IKEPoliciesTable(tables.DataTable):
|
||||||
|
id = tables.Column('id', hidden=True)
|
||||||
|
name = tables.Column("name_or_id", verbose_name=_('Name'),
|
||||||
|
link="horizon:project:vpn:ikepolicydetails")
|
||||||
|
description = tables.Column('description', verbose_name=_('Description'))
|
||||||
|
auth_algorithm = tables.Column('auth_algorithm',
|
||||||
|
verbose_name=_('Authorization algorithm'))
|
||||||
|
encryption_algorithm = tables.Column(
|
||||||
|
'encryption_algorithm',
|
||||||
|
verbose_name=_('Encryption algorithm'))
|
||||||
|
pfs = tables.Column("pfs", verbose_name=_('PFS'))
|
||||||
|
|
||||||
|
def get_object_display(self, ikepolicy):
|
||||||
|
return ikepolicy.name_or_id
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = "ikepoliciestable"
|
||||||
|
verbose_name = _("IKE Policies")
|
||||||
|
table_actions = (AddIKEPolicyLink,
|
||||||
|
DeleteIKEPolicyLink,
|
||||||
|
PoliciesFilterAction)
|
||||||
|
row_actions = (UpdateIKEPolicyLink, DeleteIKEPolicyLink)
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecPoliciesTable(tables.DataTable):
|
||||||
|
id = tables.Column('id', hidden=True)
|
||||||
|
name = tables.Column("name_or_id", verbose_name=_('Name'),
|
||||||
|
link="horizon:project:vpn:ipsecpolicydetails")
|
||||||
|
description = tables.Column('description', verbose_name=_('Description'))
|
||||||
|
auth_algorithm = tables.Column('auth_algorithm',
|
||||||
|
verbose_name=_('Authorization algorithm'))
|
||||||
|
encryption_algorithm = tables.Column(
|
||||||
|
'encryption_algorithm',
|
||||||
|
verbose_name=_('Encryption algorithm'))
|
||||||
|
pfs = tables.Column("pfs", verbose_name=_('PFS'))
|
||||||
|
|
||||||
|
def get_object_display(self, ipsecpolicy):
|
||||||
|
return ipsecpolicy.name_or_id
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = "ipsecpoliciestable"
|
||||||
|
verbose_name = _("IPSec Policies")
|
||||||
|
table_actions = (AddIPSecPolicyLink,
|
||||||
|
DeleteIPSecPolicyLink,
|
||||||
|
PoliciesFilterAction)
|
||||||
|
row_actions = (UpdateIPSecPolicyLink, DeleteIPSecPolicyLink)
|
233
neutron_vpnaas_dashboard/dashboards/project/tabs.py
Normal file
233
neutron_vpnaas_dashboard/dashboards/project/tabs.py
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
# Copyright 2013, Mirantis Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import tables as htables
|
||||||
|
from horizon import tabs
|
||||||
|
|
||||||
|
from openstack_dashboard import api
|
||||||
|
|
||||||
|
from neutron_vpnaas_dashboard import api as api_vpn
|
||||||
|
from neutron_vpnaas_dashboard.dashboards.project import tables
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecSiteConnectionsTab(tabs.TableTab, htables.DataTableView):
|
||||||
|
table_classes = (tables.IPSecSiteConnectionsTable,)
|
||||||
|
name = _("IPSec Site Connections")
|
||||||
|
slug = "ipsecsiteconnections"
|
||||||
|
template_name = ("horizon/common/_detail_table.html")
|
||||||
|
FILTERS_MAPPING = {'admin_state_up': {_("up"): True, _("down"): False}}
|
||||||
|
|
||||||
|
def get_ipsecsiteconnectionstable_data(self):
|
||||||
|
try:
|
||||||
|
filters = self.get_filters()
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
if 'vpnservice' in filters:
|
||||||
|
filters['vpnservice_id'] = \
|
||||||
|
[v.id for v in api_vpn.vpnservice_list(
|
||||||
|
self.tab_group.request, tenant_id=tenant_id,
|
||||||
|
name=filters['vpnservice'])]
|
||||||
|
del filters['vpnservice']
|
||||||
|
if 'ikepolicy' in filters:
|
||||||
|
filters['ikepolicy_id'] = \
|
||||||
|
[i.id for i in api_vpn.ikepolicy_list(
|
||||||
|
self.tab_group.request, tenant_id=tenant_id,
|
||||||
|
name=filters['ikepolicy'])]
|
||||||
|
del filters['ikepolicy']
|
||||||
|
if 'ipsecpolicy' in filters:
|
||||||
|
filters['ipsecpolicy_id'] = \
|
||||||
|
[i.id for i in api_vpn.ipsecpolicy_list(
|
||||||
|
self.tab_group.request, tenant_id=tenant_id,
|
||||||
|
name=filters['ipsecpolicy'])]
|
||||||
|
del filters['ipsecpolicy']
|
||||||
|
ipsecsiteconnections = api_vpn.ipsecsiteconnection_list(
|
||||||
|
self.tab_group.request, tenant_id=tenant_id, **filters)
|
||||||
|
except Exception:
|
||||||
|
ipsecsiteconnections = []
|
||||||
|
exceptions.handle(
|
||||||
|
self.tab_group.request,
|
||||||
|
_('Unable to retrieve IPSec Site Connections list.'))
|
||||||
|
return ipsecsiteconnections
|
||||||
|
|
||||||
|
def get_filters(self):
|
||||||
|
self.table = self._tables['ipsecsiteconnectionstable']
|
||||||
|
self.handle_server_filter(self.request, table=self.table)
|
||||||
|
self.update_server_filter_action(self.request, table=self.table)
|
||||||
|
|
||||||
|
return super(IPSecSiteConnectionsTab,
|
||||||
|
self).get_filters(filters_map=self.FILTERS_MAPPING)
|
||||||
|
|
||||||
|
|
||||||
|
class VPNServicesTab(tabs.TableTab, htables.DataTableView):
|
||||||
|
table_classes = (tables.VPNServicesTable,)
|
||||||
|
name = _("VPN Services")
|
||||||
|
slug = "vpnservices"
|
||||||
|
template_name = ("horizon/common/_detail_table.html")
|
||||||
|
|
||||||
|
def get_vpnservicestable_data(self):
|
||||||
|
try:
|
||||||
|
filters = self.get_filters()
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
if 'subnet_name' in filters:
|
||||||
|
subnets = api.neutron.subnet_list(self.tab_group.request,
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
cidr=filters['subnet_name'])
|
||||||
|
subnets_ids = [n.id for n in subnets]
|
||||||
|
del filters['subnet_name']
|
||||||
|
if not subnets_ids:
|
||||||
|
return []
|
||||||
|
filters['subnet_id'] = subnets_ids
|
||||||
|
if 'router_name' in filters:
|
||||||
|
routers = api.neutron.router_list(self.tab_group.request,
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
name=filters['router_name'])
|
||||||
|
routers_ids = [r.id for r in routers]
|
||||||
|
if not routers:
|
||||||
|
return []
|
||||||
|
filters['router_id'] = routers_ids
|
||||||
|
vpnservices = api_vpn.vpnservice_list(
|
||||||
|
self.tab_group.request, tenant_id=tenant_id, **filters)
|
||||||
|
except Exception:
|
||||||
|
vpnservices = []
|
||||||
|
exceptions.handle(self.tab_group.request,
|
||||||
|
_('Unable to retrieve VPN Services list.'))
|
||||||
|
return vpnservices
|
||||||
|
|
||||||
|
def get_filters(self):
|
||||||
|
self.table = self._tables['vpnservicestable']
|
||||||
|
self.handle_server_filter(self.request, table=self.table)
|
||||||
|
self.update_server_filter_action(self.request, table=self.table)
|
||||||
|
|
||||||
|
return super(VPNServicesTab, self).get_filters()
|
||||||
|
|
||||||
|
|
||||||
|
class IKEPoliciesTab(tabs.TableTab, htables.DataTableView):
|
||||||
|
table_classes = (tables.IKEPoliciesTable,)
|
||||||
|
name = _("IKE Policies")
|
||||||
|
slug = "ikepolicies"
|
||||||
|
template_name = ("horizon/common/_detail_table.html")
|
||||||
|
|
||||||
|
def get_ikepoliciestable_data(self):
|
||||||
|
try:
|
||||||
|
filters = self.get_filters()
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
ikepolicies = api_vpn.ikepolicy_list(
|
||||||
|
self.tab_group.request, tenant_id=tenant_id, **filters)
|
||||||
|
except Exception:
|
||||||
|
ikepolicies = []
|
||||||
|
exceptions.handle(self.tab_group.request,
|
||||||
|
_('Unable to retrieve IKE Policies list.'))
|
||||||
|
return ikepolicies
|
||||||
|
|
||||||
|
def get_filters(self):
|
||||||
|
self.table = self._tables['ikepoliciestable']
|
||||||
|
self.handle_server_filter(self.request, table=self.table)
|
||||||
|
self.update_server_filter_action(self.request, table=self.table)
|
||||||
|
|
||||||
|
return super(IKEPoliciesTab, self).get_filters()
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecPoliciesTab(tabs.TableTab, htables.DataTableView):
|
||||||
|
table_classes = (tables.IPSecPoliciesTable,)
|
||||||
|
name = _("IPSec Policies")
|
||||||
|
slug = "ipsecpolicies"
|
||||||
|
template_name = ("horizon/common/_detail_table.html")
|
||||||
|
|
||||||
|
def get_ipsecpoliciestable_data(self):
|
||||||
|
try:
|
||||||
|
filters = self.get_filters()
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
ipsecpolicies = api_vpn.ipsecpolicy_list(
|
||||||
|
self.tab_group.request, tenant_id=tenant_id, **filters)
|
||||||
|
except Exception:
|
||||||
|
ipsecpolicies = []
|
||||||
|
exceptions.handle(self.tab_group.request,
|
||||||
|
_('Unable to retrieve IPSec Policies list.'))
|
||||||
|
return ipsecpolicies
|
||||||
|
|
||||||
|
def get_filters(self):
|
||||||
|
self.table = self._tables['ipsecpoliciestable']
|
||||||
|
self.handle_server_filter(self.request, table=self.table)
|
||||||
|
self.update_server_filter_action(self.request, table=self.table)
|
||||||
|
|
||||||
|
return super(IPSecPoliciesTab, self).get_filters()
|
||||||
|
|
||||||
|
|
||||||
|
class VPNTabs(tabs.TabGroup):
|
||||||
|
slug = "vpntabs"
|
||||||
|
tabs = (IKEPoliciesTab, IPSecPoliciesTab,
|
||||||
|
VPNServicesTab, IPSecSiteConnectionsTab,)
|
||||||
|
sticky = True
|
||||||
|
|
||||||
|
|
||||||
|
class IKEPolicyDetailsTab(tabs.Tab):
|
||||||
|
name = _("IKE Policy Details")
|
||||||
|
slug = "ikepolicydetails"
|
||||||
|
template_name = "project/vpn/_ikepolicy_details.html"
|
||||||
|
|
||||||
|
def get_context_data(self, request):
|
||||||
|
ikepolicy = self.tab_group.kwargs['ikepolicy']
|
||||||
|
return {'ikepolicy': ikepolicy}
|
||||||
|
|
||||||
|
|
||||||
|
class IKEPolicyDetailsTabs(tabs.TabGroup):
|
||||||
|
slug = "ikepolicytabs"
|
||||||
|
tabs = (IKEPolicyDetailsTab,)
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecPolicyDetailsTab(tabs.Tab):
|
||||||
|
name = _("IPSec Policy Details")
|
||||||
|
slug = "ipsecpolicydetails"
|
||||||
|
template_name = "project/vpn/_ipsecpolicy_details.html"
|
||||||
|
|
||||||
|
def get_context_data(self, request):
|
||||||
|
ipsecpolicy = self.tab_group.kwargs['ipsecpolicy']
|
||||||
|
return {'ipsecpolicy': ipsecpolicy}
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecPolicyDetailsTabs(tabs.TabGroup):
|
||||||
|
slug = "ipsecpolicytabs"
|
||||||
|
tabs = (IPSecPolicyDetailsTab,)
|
||||||
|
|
||||||
|
|
||||||
|
class VPNServiceDetailsTab(tabs.Tab):
|
||||||
|
name = _("VPN Service Details")
|
||||||
|
slug = "vpnservicedetails"
|
||||||
|
template_name = "project/vpn/_vpnservice_details.html"
|
||||||
|
|
||||||
|
def get_context_data(self, request):
|
||||||
|
vpnservice = self.tab_group.kwargs['vpnservice']
|
||||||
|
return {'vpnservice': vpnservice}
|
||||||
|
|
||||||
|
|
||||||
|
class VPNServiceDetailsTabs(tabs.TabGroup):
|
||||||
|
slug = "vpnservicetabs"
|
||||||
|
tabs = (VPNServiceDetailsTab,)
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecSiteConnectionDetailsTab(tabs.Tab):
|
||||||
|
name = _("IPSec Site Connection Details")
|
||||||
|
slug = "ipsecsiteconnectiondetails"
|
||||||
|
template_name = "project/vpn/_ipsecsiteconnection_details.html"
|
||||||
|
|
||||||
|
def get_context_data(self, request):
|
||||||
|
ipsecsiteconnection = self.tab_group.kwargs['ipsecsiteconnection']
|
||||||
|
return {'ipsecsiteconnection': ipsecsiteconnection}
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecSiteConnectionDetailsTabs(tabs.TabGroup):
|
||||||
|
slug = "ipsecsiteconnectiontabs"
|
||||||
|
tabs = (IPSecSiteConnectionDetailsTab,)
|
@ -0,0 +1,20 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
<p>{% trans "Create IKE Policy for current project." %}</p>
|
||||||
|
<p>{% trans "An IKE policy is an association of the following attributes:" %}</p>
|
||||||
|
<dl class="dl-readable">
|
||||||
|
<dt>{% trans 'Authorization algorithm' %}</dt>
|
||||||
|
<dd>{% trans 'Auth algorithm limited to SHA1 only.' %}</dd>
|
||||||
|
<dt>{% trans 'Encryption algorithm' %}</dt>
|
||||||
|
<dd>{% trans 'The type of algorithm (3des, aes-128, aes-192, aes-256) used in the IKE Policy.' %}</dd>
|
||||||
|
<dt>{% trans 'IKE version' %}</dt>
|
||||||
|
<dd>{% trans 'The type of version (v1/v2) that needs to be filtered.' %}</dd>
|
||||||
|
<dt>{% trans 'Lifetime' %}</dt>
|
||||||
|
<dd>{% trans "Life time consists of units and value. Units in 'seconds' and the default value is 3600." %}</dd>
|
||||||
|
<dt>{% trans 'Perfect Forward Secrecy' %}</dt>
|
||||||
|
<dd>{% trans 'PFS limited to using Diffie-Hellman groups 2, 5 (default) and 14.' %}</dd>
|
||||||
|
<dt>{% trans 'IKE Phase 1 negotiation mode' %}</dt>
|
||||||
|
<dd>{% trans "Limited to 'main' mode only." %}</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<p>{% trans "All fields are optional." %}</p>
|
@ -0,0 +1,19 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
<p>{% trans 'Create IPSec Policy for current project.' %}</p>
|
||||||
|
<p>{% trans 'An IPSec policy is an association of the following attributes' %}</p>
|
||||||
|
<dl class="dl-readable">
|
||||||
|
<dt>{% trans 'Authorization algorithm' %}</dt>
|
||||||
|
<dd>{% trans 'Auth algorithm limited to SHA1 only.' %}</dd>
|
||||||
|
<dt>{% trans 'Encapsulation mode' %}</dt>
|
||||||
|
<dd>{% trans 'The type of IPsec tunnel (tunnel/transport) to be used.' %}</dd>
|
||||||
|
<dt>{% trans 'Encryption algorithm' %}</dt>
|
||||||
|
<dd>{% trans 'The type of algorithm (3des, aes-128, aes-192, aes-256) used in the IPSec Policy.' %}</dd>
|
||||||
|
<dt>{% trans 'Lifetime' %}</dt>
|
||||||
|
<dd>{% trans "Life time consists of units and value. Units in 'seconds' and the default value is 3600." %}</dd>
|
||||||
|
<dt>{% trans 'Perfect Forward Secrecy' %}</dt>
|
||||||
|
<dd>{% trans 'PFS limited to using Diffie-Hellman groups 2, 5 (default) and 14.' %}</dd>
|
||||||
|
<dt>{% trans 'Transform Protocol' %}</dt>
|
||||||
|
<dd>{% trans 'The type of protocol (esp, ah, ah-esp) used in IPSec Policy.' %}</dd>
|
||||||
|
</dl>
|
||||||
|
<p>{% trans 'All fields are optional.' %}</p>
|
@ -0,0 +1,7 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
<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>{% trans "Specify a name, description, router, and subnet for the VPN Service." %}</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>
|
@ -0,0 +1,38 @@
|
|||||||
|
{% load i18n sizeformat parse_date %}
|
||||||
|
|
||||||
|
<div class="detail">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>{% trans "Name" %}</dt>
|
||||||
|
<dd data-display="{{ ikepolicy.name_or_id }}">{{ ikepolicy.name|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Description" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.description|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "ID" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Project ID" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.tenant_id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Authorization algorithm" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.auth_algorithm }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Encryption algorithm" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.encryption_algorithm }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "IKE version" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.ike_version }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Lifetime Units" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.lifetime.units }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Lifetime Value" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.lifetime.value }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Perfect Forward Secrecy" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.pfs }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "IKE Phase1 negotiation mode" %}</dt>
|
||||||
|
<dd>{{ ikepolicy.phase1_negotiation_mode }}</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
@ -0,0 +1,38 @@
|
|||||||
|
{% load i18n sizeformat parse_date %}
|
||||||
|
|
||||||
|
<div class="detail">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>{% trans "Name" %}</dt>
|
||||||
|
<dd data-display="{{ ipsecpolicy.name_or_id }}">{{ ipsecpolicy.name|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Description" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.description|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "ID" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Project ID" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.tenant_id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Authorization algorithm" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.auth_algorithm }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Encapsulation mode" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.encapsulation_mode }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Encryption algorithm" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.encryption_algorithm }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Lifetime Units" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.lifetime.units }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Lifetime Value" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.lifetime.value }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Perfect Forward Secrecy" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.pfs }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Transform Protocol" %}</dt>
|
||||||
|
<dd>{{ ipsecpolicy.transform_protocol }}</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
@ -0,0 +1,69 @@
|
|||||||
|
{% load i18n sizeformat parse_date %}
|
||||||
|
|
||||||
|
<div class="detail">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>{% trans "Name" %}</dt>
|
||||||
|
<dd data-display="{{ ipsecsiteconnection.name_or_id }}">{{ ipsecsiteconnection.name|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Description" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.description|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "ID" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Project ID" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.tenant_id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "VPN Service" %}</dt>
|
||||||
|
{% url 'horizon:project:vpn:vpnservicedetails' ipsecsiteconnection.vpnservice_id as vpnservice_url %}
|
||||||
|
<dd><a href="{{ vpnservice_url }}">{{ ipsecsiteconnection.vpnservice.name_or_id }}</a></dd>
|
||||||
|
|
||||||
|
<dt>{% trans "IKE Policy" %}</dt>
|
||||||
|
{% url 'horizon:project:vpn:ikepolicydetails' ipsecsiteconnection.ikepolicy_id as ikepolicy_url %}
|
||||||
|
<dd><a href="{{ ikepolicy_url }}">{{ ipsecsiteconnection.ikepolicy.name_or_id }}</a></dd>
|
||||||
|
|
||||||
|
<dt>{% trans "IPSec Policy" %}</dt>
|
||||||
|
{% url 'horizon:project:vpn:ipsecpolicydetails' ipsecsiteconnection.ipsecpolicy_id as ipsecpolicy_url %}
|
||||||
|
<dd><a href="{{ ipsecpolicy_url }}">{{ ipsecsiteconnection.ipsecpolicy.name_or_id }}</a></dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Peer gateway public IPv4/IPv6 Address or FQDN" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.peer_address }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Peer router identity for authentication (Peer ID)" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.peer_id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Remote peer subnet" %}</dt>
|
||||||
|
<dd>
|
||||||
|
{% for peer_cidr in ipsecsiteconnection.peer_cidrs %}
|
||||||
|
{{ peer_cidr }}<br>
|
||||||
|
{% endfor %}
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "MTU" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.mtu }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Initiator state" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.initiator }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Dead peer detection action" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.dpd.action }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Dead peer detection interval" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.dpd.interval }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Dead peer detection timeout" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.dpd.timeout }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Authorization mode" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.auth_mode }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Route mode" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.route_mode }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Admin State" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.admin_state_up }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Status" %}</dt>
|
||||||
|
<dd>{{ ipsecsiteconnection.status }}</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
@ -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 IKE Policy details here." %}</p>
|
||||||
|
{% endblock %}
|
@ -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 IPSec Policy details here." %}</p>
|
||||||
|
{% endblock %}
|
@ -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 IPSec Site Connection details here." %}</p>
|
||||||
|
{% endblock %}
|
@ -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 VPN Service details here." %}</p>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,13 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
{% if external_v4_ip or external_v6_ip %}
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>{% trans "IPv4:" %}</strong> {{ external_v4_ip }}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>{% trans "IPv6:" %}</strong> {{ external_v6_ip }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
{% trans "-" %}
|
||||||
|
{% endif %}
|
@ -0,0 +1,54 @@
|
|||||||
|
{% load i18n sizeformat parse_date %}
|
||||||
|
|
||||||
|
<div class="detail">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>{% trans "Name" %}</dt>
|
||||||
|
<dd data-display="{{ vpnservice.name_or_id }}">{{ vpnservice.name|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Description" %}</dt>
|
||||||
|
<dd>{{ vpnservice.description|default:_("None") }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "ID" %}</dt>
|
||||||
|
<dd>{{ vpnservice.id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Project ID" %}</dt>
|
||||||
|
<dd>{{ vpnservice.tenant_id }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Router ID" %}</dt>
|
||||||
|
{% url 'horizon:project:routers:detail' vpnservice.router_id as router_url %}
|
||||||
|
<dd><a href="{{ router_url }}">{{ vpnservice.router.name_or_id }}</a></dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Subnet ID" %}</dt>
|
||||||
|
{% 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>
|
||||||
|
|
||||||
|
<dt>{% trans "VPN Connections" %}</dt>
|
||||||
|
<dd>
|
||||||
|
{% if vpnservice.ipsecsiteconns %}
|
||||||
|
{% for conn in vpnservice.ipsecsiteconns %}
|
||||||
|
{% url 'horizon:project:vpn:ipsecsiteconnectiondetails' conn.id as conn_url %}
|
||||||
|
<a href="{{ conn_url }}">{{ conn.name_or_id }}</a><br>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
None
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Admin State" %}</dt>
|
||||||
|
<dd>{{ vpnservice.admin_state_up }}</dd>
|
||||||
|
|
||||||
|
<dt>{% trans "Status" %}</dt>
|
||||||
|
<dd>{{ vpnservice.status }}</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
{% if vpnservice.external_v4_ip or vpnservice.external_v6_ip %}
|
||||||
|
<h4>Local Side Public IP Addresses</h4>
|
||||||
|
<hr class="header_rule">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>{% trans "IPv4" %}</dt>
|
||||||
|
<dd>{{ vpnservice.external_v4_ip|default:_("None") }}</dd>
|
||||||
|
<dt>{% trans "IPv6" %}</dt>
|
||||||
|
<dd>{{ vpnservice.external_v6_ip|default:_("None") }}</dd>
|
||||||
|
</dl>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
@ -0,0 +1,11 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Virtual Private Network" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
{{ tab_group.render }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,7 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Edit IKE Policy" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% include 'project/vpn/_update_ikepolicy.html' %}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,7 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Edit IPSec Policy" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% include 'project/vpn/_update_ipsecpolicy.html' %}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,7 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Edit IPSec Site Connection" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% include 'project/vpn/_update_ipsecsiteconnection.html' %}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,7 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Edit VPN Service" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% include 'project/vpn/_update_vpnservice.html' %}
|
||||||
|
{% endblock %}
|
813
neutron_vpnaas_dashboard/dashboards/project/tests.py
Normal file
813
neutron_vpnaas_dashboard/dashboards/project/tests.py
Normal file
@ -0,0 +1,813 @@
|
|||||||
|
# Copyright 2013, Mirantis Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from mox3.mox import IsA
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django import http
|
||||||
|
|
||||||
|
from horizon.workflows import views
|
||||||
|
|
||||||
|
from openstack_dashboard import api
|
||||||
|
from openstack_dashboard.test import helpers as test
|
||||||
|
|
||||||
|
from openstack_dashboard.dashboards.project.vpn import workflows
|
||||||
|
|
||||||
|
|
||||||
|
class VPNTests(test.TestCase):
|
||||||
|
class AttributeDict(dict):
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return self[attr]
|
||||||
|
|
||||||
|
def __setattr__(self, attr, value):
|
||||||
|
self[attr] = value
|
||||||
|
|
||||||
|
DASHBOARD = 'project'
|
||||||
|
INDEX_URL = reverse('horizon:%s:vpn:index' % DASHBOARD)
|
||||||
|
|
||||||
|
ADDIKEPOLICY_PATH = 'horizon:%s:vpn:addikepolicy' % DASHBOARD
|
||||||
|
ADDIPSECPOLICY_PATH = 'horizon:%s:vpn:addipsecpolicy' % DASHBOARD
|
||||||
|
ADDVPNSERVICE_PATH = 'horizon:%s:vpn:addvpnservice' % DASHBOARD
|
||||||
|
ADDVPNCONNECTION_PATH = 'horizon:%s:vpn:addipsecsiteconnection' % DASHBOARD
|
||||||
|
|
||||||
|
IKEPOLICY_DETAIL_PATH = 'horizon:%s:vpn:ikepolicydetails' % DASHBOARD
|
||||||
|
IPSECPOLICY_DETAIL_PATH = 'horizon:%s:vpn:ipsecpolicydetails' % DASHBOARD
|
||||||
|
VPNSERVICE_DETAIL_PATH = 'horizon:%s:vpn:vpnservicedetails' % DASHBOARD
|
||||||
|
VPNCONNECTION_DETAIL_PATH = 'horizon:%s:vpn:ipsecsiteconnectiondetails' %\
|
||||||
|
DASHBOARD
|
||||||
|
|
||||||
|
UPDATEIKEPOLICY_PATH = 'horizon:%s:vpn:update_ikepolicy' % DASHBOARD
|
||||||
|
UPDATEIPSECPOLICY_PATH = 'horizon:%s:vpn:update_ipsecpolicy' % DASHBOARD
|
||||||
|
UPDATEVPNSERVICE_PATH = 'horizon:%s:vpn:update_vpnservice' % DASHBOARD
|
||||||
|
UPDATEVPNCONNECTION_PATH = 'horizon:%s:vpn:update_ipsecsiteconnection' %\
|
||||||
|
DASHBOARD
|
||||||
|
|
||||||
|
def set_up_expect(self):
|
||||||
|
# retrieves vpnservices
|
||||||
|
api.vpn.vpnservice_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.vpnservices.list())
|
||||||
|
|
||||||
|
# retrieves ikepolicies
|
||||||
|
api.vpn.ikepolicy_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.ikepolicies.list())
|
||||||
|
|
||||||
|
# retrieves ipsecpolicies
|
||||||
|
api.vpn.ipsecpolicy_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.ipsecpolicies.list())
|
||||||
|
|
||||||
|
# retrieves ipsecsiteconnections
|
||||||
|
api.vpn.ipsecsiteconnection_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.ipsecsiteconnections.list())
|
||||||
|
|
||||||
|
def set_up_expect_with_exception(self):
|
||||||
|
api.vpn.vpnservice_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
||||||
|
api.vpn.ikepolicy_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
||||||
|
api.vpn.ipsecpolicy_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
||||||
|
api.vpn.ipsecsiteconnection_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndRaise(self.exceptions.neutron)
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_vpnservices(self):
|
||||||
|
self.set_up_expect()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(self.INDEX_URL)
|
||||||
|
|
||||||
|
self.assertTemplateUsed(res, '%s/vpn/index.html'
|
||||||
|
% self.DASHBOARD)
|
||||||
|
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||||
|
self.assertEqual(len(res.context['table'].data),
|
||||||
|
len(self.vpnservices.list()))
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_ikepolicies(self):
|
||||||
|
self.set_up_expect()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(self.INDEX_URL + '?tab=vpntabs__ikepolicies')
|
||||||
|
|
||||||
|
self.assertTemplateUsed(res, '%s/vpn/index.html'
|
||||||
|
% self.DASHBOARD)
|
||||||
|
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||||
|
self.assertEqual(len(res.context['ikepoliciestable_table'].data),
|
||||||
|
len(self.ikepolicies.list()))
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_ipsecpolicies(self):
|
||||||
|
self.set_up_expect()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(self.INDEX_URL + '?tab=vpntabs__ipsecpolicies')
|
||||||
|
|
||||||
|
self.assertTemplateUsed(res, '%s/vpn/index.html'
|
||||||
|
% self.DASHBOARD)
|
||||||
|
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||||
|
self.assertEqual(len(res.context['ipsecpoliciestable_table'].data),
|
||||||
|
len(self.ipsecpolicies.list()))
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_ipsecsiteconnections(self):
|
||||||
|
self.set_up_expect()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(
|
||||||
|
self.INDEX_URL + '?tab=vpntabs__ipsecsiteconnections')
|
||||||
|
|
||||||
|
self.assertTemplateUsed(res, '%s/vpn/index.html'
|
||||||
|
% self.DASHBOARD)
|
||||||
|
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||||
|
self.assertEqual(
|
||||||
|
len(res.context['ipsecsiteconnectionstable_table'].data),
|
||||||
|
len(self.ipsecsiteconnections.list()))
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_exception_vpnservices(self):
|
||||||
|
self.set_up_expect_with_exception()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(self.INDEX_URL)
|
||||||
|
|
||||||
|
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',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_exception_ikepolicies(self):
|
||||||
|
self.set_up_expect_with_exception()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(self.INDEX_URL + '?tab=vpntabs__ikepolicies')
|
||||||
|
|
||||||
|
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',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_exception_ipsecpolicies(self):
|
||||||
|
self.set_up_expect_with_exception()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(self.INDEX_URL + '?tab=vpntabs__ipsecpolicies')
|
||||||
|
|
||||||
|
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',
|
||||||
|
'ipsecsiteconnection_list')})
|
||||||
|
def test_index_exception_ipsecsiteconnections(self):
|
||||||
|
self.set_up_expect_with_exception()
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(
|
||||||
|
self.INDEX_URL + '?tab=vpntabs__ipsecsiteconnections')
|
||||||
|
|
||||||
|
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.neutron: ('network_list_for_tenant',
|
||||||
|
'router_list')})
|
||||||
|
def test_add_vpnservice_get(self):
|
||||||
|
networks = [{'subnets': [self.subnets.first(), ]}, ]
|
||||||
|
routers = self.routers.list()
|
||||||
|
|
||||||
|
api.neutron.network_list_for_tenant(
|
||||||
|
IsA(http.HttpRequest), self.tenant.id).AndReturn(networks)
|
||||||
|
api.neutron.router_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id).AndReturn(routers)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(reverse(self.ADDVPNSERVICE_PATH))
|
||||||
|
|
||||||
|
workflow = res.context['workflow']
|
||||||
|
self.assertTemplateUsed(res, views.WorkflowView.template_name)
|
||||||
|
self.assertEqual(workflow.name, workflows.AddVPNService.name)
|
||||||
|
|
||||||
|
expected_objs = ['<AddVPNServiceStep: addvpnserviceaction>', ]
|
||||||
|
self.assertQuerysetEqual(workflow.steps, expected_objs)
|
||||||
|
|
||||||
|
@test.create_stubs({api.neutron: ('router_list',
|
||||||
|
'network_list_for_tenant'),
|
||||||
|
api.vpn: ('vpnservice_create', )})
|
||||||
|
def test_add_vpnservice_post(self):
|
||||||
|
vpnservice = self.vpnservices.first()
|
||||||
|
networks = [{'subnets': [self.subnets.first(), ]}, ]
|
||||||
|
routers = self.routers.list()
|
||||||
|
|
||||||
|
api.neutron.network_list_for_tenant(
|
||||||
|
IsA(http.HttpRequest), self.tenant.id).AndReturn(networks)
|
||||||
|
api.neutron.router_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id).AndReturn(routers)
|
||||||
|
|
||||||
|
form_data = {'name': vpnservice['name'],
|
||||||
|
'description': vpnservice['description'],
|
||||||
|
'subnet_id': vpnservice['subnet_id'],
|
||||||
|
'router_id': vpnservice['router_id'],
|
||||||
|
'admin_state_up': vpnservice['admin_state_up']}
|
||||||
|
|
||||||
|
api.vpn.vpnservice_create(
|
||||||
|
IsA(http.HttpRequest), **form_data).AndReturn(vpnservice)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDVPNSERVICE_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
@test.create_stubs({api.neutron: ('router_list',
|
||||||
|
'network_list_for_tenant')})
|
||||||
|
def test_add_vpnservice_post_error(self):
|
||||||
|
vpnservice = self.vpnservices.first()
|
||||||
|
networks = [{'subnets': [self.subnets.first(), ]}, ]
|
||||||
|
routers = self.routers.list()
|
||||||
|
|
||||||
|
api.neutron.network_list_for_tenant(
|
||||||
|
IsA(http.HttpRequest), self.tenant.id).AndReturn(networks)
|
||||||
|
api.neutron.router_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id).AndReturn(routers)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = {'name': vpnservice['name'],
|
||||||
|
'description': vpnservice['description'],
|
||||||
|
'subnet_id': '',
|
||||||
|
'router_id': '',
|
||||||
|
'admin_state_up': vpnservice['admin_state_up']}
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDVPNSERVICE_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertFormErrors(res, 2)
|
||||||
|
|
||||||
|
def test_add_ikepolicy_get(self):
|
||||||
|
res = self.client.get(reverse(self.ADDIKEPOLICY_PATH))
|
||||||
|
|
||||||
|
workflow = res.context['workflow']
|
||||||
|
self.assertTemplateUsed(res, views.WorkflowView.template_name)
|
||||||
|
self.assertEqual(workflow.name, workflows.AddIKEPolicy.name)
|
||||||
|
|
||||||
|
expected_objs = ['<AddIKEPolicyStep: addikepolicyaction>', ]
|
||||||
|
self.assertQuerysetEqual(workflow.steps, expected_objs)
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_create', )})
|
||||||
|
def test_add_ikepolicy_post(self):
|
||||||
|
ikepolicy = self.ikepolicies.first()
|
||||||
|
|
||||||
|
form_data = {'name': ikepolicy['name'],
|
||||||
|
'description': ikepolicy['description'],
|
||||||
|
'auth_algorithm': ikepolicy['auth_algorithm'],
|
||||||
|
'encryption_algorithm': ikepolicy[
|
||||||
|
'encryption_algorithm'],
|
||||||
|
'ike_version': ikepolicy['ike_version'],
|
||||||
|
'lifetime_units': ikepolicy['lifetime']['units'],
|
||||||
|
'lifetime_value': ikepolicy['lifetime']['value'],
|
||||||
|
'phase1_negotiation_mode': ikepolicy[
|
||||||
|
'phase1_negotiation_mode'],
|
||||||
|
'pfs': ikepolicy['pfs']}
|
||||||
|
|
||||||
|
api.vpn.ikepolicy_create(
|
||||||
|
IsA(http.HttpRequest), **form_data).AndReturn(ikepolicy)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDIKEPOLICY_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
def test_add_ikepolicy_post_error(self):
|
||||||
|
ikepolicy = self.ikepolicies.first()
|
||||||
|
|
||||||
|
form_data = {'name': ikepolicy['name'],
|
||||||
|
'description': ikepolicy['description'],
|
||||||
|
'auth_algorithm': ikepolicy['auth_algorithm'],
|
||||||
|
'encryption_algorithm': ikepolicy[
|
||||||
|
'encryption_algorithm'],
|
||||||
|
'ike_version': ikepolicy['ike_version'],
|
||||||
|
'lifetime_units': ikepolicy['lifetime']['units'],
|
||||||
|
'lifetime_value': 10,
|
||||||
|
'phase1_negotiation_mode': ikepolicy[
|
||||||
|
'phase1_negotiation_mode'],
|
||||||
|
'pfs': ikepolicy['pfs']}
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDIKEPOLICY_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertFormErrors(res, 1)
|
||||||
|
|
||||||
|
def test_add_ipsecpolicy_get(self):
|
||||||
|
res = self.client.get(reverse(self.ADDIPSECPOLICY_PATH))
|
||||||
|
|
||||||
|
workflow = res.context['workflow']
|
||||||
|
self.assertTemplateUsed(res, views.WorkflowView.template_name)
|
||||||
|
self.assertEqual(workflow.name, workflows.AddIPSecPolicy.name)
|
||||||
|
|
||||||
|
expected_objs = ['<AddIPSecPolicyStep: addipsecpolicyaction>', ]
|
||||||
|
self.assertQuerysetEqual(workflow.steps, expected_objs)
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ipsecpolicy_create', )})
|
||||||
|
def test_add_ipsecpolicy_post(self):
|
||||||
|
ipsecpolicy = self.ipsecpolicies.first()
|
||||||
|
|
||||||
|
form_data = {'name': ipsecpolicy['name'],
|
||||||
|
'description': ipsecpolicy['description'],
|
||||||
|
'auth_algorithm': ipsecpolicy['auth_algorithm'],
|
||||||
|
'encryption_algorithm': ipsecpolicy[
|
||||||
|
'encryption_algorithm'],
|
||||||
|
'encapsulation_mode': ipsecpolicy[
|
||||||
|
'encapsulation_mode'],
|
||||||
|
'lifetime_units': ipsecpolicy['lifetime']['units'],
|
||||||
|
'lifetime_value': ipsecpolicy['lifetime']['value'],
|
||||||
|
'pfs': ipsecpolicy['pfs'],
|
||||||
|
'transform_protocol': ipsecpolicy[
|
||||||
|
'transform_protocol']}
|
||||||
|
|
||||||
|
api.vpn.ipsecpolicy_create(
|
||||||
|
IsA(http.HttpRequest), **form_data).AndReturn(ipsecpolicy)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDIPSECPOLICY_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
def test_add_ipsecpolicy_post_error(self):
|
||||||
|
ipsecpolicy = self.ipsecpolicies.first()
|
||||||
|
|
||||||
|
form_data = {'name': ipsecpolicy['name'],
|
||||||
|
'description': ipsecpolicy['description'],
|
||||||
|
'auth_algorithm': ipsecpolicy['auth_algorithm'],
|
||||||
|
'encryption_algorithm': ipsecpolicy[
|
||||||
|
'encryption_algorithm'],
|
||||||
|
'encapsulation_mode': ipsecpolicy[
|
||||||
|
'encapsulation_mode'],
|
||||||
|
'lifetime_units': ipsecpolicy['lifetime']['units'],
|
||||||
|
'lifetime_value': 10,
|
||||||
|
'pfs': ipsecpolicy['pfs'],
|
||||||
|
'transform_protocol': ipsecpolicy[
|
||||||
|
'transform_protocol']}
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDIPSECPOLICY_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertFormErrors(res, 1)
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list')})
|
||||||
|
def test_add_ipsecsiteconnection_get(self):
|
||||||
|
ikepolicies = self.ikepolicies.list()
|
||||||
|
ipsecpolicies = self.ipsecpolicies.list()
|
||||||
|
vpnservices = self.vpnservices.list()
|
||||||
|
|
||||||
|
api.vpn.ikepolicy_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndReturn(ikepolicies)
|
||||||
|
api.vpn.ipsecpolicy_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndReturn(ipsecpolicies)
|
||||||
|
api.vpn.vpnservice_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndReturn(vpnservices)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(reverse(self.ADDVPNCONNECTION_PATH))
|
||||||
|
|
||||||
|
workflow = res.context['workflow']
|
||||||
|
self.assertTemplateUsed(res, views.WorkflowView.template_name)
|
||||||
|
self.assertEqual(workflow.name, workflows.AddIPSecSiteConnection.name)
|
||||||
|
|
||||||
|
expected_objs = ['<AddIPSecSiteConnectionStep: '
|
||||||
|
'addipsecsiteconnectionaction>',
|
||||||
|
'<AddIPSecSiteConnectionOptionalStep: '
|
||||||
|
'addipsecsiteconnectionoptionalaction>', ]
|
||||||
|
self.assertQuerysetEqual(workflow.steps, expected_objs)
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list',
|
||||||
|
'ipsecsiteconnection_create')})
|
||||||
|
def test_add_ipsecsiteconnection_post(self):
|
||||||
|
self._test_add_ipsecsiteconnection_post()
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list',
|
||||||
|
'ipsecsiteconnection_create')})
|
||||||
|
def test_add_ipsecsiteconnection_post_single_subnet(self):
|
||||||
|
self._test_add_ipsecsiteconnection_post(subnet_list=False)
|
||||||
|
|
||||||
|
def _test_add_ipsecsiteconnection_post(self, subnet_list=True):
|
||||||
|
if subnet_list:
|
||||||
|
ipsecsiteconnection = self.ipsecsiteconnections.first()
|
||||||
|
else:
|
||||||
|
ipsecsiteconnection = self.ipsecsiteconnections.list()[1]
|
||||||
|
ikepolicies = self.ikepolicies.list()
|
||||||
|
ipsecpolicies = self.ipsecpolicies.list()
|
||||||
|
vpnservices = self.vpnservices.list()
|
||||||
|
|
||||||
|
api.vpn.ikepolicy_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndReturn(ikepolicies)
|
||||||
|
api.vpn.ipsecpolicy_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndReturn(ipsecpolicies)
|
||||||
|
api.vpn.vpnservice_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndReturn(vpnservices)
|
||||||
|
|
||||||
|
form_data = {'name': ipsecsiteconnection['name'],
|
||||||
|
'description': ipsecsiteconnection['description'],
|
||||||
|
'dpd_action': ipsecsiteconnection['dpd']['action'],
|
||||||
|
'dpd_interval': ipsecsiteconnection['dpd']['interval'],
|
||||||
|
'dpd_timeout': ipsecsiteconnection['dpd']['timeout'],
|
||||||
|
'ikepolicy_id': ipsecsiteconnection['ikepolicy_id'],
|
||||||
|
'initiator': ipsecsiteconnection['initiator'],
|
||||||
|
'ipsecpolicy_id': ipsecsiteconnection[
|
||||||
|
'ipsecpolicy_id'],
|
||||||
|
'mtu': ipsecsiteconnection['mtu'],
|
||||||
|
'peer_address': ipsecsiteconnection['peer_address'],
|
||||||
|
'peer_cidrs': ipsecsiteconnection['peer_cidrs'],
|
||||||
|
'peer_id': ipsecsiteconnection['peer_id'],
|
||||||
|
'psk': ipsecsiteconnection['psk'],
|
||||||
|
'vpnservice_id': ipsecsiteconnection['vpnservice_id'],
|
||||||
|
'admin_state_up': ipsecsiteconnection[
|
||||||
|
'admin_state_up']}
|
||||||
|
|
||||||
|
api.vpn.ipsecsiteconnection_create(
|
||||||
|
IsA(http.HttpRequest), **form_data).AndReturn(ipsecsiteconnection)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDVPNCONNECTION_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list',
|
||||||
|
'ipsecsiteconnection_create')})
|
||||||
|
def test_add_ipsecsiteconnection_post_required_fields_error(self):
|
||||||
|
self._test_add_ipsecsiteconnection_post_error()
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ipsecpolicy_list',
|
||||||
|
'vpnservice_list',
|
||||||
|
'ipsecsiteconnection_create')})
|
||||||
|
def test_add_ipsecsiteconnection_post_peer_cidrs_error(self):
|
||||||
|
self._test_add_ipsecsiteconnection_post_error(subnets=True)
|
||||||
|
|
||||||
|
def _test_add_ipsecsiteconnection_post_error(self, subnets=False):
|
||||||
|
ipsecsiteconnection = self.ipsecsiteconnections.first()
|
||||||
|
ikepolicies = self.ikepolicies.list()
|
||||||
|
ipsecpolicies = self.ipsecpolicies.list()
|
||||||
|
vpnservices = self.vpnservices.list()
|
||||||
|
|
||||||
|
api.vpn.ikepolicy_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndReturn(ikepolicies)
|
||||||
|
api.vpn.ipsecpolicy_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndReturn(ipsecpolicies)
|
||||||
|
api.vpn.vpnservice_list(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
tenant_id=self.tenant.id).AndReturn(vpnservices)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = {'name': '',
|
||||||
|
'description': ipsecsiteconnection['description'],
|
||||||
|
'dpd_action': ipsecsiteconnection['dpd']['action'],
|
||||||
|
'dpd_interval': ipsecsiteconnection['dpd']['interval'],
|
||||||
|
'dpd_timeout': ipsecsiteconnection['dpd']['timeout'],
|
||||||
|
'ikepolicy_id': '',
|
||||||
|
'initiator': ipsecsiteconnection['initiator'],
|
||||||
|
'ipsecpolicy_id': '',
|
||||||
|
'mtu': ipsecsiteconnection['mtu'],
|
||||||
|
'peer_address': '',
|
||||||
|
'peer_cidrs': '',
|
||||||
|
'peer_id': '',
|
||||||
|
'psk': '',
|
||||||
|
'vpnservice_id': '',
|
||||||
|
'admin_state_up': ipsecsiteconnection[
|
||||||
|
'admin_state_up']}
|
||||||
|
if subnets:
|
||||||
|
form_data['peer_cidrs'] = '20.1.0.0/24; 21.1.0.0/24'
|
||||||
|
|
||||||
|
res = self.client.post(reverse(self.ADDVPNCONNECTION_PATH), form_data)
|
||||||
|
|
||||||
|
self.assertFormErrors(res, 7)
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('vpnservice_get', )})
|
||||||
|
def test_update_vpnservice_get(self):
|
||||||
|
vpnservice = self.vpnservices.first()
|
||||||
|
|
||||||
|
api.vpn.vpnservice_get(IsA(http.HttpRequest), vpnservice.id)\
|
||||||
|
.AndReturn(vpnservice)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(
|
||||||
|
reverse(self.UPDATEVPNSERVICE_PATH, args=(vpnservice.id,)))
|
||||||
|
|
||||||
|
self.assertTemplateUsed(
|
||||||
|
res, 'project/vpn/update_vpnservice.html')
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('vpnservice_get', 'vpnservice_update')})
|
||||||
|
def test_update_vpnservice_post(self):
|
||||||
|
vpnservice = self.vpnservices.first()
|
||||||
|
|
||||||
|
api.vpn.vpnservice_get(IsA(http.HttpRequest), vpnservice.id)\
|
||||||
|
.AndReturn(vpnservice)
|
||||||
|
|
||||||
|
data = {'name': vpnservice.name,
|
||||||
|
'description': vpnservice.description,
|
||||||
|
'admin_state_up': vpnservice.admin_state_up}
|
||||||
|
|
||||||
|
api.vpn.vpnservice_update(IsA(http.HttpRequest), vpnservice.id,
|
||||||
|
vpnservice=data).AndReturn(vpnservice)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = data.copy()
|
||||||
|
form_data['vpnservice_id'] = vpnservice.id
|
||||||
|
|
||||||
|
res = self.client.post(reverse(
|
||||||
|
self.UPDATEVPNSERVICE_PATH, args=(vpnservice.id,)), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_get', )})
|
||||||
|
def test_update_ikepolicy_get(self):
|
||||||
|
ikepolicy = self.ikepolicies.first()
|
||||||
|
|
||||||
|
api.vpn.ikepolicy_get(IsA(http.HttpRequest), ikepolicy.id)\
|
||||||
|
.AndReturn(ikepolicy)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(
|
||||||
|
reverse(self.UPDATEIKEPOLICY_PATH, args=(ikepolicy.id,)))
|
||||||
|
|
||||||
|
self.assertTemplateUsed(
|
||||||
|
res, 'project/vpn/update_ikepolicy.html')
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_get', 'ikepolicy_update')})
|
||||||
|
def test_update_ikepolicy_post(self):
|
||||||
|
ikepolicy = self.ikepolicies.first()
|
||||||
|
|
||||||
|
api.vpn.ikepolicy_get(IsA(http.HttpRequest), ikepolicy.id)\
|
||||||
|
.AndReturn(ikepolicy)
|
||||||
|
|
||||||
|
data = {'name': ikepolicy.name,
|
||||||
|
'description': ikepolicy.description,
|
||||||
|
'auth_algorithm': ikepolicy.auth_algorithm,
|
||||||
|
'encryption_algorithm': ikepolicy.encryption_algorithm,
|
||||||
|
'ike_version': ikepolicy.ike_version,
|
||||||
|
'lifetime': ikepolicy.lifetime,
|
||||||
|
'pfs': ikepolicy.pfs,
|
||||||
|
'phase1_negotiation_mode': ikepolicy.phase1_negotiation_mode}
|
||||||
|
|
||||||
|
api.vpn.ikepolicy_update(IsA(http.HttpRequest), ikepolicy.id,
|
||||||
|
ikepolicy=data).AndReturn(ikepolicy)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = data.copy()
|
||||||
|
|
||||||
|
form_data.update({'lifetime_units': form_data['lifetime']['units'],
|
||||||
|
'lifetime_value': form_data['lifetime']['value'],
|
||||||
|
'ikepolicy_id': ikepolicy.id})
|
||||||
|
form_data.pop('lifetime')
|
||||||
|
|
||||||
|
res = self.client.post(reverse(
|
||||||
|
self.UPDATEIKEPOLICY_PATH, args=(ikepolicy.id,)), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ipsecpolicy_get', )})
|
||||||
|
def test_update_ipsecpolicy_get(self):
|
||||||
|
ipsecpolicy = self.ipsecpolicies.first()
|
||||||
|
|
||||||
|
api.vpn.ipsecpolicy_get(IsA(http.HttpRequest), ipsecpolicy.id)\
|
||||||
|
.AndReturn(ipsecpolicy)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(
|
||||||
|
reverse(self.UPDATEIPSECPOLICY_PATH, args=(ipsecpolicy.id,)))
|
||||||
|
|
||||||
|
self.assertTemplateUsed(
|
||||||
|
res, 'project/vpn/update_ipsecpolicy.html')
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ipsecpolicy_get', 'ipsecpolicy_update')})
|
||||||
|
def test_update_ipsecpolicy_post(self):
|
||||||
|
ipsecpolicy = self.ipsecpolicies.first()
|
||||||
|
|
||||||
|
api.vpn.ipsecpolicy_get(IsA(http.HttpRequest), ipsecpolicy.id)\
|
||||||
|
.AndReturn(ipsecpolicy)
|
||||||
|
|
||||||
|
data = {'name': ipsecpolicy.name,
|
||||||
|
'description': ipsecpolicy.description,
|
||||||
|
'auth_algorithm': ipsecpolicy.auth_algorithm,
|
||||||
|
'encapsulation_mode': ipsecpolicy.encapsulation_mode,
|
||||||
|
'encryption_algorithm': ipsecpolicy.encryption_algorithm,
|
||||||
|
'lifetime': ipsecpolicy.lifetime,
|
||||||
|
'pfs': ipsecpolicy.pfs,
|
||||||
|
'transform_protocol': ipsecpolicy.transform_protocol}
|
||||||
|
|
||||||
|
api.vpn.ipsecpolicy_update(IsA(http.HttpRequest), ipsecpolicy.id,
|
||||||
|
ipsecpolicy=data).AndReturn(ipsecpolicy)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = data.copy()
|
||||||
|
|
||||||
|
form_data.update({'lifetime_units': form_data['lifetime']['units'],
|
||||||
|
'lifetime_value': form_data['lifetime']['value'],
|
||||||
|
'ipsecpolicy_id': ipsecpolicy.id})
|
||||||
|
form_data.pop('lifetime')
|
||||||
|
|
||||||
|
res = self.client.post(reverse(
|
||||||
|
self.UPDATEIPSECPOLICY_PATH, args=(ipsecpolicy.id,)), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ipsecsiteconnection_get', )})
|
||||||
|
def test_update_ipsecsiteconnection_get(self):
|
||||||
|
ipsecsiteconnection = self.ipsecsiteconnections.first()
|
||||||
|
|
||||||
|
api.vpn.ipsecsiteconnection_get(
|
||||||
|
IsA(http.HttpRequest), ipsecsiteconnection.id)\
|
||||||
|
.AndReturn(ipsecsiteconnection)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(
|
||||||
|
reverse(self.UPDATEVPNCONNECTION_PATH,
|
||||||
|
args=(ipsecsiteconnection.id,)))
|
||||||
|
|
||||||
|
self.assertTemplateUsed(
|
||||||
|
res, 'project/vpn/update_ipsecsiteconnection.html')
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ipsecsiteconnection_get',
|
||||||
|
'ipsecsiteconnection_update')})
|
||||||
|
def test_update_ipsecsiteconnection_post(self):
|
||||||
|
ipsecsiteconnection = self.ipsecsiteconnections.first()
|
||||||
|
|
||||||
|
api.vpn.ipsecsiteconnection_get(
|
||||||
|
IsA(http.HttpRequest), ipsecsiteconnection.id)\
|
||||||
|
.AndReturn(ipsecsiteconnection)
|
||||||
|
|
||||||
|
data = {'name': ipsecsiteconnection.name,
|
||||||
|
'description': ipsecsiteconnection.description,
|
||||||
|
'peer_address': ipsecsiteconnection.peer_address,
|
||||||
|
'peer_id': ipsecsiteconnection.peer_id,
|
||||||
|
'peer_cidrs': ipsecsiteconnection.peer_cidrs,
|
||||||
|
'psk': ipsecsiteconnection.psk,
|
||||||
|
'mtu': ipsecsiteconnection.mtu,
|
||||||
|
'dpd': ipsecsiteconnection.dpd,
|
||||||
|
'initiator': ipsecsiteconnection.initiator,
|
||||||
|
'admin_state_up': ipsecsiteconnection.admin_state_up}
|
||||||
|
|
||||||
|
api.vpn.ipsecsiteconnection_update(
|
||||||
|
IsA(http.HttpRequest), ipsecsiteconnection.id,
|
||||||
|
ipsec_site_connection=data).AndReturn(ipsecsiteconnection)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = data.copy()
|
||||||
|
|
||||||
|
form_data.update({
|
||||||
|
'dpd_action': form_data['dpd']['action'],
|
||||||
|
'dpd_interval': form_data['dpd']['interval'],
|
||||||
|
'dpd_timeout': form_data['dpd']['timeout'],
|
||||||
|
'peer_cidrs': ", ".join(ipsecsiteconnection['peer_cidrs']),
|
||||||
|
'ipsecsiteconnection_id': ipsecsiteconnection.id,
|
||||||
|
})
|
||||||
|
form_data.pop('dpd')
|
||||||
|
|
||||||
|
res = self.client.post(
|
||||||
|
reverse(self.UPDATEVPNCONNECTION_PATH,
|
||||||
|
args=(ipsecsiteconnection.id,)), form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('vpnservice_list', 'vpnservice_delete',)})
|
||||||
|
def test_delete_vpnservice(self):
|
||||||
|
vpnservice = self.vpnservices.list()[1]
|
||||||
|
api.vpn.vpnservice_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.vpnservices.list())
|
||||||
|
api.vpn.vpnservice_delete(IsA(http.HttpRequest), vpnservice.id)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = {"action":
|
||||||
|
"vpnservicestable__deletevpnservice__%s" % vpnservice.id}
|
||||||
|
res = self.client.post(self.INDEX_URL, form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ikepolicy_list', 'ikepolicy_delete',)})
|
||||||
|
def test_delete_ikepolicy(self):
|
||||||
|
ikepolicy = self.ikepolicies.list()[1]
|
||||||
|
api.vpn.ikepolicy_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.ikepolicies.list())
|
||||||
|
api.vpn.ikepolicy_delete(IsA(http.HttpRequest), ikepolicy.id)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = {"action":
|
||||||
|
"ikepoliciestable__deleteikepolicy__%s" % ikepolicy.id}
|
||||||
|
res = self.client.post(self.INDEX_URL, form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ipsecpolicy_list', 'ipsecpolicy_delete',)})
|
||||||
|
def test_delete_ipsecpolicy(self):
|
||||||
|
ipsecpolicy = self.ipsecpolicies.list()[1]
|
||||||
|
api.vpn.ipsecpolicy_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.ipsecpolicies.list())
|
||||||
|
api.vpn.ipsecpolicy_delete(IsA(http.HttpRequest), ipsecpolicy.id)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = {"action":
|
||||||
|
"ipsecpoliciestable__deleteipsecpolicy__%s"
|
||||||
|
% ipsecpolicy.id}
|
||||||
|
res = self.client.post(self.INDEX_URL, form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
|
||||||
|
@test.create_stubs({api.vpn: ('ipsecsiteconnection_list',
|
||||||
|
'ipsecsiteconnection_delete',)})
|
||||||
|
def test_delete_ipsecsiteconnection(self):
|
||||||
|
ipsecsiteconnection = self.ipsecsiteconnections.first()
|
||||||
|
api.vpn.ipsecsiteconnection_list(
|
||||||
|
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
|
||||||
|
.AndReturn(self.ipsecsiteconnections.list())
|
||||||
|
api.vpn.ipsecsiteconnection_delete(
|
||||||
|
IsA(http.HttpRequest), ipsecsiteconnection.id)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = {"action":
|
||||||
|
"ipsecsiteconnectionstable__deleteipsecsiteconnection__%s"
|
||||||
|
% ipsecsiteconnection.id}
|
||||||
|
res = self.client.post(self.INDEX_URL, form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
48
neutron_vpnaas_dashboard/dashboards/project/urls.py
Normal file
48
neutron_vpnaas_dashboard/dashboards/project/urls.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# Copyright 2013, Mirantis Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from neutron_vpnaas_dashboard.dashboards.project import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||||
|
url(r'^addikepolicy$',
|
||||||
|
views.AddIKEPolicyView.as_view(), name='addikepolicy'),
|
||||||
|
url(r'^update_ikepolicy/(?P<ikepolicy_id>[^/]+)/$',
|
||||||
|
views.UpdateIKEPolicyView.as_view(), name='update_ikepolicy'),
|
||||||
|
url(r'^addipsecpolicy$',
|
||||||
|
views.AddIPSecPolicyView.as_view(), name='addipsecpolicy'),
|
||||||
|
url(r'^update_ipsecpolicy/(?P<ipsecpolicy_id>[^/]+)/$',
|
||||||
|
views.UpdateIPSecPolicyView.as_view(), name='update_ipsecpolicy'),
|
||||||
|
url(r'^addipsecsiteconnection$',
|
||||||
|
views.AddIPSecSiteConnectionView.as_view(),
|
||||||
|
name='addipsecsiteconnection'),
|
||||||
|
url(r'^update_ipsecsiteconnection/(?P<ipsecsiteconnection_id>[^/]+)/$',
|
||||||
|
views.UpdateIPSecSiteConnectionView.as_view(),
|
||||||
|
name='update_ipsecsiteconnection'),
|
||||||
|
url(r'^addvpnservice$',
|
||||||
|
views.AddVPNServiceView.as_view(), name='addvpnservice'),
|
||||||
|
url(r'^update_vpnservice/(?P<vpnservice_id>[^/]+)/$',
|
||||||
|
views.UpdateVPNServiceView.as_view(), name='update_vpnservice'),
|
||||||
|
url(r'^ikepolicy/(?P<ikepolicy_id>[^/]+)/$',
|
||||||
|
views.IKEPolicyDetailsView.as_view(), name='ikepolicydetails'),
|
||||||
|
url(r'^ipsecpolicy/(?P<ipsecpolicy_id>[^/]+)/$',
|
||||||
|
views.IPSecPolicyDetailsView.as_view(), name='ipsecpolicydetails'),
|
||||||
|
url(r'^vpnservice/(?P<vpnservice_id>[^/]+)/$',
|
||||||
|
views.VPNServiceDetailsView.as_view(), name='vpnservicedetails'),
|
||||||
|
url(r'^ipsecsiteconnection/(?P<ipsecsiteconnection_id>[^/]+)/$',
|
||||||
|
views.IPSecSiteConnectionDetailsView.as_view(),
|
||||||
|
name='ipsecsiteconnectiondetails'),
|
||||||
|
]
|
361
neutron_vpnaas_dashboard/dashboards/project/views.py
Normal file
361
neutron_vpnaas_dashboard/dashboards/project/views.py
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
# Copyright 2013, Mirantis Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.core.urlresolvers import reverse_lazy
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import forms
|
||||||
|
from horizon import tabs
|
||||||
|
from horizon.utils import memoized
|
||||||
|
from horizon import workflows
|
||||||
|
|
||||||
|
from neutron_vpnaas_dashboard import api as api_vpn
|
||||||
|
from neutron_vpnaas_dashboard.dashboards.project import forms as vpn_forms
|
||||||
|
from neutron_vpnaas_dashboard.dashboards.project import tables as vpn_tables
|
||||||
|
from neutron_vpnaas_dashboard.dashboards.project import tabs as vpn_tabs
|
||||||
|
from neutron_vpnaas_dashboard.dashboards.project import workflows as vpn_workflows
|
||||||
|
|
||||||
|
|
||||||
|
class IndexView(tabs.TabbedTableView):
|
||||||
|
tab_group_class = vpn_tabs.VPNTabs
|
||||||
|
template_name = 'project/vpn/index.html'
|
||||||
|
page_title = _("Virtual Private Network")
|
||||||
|
|
||||||
|
|
||||||
|
class AddVPNServiceView(workflows.WorkflowView):
|
||||||
|
workflow_class = vpn_workflows.AddVPNService
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecSiteConnectionView(workflows.WorkflowView):
|
||||||
|
workflow_class = vpn_workflows.AddIPSecSiteConnection
|
||||||
|
|
||||||
|
|
||||||
|
class AddIKEPolicyView(workflows.WorkflowView):
|
||||||
|
workflow_class = vpn_workflows.AddIKEPolicy
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecPolicyView(workflows.WorkflowView):
|
||||||
|
workflow_class = vpn_workflows.AddIPSecPolicy
|
||||||
|
|
||||||
|
|
||||||
|
class IKEPolicyDetailsView(tabs.TabView):
|
||||||
|
tab_group_class = vpn_tabs.IKEPolicyDetailsTabs
|
||||||
|
template_name = 'horizon/common/_detail.html'
|
||||||
|
page_title = "{{ ikepolicy.name|default:ikepolicy.id }}"
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def get_data(self):
|
||||||
|
pid = self.kwargs['ikepolicy_id']
|
||||||
|
try:
|
||||||
|
return api_vpn.ikepolicy_get(self.request, pid)
|
||||||
|
except Exception:
|
||||||
|
msg = _('Unable to retrieve IKE Policy details.')
|
||||||
|
exceptions.handle(self.request, msg,
|
||||||
|
redirect=self.get_redirect_url())
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(IKEPolicyDetailsView, self).get_context_data(**kwargs)
|
||||||
|
ikepolicy = self.get_data()
|
||||||
|
table = vpn_tables.IKEPoliciesTable(self.request)
|
||||||
|
context["ikepolicy"] = ikepolicy
|
||||||
|
context["url"] = self.get_redirect_url()
|
||||||
|
context["actions"] = table.render_row_actions(ikepolicy)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_tabs(self, request, *args, **kwargs):
|
||||||
|
ikepolicy = self.get_data()
|
||||||
|
return self.tab_group_class(request, ikepolicy=ikepolicy, **kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_redirect_url():
|
||||||
|
return reverse_lazy('horizon:project:vpn:index')
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecPolicyDetailsView(tabs.TabView):
|
||||||
|
tab_group_class = vpn_tabs.IPSecPolicyDetailsTabs
|
||||||
|
template_name = 'horizon/common/_detail.html'
|
||||||
|
page_title = "{{ ipsecpolicy.name|default:ipsecpolicy.id }}"
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def get_data(self):
|
||||||
|
pid = self.kwargs['ipsecpolicy_id']
|
||||||
|
try:
|
||||||
|
return api_vpn.ipsecpolicy_get(self.request, pid)
|
||||||
|
except Exception:
|
||||||
|
msg = _('Unable to retrieve IPSec Policy details.')
|
||||||
|
exceptions.handle(self.request, msg,
|
||||||
|
redirect=self.get_redirect_url())
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(IPSecPolicyDetailsView, self).get_context_data(
|
||||||
|
**kwargs)
|
||||||
|
ipsecpolicy = self.get_data()
|
||||||
|
table = vpn_tables.IPSecPoliciesTable(self.request)
|
||||||
|
context["ipsecpolicy"] = ipsecpolicy
|
||||||
|
context["url"] = self.get_redirect_url()
|
||||||
|
context["actions"] = table.render_row_actions(ipsecpolicy)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_tabs(self, request, *args, **kwargs):
|
||||||
|
ipsecpolicy = self.get_data()
|
||||||
|
return self.tab_group_class(request, ipsecpolicy=ipsecpolicy, **kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_redirect_url():
|
||||||
|
return reverse_lazy('horizon:project:vpn:index')
|
||||||
|
|
||||||
|
|
||||||
|
class VPNServiceDetailsView(tabs.TabView):
|
||||||
|
tab_group_class = vpn_tabs.VPNServiceDetailsTabs
|
||||||
|
template_name = 'horizon/common/_detail.html'
|
||||||
|
page_title = "{{ vpnservice.name|default:vpnservice.id }}"
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def get_data(self):
|
||||||
|
sid = self.kwargs['vpnservice_id']
|
||||||
|
|
||||||
|
try:
|
||||||
|
vpnservice = api_vpn.vpnservice_get(self.request, sid)
|
||||||
|
except Exception:
|
||||||
|
vpnservice = []
|
||||||
|
msg = _('Unable to retrieve VPN Service details.')
|
||||||
|
exceptions.handle(self.request, msg,
|
||||||
|
redirect=self.get_redirect_url())
|
||||||
|
try:
|
||||||
|
connections = api_vpn.ipsecsiteconnection_list(
|
||||||
|
self.request, vpnservice_id=sid)
|
||||||
|
vpnservice.vpnconnections = connections
|
||||||
|
except Exception:
|
||||||
|
vpnservice.vpnconnections = []
|
||||||
|
|
||||||
|
return vpnservice
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(VPNServiceDetailsView, self).get_context_data(**kwargs)
|
||||||
|
vpnservice = self.get_data()
|
||||||
|
table = vpn_tables.VPNServicesTable(self.request)
|
||||||
|
context["vpnservice"] = vpnservice
|
||||||
|
context["url"] = self.get_redirect_url()
|
||||||
|
context["actions"] = table.render_row_actions(vpnservice)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_tabs(self, request, *args, **kwargs):
|
||||||
|
vpnservice = self.get_data()
|
||||||
|
return self.tab_group_class(request, vpnservice=vpnservice, **kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_redirect_url():
|
||||||
|
return reverse_lazy('horizon:project:vpn:index')
|
||||||
|
|
||||||
|
|
||||||
|
class IPSecSiteConnectionDetailsView(tabs.TabView):
|
||||||
|
tab_group_class = vpn_tabs.IPSecSiteConnectionDetailsTabs
|
||||||
|
template_name = 'horizon/common/_detail.html'
|
||||||
|
page_title = "{{ ipsecsiteconnection.name|default:ipsecsiteconnection.id}}"
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def get_data(self):
|
||||||
|
cid = self.kwargs['ipsecsiteconnection_id']
|
||||||
|
try:
|
||||||
|
return api_vpn.ipsecsiteconnection_get(self.request, cid)
|
||||||
|
except Exception:
|
||||||
|
msg = _('Unable to retrieve IPSec Site Connection details.')
|
||||||
|
exceptions.handle(self.request, msg,
|
||||||
|
redirect=self.get_redirect_url())
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(IPSecSiteConnectionDetailsView, self).get_context_data(
|
||||||
|
**kwargs)
|
||||||
|
ipsecsiteconnection = self.get_data()
|
||||||
|
table = vpn_tables.IPSecSiteConnectionsTable(self.request)
|
||||||
|
context["ipsecsiteconnection"] = ipsecsiteconnection
|
||||||
|
context["url"] = self.get_redirect_url()
|
||||||
|
context["actions"] = table.render_row_actions(ipsecsiteconnection)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_tabs(self, request, *args, **kwargs):
|
||||||
|
ipsecsiteconnection = self.get_data()
|
||||||
|
return self.tab_group_class(request,
|
||||||
|
ipsecsiteconnection=ipsecsiteconnection,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_redirect_url():
|
||||||
|
return reverse_lazy('horizon:project:vpn:index')
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateVPNServiceView(forms.ModalFormView):
|
||||||
|
form_class = vpn_forms.UpdateVPNService
|
||||||
|
form_id = "update_vpnservice_form"
|
||||||
|
template_name = "project/vpn/update_vpnservice.html"
|
||||||
|
context_object_name = 'vpnservice'
|
||||||
|
submit_label = _("Save Changes")
|
||||||
|
submit_url = "horizon:project:vpn:update_vpnservice"
|
||||||
|
success_url = reverse_lazy("horizon:project:vpn:index")
|
||||||
|
page_title = _("Edit VPN Service")
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(UpdateVPNServiceView, self).get_context_data(**kwargs)
|
||||||
|
context["vpnservice_id"] = self.kwargs['vpnservice_id']
|
||||||
|
args = (self.kwargs['vpnservice_id'],)
|
||||||
|
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||||
|
return context
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def _get_object(self, *args, **kwargs):
|
||||||
|
vpnservice_id = self.kwargs['vpnservice_id']
|
||||||
|
try:
|
||||||
|
return api_vpn.vpnservice_get(self.request, vpnservice_id)
|
||||||
|
except Exception as e:
|
||||||
|
redirect = self.success_url
|
||||||
|
msg = _('Unable to retrieve VPN Service details. %s') % e
|
||||||
|
exceptions.handle(self.request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
vpnservice = self._get_object()
|
||||||
|
return {'name': vpnservice['name'],
|
||||||
|
'vpnservice_id': vpnservice['id'],
|
||||||
|
'description': vpnservice['description'],
|
||||||
|
'admin_state_up': vpnservice['admin_state_up']}
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIKEPolicyView(forms.ModalFormView):
|
||||||
|
form_class = vpn_forms.UpdateIKEPolicy
|
||||||
|
form_id = "update_ikepolicy_form"
|
||||||
|
template_name = "project/vpn/update_ikepolicy.html"
|
||||||
|
context_object_name = 'ikepolicy'
|
||||||
|
submit_label = _("Save Changes")
|
||||||
|
submit_url = "horizon:project:vpn:update_ikepolicy"
|
||||||
|
success_url = reverse_lazy("horizon:project:vpn:index")
|
||||||
|
page_title = _("Edit IKE Policy")
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(UpdateIKEPolicyView, self).get_context_data(**kwargs)
|
||||||
|
context["ikepolicy_id"] = self.kwargs['ikepolicy_id']
|
||||||
|
args = (self.kwargs['ikepolicy_id'],)
|
||||||
|
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||||
|
return context
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def _get_object(self, *args, **kwargs):
|
||||||
|
ikepolicy_id = self.kwargs['ikepolicy_id']
|
||||||
|
try:
|
||||||
|
return api_vpn.ikepolicy_get(self.request, ikepolicy_id)
|
||||||
|
except Exception as e:
|
||||||
|
redirect = self.success_url
|
||||||
|
msg = _('Unable to retrieve IKE Policy details. %s') % e
|
||||||
|
exceptions.handle(self.request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
ikepolicy = self._get_object()
|
||||||
|
return {'name': ikepolicy['name'],
|
||||||
|
'ikepolicy_id': ikepolicy['id'],
|
||||||
|
'description': ikepolicy['description'],
|
||||||
|
'auth_algorithm': ikepolicy['auth_algorithm'],
|
||||||
|
'encryption_algorithm': ikepolicy['encryption_algorithm'],
|
||||||
|
'ike_version': ikepolicy['ike_version'],
|
||||||
|
'lifetime_units': ikepolicy['lifetime']['units'],
|
||||||
|
'lifetime_value': ikepolicy['lifetime']['value'],
|
||||||
|
'pfs': ikepolicy['pfs'],
|
||||||
|
'phase1_negotiation_mode': ikepolicy[
|
||||||
|
'phase1_negotiation_mode']}
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIPSecPolicyView(forms.ModalFormView):
|
||||||
|
form_class = vpn_forms.UpdateIPSecPolicy
|
||||||
|
form_id = "update_ipsecpolicy_form"
|
||||||
|
template_name = "project/vpn/update_ipsecpolicy.html"
|
||||||
|
context_object_name = 'ipsecpolicy'
|
||||||
|
submit_label = _("Save Changes")
|
||||||
|
submit_url = "horizon:project:vpn:update_ipsecpolicy"
|
||||||
|
success_url = reverse_lazy("horizon:project:vpn:index")
|
||||||
|
page_title = _("Edit IPSec Policy")
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(UpdateIPSecPolicyView, self).get_context_data(**kwargs)
|
||||||
|
context["ipsecpolicy_id"] = self.kwargs['ipsecpolicy_id']
|
||||||
|
args = (self.kwargs['ipsecpolicy_id'],)
|
||||||
|
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||||
|
return context
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def _get_object(self, *args, **kwargs):
|
||||||
|
ipsecpolicy_id = self.kwargs['ipsecpolicy_id']
|
||||||
|
try:
|
||||||
|
return api_vpn.ipsecpolicy_get(self.request, ipsecpolicy_id)
|
||||||
|
except Exception as e:
|
||||||
|
redirect = self.success_url
|
||||||
|
msg = _('Unable to retrieve IPSec Policy details. %s') % e
|
||||||
|
exceptions.handle(self.request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
ipsecpolicy = self._get_object()
|
||||||
|
return {'name': ipsecpolicy['name'],
|
||||||
|
'ipsecpolicy_id': ipsecpolicy['id'],
|
||||||
|
'description': ipsecpolicy['description'],
|
||||||
|
'auth_algorithm': ipsecpolicy['auth_algorithm'],
|
||||||
|
'encapsulation_mode': ipsecpolicy['encapsulation_mode'],
|
||||||
|
'encryption_algorithm': ipsecpolicy['encryption_algorithm'],
|
||||||
|
'lifetime_units': ipsecpolicy['lifetime']['units'],
|
||||||
|
'lifetime_value': ipsecpolicy['lifetime']['value'],
|
||||||
|
'pfs': ipsecpolicy['pfs'],
|
||||||
|
'transform_protocol': ipsecpolicy['transform_protocol']}
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateIPSecSiteConnectionView(forms.ModalFormView):
|
||||||
|
form_class = vpn_forms.UpdateIPSecSiteConnection
|
||||||
|
form_id = "update_ipsecsiteconnection_form"
|
||||||
|
template_name = "project/vpn/update_ipsecsiteconnection.html"
|
||||||
|
context_object_name = 'ipsecsiteconnection'
|
||||||
|
submit_label = _("Save Changes")
|
||||||
|
submit_url = "horizon:project:vpn:update_ipsecsiteconnection"
|
||||||
|
success_url = reverse_lazy("horizon:project:vpn:index")
|
||||||
|
page_title = _("Edit IPSec Site Connection")
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(
|
||||||
|
UpdateIPSecSiteConnectionView, self).get_context_data(**kwargs)
|
||||||
|
context["ipsecsiteconnection_id"] = self.kwargs[
|
||||||
|
'ipsecsiteconnection_id']
|
||||||
|
args = (self.kwargs['ipsecsiteconnection_id'],)
|
||||||
|
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||||
|
return context
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def _get_object(self, *args, **kwargs):
|
||||||
|
connection_id = self.kwargs['ipsecsiteconnection_id']
|
||||||
|
try:
|
||||||
|
return api_vpn.ipsecsiteconnection_get(self.request, connection_id)
|
||||||
|
except Exception as e:
|
||||||
|
redirect = self.success_url
|
||||||
|
msg = _('Unable to retrieve IPSec Site Connection details. %s') % e
|
||||||
|
exceptions.handle(self.request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
ipsecsiteconnection = self._get_object()
|
||||||
|
return {'name': ipsecsiteconnection['name'],
|
||||||
|
'ipsecsiteconnection_id': ipsecsiteconnection['id'],
|
||||||
|
'description': ipsecsiteconnection['description'],
|
||||||
|
'peer_address': ipsecsiteconnection['peer_address'],
|
||||||
|
'peer_id': ipsecsiteconnection['peer_id'],
|
||||||
|
'peer_cidrs': ", ".join(ipsecsiteconnection['peer_cidrs']),
|
||||||
|
'psk': ipsecsiteconnection['psk'],
|
||||||
|
'mtu': ipsecsiteconnection['mtu'],
|
||||||
|
'dpd_action': ipsecsiteconnection['dpd']['action'],
|
||||||
|
'dpd_interval': ipsecsiteconnection['dpd']['interval'],
|
||||||
|
'dpd_timeout': ipsecsiteconnection['dpd']['timeout'],
|
||||||
|
'initiator': ipsecsiteconnection['initiator'],
|
||||||
|
'admin_state_up': ipsecsiteconnection['admin_state_up']}
|
516
neutron_vpnaas_dashboard/dashboards/project/workflows.py
Normal file
516
neutron_vpnaas_dashboard/dashboards/project/workflows.py
Normal file
@ -0,0 +1,516 @@
|
|||||||
|
# Copyright 2013, Mirantis Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import forms
|
||||||
|
from horizon import workflows
|
||||||
|
|
||||||
|
from openstack_dashboard import api
|
||||||
|
|
||||||
|
from neutron_vpnaas_dashboard import api as api_vpn
|
||||||
|
|
||||||
|
|
||||||
|
class AddVPNServiceAction(workflows.Action):
|
||||||
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
|
description = forms.CharField(
|
||||||
|
initial="", required=False,
|
||||||
|
max_length=80, label=_("Description"))
|
||||||
|
router_id = forms.ChoiceField(label=_("Router"))
|
||||||
|
subnet_id = forms.ChoiceField(label=_("Subnet"))
|
||||||
|
admin_state_up = forms.BooleanField(
|
||||||
|
label=_("Enable Admin State"),
|
||||||
|
help_text=_("The state of VPN service to start in. If disabled "
|
||||||
|
"(not checked), VPN service does not forward packets."),
|
||||||
|
initial=True,
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
def __init__(self, request, *args, **kwargs):
|
||||||
|
super(AddVPNServiceAction, self).__init__(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def populate_subnet_id_choices(self, request, context):
|
||||||
|
subnet_id_choices = [('', _("Select a Subnet"))]
|
||||||
|
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']:
|
||||||
|
subnet_id_choices.append((s.id, s.cidr))
|
||||||
|
self.fields['subnet_id'].choices = subnet_id_choices
|
||||||
|
return subnet_id_choices
|
||||||
|
|
||||||
|
def populate_router_id_choices(self, request, context):
|
||||||
|
router_id_choices = [('', _("Select a Router"))]
|
||||||
|
try:
|
||||||
|
tenant_id = request.user.tenant_id
|
||||||
|
routers = api.neutron.router_list(request, tenant_id=tenant_id)
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request,
|
||||||
|
_('Unable to retrieve routers list.'))
|
||||||
|
routers = []
|
||||||
|
for r in routers:
|
||||||
|
router_id_choices.append((r.id, r.name))
|
||||||
|
self.fields['router_id'].choices = router_id_choices
|
||||||
|
return router_id_choices
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = _("Add New VPN Service")
|
||||||
|
permissions = ('openstack.services.network',)
|
||||||
|
help_text_template = "project/vpn/_add_vpn_service_help.html"
|
||||||
|
|
||||||
|
|
||||||
|
class AddVPNServiceStep(workflows.Step):
|
||||||
|
action_class = AddVPNServiceAction
|
||||||
|
contributes = ("name", "description", "subnet_id",
|
||||||
|
"router_id", "admin_state_up")
|
||||||
|
|
||||||
|
def contribute(self, data, context):
|
||||||
|
context = super(AddVPNServiceStep, self).contribute(data, context)
|
||||||
|
if data:
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class AddVPNService(workflows.Workflow):
|
||||||
|
slug = "addvpnservice"
|
||||||
|
name = _("Add VPN Service")
|
||||||
|
finalize_button_name = _("Add")
|
||||||
|
success_message = _('Added VPN Service "%s".')
|
||||||
|
failure_message = _('Unable to add VPN Service "%s".')
|
||||||
|
success_url = "horizon:project:vpn:index"
|
||||||
|
default_steps = (AddVPNServiceStep,)
|
||||||
|
|
||||||
|
def format_status_message(self, message):
|
||||||
|
return message % self.context.get('name')
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
api_vpn.vpnservice_create(request, **context)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class AddIKEPolicyAction(workflows.Action):
|
||||||
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
|
description = forms.CharField(
|
||||||
|
initial="", required=False,
|
||||||
|
max_length=80, label=_("Description"))
|
||||||
|
auth_algorithm = forms.ChoiceField(label=_("Authorization algorithm"),
|
||||||
|
required=False)
|
||||||
|
encryption_algorithm = forms.ChoiceField(label=_("Encryption algorithm"),
|
||||||
|
required=False)
|
||||||
|
ike_version = forms.ChoiceField(label=_("IKE version"), required=False)
|
||||||
|
lifetime_units = forms.ChoiceField(label=_("Lifetime units for IKE keys"),
|
||||||
|
required=False)
|
||||||
|
lifetime_value = forms.IntegerField(
|
||||||
|
min_value=60, label=_("Lifetime value for IKE keys"),
|
||||||
|
initial=3600,
|
||||||
|
help_text=_("Equal to or greater than 60"),
|
||||||
|
required=False)
|
||||||
|
pfs = forms.ChoiceField(label=_("Perfect Forward Secrecy"), required=False)
|
||||||
|
phase1_negotiation_mode = forms.ChoiceField(
|
||||||
|
label=_("IKE Phase1 negotiation mode"), required=False)
|
||||||
|
|
||||||
|
def __init__(self, request, *args, **kwargs):
|
||||||
|
super(AddIKEPolicyAction, self).__init__(request, *args, **kwargs)
|
||||||
|
|
||||||
|
auth_algorithm_choices = [("sha1", "sha1")]
|
||||||
|
self.fields['auth_algorithm'].choices = auth_algorithm_choices
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
self.fields['auth_algorithm'].widget.attrs['readonly'] = True
|
||||||
|
|
||||||
|
encryption_algorithm_choices = [("3des", "3des"),
|
||||||
|
("aes-128", "aes-128"),
|
||||||
|
("aes-192", "aes-192"),
|
||||||
|
("aes-256", "aes-256")]
|
||||||
|
self.fields[
|
||||||
|
'encryption_algorithm'].choices = encryption_algorithm_choices
|
||||||
|
self.fields['encryption_algorithm'].initial = "aes-128"
|
||||||
|
|
||||||
|
ike_version_choices = [("v1", "v1"),
|
||||||
|
("v2", "v2")]
|
||||||
|
self.fields['ike_version'].choices = ike_version_choices
|
||||||
|
|
||||||
|
lifetime_units_choices = [("seconds", "seconds")]
|
||||||
|
self.fields['lifetime_units'].choices = lifetime_units_choices
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
self.fields['lifetime_units'].widget.attrs['readonly'] = True
|
||||||
|
|
||||||
|
pfs_choices = [("group2", "group2"),
|
||||||
|
("group5", "group5"),
|
||||||
|
("group14", "group14")]
|
||||||
|
self.fields['pfs'].choices = pfs_choices
|
||||||
|
self.fields['pfs'].initial = "group5"
|
||||||
|
|
||||||
|
phase1_neg_mode_choices = [("main", "main")]
|
||||||
|
self.fields[
|
||||||
|
'phase1_negotiation_mode'].choices = phase1_neg_mode_choices
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
self.fields['phase1_negotiation_mode'].widget.attrs['readonly'] = True
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = _("Add New IKE Policy")
|
||||||
|
permissions = ('openstack.services.network',)
|
||||||
|
help_text_template = "project/vpn/_add_ike_policy_help.html"
|
||||||
|
|
||||||
|
|
||||||
|
class AddIKEPolicyStep(workflows.Step):
|
||||||
|
action_class = AddIKEPolicyAction
|
||||||
|
contributes = ("name", "description", "auth_algorithm",
|
||||||
|
"encryption_algorithm", "ike_version",
|
||||||
|
"lifetime_units", "lifetime_value",
|
||||||
|
"pfs", "phase1_negotiation_mode")
|
||||||
|
|
||||||
|
def contribute(self, data, context):
|
||||||
|
context = super(AddIKEPolicyStep, self).contribute(data, context)
|
||||||
|
context['lifetime'] = {'units': data['lifetime_units'],
|
||||||
|
'value': data['lifetime_value']}
|
||||||
|
context.pop('lifetime_units')
|
||||||
|
context.pop('lifetime_value')
|
||||||
|
if data:
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class AddIKEPolicy(workflows.Workflow):
|
||||||
|
slug = "addikepolicy"
|
||||||
|
name = _("Add IKE Policy")
|
||||||
|
finalize_button_name = _("Add")
|
||||||
|
success_message = _('Added IKE Policy "%s".')
|
||||||
|
failure_message = _('Unable to add IKE Policy "%s".')
|
||||||
|
success_url = "horizon:project:vpn:index"
|
||||||
|
default_steps = (AddIKEPolicyStep,)
|
||||||
|
|
||||||
|
def format_status_message(self, message):
|
||||||
|
return message % self.context.get('name')
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
api_vpn.ikepolicy_create(request, **context)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecPolicyAction(workflows.Action):
|
||||||
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
|
description = forms.CharField(
|
||||||
|
initial="", required=False,
|
||||||
|
max_length=80, label=_("Description"))
|
||||||
|
auth_algorithm = forms.ChoiceField(label=_("Authorization algorithm"),
|
||||||
|
required=False)
|
||||||
|
encapsulation_mode = forms.ChoiceField(label=_("Encapsulation mode"),
|
||||||
|
required=False)
|
||||||
|
encryption_algorithm = forms.ChoiceField(label=_("Encryption algorithm"),
|
||||||
|
required=False)
|
||||||
|
lifetime_units = forms.ChoiceField(label=_("Lifetime units"),
|
||||||
|
required=False)
|
||||||
|
lifetime_value = forms.IntegerField(
|
||||||
|
min_value=60, label=_("Lifetime value for IKE keys "),
|
||||||
|
initial=3600,
|
||||||
|
help_text=_("Equal to or greater than 60"),
|
||||||
|
required=False)
|
||||||
|
pfs = forms.ChoiceField(label=_("Perfect Forward Secrecy"), required=False)
|
||||||
|
transform_protocol = forms.ChoiceField(label=_("Transform Protocol"),
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
def __init__(self, request, *args, **kwargs):
|
||||||
|
super(AddIPSecPolicyAction, self).__init__(request, *args, **kwargs)
|
||||||
|
|
||||||
|
auth_algorithm_choices = [("sha1", "sha1")]
|
||||||
|
self.fields['auth_algorithm'].choices = auth_algorithm_choices
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
self.fields['auth_algorithm'].widget.attrs['readonly'] = True
|
||||||
|
|
||||||
|
encapsulation_mode_choices = [("tunnel", "tunnel"),
|
||||||
|
("transport", "transport")]
|
||||||
|
self.fields['encapsulation_mode'].choices = encapsulation_mode_choices
|
||||||
|
|
||||||
|
encryption_algorithm_choices = [("3des", "3des"),
|
||||||
|
("aes-128", "aes-128"),
|
||||||
|
("aes-192", "aes-192"),
|
||||||
|
("aes-256", "aes-256")]
|
||||||
|
self.fields[
|
||||||
|
'encryption_algorithm'].choices = encryption_algorithm_choices
|
||||||
|
self.fields['encryption_algorithm'].initial = "aes-128"
|
||||||
|
|
||||||
|
lifetime_units_choices = [("seconds", "seconds")]
|
||||||
|
self.fields['lifetime_units'].choices = lifetime_units_choices
|
||||||
|
# Currently this field has only one choice, so mark it as readonly.
|
||||||
|
self.fields['lifetime_units'].widget.attrs['readonly'] = True
|
||||||
|
|
||||||
|
pfs_choices = [("group2", "group2"),
|
||||||
|
("group5", "group5"),
|
||||||
|
("group14", "group14")]
|
||||||
|
self.fields['pfs'].choices = pfs_choices
|
||||||
|
self.fields['pfs'].initial = "group5"
|
||||||
|
|
||||||
|
transform_protocol_choices = [("esp", "esp"),
|
||||||
|
("ah", "ah"),
|
||||||
|
("ah-esp", "ah-esp")]
|
||||||
|
self.fields['transform_protocol'].choices = transform_protocol_choices
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = _("Add New IPSec Policy")
|
||||||
|
permissions = ('openstack.services.network',)
|
||||||
|
help_text_template = 'project/vpn/_add_ipsec_policy_help.html'
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecPolicyStep(workflows.Step):
|
||||||
|
action_class = AddIPSecPolicyAction
|
||||||
|
contributes = ("name", "description", "auth_algorithm",
|
||||||
|
"encapsulation_mode", "encryption_algorithm",
|
||||||
|
"lifetime_units", "lifetime_value",
|
||||||
|
"pfs", "transform_protocol")
|
||||||
|
|
||||||
|
def contribute(self, data, context):
|
||||||
|
context = super(AddIPSecPolicyStep, self).contribute(data, context)
|
||||||
|
context['lifetime'] = {'units': data['lifetime_units'],
|
||||||
|
'value': data['lifetime_value']}
|
||||||
|
context.pop('lifetime_units')
|
||||||
|
context.pop('lifetime_value')
|
||||||
|
if data:
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecPolicy(workflows.Workflow):
|
||||||
|
slug = "addipsecpolicy"
|
||||||
|
name = _("Add IPSec Policy")
|
||||||
|
finalize_button_name = _("Add")
|
||||||
|
success_message = _('Added IPSec Policy "%s".')
|
||||||
|
failure_message = _('Unable to add IPSec Policy "%s".')
|
||||||
|
success_url = "horizon:project:vpn:index"
|
||||||
|
default_steps = (AddIPSecPolicyStep,)
|
||||||
|
|
||||||
|
def format_status_message(self, message):
|
||||||
|
return message % self.context.get('name')
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
api_vpn.ipsecpolicy_create(request, **context)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecSiteConnectionAction(workflows.Action):
|
||||||
|
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||||
|
description = forms.CharField(
|
||||||
|
initial="", required=False,
|
||||||
|
max_length=80, label=_("Description"))
|
||||||
|
vpnservice_id = forms.ChoiceField(
|
||||||
|
label=_("VPN Service associated with this connection"))
|
||||||
|
ikepolicy_id = forms.ChoiceField(
|
||||||
|
label=_("IKE Policy associated with this connection"))
|
||||||
|
ipsecpolicy_id = forms.ChoiceField(
|
||||||
|
label=_("IPSec Policy associated with this connection"))
|
||||||
|
peer_address = forms.IPField(
|
||||||
|
label=_("Peer gateway public IPv4/IPv6 Address or FQDN"),
|
||||||
|
help_text=_("Peer gateway public IPv4/IPv6 address or FQDN for "
|
||||||
|
"the VPN Connection"),
|
||||||
|
version=forms.IPv4 | forms.IPv6,
|
||||||
|
mask=False)
|
||||||
|
peer_id = forms.IPField(
|
||||||
|
label=_("Peer router identity for authentication (Peer ID)"),
|
||||||
|
help_text=_("Peer router identity for authentication. "
|
||||||
|
"Can be IPv4/IPv6 address, e-mail, key ID, or FQDN"),
|
||||||
|
version=forms.IPv4 | forms.IPv6,
|
||||||
|
mask=False)
|
||||||
|
peer_cidrs = forms.MultiIPField(
|
||||||
|
label=_("Remote peer subnet(s)"),
|
||||||
|
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)"),
|
||||||
|
version=forms.IPv4 | forms.IPv6,
|
||||||
|
mask=True)
|
||||||
|
psk = forms.CharField(
|
||||||
|
max_length=80,
|
||||||
|
label=_("Pre-Shared Key (PSK) string"),
|
||||||
|
widget=forms.PasswordInput(render_value=False),
|
||||||
|
help_text=_("The pre-defined key string "
|
||||||
|
"between the two peers of the VPN connection"))
|
||||||
|
|
||||||
|
def populate_ikepolicy_id_choices(self, request, context):
|
||||||
|
ikepolicy_id_choices = [('', _("Select IKE Policy"))]
|
||||||
|
try:
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
ikepolicies = api_vpn.ikepolicy_list(request, tenant_id=tenant_id)
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request,
|
||||||
|
_('Unable to retrieve IKE Policies list.'))
|
||||||
|
ikepolicies = []
|
||||||
|
for p in ikepolicies:
|
||||||
|
ikepolicy_id_choices.append((p.id, p.name))
|
||||||
|
self.fields['ikepolicy_id'].choices = ikepolicy_id_choices
|
||||||
|
return ikepolicy_id_choices
|
||||||
|
|
||||||
|
def populate_ipsecpolicy_id_choices(self, request, context):
|
||||||
|
ipsecpolicy_id_choices = [('', _("Select IPSec Policy"))]
|
||||||
|
try:
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
ipsecpolicies = api_vpn.ipsecpolicy_list(request,
|
||||||
|
tenant_id=tenant_id)
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request,
|
||||||
|
_('Unable to retrieve IPSec Policies list.'))
|
||||||
|
ipsecpolicies = []
|
||||||
|
for p in ipsecpolicies:
|
||||||
|
ipsecpolicy_id_choices.append((p.id, p.name))
|
||||||
|
self.fields['ipsecpolicy_id'].choices = ipsecpolicy_id_choices
|
||||||
|
return ipsecpolicy_id_choices
|
||||||
|
|
||||||
|
def populate_vpnservice_id_choices(self, request, context):
|
||||||
|
vpnservice_id_choices = [('', _("Select VPN Service"))]
|
||||||
|
try:
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
|
vpnservices = api_vpn.vpnservice_list(request, tenant_id=tenant_id)
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request,
|
||||||
|
_('Unable to retrieve VPN Services list.'))
|
||||||
|
vpnservices = []
|
||||||
|
for s in vpnservices:
|
||||||
|
vpnservice_id_choices.append((s.id, s.name))
|
||||||
|
self.fields['vpnservice_id'].choices = vpnservice_id_choices
|
||||||
|
return vpnservice_id_choices
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = _("Add New IPSec Site Connection")
|
||||||
|
permissions = ('openstack.services.network',)
|
||||||
|
help_text = _("Create IPSec Site Connection for current "
|
||||||
|
"project. Assign a name and description for the "
|
||||||
|
"IPSec Site Connection. "
|
||||||
|
"All fields in this tab are required."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecSiteConnectionStep(workflows.Step):
|
||||||
|
action_class = AddIPSecSiteConnectionAction
|
||||||
|
contributes = ("name", "description",
|
||||||
|
"vpnservice_id", "ikepolicy_id", "ipsecpolicy_id",
|
||||||
|
"peer_address", "peer_id", "peer_cidrs", "psk")
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecSiteConnectionOptionalAction(workflows.Action):
|
||||||
|
mtu = forms.IntegerField(
|
||||||
|
min_value=68,
|
||||||
|
label=_("Maximum Transmission Unit size for the connection"),
|
||||||
|
initial=1500,
|
||||||
|
required=False,
|
||||||
|
help_text=_("Equal to or greater than 68 if the local subnet is IPv4. "
|
||||||
|
"Equal to or greater than 1280 if the local subnet "
|
||||||
|
"is IPv6."))
|
||||||
|
dpd_action = forms.ChoiceField(label=_("Dead peer detection actions"),
|
||||||
|
required=False)
|
||||||
|
dpd_interval = forms.IntegerField(
|
||||||
|
min_value=1, label=_("Dead peer detection interval"),
|
||||||
|
initial=30,
|
||||||
|
required=False,
|
||||||
|
help_text=_("Valid integer lesser than DPD timeout"))
|
||||||
|
dpd_timeout = forms.IntegerField(
|
||||||
|
min_value=1, label=_("Dead peer detection timeout"),
|
||||||
|
initial=120,
|
||||||
|
required=False,
|
||||||
|
help_text=_("Valid integer greater than the DPD interval"))
|
||||||
|
initiator = forms.ChoiceField(label=_("Initiator state"), required=False)
|
||||||
|
admin_state_up = forms.BooleanField(
|
||||||
|
label=_("Enable Admin State"),
|
||||||
|
help_text=_("The state of IPSec site connection to start in. "
|
||||||
|
"If disabled (not checked), IPSec site connection "
|
||||||
|
"does not forward packets."),
|
||||||
|
initial=True,
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
def __init__(self, request, *args, **kwargs):
|
||||||
|
super(AddIPSecSiteConnectionOptionalAction, self).__init__(
|
||||||
|
request, *args, **kwargs)
|
||||||
|
|
||||||
|
initiator_choices = [("bi-directional", "bi-directional"),
|
||||||
|
("response-only", "response-only")]
|
||||||
|
self.fields['initiator'].choices = initiator_choices
|
||||||
|
|
||||||
|
def populate_dpd_action_choices(self, request, context):
|
||||||
|
dpd_action_choices = [("hold", "hold"),
|
||||||
|
("clear", "clear"),
|
||||||
|
("disabled", "disabled"),
|
||||||
|
("restart", "restart"),
|
||||||
|
("restart-by-peer", "restart-by-peer")]
|
||||||
|
self.fields['dpd_action'].choices = dpd_action_choices
|
||||||
|
return dpd_action_choices
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super(AddIPSecSiteConnectionOptionalAction,
|
||||||
|
self).clean()
|
||||||
|
interval = cleaned_data.get('dpd_interval')
|
||||||
|
timeout = cleaned_data.get('dpd_timeout')
|
||||||
|
|
||||||
|
if not interval < timeout:
|
||||||
|
msg = _("DPD Timeout must be greater than DPD Interval")
|
||||||
|
self._errors['dpd_timeout'] = self.error_class([msg])
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = _("Optional Parameters")
|
||||||
|
permissions = ('openstack.services.network',)
|
||||||
|
help_text = _("Fields in this tab are optional. "
|
||||||
|
"You can configure the detail of "
|
||||||
|
"IPSec site connection created."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecSiteConnectionOptionalStep(workflows.Step):
|
||||||
|
action_class = AddIPSecSiteConnectionOptionalAction
|
||||||
|
contributes = ("dpd_action", "dpd_interval", "dpd_timeout",
|
||||||
|
"initiator", "mtu", "admin_state_up")
|
||||||
|
|
||||||
|
def contribute(self, data, context):
|
||||||
|
context = super(
|
||||||
|
AddIPSecSiteConnectionOptionalStep, self).contribute(data, context)
|
||||||
|
context['dpd'] = {'action': data['dpd_action'],
|
||||||
|
'interval': data['dpd_interval'],
|
||||||
|
'timeout': data['dpd_timeout']}
|
||||||
|
context.pop('dpd_action')
|
||||||
|
context.pop('dpd_interval')
|
||||||
|
context.pop('dpd_timeout')
|
||||||
|
|
||||||
|
cidrs = context['peer_cidrs']
|
||||||
|
context['peer_cidrs'] = cidrs.replace(" ", "").split(",")
|
||||||
|
|
||||||
|
if data:
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class AddIPSecSiteConnection(workflows.Workflow):
|
||||||
|
slug = "addipsecsiteconnection"
|
||||||
|
name = _("Add IPSec Site Connection")
|
||||||
|
finalize_button_name = _("Add")
|
||||||
|
success_message = _('Added IPSec Site Connection "%s".')
|
||||||
|
failure_message = _('Unable to add IPSec Site Connection "%s".')
|
||||||
|
success_url = "horizon:project:vpn:index"
|
||||||
|
default_steps = (AddIPSecSiteConnectionStep,
|
||||||
|
AddIPSecSiteConnectionOptionalStep)
|
||||||
|
|
||||||
|
def format_status_message(self, message):
|
||||||
|
return message % self.context.get('name')
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
api_vpn.ipsecsiteconnection_create(request, **context)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
23
neutron_vpnaas_dashboard/enabled/_1470_project_vpn_panel.py
Normal file
23
neutron_vpnaas_dashboard/enabled/_1470_project_vpn_panel.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||||
|
PANEL = 'vpn'
|
||||||
|
# The slug of the dashboard the PANEL associated with. Required.
|
||||||
|
PANEL_DASHBOARD = 'project'
|
||||||
|
# The slug of the panel group the PANEL is associated with.
|
||||||
|
PANEL_GROUP = 'network'
|
||||||
|
|
||||||
|
# Python panel class of the PANEL to be added.
|
||||||
|
ADD_PANEL = 'neutron_vpnaas_dashboard.dashboards.project.panel.VPN'
|
||||||
|
|
||||||
|
ADD_INSTALLED_APPS = ["neutron_vpnaas_dashboard"]
|
7
requirements.txt
Normal file
7
requirements.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# The order of packages is significant, because pip processes them in the order
|
||||||
|
# of appearance. Changing the order has an impact on the overall integration
|
||||||
|
# process, which may cause wedges in the gate later.
|
||||||
|
|
||||||
|
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||||
|
Django<1.10,>=1.8 # BSD
|
||||||
|
python-neutronclient>=5.1.0 # Apache-2.0
|
32
setup.cfg
Normal file
32
setup.cfg
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
[metadata]
|
||||||
|
name = neutron-vpnaas-dashboard
|
||||||
|
summary = Neutron VPNaaS Dashboard
|
||||||
|
description-file =
|
||||||
|
README.rst
|
||||||
|
author = OpenStack
|
||||||
|
author-email = openstack-dev@lists.openstack.org
|
||||||
|
home-page = http://docs.openstack.org/developer/trove/
|
||||||
|
classifier =
|
||||||
|
Environment :: OpenStack
|
||||||
|
Intended Audience :: Information Technology
|
||||||
|
Intended Audience :: System Administrators
|
||||||
|
License :: OSI Approved :: Apache Software License
|
||||||
|
Operating System :: POSIX :: Linux
|
||||||
|
Programming Language :: Python
|
||||||
|
Programming Language :: Python :: 2
|
||||||
|
Programming Language :: Python :: 2.7
|
||||||
|
Programming Language :: Python :: 3
|
||||||
|
Programming Language :: Python :: 3.5
|
||||||
|
|
||||||
|
[files]
|
||||||
|
packages =
|
||||||
|
neutron_vpnaas_dashboard
|
||||||
|
|
||||||
|
[build_sphinx]
|
||||||
|
source-dir = doc/source
|
||||||
|
build-dir = doc/build
|
||||||
|
all-files = 1
|
||||||
|
warning-is-error = 1
|
||||||
|
|
||||||
|
[upload_sphinx]
|
||||||
|
upload-dir = doc/build/html
|
29
setup.py
Normal file
29
setup.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||||
|
import setuptools
|
||||||
|
|
||||||
|
# In python < 2.7.4, a lazy loading of package `pbr` will break
|
||||||
|
# setuptools if some other modules registered functions in `atexit`.
|
||||||
|
# solution from: http://bugs.python.org/issue15881#msg170215
|
||||||
|
try:
|
||||||
|
import multiprocessing # noqa
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
setuptools.setup(
|
||||||
|
setup_requires=['pbr>=2.0.0'],
|
||||||
|
pbr=True)
|
Loading…
Reference in New Issue
Block a user