Revert "Retire neutron-fwaas-dashboard project"
This reverts commit 4a0f1a3ae54a69f37ab38a0209e3a9996f727693. Reason for revert: Neutron drivers team agreed to include neutron-fwaas again to Neutron stadium[1], and goverance change is proposed at [2]. [1] https://meetings.opendev.org/meetings/neutron_drivers/2022/neutron_drivers.2022-01-28-14.00.log.html#l-14 [2] https://review.opendev.org/c/openstack/governance/+/828078 Change-Id: I5018dfdf9ea866e113a17f9bd5a3b153e4f1c08f
This commit is contained in:
parent
dffb01f9b9
commit
e8463a1ad4
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
*.pyc
|
||||
*.swp
|
||||
*.egg*/
|
||||
.coverage
|
||||
.tox/
|
||||
build/
|
||||
cover/
|
||||
dist/
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
|
||||
# Translation catalogs
|
||||
*.mo
|
||||
*.pot
|
35
.zuul.yaml
Normal file
35
.zuul.yaml
Normal file
@ -0,0 +1,35 @@
|
||||
- job:
|
||||
name: neutron-fwaas-dashboard-integration-tests
|
||||
parent: horizon-integration-tests
|
||||
required-projects:
|
||||
- name: openstack/horizon
|
||||
- name: openstack/neutron-fwaas
|
||||
- name: openstack/neutron-fwaas-dashboard
|
||||
roles:
|
||||
- zuul: openstack-infra/devstack
|
||||
- zuul: openstack/horizon
|
||||
irrelevant-files:
|
||||
- ^.*\.rst$
|
||||
- ^doc/.*$
|
||||
- ^releasenotes/.*$
|
||||
vars:
|
||||
devstack_plugins:
|
||||
neutron-fwaas: https://git.openstack.org/openstack/neutron-fwaas
|
||||
neutron-fwaas-dashboard: https://git.openstack.org/openstack/neutron-fwaas-dashboard
|
||||
devstack_services:
|
||||
horizon: true
|
||||
tox_envlist: integration
|
||||
|
||||
- project:
|
||||
templates:
|
||||
- check-requirements
|
||||
- horizon-non-primary-django-jobs
|
||||
- openstack-cover-jobs-horizon
|
||||
- openstack-lower-constraints-jobs-horizon
|
||||
- openstack-python3-victoria-jobs-horizon
|
||||
- publish-openstack-docs-pti
|
||||
- release-notes-jobs-python3
|
||||
check:
|
||||
jobs:
|
||||
- neutron-fwaas-dashboard-integration-tests:
|
||||
voting: false
|
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:
|
||||
|
||||
https://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:
|
||||
|
||||
https://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-fwaas-dashboard
|
13
HACKING.rst
Normal file
13
HACKING.rst
Normal file
@ -0,0 +1,13 @@
|
||||
==========================================
|
||||
Neutron FWaaS Dashboard Style Commandments
|
||||
==========================================
|
||||
|
||||
Read the OpenStack Style Commandments
|
||||
https://docs.openstack.org/hacking/latest/user/hacking.html
|
||||
|
||||
Project Specific Commandments
|
||||
-----------------------------
|
||||
|
||||
- Read the Horizon contributing documentation at
|
||||
https://docs.openstack.org/horizon/latest/contributor/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.
|
||||
|
24
README.rst
24
README.rst
@ -1,10 +1,18 @@
|
||||
This project is no longer maintained.
|
||||
=======================
|
||||
Neutron FWaaS Dashboard
|
||||
=======================
|
||||
|
||||
The contents of this repository are still available in the Git
|
||||
source code management system. To see the contents of this
|
||||
repository before it reached its end of life, please check out the
|
||||
previous commit with "git checkout HEAD^1".
|
||||
.. warning::
|
||||
Due to lack of maintainers this project is now deprecated in the Neutron
|
||||
stadium and will be removed from stadium in ``W`` cycle.
|
||||
If You want to step in and be maintainer of this project to keep it in the
|
||||
Neutron stadium, please contact the ``neutron team`` via
|
||||
openstack-discuss@lists.openstack.org or IRC channel #openstack-neutron
|
||||
@freenode.
|
||||
|
||||
For any further questions, please email
|
||||
openstack-discuss@lists.openstack.org or join #openstack-dev on
|
||||
OFTC.
|
||||
OpenStack Dashboard panels for Neutron FWaaS
|
||||
|
||||
* Documentation: https://docs.openstack.org/neutron-fwaas-dashboard/latest/
|
||||
* Source: https://opendev.org/openstack/neutron-fwaas-dashboard
|
||||
* Bugs: https://bugs.launchpad.net/neutron-fwaas-dashboard
|
||||
* Release Notes: https://docs.openstack.org/releasenotes/neutron-fwaas-dashboard/
|
||||
|
2
babel-django.cfg
Normal file
2
babel-django.cfg
Normal file
@ -0,0 +1,2 @@
|
||||
[python: **.py]
|
||||
[django: **/templates/**.html]
|
2
babel-djangojs.cfg
Normal file
2
babel-djangojs.cfg
Normal file
@ -0,0 +1,2 @@
|
||||
[javascript: **.js]
|
||||
[angular: **/static/**.html]
|
5
bindep.txt
Normal file
5
bindep.txt
Normal file
@ -0,0 +1,5 @@
|
||||
# selenium tests
|
||||
firefox [selenium]
|
||||
xvfb [selenium platform:dpkg]
|
||||
# already part of xorg-x11-server on openSUSE
|
||||
xorg-x11-server-Xvfb [selenium platform:redhat]
|
25
devstack/README.rst
Normal file
25
devstack/README.rst
Normal file
@ -0,0 +1,25 @@
|
||||
===========================================
|
||||
DevStack plugin for neutron-fwaas-dashboard
|
||||
===========================================
|
||||
|
||||
This is setup as a DevStack plugin.
|
||||
For more information on DevStack plugins,
|
||||
see the `DevStack Plugins documentation
|
||||
<https://docs.openstack.org/developer/devstack/plugins.html>`__.
|
||||
|
||||
If neutron-fwaas-dashboard DevStack plugin is enabled,
|
||||
Neutron FWaaS dashboard is automatically enabled and
|
||||
the appropriate version of FWaaS panel is displayed based on
|
||||
the FWaaS version enabled in your neutron server.
|
||||
You do not need to specify FWaaS API version in the DevStack plugin
|
||||
configuration.
|
||||
|
||||
To enable FWaaS dashboard, add the following to the localrc section
|
||||
of your local.conf.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[[local|localrc]]
|
||||
enable_plugin neutron-fwaas https://opendev.org/openstack/neutron-fwaas master
|
||||
enable_service q-fwaas-v2
|
||||
enable_plugin neutron-fwaas-dashboard https://opendev.org/openstack/neutron-fwaas-dashboard master
|
64
devstack/plugin.sh
Normal file
64
devstack/plugin.sh
Normal file
@ -0,0 +1,64 @@
|
||||
# plugin.sh - DevStack plugin.sh dispatch script neutron-fwaas-dashboard
|
||||
|
||||
FWAAS_DASHBOARD_DIR=$(cd $(dirname $BASH_SOURCE)/.. && pwd)
|
||||
FWAAS_ENABLED_DIR=$FWAAS_DASHBOARD_DIR/neutron_fwaas_dashboard/enabled
|
||||
OPENSTACK_DASHBOARD_DIR=$DEST/horizon/openstack_dashboard
|
||||
HORIZON_ENABLED_DIR=$OPENSTACK_DASHBOARD_DIR/local/enabled
|
||||
|
||||
function install_neutron_fwaas_dashboard {
|
||||
setup_develop $FWAAS_DASHBOARD_DIR
|
||||
}
|
||||
|
||||
function configure_neutron_fwaas_dashboard {
|
||||
cp -a $FWAAS_ENABLED_DIR/_[0-9]*.py $HORIZON_ENABLED_DIR
|
||||
# NOTE: If locale directory does not exist, compilemessages will fail,
|
||||
# so check for an existence of locale directory is required.
|
||||
if [ -d $FWAAS_DASHBOARD_DIR/neutron_fwaas_dashboard/locale ]; then
|
||||
(cd $FWAAS_DASHBOARD_DIR/neutron_fwaas_dashboard; \
|
||||
DJANGO_SETTINGS_MODULE=openstack_dashboard.settings $PYTHON ../manage.py compilemessages)
|
||||
fi
|
||||
# Add policy file for FWaaS
|
||||
cp $FWAAS_DASHBOARD_DIR/etc/neutron-fwaas-policy.json $OPENSTACK_DASHBOARD_DIR/conf/
|
||||
cp $FWAAS_DASHBOARD_DIR/neutron_fwaas_dashboard/local_settings.d/_7000_neutron_fwaas.py \
|
||||
$OPENSTACK_DASHBOARD_DIR/local/local_settings.d/
|
||||
}
|
||||
|
||||
# check for service enabled
|
||||
if is_service_enabled neutron-fwaas-dashboard; then
|
||||
|
||||
if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
|
||||
# Set up system services
|
||||
# no-op
|
||||
:
|
||||
|
||||
elif [[ "$1" == "stack" && "$2" == "install" ]]; then
|
||||
# Perform installation of service source
|
||||
echo_summary "Installing Neutron FWaaS Dashboard"
|
||||
install_neutron_fwaas_dashboard
|
||||
|
||||
elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
|
||||
# Configure after the other layer 1 and 2 services have been configured
|
||||
echo_summary "Configurng Neutron FWaaS Dashboard"
|
||||
configure_neutron_fwaas_dashboard
|
||||
|
||||
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
|
||||
# no-op
|
||||
:
|
||||
fi
|
||||
|
||||
if [[ "$1" == "unstack" ]]; then
|
||||
# Remove enabled file(s)
|
||||
for _enabled_file in $FWAAS_ENABLED_DIR/_[0-9]*.py; do
|
||||
_enabled_basename=$(basename $_enabled_file .py)
|
||||
rm -f $HORIZON_ENABLED_DIR/${_enabled_basename}.py*
|
||||
rm -f $HORIZON_ENABLED_DIR/__pycache__/${_enabled_basename}.*pyc
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "$1" == "clean" ]]; then
|
||||
# Remove state and transient data
|
||||
# Remember clean.sh first calls unstack.sh
|
||||
rm -f $OPENSTACK_DASHBOARD_DIR/local/local_settings.d/_7000_neutron_fwaas.py*
|
||||
rm -f $OPENSTACK_DASHBOARD_DIR/conf/neutron-fwaas-policy.json
|
||||
fi
|
||||
fi
|
2
devstack/settings
Normal file
2
devstack/settings
Normal file
@ -0,0 +1,2 @@
|
||||
# settings file for neutron-fwaas-dashboard plugin
|
||||
enable_service neutron-fwaas-dashboard
|
215
doc/source/conf.py
Normal file
215
doc/source/conf.py
Normal file
@ -0,0 +1,215 @@
|
||||
# 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.
|
||||
#
|
||||
# Horizon documentation build configuration file, created by
|
||||
# sphinx-quickstart on Thu Oct 27 11:38:59 2011.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import django
|
||||
|
||||
PROJECT = 'neutron-fwaas-dashboard'
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
ROOT = os.path.abspath(os.path.join(BASE_DIR, "..", ".."))
|
||||
|
||||
sys.path.insert(0, ROOT)
|
||||
|
||||
# This is required for ReadTheDocs.org, but isn't a bad idea anyway.
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE',
|
||||
'neutron_fwaas_dashboard.test.settings')
|
||||
|
||||
django.setup()
|
||||
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings.
|
||||
# They can be extensions coming with Sphinx (named 'sphinx.ext.*')
|
||||
# or your custom ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.coverage',
|
||||
'sphinx.ext.viewcode',
|
||||
'reno.sphinxext',
|
||||
'openstackdocstheme',
|
||||
]
|
||||
|
||||
# openstackdocstheme options
|
||||
openstackdocs_repo_name = 'openstack/neutron-fwaas-dashboard'
|
||||
openstackdocs_pdf_link = True
|
||||
openstackdocs_auto_name = False
|
||||
openstackdocs_bug_project = 'neutron-fwaas-dashboard'
|
||||
openstackdocs_bug_tag = 'doc'
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Neutron FWaaS Dashboard'
|
||||
copyright = u'2017, OpenStack Foundation'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
# language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['**/#*', '**~', '**/#*#']
|
||||
|
||||
# The reST default role (used for this markup: `text`)
|
||||
# to use for all documents.
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'native'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
modindex_common_prefix = ['neutron_fwaas_dashboard.']
|
||||
|
||||
primary_domain = 'py'
|
||||
nitpicky = False
|
||||
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
# html_theme_path = ['.']
|
||||
html_theme = 'openstackdocs'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
html_theme_options = {
|
||||
"nosidebar": "false"
|
||||
}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
# html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'neutronfwaasdashboarddoc'
|
||||
|
||||
# -- Options for LaTeX output ------------------------------------------------
|
||||
|
||||
latex_documents = [
|
||||
('index', 'doc-neutron-fwaas-dashboard.tex',
|
||||
u'Neutron FWaaS Dashboard Documentation',
|
||||
u'Neutron Contributors', 'howto'),
|
||||
]
|
28
doc/source/configuration/index.rst
Normal file
28
doc/source/configuration/index.rst
Normal file
@ -0,0 +1,28 @@
|
||||
..
|
||||
Copyright 2017 OpenStack Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
=============
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Neutron FWaaS dashboard has no configuration option.
|
||||
It checks if Neutron FWaaS service is enabled in your neutron server
|
||||
and the FWaaS panel is displayed if enabled.
|
||||
|
||||
For more configurations, see
|
||||
`Settings Reference
|
||||
<https://docs.openstack.org/horizon/latest/configuration/settings.html>`__
|
||||
in the Horizon documentation.
|
1
doc/source/contributor/devstack-plugin.rst
Normal file
1
doc/source/contributor/devstack-plugin.rst
Normal file
@ -0,0 +1 @@
|
||||
.. include:: ../../../devstack/README.rst
|
32
doc/source/contributor/index.rst
Normal file
32
doc/source/contributor/index.rst
Normal file
@ -0,0 +1,32 @@
|
||||
..
|
||||
Copyright 2017 OpenStack Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
=================
|
||||
Contributor Guide
|
||||
=================
|
||||
|
||||
There is no topic specific to neutron-fwaas-dashboard now.
|
||||
|
||||
See `Horizon Contributor Documentation
|
||||
<https://docs.openstack.org/horizon/latest/contributor/>`__
|
||||
for general topic on developing a dashboard on horizon.
|
||||
|
||||
----
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
DevStack plugin <devstack-plugin>
|
37
doc/source/index.rst
Normal file
37
doc/source/index.rst
Normal file
@ -0,0 +1,37 @@
|
||||
..
|
||||
Copyright 2017 OpenStack Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
================================
|
||||
Neutron FWaaS Dashboard Project
|
||||
================================
|
||||
|
||||
.. warning::
|
||||
Due to lack of maintainers this project is now deprecated in the Neutron
|
||||
stadium and will be removed from stadium in ``W`` cycle.
|
||||
If You want to step in and be maintainer of this project to keep it in the
|
||||
Neutron stadium, please contact the ``neutron team`` via
|
||||
openstack-discuss@lists.openstack.org or IRC channel #openstack-neutron
|
||||
@freenode.
|
||||
|
||||
Neutron FWaaS Dashboard is a horizon plugin for Neutron FWaaS.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
install/index
|
||||
configuration/index
|
||||
contributor/index
|
||||
Release Notes <https://docs.openstack.org/releasenotes/neutron-fwaas-dashboard/>
|
99
doc/source/install/index.rst
Normal file
99
doc/source/install/index.rst
Normal file
@ -0,0 +1,99 @@
|
||||
..
|
||||
Copyright 2017 OpenStack Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
Manual Installation
|
||||
-------------------
|
||||
|
||||
Before installing neutron-fwaas-dashboard,
|
||||
you first need to install horizon in your environment.
|
||||
|
||||
Fetch the source code from git and run pip install.
|
||||
Make sure to install neutron-fwaas-dashboard into the same python environment
|
||||
where horizon is installed.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git clone https://opendev.org/openstack/neutron-fwaas-dashboard
|
||||
$ cd neutron-fwaas-dashboard
|
||||
$ sudo pip install .
|
||||
|
||||
Enable the horizon plugin.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cp neutron_fwaas_dashboard/enabled/_70*_*.py \
|
||||
/opt/stack/horizon/openstack_dashboard/local/enabled/
|
||||
|
||||
.. note::
|
||||
|
||||
The directory ``local/enabled`` may be different depending on your
|
||||
environment or distribution used. For example, for Ubuntu, this is
|
||||
``/usr/share/openstack-dashboard/openstack_dashboard/local/enabled``.
|
||||
|
||||
.. note::
|
||||
|
||||
The number of the plugin enabled file determines the order of panels.
|
||||
If you would like to configure the place of the Neutron FWaaS dashboard,
|
||||
change the number of the file.
|
||||
|
||||
.. note::
|
||||
|
||||
For more detail of the horizon plugin settings,
|
||||
see `Pluggable Settings
|
||||
<https://docs.openstack.org/horizon/latest/configuration/pluggable_panels.html>`__
|
||||
in the horizon documentation.
|
||||
|
||||
Configure the policy file for Neutron FWaaS dashboard
|
||||
in OpenStack Dashboard ``local_settings.py``.
|
||||
``<fwaas-dashboard-config-dir>`` is a directory which contains
|
||||
configurations for Neutron FWaaS dashboard and the location varies
|
||||
across distributions or deployments.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
POLICY_FILES['neutron-fwaas'] = '<fwaas-dashboard-config-dir>/etc/neutron-fwaas-policy.json'
|
||||
|
||||
.. note::
|
||||
|
||||
If you do not configure ``POLICY_FILES`` in your ``local_settings.py``,
|
||||
you also need to define the default ``POLICY_FILES`` in
|
||||
``local_settings.py``. If you use the example ``local_settings.py`` file
|
||||
from horizon, what you need is to uncomment ``POLICY_FILES`` (which contains
|
||||
the default values).
|
||||
|
||||
Compile the message catalogs of Neutron FWaaS dashboard.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd neutron-fwaas-dashboard
|
||||
$ ./manage.py compilemessages
|
||||
|
||||
Run the Django update commands (if you use).
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ DJANGO_SETTINGS_MODULE=openstack_dashboard.settings python manage.py collectstatic --noinput
|
||||
$ DJANGO_SETTINGS_MODULE=openstack_dashboard.settings python manage.py compress --force
|
||||
|
||||
Restart Apache:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo service apache2 restart
|
36
etc/neutron-fwaas-policy.json
Normal file
36
etc/neutron-fwaas-policy.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"context_is_admin": "role:admin",
|
||||
"owner": "tenant_id:%(tenant_id)s",
|
||||
"admin_or_owner": "rule:context_is_admin or rule:owner",
|
||||
"admin_only": "rule:context_is_admin",
|
||||
"shared_firewalls": "field:firewalls:shared=True",
|
||||
"shared_firewall_policies": "field:firewall_policies:shared=True",
|
||||
"default": "rule:admin_or_owner",
|
||||
|
||||
"create_firewall": "",
|
||||
"get_firewall": "rule:admin_or_owner",
|
||||
"create_firewall:shared": "rule:admin_only",
|
||||
"get_firewall:shared": "rule:admin_only",
|
||||
"update_firewall": "rule:admin_or_owner",
|
||||
"update_firewall:shared": "rule:admin_only",
|
||||
"delete_firewall": "rule:admin_or_owner",
|
||||
|
||||
"create_firewall_policy": "",
|
||||
"get_firewall_policy": "rule:admin_or_owner or rule:shared_firewall_policies",
|
||||
"update_firewall_policy": "rule:admin_or_owner",
|
||||
"delete_firewall_policy": "rule:admin_or_owner",
|
||||
"create_firewall_policy:shared": "rule:admin_only",
|
||||
"update_firewall_policy:shared": "rule:admin_only",
|
||||
"delete_firewall_policy:shared": "rule:admin_only",
|
||||
|
||||
"insert_rule": "rule:admin_or_owner",
|
||||
"remove_rule": "rule:admin_or_owner",
|
||||
|
||||
"create_firewall_rule": "",
|
||||
"get_firewall_rule": "rule:admin_or_owner or rule:shared_firewalls",
|
||||
"update_firewall_rule": "rule:admin_or_owner",
|
||||
"delete_firewall_rule": "rule:admin_or_owner",
|
||||
"create_firewall_rule:shared": "rule:admin_only",
|
||||
"update_firewall_rule:shared": "rule:admin_only",
|
||||
"delete_firewall_rule:shared": "rule:admin_only"
|
||||
}
|
151
lower-constraints.txt
Normal file
151
lower-constraints.txt
Normal file
@ -0,0 +1,151 @@
|
||||
alabaster==0.7.10
|
||||
amqp==2.1.1
|
||||
appdirs==1.3.0
|
||||
asn1crypto==0.23.0
|
||||
Babel==2.3.4
|
||||
cachetools==2.0.0
|
||||
cffi==1.7.0
|
||||
cliff==2.8.0
|
||||
cmd2==0.8.0
|
||||
contextlib2==0.4.0
|
||||
coverage==4.0
|
||||
cryptography==2.1
|
||||
debtcollector==1.2.0
|
||||
decorator==4.1.0
|
||||
deprecation==1.0
|
||||
Django==2.2
|
||||
django-appconf==1.0.2
|
||||
django-babel==0.6.2
|
||||
django-compressor==2.0
|
||||
django-pyscss==2.0.2
|
||||
docutils==0.12
|
||||
dogpile.cache==0.6.2
|
||||
dulwich==0.15.0
|
||||
eventlet==0.18.2
|
||||
extras==1.0.0
|
||||
fasteners==0.7.0
|
||||
fixtures==3.0.0
|
||||
flake8==3.6.0
|
||||
flake8-import-order==0.13
|
||||
futurist==1.2.0
|
||||
greenlet==0.4.10
|
||||
hacking==3.0.1
|
||||
horizon==17.1.0
|
||||
idna==2.6
|
||||
imagesize==0.7.1
|
||||
iso8601==0.1.11
|
||||
Jinja2==2.10
|
||||
jmespath==0.9.0
|
||||
jsonpatch==1.16
|
||||
jsonpointer==1.13
|
||||
jsonschema==2.6.0
|
||||
keystoneauth1==3.4.0
|
||||
kombu==4.0.0
|
||||
linecache2==1.0.0
|
||||
MarkupSafe==1.1.1
|
||||
mccabe==0.6.0
|
||||
monotonic==0.6
|
||||
msgpack-python==0.4.0
|
||||
munch==2.1.0
|
||||
netaddr==0.7.18
|
||||
netifaces==0.10.4
|
||||
openstackdocstheme==2.2.1
|
||||
openstacksdk==0.11.2
|
||||
os-client-config==1.28.0
|
||||
os-service-types==1.2.0
|
||||
osc-lib==1.8.0
|
||||
oslo.concurrency==3.26.0
|
||||
oslo.config==5.2.0
|
||||
oslo.context==2.19.2
|
||||
oslo.i18n==3.15.3
|
||||
oslo.log==3.36.0
|
||||
oslo.messaging==5.29.0
|
||||
oslo.middleware==3.31.0
|
||||
oslo.policy==1.30.0
|
||||
oslo.serialization==2.18.0
|
||||
oslo.service==1.24.0
|
||||
oslo.utils==3.33.0
|
||||
osprofiler==2.3.0
|
||||
Paste==2.0.2
|
||||
PasteDeploy==1.5.0
|
||||
pbr==2.0.0
|
||||
pep8==1.5.7
|
||||
pika==0.10.0
|
||||
pika-pool==0.1.3
|
||||
Pint==0.5
|
||||
positional==1.2.1
|
||||
prettytable==0.7.2
|
||||
pycodestyle==2.4.0
|
||||
pycparser==2.18
|
||||
pyflakes==2.0.0
|
||||
Pygments==2.2.0
|
||||
pyinotify==0.9.6
|
||||
pymongo==3.0.2
|
||||
pyOpenSSL==17.1.0
|
||||
pyparsing==2.1.0
|
||||
pyperclip==1.5.27
|
||||
pyScss==1.3.7
|
||||
python-cinderclient==5.0.0
|
||||
python-dateutil==2.5.3
|
||||
python-glanceclient==2.8.0
|
||||
python-keystoneclient==3.22.0
|
||||
python-mimeparse==1.6.0
|
||||
python-neutronclient==6.7.0
|
||||
python-novaclient==9.1.0
|
||||
python-swiftclient==3.2.0
|
||||
pytz==2013.6
|
||||
PyYAML==3.12
|
||||
rcssmin==1.0.6
|
||||
reno==3.1.0
|
||||
repoze.lru==0.7
|
||||
requests==2.14.2
|
||||
requestsexceptions==1.2.0
|
||||
rfc3986==0.3.1
|
||||
rjsmin==1.0.12
|
||||
Routes==2.3.1
|
||||
selenium==2.50.1
|
||||
semantic-version==2.3.1
|
||||
simplejson==3.5.1
|
||||
six==1.10.0
|
||||
snowballstemmer==1.2.1
|
||||
Sphinx==2.0.0
|
||||
sphinxcontrib-websupport==1.0.1
|
||||
statsd==3.2.1
|
||||
stevedore==1.20.0
|
||||
tenacity==3.2.1
|
||||
testtools==2.2.0
|
||||
traceback2==1.4.0
|
||||
unittest2==1.1.0
|
||||
vine==1.1.4
|
||||
warlock==1.2.0
|
||||
WebOb==1.7.1
|
||||
wrapt==1.7.0
|
||||
XStatic==1.0.0
|
||||
XStatic-Angular==1.5.8.0
|
||||
XStatic-Angular-Bootstrap==2.2.0.0
|
||||
XStatic-Angular-FileUpload==12.0.4.0
|
||||
XStatic-Angular-Gettext==2.3.8.0
|
||||
XStatic-Angular-lrdragndrop==1.0.2.2
|
||||
XStatic-Angular-Schema-Form==0.8.13.0
|
||||
XStatic-Bootstrap-Datepicker==1.3.1.0
|
||||
XStatic-Bootstrap-SCSS==3.3.7.1
|
||||
XStatic-bootswatch==3.3.7.0
|
||||
XStatic-D3==3.5.17.0
|
||||
XStatic-Font-Awesome==4.7.0.0
|
||||
XStatic-Hogan==2.0.0.2
|
||||
XStatic-Jasmine==2.4.1.1
|
||||
XStatic-jQuery==1.8.2.1
|
||||
XStatic-JQuery-Migrate==1.2.1.1
|
||||
XStatic-jquery-ui==1.10.4.1
|
||||
XStatic-JQuery.quicksearch==2.0.3.1
|
||||
XStatic-JQuery.TableSorter==2.14.5.1
|
||||
XStatic-JSEncrypt==2.3.1.1
|
||||
XStatic-mdi==1.4.57.0
|
||||
XStatic-objectpath==1.2.1.0
|
||||
XStatic-Rickshaw==1.5.0.0
|
||||
XStatic-roboto-fontface==0.5.0.0
|
||||
XStatic-smart-table==1.4.13.2
|
||||
XStatic-Spin==1.2.5.2
|
||||
XStatic-term.js==0.0.7.0
|
||||
XStatic-tv4==1.2.7.0
|
||||
xvfbwrapper==0.1.3
|
23
manage.py
Executable file
23
manage.py
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# 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 os
|
||||
import sys
|
||||
|
||||
from django.core.management import execute_from_command_line # noqa
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE",
|
||||
"neutron_fwaas_dashboard.test.settings")
|
||||
execute_from_command_line(sys.argv)
|
0
neutron_fwaas_dashboard/__init__.py
Normal file
0
neutron_fwaas_dashboard/__init__.py
Normal file
0
neutron_fwaas_dashboard/api/__init__.py
Normal file
0
neutron_fwaas_dashboard/api/__init__.py
Normal file
348
neutron_fwaas_dashboard/api/fwaas_v2.py
Normal file
348
neutron_fwaas_dashboard/api/fwaas_v2.py
Normal file
@ -0,0 +1,348 @@
|
||||
# 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 collections
|
||||
|
||||
from openstack_dashboard.api import neutron
|
||||
import openstack_dashboard.api.nova as nova
|
||||
from openstack_dashboard.contrib.developer.profiler import api as profiler
|
||||
|
||||
|
||||
neutronclient = neutron.neutronclient
|
||||
|
||||
|
||||
class Port(neutron.NeutronAPIDictWrapper):
|
||||
"""Wrapper for neutron port."""
|
||||
|
||||
|
||||
class Rule(neutron.NeutronAPIDictWrapper):
|
||||
"""Wrapper for neutron firewall rule."""
|
||||
|
||||
|
||||
class Policy(neutron.NeutronAPIDictWrapper):
|
||||
"""Wrapper for neutron firewall policy."""
|
||||
|
||||
|
||||
class FirewallGroup(neutron.NeutronAPIDictWrapper):
|
||||
"""Wrapper for neutron firewall group."""
|
||||
|
||||
|
||||
def rule_create(request, **kwargs):
|
||||
"""Create a firewall rule
|
||||
|
||||
:param request: request context
|
||||
:param name: name for rule
|
||||
:param description: description for rule
|
||||
:param protocol: protocol for rule
|
||||
:param action: action for rule
|
||||
:param source_ip_address: source IP address or subnet
|
||||
:param source_port: integer in [1, 65535] or range in a:b
|
||||
:param destination_ip_address: destination IP address or subnet
|
||||
:param destination_port: integer in [1, 65535] or range in a:b
|
||||
:param shared: boolean (default false)
|
||||
:param enabled: boolean (default true)
|
||||
:return: Rule object
|
||||
"""
|
||||
body = {'firewall_rule': kwargs}
|
||||
rule = neutronclient(request).create_fwaas_firewall_rule(
|
||||
body).get('firewall_rule')
|
||||
return Rule(rule)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def get_network_names(request):
|
||||
networks = neutronclient(request).list_networks(fields=["name", "id"])\
|
||||
.get('networks', [])
|
||||
mapped = {n['id']: neutron.Network(n) for n in networks}
|
||||
return mapped
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def get_router_names(request):
|
||||
routers = neutronclient(request).list_routers(fields=["name", "id"])\
|
||||
.get('routers', [])
|
||||
mapped = {r['id']: neutron.Router(r) for r in routers}
|
||||
return mapped
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def get_servers(request):
|
||||
servers = nova.server_list(request)[0]
|
||||
mapped = {s.id: s for s in servers}
|
||||
return mapped
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def rule_list(request, **kwargs):
|
||||
return _rule_list(request, **kwargs)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def port_list(request, tenant_id, **kwargs):
|
||||
kwargs['tenant_id'] = tenant_id
|
||||
ports = neutronclient(request).list_ports(**kwargs).get('ports')
|
||||
|
||||
return {
|
||||
p['id']: Port(p) for p in ports if _is_target(p)
|
||||
}
|
||||
|
||||
|
||||
# Gets ids of all ports assigned to firewall groups
|
||||
@profiler.trace
|
||||
def fwg_port_list(request, **kwargs):
|
||||
fwgs = neutronclient(request).list_fwaas_firewall_groups(
|
||||
**kwargs).get('firewall_groups')
|
||||
ports = set()
|
||||
for fwg in fwgs:
|
||||
if fwg['ports']:
|
||||
ports.update(fwg['ports'])
|
||||
return ports
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def fwg_port_list_for_tenant(request, tenant_id, **kwargs):
|
||||
kwargs['tenant_id'] = tenant_id
|
||||
ports = neutronclient(request).list_ports(**kwargs).get('ports')
|
||||
# TODO(SarathMekala): Remove ports which are already associated with a FWG
|
||||
fwgs = neutronclient(request).list_fwaas_firewall_groups(
|
||||
**kwargs).get('firewall_groups')
|
||||
fwg_ports = []
|
||||
for fwg in fwgs:
|
||||
if not fwg['ports']:
|
||||
continue
|
||||
fwg_ports += fwg['ports']
|
||||
return [Port(p) for p in ports
|
||||
if _is_target(p) and p['id'] not in fwg_ports]
|
||||
|
||||
|
||||
def _is_target(port):
|
||||
return (port['device_owner'].startswith('compute:') or
|
||||
port['device_owner'].startswith('network:router_interface'))
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def rule_list_for_tenant(request, tenant_id, **kwargs):
|
||||
"""Return a rule list available for the tenant.
|
||||
|
||||
The list contains rules owned by the tenant and shared rules.
|
||||
This is required because Neutron returns all resources including
|
||||
all tenants if a user has admin role.
|
||||
"""
|
||||
rules = rule_list(request, tenant_id=tenant_id, shared=False, **kwargs)
|
||||
shared_rules = rule_list(request, shared=True, **kwargs)
|
||||
return rules + shared_rules
|
||||
|
||||
|
||||
def _rule_list(request, **kwargs):
|
||||
rules = neutronclient(request).list_fwaas_firewall_rules(
|
||||
**kwargs).get('firewall_rules')
|
||||
return [Rule(r) for r in rules]
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def rule_get(request, rule_id):
|
||||
return _rule_get(request, rule_id)
|
||||
|
||||
|
||||
def _rule_get(request, rule_id):
|
||||
rule = neutronclient(request).show_fwaas_firewall_rule(
|
||||
rule_id).get('firewall_rule')
|
||||
return Rule(rule)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def rule_delete(request, rule_id):
|
||||
neutronclient(request).delete_fwaas_firewall_rule(rule_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def rule_update(request, rule_id, **kwargs):
|
||||
body = {'firewall_rule': kwargs}
|
||||
rule = neutronclient(request).update_fwaas_firewall_rule(
|
||||
rule_id, body).get('firewall_rule')
|
||||
return Rule(rule)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def policy_create(request, **kwargs):
|
||||
"""Create a firewall policy
|
||||
|
||||
:param request: request context
|
||||
:param name: name for policy
|
||||
:param description: description for policy
|
||||
:param firewall_rules: ordered list of rules in policy
|
||||
:param shared: boolean (default false)
|
||||
:param audited: boolean (default false)
|
||||
:return: Policy object
|
||||
"""
|
||||
body = {'firewall_policy': kwargs}
|
||||
policy = neutronclient(request).create_fwaas_firewall_policy(
|
||||
body).get('firewall_policy')
|
||||
return Policy(policy)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def policy_list(request, **kwargs):
|
||||
return _policy_list(request, expand_rule=True, **kwargs)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def policy_list_for_tenant(request, tenant_id, **kwargs):
|
||||
"""Return a policy list available for the tenant.
|
||||
|
||||
The list contains policies owned by the tenant and shared policies.
|
||||
This is required because Neutron returns all resources including
|
||||
all tenants if a user has admin role.
|
||||
"""
|
||||
policies = policy_list(request, tenant_id=tenant_id,
|
||||
shared=False, **kwargs)
|
||||
shared_policies = policy_list(request, shared=True, **kwargs)
|
||||
return policies + shared_policies
|
||||
|
||||
|
||||
def _policy_list(request, expand_rule, **kwargs):
|
||||
policies = neutronclient(request).list_fwaas_firewall_policies(
|
||||
**kwargs).get('firewall_policies')
|
||||
if expand_rule and policies:
|
||||
rules = _rule_list(request)
|
||||
rule_dict = collections.OrderedDict((rule.id, rule) for rule in rules)
|
||||
for p in policies:
|
||||
p['rules'] = [rule_dict.get(rule) for rule in p['firewall_rules']]
|
||||
return [Policy(p) for p in policies]
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def policy_get(request, policy_id):
|
||||
return _policy_get(request, policy_id, expand_rule=True)
|
||||
|
||||
|
||||
def _policy_get(request, policy_id, expand_rule):
|
||||
policy = neutronclient(request).show_fwaas_firewall_policy(
|
||||
policy_id).get('firewall_policy')
|
||||
if expand_rule:
|
||||
policy_rules = policy['firewall_rules']
|
||||
if policy_rules:
|
||||
rules = _rule_list(request, firewall_policy_id=policy_id)
|
||||
rule_dict = collections.OrderedDict((rule.id, rule)
|
||||
for rule in rules)
|
||||
policy['rules'] = [rule_dict.get(rule) for rule in policy_rules]
|
||||
else:
|
||||
policy['rules'] = []
|
||||
return Policy(policy)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def policy_delete(request, policy_id):
|
||||
neutronclient(request).delete_fwaas_firewall_policy(policy_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def policy_update(request, policy_id, **kwargs):
|
||||
body = {'firewall_policy': kwargs}
|
||||
policy = neutronclient(request).update_fwaas_firewall_policy(
|
||||
policy_id, body).get('firewall_policy')
|
||||
return Policy(policy)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def policy_insert_rule(request, policy_id, **kwargs):
|
||||
policy = neutronclient(request).insert_rule_fwaas_firewall_policy(
|
||||
policy_id, kwargs)
|
||||
return Policy(policy)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def policy_remove_rule(request, policy_id, **kwargs):
|
||||
policy = neutronclient(request).remove_rule_fwaas_firewall_policy(
|
||||
policy_id, kwargs)
|
||||
return Policy(policy)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def firewall_group_create(request, **kwargs):
|
||||
"""Create a firewall group for specified policy
|
||||
|
||||
:param request: request context
|
||||
:param name: name for firewall group
|
||||
:param description: description for firewall group
|
||||
:param firewall_policy_id: policy id used by firewall group
|
||||
:param shared: boolean (default false)
|
||||
:param admin_state_up: boolean (default true)
|
||||
:return: Firewall group object
|
||||
"""
|
||||
body = {'firewall_group': kwargs}
|
||||
firewall_group = neutronclient(request).create_fwaas_firewall_group(body)
|
||||
return FirewallGroup(firewall_group['firewall_group'])
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def firewall_group_list(request, **kwargs):
|
||||
return _firewall_group_list(request, **kwargs)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def firewall_group_list_for_tenant(request, tenant_id, **kwargs):
|
||||
"""Return a firewall group list available for the tenant.
|
||||
|
||||
The list contains firewall groups owned by the tenant and shared firewall
|
||||
groups. This is required because Neutron returns all resources including
|
||||
all tenants if a user has admin role.
|
||||
"""
|
||||
fwg = firewall_group_list(request, tenant_id=tenant_id,
|
||||
shared=False, **kwargs)
|
||||
shared_fwg = firewall_group_list(request, shared=True, **kwargs)
|
||||
return fwg + shared_fwg
|
||||
|
||||
|
||||
# TODO(SarathMekala): Support expand_policy for _firewall_group_list
|
||||
def _firewall_group_list(request, **kwargs):
|
||||
firewall_groups = neutronclient(request).list_fwaas_firewall_groups(
|
||||
**kwargs).get('firewall_groups')
|
||||
return [FirewallGroup(f) for f in firewall_groups]
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def firewall_group_get(request, firewallgroup_id):
|
||||
return _firewall_group_get(request, firewallgroup_id, expand_policy=True)
|
||||
|
||||
|
||||
def _firewall_group_get(request, firewallgroup_id, expand_policy):
|
||||
firewall_group = neutronclient(request).show_fwaas_firewall_group(
|
||||
firewallgroup_id).get('firewall_group')
|
||||
if expand_policy:
|
||||
ingress_policy_id = firewall_group['ingress_firewall_policy_id']
|
||||
if ingress_policy_id:
|
||||
firewall_group['ingress_policy'] = _policy_get(
|
||||
request, ingress_policy_id, expand_rule=False)
|
||||
else:
|
||||
firewall_group['ingress_policy'] = None
|
||||
|
||||
egress_policy_id = firewall_group['egress_firewall_policy_id']
|
||||
if egress_policy_id:
|
||||
firewall_group['egress_policy'] = _policy_get(
|
||||
request, egress_policy_id, expand_rule=False)
|
||||
else:
|
||||
firewall_group['egress_policy'] = None
|
||||
return FirewallGroup(firewall_group)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def firewall_group_delete(request, firewallgroup_id):
|
||||
neutronclient(request).delete_fwaas_firewall_group(firewallgroup_id)
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def firewall_group_update(request, firewallgroup_id, **kwargs):
|
||||
body = {'firewall_group': kwargs}
|
||||
firewall_group = neutronclient(request).update_fwaas_firewall_group(
|
||||
firewallgroup_id, body).get('firewall_group')
|
||||
return FirewallGroup(firewall_group)
|
0
neutron_fwaas_dashboard/dashboards/__init__.py
Normal file
0
neutron_fwaas_dashboard/dashboards/__init__.py
Normal file
449
neutron_fwaas_dashboard/dashboards/project/firewalls_v2/forms.py
Normal file
449
neutron_fwaas_dashboard/dashboards/project/firewalls_v2/forms.py
Normal file
@ -0,0 +1,449 @@
|
||||
# Copyright 2017, Juniper Networks, 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 operator import attrgetter
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon.utils import validators
|
||||
|
||||
from neutron_fwaas_dashboard.api import fwaas_v2 as api_fwaas_v2
|
||||
from neutron_fwaas_dashboard.dashboards.project.firewalls_v2 import widgets
|
||||
|
||||
port_validator = validators.validate_port_or_colon_separated_port_range
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UpdateRule(forms.SelfHandlingForm):
|
||||
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||
description = forms.CharField(
|
||||
required=False,
|
||||
max_length=80, label=_("Description"))
|
||||
protocol = forms.ThemableChoiceField(
|
||||
label=_("Protocol"),
|
||||
choices=[('tcp', _('TCP')), ('udp', _('UDP')), ('icmp', _('ICMP')),
|
||||
('any', _('ANY'))],
|
||||
help_text=_('Protocol for the firewall rule'))
|
||||
action = forms.ThemableChoiceField(
|
||||
label=_("Action"),
|
||||
choices=[('allow', _('ALLOW')), ('deny', _('DENY')),
|
||||
('reject', _('REJECT'))],
|
||||
help_text=_('Action for the firewall rule'))
|
||||
source_ip_address = forms.IPField(
|
||||
label=_("Source IP Address/Subnet"),
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
required=False, mask=True,
|
||||
help_text=_('Source IP address or subnet'))
|
||||
destination_ip_address = forms.IPField(
|
||||
label=_('Destination IP Address/Subnet'),
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
required=False, mask=True,
|
||||
help_text=_('Destination IP address or subnet'))
|
||||
source_port = forms.CharField(
|
||||
max_length=80,
|
||||
label=_("Source Port/Port Range"),
|
||||
required=False,
|
||||
validators=[port_validator],
|
||||
help_text=_('Source port (integer in [1, 65535] or range in a:b)'))
|
||||
destination_port = forms.CharField(
|
||||
max_length=80,
|
||||
label=_("Destination Port/Port Range"),
|
||||
required=False,
|
||||
validators=[port_validator],
|
||||
help_text=_('Destination port (integer in [1, 65535] or range'
|
||||
' in a:b)'))
|
||||
ip_version = forms.ThemableChoiceField(
|
||||
label=_("IP Version"),
|
||||
choices=[('4', '4'), ('6', '6')],
|
||||
help_text=_('IP Version for Firewall Rule'))
|
||||
shared = forms.BooleanField(label=_("Shared"), required=False)
|
||||
enabled = forms.BooleanField(label=_("Enabled"), required=False)
|
||||
|
||||
failure_url = 'horizon:project:firewalls_v2:index'
|
||||
|
||||
def _convert_req_body(self, body):
|
||||
for key in ['source_port', 'source_ip_address',
|
||||
'destination_port', 'destination_ip_address']:
|
||||
if key in body and not body[key]:
|
||||
body[key] = None
|
||||
if body.get('protocol') == 'any':
|
||||
body['protocol'] = None
|
||||
return body
|
||||
|
||||
def handle(self, request, context):
|
||||
rule_id = self.initial['id']
|
||||
name_or_id = context.get('name') or rule_id
|
||||
body = self._convert_req_body(_get_request_body(context, self.initial))
|
||||
try:
|
||||
rule = api_fwaas_v2.rule_update(request, rule_id, **body)
|
||||
msg = _('Rule %s was successfully updated.') % name_or_id
|
||||
messages.success(request, msg)
|
||||
return rule
|
||||
except Exception as e:
|
||||
msg = (_('Failed to update rule %(name)s: %(reason)s') %
|
||||
{'name': name_or_id, 'reason': e})
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
|
||||
class UpdatePolicy(forms.SelfHandlingForm):
|
||||
name = forms.CharField(max_length=80, label=_("Name"), required=False)
|
||||
description = forms.CharField(required=False,
|
||||
max_length=80, label=_("Description"))
|
||||
shared = forms.BooleanField(label=_("Shared"), required=False)
|
||||
audited = forms.BooleanField(label=_("Audited"), required=False)
|
||||
|
||||
failure_url = 'horizon:project:firewalls_v2:index'
|
||||
|
||||
def handle(self, request, context):
|
||||
policy_id = self.initial['id']
|
||||
name_or_id = context.get('name') or policy_id
|
||||
body = _get_request_body(context, self.initial)
|
||||
try:
|
||||
policy = api_fwaas_v2.policy_update(request, policy_id, **body)
|
||||
msg = _('Policy %s was successfully updated.') % name_or_id
|
||||
messages.success(request, msg)
|
||||
return policy
|
||||
except Exception as e:
|
||||
msg = (_('Failed to update policy %(name)s: %(reason)s') %
|
||||
{'name': name_or_id, 'reason': e})
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
|
||||
class UpdateFirewall(forms.SelfHandlingForm):
|
||||
name = forms.CharField(max_length=80,
|
||||
label=_("Name"),
|
||||
required=False)
|
||||
description = forms.CharField(max_length=80,
|
||||
label=_("Description"),
|
||||
required=False)
|
||||
ingress_firewall_policy_id = forms.ThemableChoiceField(
|
||||
label=_("Ingress Policy"), required=False)
|
||||
egress_firewall_policy_id = forms.ThemableChoiceField(
|
||||
label=_("Egress Policy"), required=False)
|
||||
admin_state_up = forms.BooleanField(label=_("Admin State"),
|
||||
required=False)
|
||||
shared = forms.BooleanField(label=_("Shared"), required=False)
|
||||
failure_url = 'horizon:project:firewalls_v2:index'
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(UpdateFirewall, self).__init__(request, *args, **kwargs)
|
||||
|
||||
try:
|
||||
tenant_id = self.request.user.tenant_id
|
||||
policies = api_fwaas_v2.policy_list_for_tenant(request, tenant_id)
|
||||
policies = sorted(policies, key=attrgetter('name'))
|
||||
except Exception:
|
||||
exceptions.handle(request, _('Unable to retrieve policy list.'))
|
||||
policies = []
|
||||
|
||||
egress_policy_id_choices = []
|
||||
ingress_policy_id_choices = []
|
||||
ingress_policy_id = kwargs['initial']['ingress_firewall_policy_id']
|
||||
if ingress_policy_id:
|
||||
ingress_policy_name = [
|
||||
p.name for p in policies if p.id == ingress_policy_id][0]
|
||||
ingress_policy_id_choices.append(
|
||||
(ingress_policy_id, ingress_policy_name))
|
||||
egress_policy_id = kwargs['initial']['egress_firewall_policy_id']
|
||||
if egress_policy_id:
|
||||
egress_policy_name = [
|
||||
p.name for p in policies if p.id == egress_policy_id][0]
|
||||
egress_policy_id_choices.append((egress_policy_id,
|
||||
egress_policy_name))
|
||||
|
||||
ingress_policy_id_choices.append(('', _('None')))
|
||||
egress_policy_id_choices.append(('', _('None')))
|
||||
|
||||
for p in policies:
|
||||
if p.id != ingress_policy_id:
|
||||
ingress_policy_id_choices.append((p.id, p.name_or_id))
|
||||
if p.id != egress_policy_id:
|
||||
egress_policy_id_choices.append((p.id, p.name_or_id))
|
||||
|
||||
self.fields['ingress_firewall_policy_id'].choices = \
|
||||
ingress_policy_id_choices
|
||||
self.fields['egress_firewall_policy_id'].choices = \
|
||||
egress_policy_id_choices
|
||||
|
||||
def _convert_req_body(self, body):
|
||||
for key in ['ingress_firewall_policy_id', 'egress_firewall_policy_id']:
|
||||
if key in body and not body[key]:
|
||||
body[key] = None
|
||||
return body
|
||||
|
||||
def handle(self, request, context):
|
||||
firewallgroup_id = self.initial['id']
|
||||
name_or_id = context.get('name') or firewallgroup_id
|
||||
body = self._convert_req_body(_get_request_body(context, self.initial))
|
||||
try:
|
||||
fwg = api_fwaas_v2.firewall_group_update(request,
|
||||
firewallgroup_id,
|
||||
**body)
|
||||
msg = _('Firewall group %s was successfully updated.') % name_or_id
|
||||
messages.success(request, msg)
|
||||
return fwg
|
||||
except Exception as e:
|
||||
msg = (_('Failed to update firewall group %(name)s: %(reason)s') %
|
||||
{'name': name_or_id, 'reason': e})
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
|
||||
class PortSelectionForm(forms.SelfHandlingForm):
|
||||
port_id = forms.ThemableDynamicChoiceField(
|
||||
label=_("Ports"),
|
||||
required=False,
|
||||
widget=widgets.TableSelectWidget(
|
||||
columns=['Port', 'Network', 'Owner', 'Device'],
|
||||
alternate_xs=True
|
||||
)
|
||||
)
|
||||
|
||||
networks = {}
|
||||
routers = {}
|
||||
servers = {}
|
||||
ports = {}
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(PortSelectionForm, self).__init__(request, *args, **kwargs)
|
||||
|
||||
tenant_id = self.request.user.tenant_id
|
||||
|
||||
self.ports = api_fwaas_v2.port_list(request, tenant_id, **kwargs)
|
||||
self.networks = api_fwaas_v2.get_network_names(request)
|
||||
self.routers = api_fwaas_v2.get_router_names(request)
|
||||
self.servers = api_fwaas_v2.get_servers(request)
|
||||
|
||||
self.fields['port_id'].widget.build_columns = self._build_col
|
||||
self.fields['port_id'].choices = self.get_ports(request)
|
||||
|
||||
def get_ports(self, request):
|
||||
return []
|
||||
|
||||
def _build_col(self, option):
|
||||
port = self.ports[option[0]]
|
||||
columns = self._build_option(port)
|
||||
return columns
|
||||
|
||||
def _build_option(self, port):
|
||||
network = self.networks.get(port.network_id)
|
||||
|
||||
network_label = network.name_or_id if network else port.network_id
|
||||
owner_label = ''
|
||||
device_label = ''
|
||||
|
||||
if port.device_owner.startswith('network'):
|
||||
owner_label = 'network'
|
||||
router = self.routers.get(port.device_id, None)
|
||||
device_label = router.name_or_id if router else port.device_id
|
||||
elif port.device_owner.startswith('compute'):
|
||||
owner_label = 'compute'
|
||||
server = self.servers.get(port.device_id, None)
|
||||
device_label = server.name_or_id if server else port.device_id
|
||||
|
||||
columns = (port.name_or_id, network_label, owner_label, device_label)
|
||||
|
||||
# The return value works off of the original themeable select widget
|
||||
# This needs to be maintained for the original javascript to work
|
||||
return columns
|
||||
|
||||
|
||||
class AddPort(PortSelectionForm):
|
||||
failure_url = 'horizon:project:firewalls_v2:index'
|
||||
|
||||
def get_ports(self, request):
|
||||
used_ports = api_fwaas_v2.fwg_port_list(request)
|
||||
ports = self.ports.values()
|
||||
return [(p.id, p.id) for p in ports if p.id not in used_ports]
|
||||
|
||||
def handle(self, request, context):
|
||||
firewallgroup_id = self.initial['id']
|
||||
name_or_id = context.get('name') or firewallgroup_id
|
||||
body = _get_request_body(context, self.initial)
|
||||
add_port = context['port_id']
|
||||
if add_port:
|
||||
ports = self.initial['ports']
|
||||
ports.append(add_port)
|
||||
body['ports'] = ports
|
||||
try:
|
||||
firewallgroup = api_fwaas_v2.firewall_group_update(
|
||||
request, firewallgroup_id, **body)
|
||||
msg = (_('Added the port(s) to the firewall group %s '
|
||||
'successfully.') % name_or_id)
|
||||
messages.success(request, msg)
|
||||
return firewallgroup
|
||||
except Exception as e:
|
||||
msg = (_('Failed to add the port(s) to the firewall group '
|
||||
'%(name)s: %(reason)s') %
|
||||
{'name': name_or_id, 'reason': e})
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
|
||||
class RemovePort(PortSelectionForm):
|
||||
failure_url = 'horizon:project:firewalls_v2:index'
|
||||
|
||||
def get_ports(self, request):
|
||||
ports = self.initial['ports']
|
||||
return [(p, p) for p in ports]
|
||||
|
||||
def handle(self, request, context):
|
||||
firewallgroup_id = self.initial['id']
|
||||
name_or_id = context.get('name') or firewallgroup_id
|
||||
body = _get_request_body(context, self.initial)
|
||||
remove_port = context['port_id']
|
||||
if remove_port:
|
||||
ports = self.initial['ports']
|
||||
ports.remove(remove_port)
|
||||
body['ports'] = ports
|
||||
try:
|
||||
firewallgroup = api_fwaas_v2.firewall_group_update(
|
||||
request, firewallgroup_id, **body)
|
||||
msg = _('Removed the port(s) from the firewall group %s '
|
||||
'successfully.') % name_or_id
|
||||
messages.success(request, msg)
|
||||
return firewallgroup
|
||||
except Exception as e:
|
||||
msg = (_('Failed to remove the port(s) from the firewall group '
|
||||
'%(name)s: %(reason)s') %
|
||||
{'name': name_or_id, 'reason': e})
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
|
||||
class InsertRuleToPolicy(forms.SelfHandlingForm):
|
||||
firewall_rule_id = forms.ThemableChoiceField(label=_("Insert Rule"))
|
||||
insert_before = forms.ThemableChoiceField(label=_("Before"),
|
||||
required=False)
|
||||
insert_after = forms.ThemableChoiceField(label=_("After"),
|
||||
required=False)
|
||||
|
||||
failure_url = 'horizon:project:firewalls_v2:index'
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(InsertRuleToPolicy, self).__init__(request, *args, **kwargs)
|
||||
|
||||
try:
|
||||
tenant_id = self.request.user.tenant_id
|
||||
all_rules = api_fwaas_v2.rule_list_for_tenant(request, tenant_id)
|
||||
all_rules = sorted(all_rules, key=attrgetter('name_or_id'))
|
||||
|
||||
available_rules = [r for r in all_rules]
|
||||
|
||||
current_rules = []
|
||||
for x in kwargs['initial']['firewall_rules']:
|
||||
r_obj = [rule for rule in all_rules if x == rule.id][0]
|
||||
current_rules.append(r_obj)
|
||||
|
||||
available_choices = [(r.id, r.name_or_id) for r in available_rules]
|
||||
current_choices = [(r.id, r.name_or_id) for r in current_rules]
|
||||
|
||||
except Exception as e:
|
||||
msg = _('Failed to retrieve available rules: %s') % e
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
self.fields['firewall_rule_id'].choices = available_choices
|
||||
self.fields['insert_before'].choices = [('', _('-'))] + current_choices
|
||||
self.fields['insert_after'].choices = [('', _('-'))] + current_choices
|
||||
|
||||
def handle(self, request, context):
|
||||
policy_id = self.initial['id']
|
||||
policy_name_or_id = self.initial['name'] or policy_id
|
||||
try:
|
||||
insert_rule_id = context['firewall_rule_id']
|
||||
insert_rule = api_fwaas_v2.rule_get(request, insert_rule_id)
|
||||
body = {'firewall_rule_id': insert_rule_id,
|
||||
'insert_before': context['insert_before'],
|
||||
'insert_after': context['insert_after']}
|
||||
policy = api_fwaas_v2.policy_insert_rule(request, policy_id,
|
||||
**body)
|
||||
msg = (_('Rule %(rule)s was successfully inserted to policy '
|
||||
'%(policy)s.') %
|
||||
{'rule': insert_rule.name or insert_rule.id,
|
||||
'policy': policy_name_or_id})
|
||||
messages.success(request, msg)
|
||||
return policy
|
||||
except Exception as e:
|
||||
msg = (_('Failed to insert rule to policy %(name)s: %(reason)s') %
|
||||
{'name': policy_id, 'reason': e})
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
|
||||
class RemoveRuleFromPolicy(forms.SelfHandlingForm):
|
||||
firewall_rule_id = forms.ThemableChoiceField(label=_("Remove Rule"))
|
||||
|
||||
failure_url = 'horizon:project:firewalls_v2:index'
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(RemoveRuleFromPolicy, self).__init__(request, *args, **kwargs)
|
||||
|
||||
try:
|
||||
tenant_id = request.user.tenant_id
|
||||
all_rules = api_fwaas_v2.rule_list_for_tenant(request, tenant_id)
|
||||
|
||||
current_rules = []
|
||||
for r in kwargs['initial']['firewall_rules']:
|
||||
r_obj = [rule for rule in all_rules if r == rule.id][0]
|
||||
current_rules.append(r_obj)
|
||||
|
||||
current_choices = [(r.id, r.name_or_id) for r in current_rules]
|
||||
except Exception as e:
|
||||
msg = (_('Failed to retrieve current rules in policy %(name)s: '
|
||||
'%(reason)s') %
|
||||
{'name': self.initial['name'], 'reason': e})
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
self.fields['firewall_rule_id'].choices = current_choices
|
||||
|
||||
def handle(self, request, context):
|
||||
policy_id = self.initial['id']
|
||||
policy_name_or_id = self.initial['name'] or policy_id
|
||||
try:
|
||||
remove_rule_id = context['firewall_rule_id']
|
||||
remove_rule = api_fwaas_v2.rule_get(request, remove_rule_id)
|
||||
body = {'firewall_rule_id': remove_rule_id}
|
||||
policy = api_fwaas_v2.policy_remove_rule(request, policy_id,
|
||||
**body)
|
||||
msg = (_('Rule %(rule)s was successfully removed from policy '
|
||||
'%(policy)s.') %
|
||||
{'rule': remove_rule.name or remove_rule.id,
|
||||
'policy': policy_name_or_id})
|
||||
messages.success(request, msg)
|
||||
return policy
|
||||
except Exception as e:
|
||||
msg = (_('Failed to remove rule from policy %(name)s: %(reason)s')
|
||||
% {'name': self.initial['name'], 'reason': e})
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
|
||||
def _get_request_body(context, initial_values):
|
||||
body = {}
|
||||
for key, value in context.items():
|
||||
# TODO(yushiro): Refactor after Q-2.
|
||||
if key == 'port_id':
|
||||
continue
|
||||
if value != initial_values[key]:
|
||||
body[key] = value
|
||||
return body
|
@ -0,0 +1,43 @@
|
||||
# Copyright 2017, Juniper Networks, 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 Firewall_V2(horizon.Panel):
|
||||
name = _("Firewall Groups")
|
||||
slug = "firewalls_v2"
|
||||
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_extension_supported(request, 'fwaas_v2'):
|
||||
return False
|
||||
except Exception:
|
||||
LOG.error("Call to list enabled services failed. This is likely "
|
||||
"due to a problem communicating with the Neutron "
|
||||
"endpoint. Firewall Groups panel will not be displayed.")
|
||||
return False
|
||||
if not super(Firewall_V2, self).allowed(context):
|
||||
return False
|
||||
return True
|
@ -0,0 +1,425 @@
|
||||
# Copyright 2017, Juniper Networks, 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.template import defaultfilters as filters
|
||||
from django.urls import reverse
|
||||
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.dashboards.project.networks.ports \
|
||||
import tables as port_tables
|
||||
from openstack_dashboard import policy
|
||||
|
||||
from neutron_fwaas_dashboard.api import fwaas_v2 as api_fwaas_v2
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AddRuleLink(tables.LinkAction):
|
||||
name = "addrule"
|
||||
verbose_name = _("Add Rule")
|
||||
url = "horizon:project:firewalls_v2:addrule"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
policy_rules = (("neutron-fwaas", "create_fwaas_firewall_rule"),)
|
||||
|
||||
|
||||
class AddPolicyLink(tables.LinkAction):
|
||||
name = "addpolicy"
|
||||
verbose_name = _("Add Policy")
|
||||
url = "horizon:project:firewalls_v2:addpolicy"
|
||||
classes = ("ajax-modal", "btn-addpolicy",)
|
||||
icon = "plus"
|
||||
policy_rules = (("neutron-fwaas", "create_fwaas_firewall_policy"),)
|
||||
|
||||
|
||||
class AddFirewallGroupLink(tables.LinkAction):
|
||||
name = "addfirewallgroup"
|
||||
verbose_name = _("Create Firewall Group")
|
||||
url = "horizon:project:firewalls_v2:addfirewallgroup"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
policy_rules = (("neutron-fwaas", "create_fwaas_firewall_group"),)
|
||||
|
||||
|
||||
class DeleteRuleLink(policy.PolicyTargetMixin, tables.DeleteAction):
|
||||
name = "deleterule"
|
||||
policy_rules = (("neutron-fwaas", "delete_fwaas_firewall_rule"),)
|
||||
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
return ungettext_lazy(
|
||||
u"Delete Rule",
|
||||
u"Delete Rules",
|
||||
count
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def action_past(count):
|
||||
return ungettext_lazy(
|
||||
u"Scheduled deletion of Rule",
|
||||
u"Scheduled deletion of Rules",
|
||||
count
|
||||
)
|
||||
|
||||
def allowed(self, request, datum=None):
|
||||
# TODO(Sarath Mekala): If the rule is associated with a policy then
|
||||
# return false.
|
||||
return True
|
||||
|
||||
def delete(self, request, obj_id):
|
||||
try:
|
||||
api_fwaas_v2.rule_delete(request, obj_id)
|
||||
except Exception as e:
|
||||
exceptions.handle(request, _('Unable to delete rule. %s') % e)
|
||||
|
||||
|
||||
class DeletePolicyLink(policy.PolicyTargetMixin, tables.DeleteAction):
|
||||
name = "deletepolicy"
|
||||
policy_rules = (("neutron-fwaas", "delete_fwaas_firewall_policy"),)
|
||||
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
return ungettext_lazy(
|
||||
u"Delete Policy",
|
||||
u"Delete Policies",
|
||||
count
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def action_past(count):
|
||||
return ungettext_lazy(
|
||||
u"Scheduled deletion of Policy",
|
||||
u"Scheduled deletion of Policies",
|
||||
count
|
||||
)
|
||||
|
||||
def delete(self, request, obj_id):
|
||||
try:
|
||||
api_fwaas_v2.policy_delete(request, obj_id)
|
||||
except Exception as e:
|
||||
exceptions.handle(request, _('Unable to delete policy. %s') % e)
|
||||
|
||||
|
||||
class DeleteFirewallGroupLink(policy.PolicyTargetMixin,
|
||||
tables.DeleteAction):
|
||||
name = "deletefirewallgroup"
|
||||
policy_rules = (("neutron-fwaas", "delete_fwaas_firewall_group"),)
|
||||
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
return ungettext_lazy(
|
||||
u"Delete Firewall Group",
|
||||
u"Delete Firewall Groups",
|
||||
count
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def action_past(count):
|
||||
return ungettext_lazy(
|
||||
u"Scheduled deletion of Firewall Group",
|
||||
u"Scheduled deletion of Firewall Groups",
|
||||
count
|
||||
)
|
||||
|
||||
def delete(self, request, obj_id):
|
||||
try:
|
||||
api_fwaas_v2.firewall_group_delete(request, obj_id)
|
||||
except Exception as e:
|
||||
exceptions.handle(request,
|
||||
_('Unable to delete firewall group. %s') % e)
|
||||
|
||||
|
||||
class UpdateRuleLink(policy.PolicyTargetMixin, tables.LinkAction):
|
||||
name = "updaterule"
|
||||
verbose_name = _("Edit Rule")
|
||||
classes = ("ajax-modal", "btn-update",)
|
||||
policy_rules = (("neutron-fwaas", "update_fwaas_firewall_rule"),)
|
||||
|
||||
def get_link_url(self, rule):
|
||||
return reverse("horizon:project:firewalls_v2:updaterule",
|
||||
kwargs={'rule_id': rule.id})
|
||||
|
||||
|
||||
class UpdatePolicyLink(policy.PolicyTargetMixin, tables.LinkAction):
|
||||
name = "updatepolicy"
|
||||
verbose_name = _("Edit Policy")
|
||||
classes = ("ajax-modal", "btn-update",)
|
||||
policy_rules = (("neutron-fwaas", "update_fwaas_firewall_policy"),)
|
||||
|
||||
def get_link_url(self, policy):
|
||||
return reverse("horizon:project:firewalls_v2:updatepolicy",
|
||||
kwargs={'policy_id': policy.id})
|
||||
|
||||
|
||||
class UpdateFirewallGroupLink(policy.PolicyTargetMixin, tables.LinkAction):
|
||||
name = "updatefirewall"
|
||||
verbose_name = _("Edit Firewall Group")
|
||||
classes = ("ajax-modal", "btn-update",)
|
||||
policy_rules = (("neutron-fwaas", "update_firewall"),)
|
||||
|
||||
def get_link_url(self, firewallgroup):
|
||||
return reverse("horizon:project:firewalls_v2:updatefirewall",
|
||||
kwargs={'firewall_id': firewallgroup.id})
|
||||
|
||||
def allowed(self, request, firewallgroup):
|
||||
return firewallgroup.status not in (
|
||||
"PENDING_CREATE",
|
||||
"PENDING_UPDATE",
|
||||
"PENDING_DELETE")
|
||||
|
||||
|
||||
class InsertRuleToPolicyLink(policy.PolicyTargetMixin,
|
||||
tables.LinkAction):
|
||||
name = "insertrule"
|
||||
verbose_name = _("Insert Rule")
|
||||
classes = ("ajax-modal", "btn-update",)
|
||||
policy_rules = (("neutron-fwaas", "show_fwaas_firewall_policy"),
|
||||
("neutron-fwaas", "insert_rule_fwaas_firewall_policy"),)
|
||||
|
||||
def get_link_url(self, policy):
|
||||
return reverse("horizon:project:firewalls_v2:insertrule",
|
||||
kwargs={'policy_id': policy.id})
|
||||
|
||||
|
||||
class RemoveRuleFromPolicyLink(policy.PolicyTargetMixin,
|
||||
tables.LinkAction):
|
||||
name = "removerule"
|
||||
verbose_name = _("Remove Rule")
|
||||
classes = ("ajax-modal",)
|
||||
policy_rules = (("neutron-fwaas", "show_fwaas_firewall_policy"),
|
||||
("neutron-fwaas", "firewall_policy_remove_rule"),)
|
||||
action_type = "danger"
|
||||
|
||||
def get_link_url(self, policy):
|
||||
return reverse("horizon:project:firewalls_v2:removerule",
|
||||
kwargs={'policy_id': policy.id})
|
||||
|
||||
def allowed(self, request, policy):
|
||||
return bool(policy.rules)
|
||||
|
||||
|
||||
class AddPortToFirewallGroupLink(policy.PolicyTargetMixin,
|
||||
tables.LinkAction):
|
||||
name = "addport"
|
||||
verbose_name = _("Add Port")
|
||||
classes = ("ajax-modal", "btn-update",)
|
||||
policy_rules = (("neutron-fwaas", "update_fwaas_firewall_group"),)
|
||||
|
||||
def get_link_url(self, firewallgroup):
|
||||
return reverse("horizon:project:firewalls_v2:addport",
|
||||
kwargs={'firewallgroup_id': firewallgroup.id})
|
||||
|
||||
def allowed(self, request, firewallgroup):
|
||||
return firewallgroup.status not in (
|
||||
"PENDING_CREATE",
|
||||
"PENDING_UPDATE",
|
||||
"PENDING_DELETE")
|
||||
|
||||
|
||||
class RemovePortFromFirewallGroupLink(policy.PolicyTargetMixin,
|
||||
tables.LinkAction):
|
||||
name = "removeport"
|
||||
verbose_name = _("Remove Port")
|
||||
classes = ("ajax-modal", "btn-update",)
|
||||
policy_rules = (("neutron-fwaas", "update_fwaas_firewall_group"),)
|
||||
|
||||
def get_link_url(self, firewallgroup):
|
||||
return reverse("horizon:project:firewalls_v2:removeport",
|
||||
kwargs={'firewallgroup_id': firewallgroup.id})
|
||||
|
||||
def allowed(self, request, firewallgroup):
|
||||
return firewallgroup.status not in (
|
||||
"PENDING_CREATE",
|
||||
"PENDING_UPDATE",
|
||||
"PENDING_DELETE")
|
||||
|
||||
|
||||
def get_rules_name(datum):
|
||||
return ', '.join([rule.name_or_id for rule in datum.rules])
|
||||
|
||||
|
||||
def get_ports_name(datum):
|
||||
return len(datum.ports)
|
||||
|
||||
|
||||
def get_ports_link(datum):
|
||||
url = reverse("horizon:project:firewalls_v2:firewallgroupdetails",
|
||||
args=(datum.id,))
|
||||
return '%s?tab=%s__%s' % (url, 'firewallgrouptabs', 'ports_tab')
|
||||
|
||||
|
||||
def get_ingress_policy_link(datum):
|
||||
if datum.ingress_firewall_policy_id:
|
||||
return reverse('horizon:project:firewalls_v2:policydetails',
|
||||
kwargs={'policy_id': datum.ingress_firewall_policy_id})
|
||||
|
||||
|
||||
def get_egress_policy_link(datum):
|
||||
if datum.egress_firewall_policy_id:
|
||||
return reverse('horizon:project:firewalls_v2:policydetails',
|
||||
kwargs={'policy_id': datum.egress_firewall_policy_id})
|
||||
|
||||
|
||||
def get_ingress_policy_name(datum):
|
||||
if datum.ingress_firewall_policy_id:
|
||||
return datum.ingress_policy.name
|
||||
|
||||
|
||||
def get_egress_policy_name(datum):
|
||||
if datum.egress_firewall_policy_id:
|
||||
return datum.egress_policy.name
|
||||
|
||||
|
||||
class RulesTable(tables.DataTable):
|
||||
ACTION_DISPLAY_CHOICES = (
|
||||
("Allow", pgettext_lazy("Action Name of a Firewall Rule", u"ALLOW")),
|
||||
("Deny", pgettext_lazy("Action Name of a Firewall Rule", u"DENY")),
|
||||
("Reject", pgettext_lazy("Action Name of a Firewall Rule", u"REJECT")),
|
||||
)
|
||||
name = tables.Column("name_or_id",
|
||||
verbose_name=_("Name"),
|
||||
link="horizon:project:firewalls_v2:ruledetails")
|
||||
description = tables.Column('description', verbose_name=_('Description'))
|
||||
ip_version = tables.Column('ip_version', verbose_name=('IP Version'))
|
||||
protocol = tables.Column("protocol",
|
||||
filters=(lambda v: filters.default(v, _("ANY")),
|
||||
filters.upper,),
|
||||
verbose_name=_("Protocol"))
|
||||
source_ip_address = tables.Column("source_ip_address",
|
||||
verbose_name=_("Source IP"))
|
||||
source_port = tables.Column("source_port",
|
||||
verbose_name=_("Source Port"))
|
||||
destination_ip_address = tables.Column("destination_ip_address",
|
||||
verbose_name=_("Destination IP"))
|
||||
destination_port = tables.Column("destination_port",
|
||||
verbose_name=_("Destination Port"))
|
||||
action = tables.Column("action",
|
||||
display_choices=ACTION_DISPLAY_CHOICES,
|
||||
verbose_name=_("Action"))
|
||||
shared = tables.Column("shared",
|
||||
verbose_name=_("Shared"),
|
||||
filters=(filters.yesno, filters.capfirst))
|
||||
enabled = tables.Column("enabled",
|
||||
verbose_name=_("Enabled"),
|
||||
filters=(filters.yesno, filters.capfirst))
|
||||
|
||||
class Meta(object):
|
||||
name = "rulestable"
|
||||
verbose_name = _("Rules")
|
||||
table_actions = (AddRuleLink,
|
||||
DeleteRuleLink,
|
||||
tables.NameFilterAction)
|
||||
row_actions = (UpdateRuleLink, DeleteRuleLink)
|
||||
|
||||
|
||||
class PoliciesTable(tables.DataTable):
|
||||
name = tables.Column("name_or_id",
|
||||
verbose_name=_("Name"),
|
||||
link="horizon:project:firewalls_v2:policydetails")
|
||||
description = tables.Column('description', verbose_name=_('Description'))
|
||||
firewall_rules = tables.Column(get_rules_name,
|
||||
verbose_name=_("Rules"))
|
||||
shared = tables.Column("shared",
|
||||
verbose_name=_("Shared"),
|
||||
filters=(filters.yesno, filters.capfirst))
|
||||
audited = tables.Column("audited",
|
||||
verbose_name=_("Audited"),
|
||||
filters=(filters.yesno, filters.capfirst))
|
||||
|
||||
class Meta(object):
|
||||
name = "policiestable"
|
||||
verbose_name = _("Policies")
|
||||
table_actions = (AddPolicyLink,
|
||||
DeletePolicyLink,
|
||||
tables.NameFilterAction)
|
||||
row_actions = (UpdatePolicyLink, InsertRuleToPolicyLink,
|
||||
RemoveRuleFromPolicyLink, DeletePolicyLink)
|
||||
|
||||
|
||||
class FirewallGroupsTable(tables.DataTable):
|
||||
STATUS_DISPLAY_CHOICES = (
|
||||
("Active", pgettext_lazy("Current status of a Firewall Group",
|
||||
u"Active")),
|
||||
("Down", pgettext_lazy("Current status of a Firewall Group",
|
||||
u"Down")),
|
||||
("Error", pgettext_lazy("Current status of a Firewall Group",
|
||||
u"Error")),
|
||||
("Created", pgettext_lazy("Current status of a Firewall Group",
|
||||
u"Created")),
|
||||
("Pending_Create", pgettext_lazy("Current status of a Firewall Group",
|
||||
u"Pending Create")),
|
||||
("Pending_Update", pgettext_lazy("Current status of a Firewall Group",
|
||||
u"Pending Update")),
|
||||
("Pending_Delete", pgettext_lazy("Current status of a Firewall Group",
|
||||
u"Pending Delete")),
|
||||
("Inactive", pgettext_lazy("Current status of a Firewall Group",
|
||||
u"Inactive")),
|
||||
)
|
||||
ADMIN_STATE_DISPLAY_CHOICES = (
|
||||
("UP", pgettext_lazy("Admin state of a Firewall Group", u"UP")),
|
||||
("DOWN", pgettext_lazy("Admin state of a Firewall Group", u"DOWN")),
|
||||
)
|
||||
|
||||
name = tables.Column(
|
||||
"name_or_id",
|
||||
verbose_name=_("Name"),
|
||||
link="horizon:project:firewalls_v2:firewallgroupdetails")
|
||||
description = tables.Column('description', verbose_name=_('Description'))
|
||||
ingress_firewall_policy_id = tables.Column(
|
||||
get_ingress_policy_name,
|
||||
link=get_ingress_policy_link,
|
||||
verbose_name=_("Ingress Policy"))
|
||||
egress_firewall_policy_id = tables.Column(get_egress_policy_name,
|
||||
link=get_egress_policy_link,
|
||||
verbose_name=_("Egress Policy"))
|
||||
ports = tables.Column(get_ports_name,
|
||||
link=get_ports_link,
|
||||
verbose_name=_("Ports"))
|
||||
|
||||
status = tables.Column("status",
|
||||
verbose_name=_("Status"),
|
||||
display_choices=STATUS_DISPLAY_CHOICES)
|
||||
admin_state_up = tables.Column("admin_state_up",
|
||||
verbose_name=_("Admin State"))
|
||||
shared = tables.Column("shared",
|
||||
verbose_name=_("Shared"),
|
||||
filters=(filters.yesno, filters.capfirst))
|
||||
|
||||
class Meta(object):
|
||||
name = "FirewallGroupsTable"
|
||||
verbose_name = _("Firewall Groups")
|
||||
table_actions = (AddFirewallGroupLink,
|
||||
DeleteFirewallGroupLink,
|
||||
tables.NameFilterAction)
|
||||
row_actions = (
|
||||
UpdateFirewallGroupLink,
|
||||
DeleteFirewallGroupLink,
|
||||
AddPortToFirewallGroupLink,
|
||||
RemovePortFromFirewallGroupLink)
|
||||
|
||||
|
||||
class FirewallGroupPortsTable(port_tables.PortsTable):
|
||||
|
||||
class Meta(object):
|
||||
name = 'ports'
|
||||
verbose_name = _('Ports')
|
||||
table_actions = []
|
||||
row_actions = []
|
165
neutron_fwaas_dashboard/dashboards/project/firewalls_v2/tabs.py
Normal file
165
neutron_fwaas_dashboard/dashboards/project/firewalls_v2/tabs.py
Normal file
@ -0,0 +1,165 @@
|
||||
# Copyright 2017, Juniper Networks, 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 tabs
|
||||
from openstack_dashboard.api import neutron as api_neutron
|
||||
|
||||
from neutron_fwaas_dashboard.api import fwaas_v2 as api_fwaas_v2
|
||||
from neutron_fwaas_dashboard.dashboards.project.firewalls_v2 import tables
|
||||
|
||||
FirewallGroupsTable = tables.FirewallGroupsTable
|
||||
PoliciesTable = tables.PoliciesTable
|
||||
RulesTable = tables.RulesTable
|
||||
|
||||
|
||||
class RulesTab(tabs.TableTab):
|
||||
table_classes = (RulesTable,)
|
||||
name = _("Firewall Rules")
|
||||
slug = "rules"
|
||||
template_name = "horizon/common/_detail_table.html"
|
||||
|
||||
def get_rulestable_data(self):
|
||||
try:
|
||||
tenant_id = self.request.user.tenant_id
|
||||
request = self.tab_group.request
|
||||
rules = api_fwaas_v2.rule_list_for_tenant(request, tenant_id)
|
||||
except Exception:
|
||||
rules = []
|
||||
exceptions.handle(self.tab_group.request,
|
||||
_('Unable to retrieve rules list.'))
|
||||
|
||||
return rules
|
||||
|
||||
|
||||
class PoliciesTab(tabs.TableTab):
|
||||
table_classes = (PoliciesTable,)
|
||||
name = _("Firewall Policies")
|
||||
slug = "policies"
|
||||
template_name = "horizon/common/_detail_table.html"
|
||||
|
||||
def get_policiestable_data(self):
|
||||
try:
|
||||
tenant_id = self.request.user.tenant_id
|
||||
request = self.tab_group.request
|
||||
policies = api_fwaas_v2.policy_list_for_tenant(request, tenant_id)
|
||||
except Exception:
|
||||
policies = []
|
||||
exceptions.handle(self.tab_group.request,
|
||||
_('Unable to retrieve policies list.'))
|
||||
|
||||
return policies
|
||||
|
||||
|
||||
class FirewallGroupsTab(tabs.TableTab):
|
||||
table_classes = (FirewallGroupsTable,)
|
||||
name = _("Firewall Groups")
|
||||
slug = "firewallgroups"
|
||||
template_name = "horizon/common/_detail_table.html"
|
||||
|
||||
def get_policy_dict(self, policies):
|
||||
return dict((policy.id, policy) for policy in policies)
|
||||
|
||||
def get_FirewallGroupsTable_data(self):
|
||||
try:
|
||||
tenant_id = self.request.user.tenant_id
|
||||
request = self.tab_group.request
|
||||
fw_groups = api_fwaas_v2.firewall_group_list_for_tenant(request,
|
||||
tenant_id)
|
||||
tenant_policies = api_fwaas_v2.policy_list_for_tenant(
|
||||
request, tenant_id)
|
||||
policy_dict = self.get_policy_dict(policies=tenant_policies)
|
||||
for fw_group in fw_groups:
|
||||
if fw_group['ingress_firewall_policy_id'] in policy_dict:
|
||||
fw_group.ingress_policy = \
|
||||
policy_dict[fw_group['ingress_firewall_policy_id']]
|
||||
if fw_group['egress_firewall_policy_id'] in policy_dict:
|
||||
fw_group.egress_policy = \
|
||||
policy_dict[fw_group['egress_firewall_policy_id']]
|
||||
except Exception:
|
||||
fw_groups = []
|
||||
exceptions.handle(self.tab_group.request,
|
||||
_('Unable to retrieve firewall group list.'))
|
||||
|
||||
return fw_groups
|
||||
|
||||
|
||||
class RuleDetailsTab(tabs.Tab):
|
||||
name = _("Rule")
|
||||
slug = "ruledetails"
|
||||
template_name = "project/firewalls_v2/_rule_details.html"
|
||||
|
||||
def get_context_data(self, request):
|
||||
return {"rule": self.tab_group.kwargs['rule']}
|
||||
|
||||
|
||||
class PolicyDetailsTab(tabs.Tab):
|
||||
name = _("Policy")
|
||||
slug = "policydetails"
|
||||
template_name = "project/firewalls_v2/_policy_details.html"
|
||||
|
||||
def get_context_data(self, request):
|
||||
return {"policy": self.tab_group.kwargs['policy']}
|
||||
|
||||
|
||||
class FirewallGroupDetailsTab(tabs.Tab):
|
||||
name = _("FirewallGroup")
|
||||
slug = "firewallgroupdetails"
|
||||
template_name = "project/firewalls_v2/_firewallgroup_details.html"
|
||||
|
||||
def get_context_data(self, request):
|
||||
return {"firewall_group": self.tab_group.kwargs['firewallgroup']}
|
||||
|
||||
|
||||
class FirewallGroupPortsTab(tabs.TableTab):
|
||||
name = _("Ports")
|
||||
slug = "ports_tab"
|
||||
table_classes = (tables.FirewallGroupPortsTable,)
|
||||
template_name = ("horizon/common/_detail_table.html")
|
||||
preload = False
|
||||
|
||||
def get_ports_data(self):
|
||||
port_ids = self.tab_group.kwargs['firewallgroup']['ports']
|
||||
if not port_ids:
|
||||
return []
|
||||
try:
|
||||
ports = api_neutron.port_list(self.request, id=port_ids)
|
||||
except Exception:
|
||||
ports = []
|
||||
msg = _('Failed to retrieve port list of the firewall group.')
|
||||
exceptions.handle(self.request, msg)
|
||||
return ports
|
||||
|
||||
|
||||
class FirewallGroupTabs(tabs.TabGroup):
|
||||
slug = "fwtabs"
|
||||
tabs = (FirewallGroupsTab, PoliciesTab, RulesTab)
|
||||
sticky = True
|
||||
|
||||
|
||||
class RuleDetailsTabs(tabs.DetailTabsGroup):
|
||||
slug = "ruletabs"
|
||||
tabs = (RuleDetailsTab,)
|
||||
|
||||
|
||||
class PolicyDetailsTabs(tabs.DetailTabsGroup):
|
||||
slug = "policytabs"
|
||||
tabs = (PolicyDetailsTab,)
|
||||
|
||||
|
||||
class FirewallGroupDetailsTabs(tabs.DetailTabsGroup):
|
||||
slug = "firewallgrouptabs"
|
||||
tabs = (FirewallGroupDetailsTab, FirewallGroupPortsTab)
|
@ -0,0 +1,7 @@
|
||||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "You may add ports to firewall group here." %}</p>
|
||||
{% endblock %}
|
@ -0,0 +1,45 @@
|
||||
{% load i18n sizeformat parse_date %}
|
||||
|
||||
<div class="detail">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ firewall_group.name|default:_("-") }}</dd>
|
||||
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ firewall_group.description|default:_("-") }}</dd>
|
||||
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ firewall_group.id }} </dd>
|
||||
|
||||
<dt>{% trans "Project ID" %}</dt>
|
||||
<dd>{{ firewall_group.tenant_id }}</dd>
|
||||
|
||||
<dt>{% trans "Ingress Policy ID" %}</dt>
|
||||
<dd>
|
||||
{% if firewall_group.ingress_firewall_policy_id %}
|
||||
{% url 'horizon:project:firewalls_v2:policydetails' firewall_group.ingress_firewall_policy_id as policy_url %}
|
||||
<a href="{{ policy_url }}">{{firewall_group.ingress_policy.name|default:firewall_group.ingress_firewall_policy_id }}</a>
|
||||
{% else %}
|
||||
{% trans "-" %}
|
||||
{% endif %}
|
||||
</dd>
|
||||
<dt>{% trans "Egress Policy ID" %}</dt>
|
||||
<dd>
|
||||
{% if firewall_group.egress_firewall_policy_id %}
|
||||
{% url 'horizon:project:firewalls_v2:policydetails' firewall_group.egress_firewall_policy_id as policy_url %}
|
||||
<a href="{{ policy_url }}">{{firewall_group.egress_policy.name|default:firewall_group.egress_firewall_policy_id }}</a>
|
||||
{% else %}
|
||||
{% trans "-" %}
|
||||
{% endif %}
|
||||
</dd>
|
||||
|
||||
<dt>{% trans "Status" %}</dt>
|
||||
<dd>{{ firewall_group.status }}</dd>
|
||||
|
||||
<dt>{% trans "Admin State Up" %}</dt>
|
||||
<dd>{{ firewall_group.admin_state_up}}</dd>
|
||||
|
||||
<dt>{% trans "Shared" %}</dt>
|
||||
<dd>{{ firewall_group.shared|yesno|capfirst }}</dd>
|
||||
</dl>
|
||||
</div>
|
@ -0,0 +1,12 @@
|
||||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% blocktrans trimmed %}
|
||||
Choose the rule you want to insert.
|
||||
Specify either the rule you want to insert immediately before,
|
||||
or the rule to insert immediately after.
|
||||
If both are specified, the prior takes precedence.
|
||||
{% endblocktrans %}</p>
|
||||
{% endblock %}
|
@ -0,0 +1,37 @@
|
||||
{% load i18n sizeformat parse_date %}
|
||||
|
||||
<div class="detail">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ policy.name|default:_("-") }}</dd>
|
||||
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ policy.description|default:_("-") }}</dd>
|
||||
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ policy.id }}</dd>
|
||||
|
||||
<dt>{% trans "Project ID" %}</dt>
|
||||
<dd>{{ policy.tenant_id }}</dd>
|
||||
|
||||
<dt>{% trans "Rules" %}</dt>
|
||||
<dd>
|
||||
{% if policy.rules %}
|
||||
<ol>
|
||||
{% for rule in policy.rules %}
|
||||
{% url 'horizon:project:firewalls_v2:ruledetails' rule.id as rule_url %}
|
||||
<li><a href="{{ rule_url }}">{{ rule.name|default:rule.id }}</a></li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
{% else %}
|
||||
{% trans "-" %}
|
||||
{% endif %}
|
||||
</dd>
|
||||
|
||||
<dt>{% trans "Shared" %}</dt>
|
||||
<dd>{{ policy.shared|yesno|capfirst }}</dd>
|
||||
|
||||
<dt>{% trans "Audited" %}</dt>
|
||||
<dd>{{ policy.audited|yesno|capfirst }}</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 "Choose the rule you want to remove." %}</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 remove ports from firewall group here." %}</p>
|
||||
{% endblock %}
|
@ -0,0 +1,44 @@
|
||||
{% load i18n sizeformat parse_date %}
|
||||
|
||||
<div class="detail">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ rule.name|default:_("-") }}</dd>
|
||||
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ rule.description|default:_("-") }}</dd>
|
||||
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ rule.id }}</dd>
|
||||
|
||||
<dt>{% trans "Project ID" %}</dt>
|
||||
<dd>{{ rule.tenant_id }}</dd>
|
||||
|
||||
<dt>{% trans "Action" %}</dt>
|
||||
<dd>{{ rule.action|upper }}</dd>
|
||||
|
||||
<dt>{% trans "IP Version" %}</dt>
|
||||
<dd>{{ rule.ip_version }}</dd>
|
||||
|
||||
<dt>{% trans "Protocol" %}</dt>
|
||||
<dd>{{ rule.protocol|default:_("ANY")|upper }}</dd>
|
||||
|
||||
<dt>{% trans "Source IP Address" %}</dt>
|
||||
<dd>{{ rule.source_ip_address|default:_("ANY") }}</dd>
|
||||
|
||||
<dt>{% trans "Source Port" %}</dt>
|
||||
<dd>{{ rule.source_port|default:_("ANY") }}</dd>
|
||||
|
||||
<dt>{% trans "Destination IP Address" %}</dt>
|
||||
<dd>{{ rule.destination_ip_address|default:_("ANY") }}</dd>
|
||||
|
||||
<dt>{% trans "Destination Port"%}</dt>
|
||||
<dd>{{ rule.destination_port|default:_("ANY") }}</dd>
|
||||
|
||||
<dt>{% trans "Shared" %}</dt>
|
||||
<dd>{{ rule.shared|yesno|capfirst }}</dd>
|
||||
|
||||
<dt>{% trans "Enabled" %}</dt>
|
||||
<dd>{{ rule.enabled|yesno|capfirst }}</dd>
|
||||
</dl>
|
||||
</div>
|
@ -0,0 +1,3 @@
|
||||
{% load i18n %}
|
||||
|
||||
<p>{% blocktrans %}Choose port(s) from Available Ports. {% endblocktrans %}</p>
|
@ -0,0 +1,35 @@
|
||||
{% load i18n %}
|
||||
|
||||
<noscript><h3>{{ step }}</h3></noscript>
|
||||
<div id="portListSortContainer" class="sort-container">
|
||||
<div class="col-sm-6">
|
||||
<h4 id="selected_port_label">{% trans "Selected Ports" %}</h4>
|
||||
<ul id="selected_port" class="portlist box-list"></ul>
|
||||
<h4>{% trans "Available Ports" %}</h4>
|
||||
<ul id="available_port" class="portlist box-list"></ul>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
{% include "project/firewalls_v2/_update_port_help.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="portListIdContainer">
|
||||
<div class="actions">
|
||||
<div id="portListId">
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="help_text">
|
||||
{{ step.get_help_text }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
if (typeof $ !== 'undefined') {
|
||||
horizon.firewalls_v2.workflow_init($(".workflow"));
|
||||
} else {
|
||||
addHorizonLoadEvent(function() {
|
||||
horizon.firewalls_v2.workflow_init($(".workflow"));
|
||||
});
|
||||
}
|
||||
</script>
|
@ -0,0 +1,6 @@
|
||||
{% load i18n horizon %}
|
||||
|
||||
<p>{% blocktrans trimmed %}
|
||||
Choose rule(s) from Available Rules to Selected Rule by push button or
|
||||
drag and drop, you may change their order by drag and drop as well.
|
||||
{% endblocktrans %}</p>
|
@ -0,0 +1,35 @@
|
||||
{% load i18n %}
|
||||
|
||||
<noscript><h3>{{ step }}</h3></noscript>
|
||||
<div id="ruleListSortContainer" class="sort-container">
|
||||
<div class="col-sm-6">
|
||||
<h4 id="selected_rule_label">{% trans "Selected Rules" %}</h4>
|
||||
<ul id="selected_rule" class="rulelist box-list"></ul>
|
||||
<h4>{% trans "Available Rules" %}</h4>
|
||||
<ul id="available_rule" class="rulelist box-list"></ul>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
{% include "project/firewalls_v2/_update_rule_help.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ruleListIdContainer">
|
||||
<div class="actions">
|
||||
<div id="ruleListId">
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="help_text">
|
||||
{{ step.get_help_text }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
if (typeof $ !== 'undefined') {
|
||||
horizon.firewalls_v2.workflow_init($(".workflow"));
|
||||
} else {
|
||||
addHorizonLoadEvent(function() {
|
||||
horizon.firewalls_v2.workflow_init($(".workflow"));
|
||||
});
|
||||
}
|
||||
</script>
|
@ -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 firewall group details here." %}</p>
|
||||
{% endblock %}
|
@ -0,0 +1,10 @@
|
||||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% blocktrans trimmed %}
|
||||
You may update policy details here.
|
||||
Use 'Insert Rule' or 'Remove Rule' links instead to insert or remove a rule.
|
||||
{% endblocktrans %}</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 rule details here." %}</p>
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Add New Firewall Group" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'horizon/common/_workflow.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Add New Policy" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'horizon/common/_workflow.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Add Port to Firewall Group" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'project/firewalls_v2/_addport.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Add New Rule" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'horizon/common/_workflow.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,11 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Firewall Groups" %}{% 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 "Insert Rule to Policy" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'project/firewalls_v2/_insert_rule_to_policy.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Remove Rule from Policy" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'project/firewalls_v2/_remove_rule_from_policy.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Remove Port from Firewall Group" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'project/firewalls_v2/_removeport.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,94 @@
|
||||
{% load horizon %}
|
||||
|
||||
{% minifyspace %}
|
||||
<div class="themable-select dropdown {% if not stand_alone %} form-control{% endif %}"
|
||||
xmlns="http://www.w3.org/1999/html">
|
||||
<button type="button" class="btn btn-default dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
{% if value %} title="{{ value }}" {% endif %}
|
||||
aria-expanded="false"
|
||||
{% if options|length < 1 %}
|
||||
disabled="true"
|
||||
{% endif %}
|
||||
>
|
||||
<span class="dropdown-title">
|
||||
{% if options|length < 1 %}
|
||||
{{ empty_text }}
|
||||
{% elif initial_value %}
|
||||
{{ initial_value.1 }}
|
||||
{% endif %}
|
||||
</span>
|
||||
<span class="fa fa-caret-down"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu container-fluid dropdown-table">
|
||||
<li class="row dropdown-thead">
|
||||
<div class="col-xs-12">
|
||||
<div class="row dropdown-tr ">
|
||||
{% if alternate_xs %}
|
||||
<div class="visible-xs-block col-xs-12 dropdown-th">{{ summarized_headers }}</div>
|
||||
{% for column in columns %}
|
||||
<div class="hidden-xs col-sm-{{ column_size }} dropdown-th">{{ column }}</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for column in columns %}
|
||||
<div class="col-xs-{{ column_size }} dropdown-th">{{ column }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{% for option in options %}
|
||||
<li data-original-index="{{ forloop.counter0 }}"
|
||||
class="row dropdown-tr"
|
||||
data-toggle="tooltip"
|
||||
data-placement="top"
|
||||
>
|
||||
<a data-select-value="{{ option.0 }}"
|
||||
class="col-xs-12"
|
||||
href="#"
|
||||
>
|
||||
<div class="row">
|
||||
{% if alternate_xs %}
|
||||
<div class="visible-xs-block col-xs-12 dropdown-td">
|
||||
{{ option.1 }}
|
||||
</div>
|
||||
{% for column in option.2 %}
|
||||
<div class="hidden-xs col-sm-{{ column_size }} dropdown-td">{{ column }}</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for column in option.2 %}
|
||||
<div class="col-xs-{{ column_size }} dropdown-td">{{ column }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<select
|
||||
{% if id %}
|
||||
id="{{ id }}"{% endif %}
|
||||
{% if name %}
|
||||
name="{{ name }}"
|
||||
{% endif %}
|
||||
{% for k,v in select_attrs.items %}
|
||||
{% if k != 'class' or 'switch' in v %}
|
||||
{{ k|safe }}="{{ v }}"
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
>
|
||||
{% for option in options %}
|
||||
<option value="{{ option.0 }}"
|
||||
{% if option.0 == value %}
|
||||
selected="selected"
|
||||
{% endif %}
|
||||
{% if option.3 %}
|
||||
{{ option.3|safe }}
|
||||
{% endif %}>
|
||||
{{ option.1 }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endminifyspace %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Edit Firewall Group" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'project/firewalls_v2/_updatefirewall.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Edit Policy" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'project/firewalls_v2/_updatepolicy.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Edit Rule" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'project/firewalls_v2/_updaterule.html' %}
|
||||
{% endblock %}
|
798
neutron_fwaas_dashboard/dashboards/project/firewalls_v2/tests.py
Normal file
798
neutron_fwaas_dashboard/dashboards/project/firewalls_v2/tests.py
Normal file
@ -0,0 +1,798 @@
|
||||
# Copyright 2017, Juniper Networks, 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 unittest import mock
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
from openstack_dashboard.test import helpers
|
||||
|
||||
from neutron_fwaas_dashboard.api import fwaas_v2 as api_fwaas_v2
|
||||
from neutron_fwaas_dashboard.test import helpers as test
|
||||
|
||||
|
||||
class FirewallTests(test.TestCase):
|
||||
|
||||
INDEX_URL = reverse('horizon:project:firewalls_v2:index')
|
||||
|
||||
ADDRULE_PATH = 'horizon:project:firewalls_v2:addrule'
|
||||
ADDPOLICY_PATH = 'horizon:project:firewalls_v2:addpolicy'
|
||||
ADDFIREWALLGROUP_PATH = 'horizon:project:firewalls_v2:addfirewallgroup'
|
||||
|
||||
RULE_DETAIL_PATH = 'horizon:project:firewalls_v2:ruledetails'
|
||||
POLICY_DETAIL_PATH = 'horizon:project:firewalls_v2:policydetails'
|
||||
FIREWALLGROUP_DETAIL_PATH = \
|
||||
'horizon:project:firewalls_v2:firewallgroupdetails'
|
||||
|
||||
UPDATERULE_PATH = 'horizon:project:firewalls_v2:updaterule'
|
||||
UPDATEPOLICY_PATH = 'horizon:project:firewalls_v2:updatepolicy'
|
||||
UPDATEFIREWALLGROUP_PATH = 'horizon:project:firewalls_v2:updatefirewall'
|
||||
|
||||
INSERTRULE_PATH = 'horizon:project:firewalls_v2:insertrule'
|
||||
REMOVERULE_PATH = 'horizon:project:firewalls_v2:removerule'
|
||||
|
||||
ADDPORT_PATH = 'horizon:project:firewalls_v2:addport'
|
||||
REMOVEPORT_PATH = 'horizon:project:firewalls_v2:removeport'
|
||||
|
||||
def setup_mocks(self):
|
||||
firewallgroups = self.firewall_groups_v2.list()
|
||||
self.mock_firewall_group_list_for_tenant.return_value = firewallgroups
|
||||
policies = self.fw_policies_v2.list()
|
||||
self.mock_policy_list_for_tenant.return_value = policies
|
||||
self.mock_rule_list_for_tenant.return_value = self.fw_rules_v2.list()
|
||||
|
||||
def check_mocks(self):
|
||||
tenant_id = self.tenant.id
|
||||
|
||||
self.mock_firewall_group_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
# TODO(amotoki): get_firewallgroupstable_data() also calls
|
||||
# policy_list_for_tenant(). This needs to be clean up.
|
||||
self.assert_mock_multiple_calls_with_same_arguments(
|
||||
self.mock_policy_list_for_tenant, 2,
|
||||
mock.call(helpers.IsHttpRequest(), tenant_id))
|
||||
self.mock_rule_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
|
||||
def setup_mocks_with_exception(self):
|
||||
self.mock_rule_list_for_tenant.side_effect = self.exceptions.neutron
|
||||
self.mock_policy_list_for_tenant.side_effect = self.exceptions.neutron
|
||||
self.mock_firewall_group_list_for_tenant.side_effect = \
|
||||
self.exceptions.neutron
|
||||
|
||||
def check_mocks_with_exception(self):
|
||||
tenant_id = self.tenant.id
|
||||
self.mock_rule_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
self.mock_policy_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
self.mock_firewall_group_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_list_for_tenant',
|
||||
'policy_list_for_tenant',
|
||||
'rule_list_for_tenant',)})
|
||||
def test_index_firewallgroups(self):
|
||||
self.setup_mocks()
|
||||
|
||||
tenant_id = self.tenant.id
|
||||
|
||||
res = self.client.get(self.INDEX_URL, tenant_id=tenant_id)
|
||||
|
||||
self.assertTemplateUsed(res, 'project/firewalls_v2/details_tabs.html')
|
||||
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||
self.assertEqual(len(res.context['table'].data),
|
||||
len(self.firewall_groups_v2.list()))
|
||||
self.check_mocks()
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_list_for_tenant',
|
||||
'policy_list_for_tenant',
|
||||
'rule_list_for_tenant',)})
|
||||
def test_index_policies(self):
|
||||
self.setup_mocks()
|
||||
|
||||
tenant_id = self.tenant.id
|
||||
|
||||
res = self.client.get(self.INDEX_URL + '?tab=fwtabs__policies',
|
||||
tenant_id=tenant_id)
|
||||
|
||||
self.assertTemplateUsed(res, 'project/firewalls_v2/details_tabs.html')
|
||||
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||
self.assertEqual(len(res.context['policiestable_table'].data),
|
||||
len(self.fw_policies_v2.list()))
|
||||
self.check_mocks()
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_list_for_tenant',
|
||||
'policy_list_for_tenant',
|
||||
'rule_list_for_tenant',)})
|
||||
def test_index_rules(self):
|
||||
self.setup_mocks()
|
||||
|
||||
tenant_id = self.tenant.id
|
||||
|
||||
res = self.client.get(self.INDEX_URL + '?tab=fwtabs__rules',
|
||||
tenant_id=tenant_id)
|
||||
|
||||
self.assertTemplateUsed(res, 'project/firewalls_v2/details_tabs.html')
|
||||
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||
self.assertEqual(len(res.context['rulestable_table'].data),
|
||||
len(self.fw_rules_v2.list()))
|
||||
self.check_mocks()
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_list_for_tenant',
|
||||
'policy_list_for_tenant',
|
||||
'rule_list_for_tenant')})
|
||||
def test_index_exception_firewallgroups(self):
|
||||
self.setup_mocks_with_exception()
|
||||
|
||||
tenant_id = self.tenant.id
|
||||
|
||||
res = self.client.get(self.INDEX_URL, tenant_id=tenant_id)
|
||||
|
||||
self.assertTemplateUsed(res, 'project/firewalls_v2/details_tabs.html')
|
||||
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||
self.assertEqual(len(res.context['table'].data), 0)
|
||||
|
||||
self.check_mocks_with_exception()
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_list_for_tenant',
|
||||
'policy_list_for_tenant',
|
||||
'rule_list_for_tenant')})
|
||||
def test_index_exception_policies(self):
|
||||
self.setup_mocks_with_exception()
|
||||
|
||||
tenant_id = self.tenant.id
|
||||
|
||||
res = self.client.get(self.INDEX_URL + '?tab=fwtabs__policies',
|
||||
tenant_id=tenant_id)
|
||||
|
||||
self.assertTemplateUsed(res, 'project/firewalls_v2/details_tabs.html')
|
||||
self.assertTemplateUsed(res,
|
||||
'horizon/common/_detail_table.html')
|
||||
self.assertEqual(len(res.context['policiestable_table'].data), 0)
|
||||
|
||||
self.check_mocks_with_exception()
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_list_for_tenant',
|
||||
'policy_list_for_tenant',
|
||||
'rule_list_for_tenant')})
|
||||
def test_index_exception_rules(self):
|
||||
self.setup_mocks_with_exception()
|
||||
|
||||
tenant_id = self.tenant.id
|
||||
|
||||
res = self.client.get(self.INDEX_URL + '?tab=fwtabs__rules',
|
||||
tenant_id=tenant_id)
|
||||
|
||||
self.assertTemplateUsed(res, 'project/firewalls_v2/details_tabs.html')
|
||||
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
|
||||
self.assertEqual(len(res.context['rulestable_table'].data), 0)
|
||||
|
||||
self.check_mocks_with_exception()
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('rule_create',), })
|
||||
def test_add_rule_post(self):
|
||||
rule1 = self.fw_rules_v2.first()
|
||||
|
||||
form_data = {'name': rule1.name,
|
||||
'description': rule1.description,
|
||||
'protocol': rule1.protocol,
|
||||
'action': rule1.action,
|
||||
'source_ip_address': rule1.source_ip_address,
|
||||
'source_port': rule1.source_port,
|
||||
'destination_ip_address': rule1.destination_ip_address,
|
||||
'destination_port': rule1.destination_port,
|
||||
'shared': rule1.shared,
|
||||
'enabled': rule1.enabled,
|
||||
'ip_version': rule1.ip_version
|
||||
}
|
||||
|
||||
self.mock_rule_create.return_value = rule1
|
||||
|
||||
res = self.client.post(reverse(self.ADDRULE_PATH), form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_rule_create.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), **form_data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('rule_create',), })
|
||||
def test_add_rule_post_src_None(self):
|
||||
rule1 = self.fw_rules_v2.first()
|
||||
form_data = {'name': rule1.name,
|
||||
'description': rule1.description,
|
||||
'protocol': rule1.protocol,
|
||||
'action': rule1.action,
|
||||
'source_ip_address': '',
|
||||
'destination_ip_address': rule1.destination_ip_address,
|
||||
'source_port': '',
|
||||
'destination_port': rule1.destination_port,
|
||||
'shared': rule1.shared,
|
||||
'enabled': rule1.enabled,
|
||||
'ip_version': rule1.ip_version
|
||||
}
|
||||
|
||||
self.mock_rule_create.return_value = rule1
|
||||
|
||||
res = self.client.post(reverse(self.ADDRULE_PATH), form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
data = form_data.copy()
|
||||
data['source_ip_address'] = None
|
||||
data['source_port'] = None
|
||||
self.mock_rule_create.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), **data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('rule_create',), })
|
||||
def test_add_rule_post_dest_None(self):
|
||||
rule1 = self.fw_rules_v2.first()
|
||||
form_data = {'name': rule1.name,
|
||||
'description': rule1.description,
|
||||
'protocol': rule1.protocol,
|
||||
'action': rule1.action,
|
||||
'source_ip_address': rule1.source_ip_address,
|
||||
'destination_ip_address': '',
|
||||
'source_port': rule1.source_port,
|
||||
'destination_port': '',
|
||||
'shared': rule1.shared,
|
||||
'enabled': rule1.enabled,
|
||||
'ip_version': rule1.ip_version
|
||||
}
|
||||
|
||||
self.mock_rule_create.return_value = rule1
|
||||
|
||||
res = self.client.post(reverse(self.ADDRULE_PATH), form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
data = form_data.copy()
|
||||
data['destination_ip_address'] = None
|
||||
data['destination_port'] = None
|
||||
self.mock_rule_create.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), **data)
|
||||
|
||||
def test_add_rule_post_with_error(self):
|
||||
rule1 = self.fw_rules_v2.first()
|
||||
|
||||
form_data = {'name': rule1.name,
|
||||
'description': rule1.description,
|
||||
'protocol': 'abc',
|
||||
'action': 'pass',
|
||||
'source_ip_address': rule1.source_ip_address,
|
||||
'source_port': rule1.source_port,
|
||||
'destination_ip_address': rule1.destination_ip_address,
|
||||
'destination_port': rule1.destination_port,
|
||||
'shared': rule1.shared,
|
||||
'enabled': rule1.enabled,
|
||||
'ip_version': 6
|
||||
}
|
||||
|
||||
res = self.client.post(reverse(self.ADDRULE_PATH), form_data)
|
||||
|
||||
self.assertFormErrors(res, 3)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('policy_create',
|
||||
'rule_list_for_tenant'), })
|
||||
def test_add_policy_post(self):
|
||||
policy = self.fw_policies_v2.first()
|
||||
rules = self.fw_rules_v2.list()
|
||||
tenant_id = self.tenant.id
|
||||
form_data = {'name': policy.name,
|
||||
'description': policy.description,
|
||||
'firewall_rules': policy.firewall_rules,
|
||||
'shared': policy.shared,
|
||||
'audited': policy.audited
|
||||
}
|
||||
post_data = {'name': policy.name,
|
||||
'description': policy.description,
|
||||
'rule': policy.firewall_rules,
|
||||
'shared': policy.shared,
|
||||
'audited': policy.audited
|
||||
}
|
||||
|
||||
# NOTE: SelectRulesAction.populate_rule_choices() lists rule not
|
||||
# associated with any policy. We need to ensure that rules specified
|
||||
# in policy.firewall_rules in post_data (above) are not associated
|
||||
# with any policy. Test data in neutron_data is data in a stable state,
|
||||
# so we need to modify here.
|
||||
for rule in rules:
|
||||
if rule.id in policy.firewall_rules:
|
||||
rule.firewall_policy_id = rule.policy = None
|
||||
self.mock_rule_list_for_tenant.return_value = rules
|
||||
self.mock_policy_create.return_value = policy
|
||||
|
||||
res = self.client.post(reverse(self.ADDPOLICY_PATH), post_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_rule_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
self.mock_policy_create.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), **form_data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('rule_list_for_tenant',)})
|
||||
def test_add_policy_post_with_error(self):
|
||||
policy = self.fw_policies_v2.first()
|
||||
rules = self.fw_rules_v2.list()
|
||||
tenant_id = self.tenant.id
|
||||
form_data = {'description': policy.description,
|
||||
'firewall_rules': '',
|
||||
'shared': policy.shared,
|
||||
'audited': policy.audited
|
||||
}
|
||||
self.mock_rule_list_for_tenant.return_value = rules
|
||||
|
||||
res = self.client.post(reverse(self.ADDPOLICY_PATH), form_data)
|
||||
|
||||
self.assertFormErrors(res, 1)
|
||||
|
||||
self.mock_rule_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_create',
|
||||
'policy_list_for_tenant',
|
||||
'fwg_port_list_for_tenant',)})
|
||||
def test_add_firewall_group_post(self):
|
||||
fwg = self.firewall_groups_v2.first()
|
||||
policies = self.fw_policies_v2.list()
|
||||
tenant_id = self.tenant.id
|
||||
|
||||
form_data = {
|
||||
'name': fwg.name,
|
||||
'description': fwg.description,
|
||||
'ingress_firewall_policy_id': fwg.ingress_firewall_policy_id,
|
||||
'egress_firewall_policy_id': fwg.egress_firewall_policy_id,
|
||||
'admin_state_up': fwg.admin_state_up,
|
||||
'shared': False,
|
||||
'port': [],
|
||||
}
|
||||
|
||||
self.mock_policy_list_for_tenant.return_value = policies
|
||||
self.mock_fwg_port_list_for_tenant.return_value = []
|
||||
self.mock_firewall_group_create.return_value = fwg
|
||||
|
||||
res = self.client.post(reverse(self.ADDFIREWALLGROUP_PATH), form_data)
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_policy_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
self.mock_fwg_port_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
data = form_data.copy()
|
||||
data['ports'] = data.pop('port')
|
||||
self.mock_firewall_group_create.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), **data)
|
||||
|
||||
# TODO(SarathMekala) : Fix this test.
|
||||
# @helpers.create_mocks({api_fwaas_v2: ('firewall_group_create',
|
||||
# 'policy_list_for_tenant',
|
||||
# 'fwg_port_list_for_tenant',)})
|
||||
# def test_add_firewall_post_with_error(self):
|
||||
# firewall_groups = self.firewall_groups_v2.first()
|
||||
# policies = self.fw_policies_v2.list()
|
||||
# tenant_id = self.tenant.id
|
||||
# form_data = {'name': firewall_groups.name,
|
||||
# 'description': firewall_groups.description,
|
||||
# 'admin_state_up': False
|
||||
# }
|
||||
# self.mock_policy_list_for_tenant(
|
||||
# helpers.IsHttpRequest(), tenant_id).AndReturn(policies)
|
||||
#
|
||||
# self.mox.ReplayAll()
|
||||
# res = self.client.post(reverse(self.ADDFIREWALLGROUP_PATH), form_data)
|
||||
#
|
||||
# self.assertFormErrors(res, 1)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('rule_get',)})
|
||||
def test_update_rule_get(self):
|
||||
rule = self.fw_rules_v2.first()
|
||||
|
||||
self.mock_rule_get.return_value = rule
|
||||
|
||||
res = self.client.get(reverse(self.UPDATERULE_PATH, args=(rule.id,)))
|
||||
|
||||
self.assertTemplateUsed(res, 'project/firewalls_v2/updaterule.html')
|
||||
self.mock_rule_get.assert_called_once_with(helpers.IsHttpRequest(),
|
||||
rule.id)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('rule_get', 'rule_update')})
|
||||
def test_update_rule_post(self):
|
||||
rule = self.fw_rules_v2.first()
|
||||
|
||||
self.mock_rule_get.return_value = rule
|
||||
self.mock_rule_update.return_value = rule
|
||||
|
||||
data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'protocol': 'icmp',
|
||||
'action': 'allow',
|
||||
'shared': False,
|
||||
'enabled': True,
|
||||
'ip_version': rule.ip_version,
|
||||
'source_ip_address': rule.source_ip_address,
|
||||
'destination_ip_address': None,
|
||||
'source_port': None,
|
||||
'destination_port': rule.destination_port,
|
||||
}
|
||||
expected_put_data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'protocol': 'icmp',
|
||||
'action': 'allow',
|
||||
'shared': False,
|
||||
'destination_ip_address': None,
|
||||
'source_port': None,
|
||||
}
|
||||
|
||||
form_data = data.copy()
|
||||
form_data['destination_ip_address'] = ''
|
||||
form_data['source_port'] = ''
|
||||
|
||||
res = self.client.post(
|
||||
reverse(self.UPDATERULE_PATH, args=(rule.id,)), form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_rule_get.assert_called_once_with(helpers.IsHttpRequest(),
|
||||
rule.id)
|
||||
self.mock_rule_update.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), rule.id, **expected_put_data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('rule_get', 'rule_update')})
|
||||
def test_update_protocol_any_rule_post(self):
|
||||
# protocol any means protocol == None in neutron context.
|
||||
rule = self.fw_rules_v2.get(protocol=None)
|
||||
|
||||
self.mock_rule_get.return_value = rule
|
||||
self.mock_rule_update.return_value = rule
|
||||
|
||||
data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'protocol': 'icmp',
|
||||
'action': 'allow',
|
||||
'shared': False,
|
||||
'enabled': True,
|
||||
'ip_version': rule.ip_version,
|
||||
'source_ip_address': rule.source_ip_address,
|
||||
'destination_ip_address': None,
|
||||
'source_port': None,
|
||||
'destination_port': rule.destination_port,
|
||||
}
|
||||
expected_put_data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'protocol': 'icmp',
|
||||
'action': 'allow',
|
||||
'shared': False,
|
||||
'destination_ip_address': None,
|
||||
'source_port': None,
|
||||
}
|
||||
|
||||
form_data = data.copy()
|
||||
form_data['destination_ip_address'] = ''
|
||||
form_data['source_port'] = ''
|
||||
|
||||
res = self.client.post(
|
||||
reverse(self.UPDATERULE_PATH, args=(rule.id,)), form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_rule_get.assert_called_once_with(helpers.IsHttpRequest(),
|
||||
rule.id)
|
||||
self.mock_rule_update.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), rule.id, **expected_put_data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('rule_get', 'rule_update')})
|
||||
def test_update_rule_protocol_to_ANY_post(self):
|
||||
rule = self.fw_rules_v2.first()
|
||||
|
||||
self.mock_rule_get.return_value = rule
|
||||
self.mock_rule_update.return_value = rule
|
||||
|
||||
form_data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'protocol': 'any',
|
||||
'action': 'allow',
|
||||
'shared': False,
|
||||
'enabled': True,
|
||||
'ip_version': rule.ip_version,
|
||||
'source_ip_address': rule.source_ip_address,
|
||||
'destination_ip_address': '',
|
||||
'source_port': '',
|
||||
'destination_port': rule.destination_port,
|
||||
}
|
||||
|
||||
expected_put_data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'protocol': None,
|
||||
'action': 'allow',
|
||||
'shared': False,
|
||||
'destination_ip_address': None,
|
||||
'source_port': None,
|
||||
}
|
||||
|
||||
res = self.client.post(
|
||||
reverse(self.UPDATERULE_PATH, args=(rule.id,)), form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_rule_get.assert_called_once_with(helpers.IsHttpRequest(),
|
||||
rule.id)
|
||||
self.mock_rule_update.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), rule.id, **expected_put_data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('policy_get',)})
|
||||
def test_update_policy_get(self):
|
||||
policy = self.fw_policies_v2.first()
|
||||
|
||||
self.mock_policy_get.return_value = policy
|
||||
|
||||
res = self.client.get(
|
||||
reverse(self.UPDATEPOLICY_PATH, args=(policy.id,)))
|
||||
|
||||
self.assertTemplateUsed(res, 'project/firewalls_v2/updatepolicy.html')
|
||||
|
||||
self.mock_policy_get.assert_called_once_with(helpers.IsHttpRequest(),
|
||||
policy.id)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('policy_get', 'policy_update')})
|
||||
def test_update_policy_post(self):
|
||||
policy = self.fw_policies_v2.first()
|
||||
|
||||
self.mock_policy_get.return_value = policy
|
||||
self.mock_policy_update.return_value = policy
|
||||
|
||||
data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'shared': True,
|
||||
'audited': False
|
||||
}
|
||||
expected_put_data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'audited': False,
|
||||
}
|
||||
|
||||
res = self.client.post(
|
||||
reverse(self.UPDATEPOLICY_PATH, args=(policy.id,)), data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_policy_get.assert_called_once_with(helpers.IsHttpRequest(),
|
||||
policy.id)
|
||||
self.mock_policy_update.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), policy.id, **expected_put_data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_get',
|
||||
'policy_list_for_tenant')})
|
||||
def test_update_firewall_group_get(self):
|
||||
firewall_group = self.firewall_groups_v2.first()
|
||||
policies = self.fw_policies_v2.list()
|
||||
tenant_id = self.tenant.id
|
||||
|
||||
self.mock_policy_list_for_tenant.return_value = policies
|
||||
self.mock_firewall_group_get.return_value = firewall_group
|
||||
|
||||
res = self.client.get(
|
||||
reverse(self.UPDATEFIREWALLGROUP_PATH, args=(firewall_group.id,)))
|
||||
|
||||
self.assertTemplateUsed(res,
|
||||
'project/firewalls_v2/updatefirewall.html')
|
||||
|
||||
self.mock_policy_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
self.mock_firewall_group_get.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), firewall_group.id)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_get',
|
||||
'policy_list_for_tenant',
|
||||
'firewall_group_update')})
|
||||
def test_update_firewall_post(self):
|
||||
fwg = self.firewall_groups_v2.first()
|
||||
tenant_id = self.tenant.id
|
||||
policies = self.fw_policies_v2.list()
|
||||
|
||||
data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'ingress_firewall_policy_id': fwg.ingress_firewall_policy_id,
|
||||
'egress_firewall_policy_id': '',
|
||||
'admin_state_up': False,
|
||||
'shared': False,
|
||||
}
|
||||
|
||||
expected_put_data = {
|
||||
'name': 'new name',
|
||||
'description': 'new desc',
|
||||
'egress_firewall_policy_id': None,
|
||||
'admin_state_up': False,
|
||||
}
|
||||
|
||||
self.mock_firewall_group_get.return_value = fwg
|
||||
self.mock_policy_list_for_tenant.return_value = policies
|
||||
self.mock_firewall_group_update.return_value = fwg
|
||||
|
||||
res = self.client.post(
|
||||
reverse(
|
||||
self.UPDATEFIREWALLGROUP_PATH,
|
||||
args=(
|
||||
fwg.id,
|
||||
)),
|
||||
data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_firewall_group_get.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), fwg.id)
|
||||
self.mock_policy_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
self.mock_firewall_group_update.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), fwg.id, **expected_put_data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('policy_get', 'policy_insert_rule',
|
||||
'rule_list_for_tenant', 'rule_get')})
|
||||
def test_policy_insert_rule(self):
|
||||
policy = self.fw_policies_v2.first()
|
||||
tenant_id = self.tenant.id
|
||||
rules = self.fw_rules_v2.list()
|
||||
|
||||
new_rule_id = rules[2].id
|
||||
|
||||
data = {'firewall_rule_id': new_rule_id,
|
||||
'insert_before': rules[1].id,
|
||||
'insert_after': rules[0].id}
|
||||
|
||||
self.mock_policy_get.return_value = policy
|
||||
|
||||
policy.firewall_rules = [rules[0].id,
|
||||
new_rule_id,
|
||||
rules[1].id]
|
||||
|
||||
self.mock_rule_list_for_tenant.return_value = rules
|
||||
self.mock_rule_get.return_value = rules[2]
|
||||
self.mock_policy_insert_rule.return_value = policy
|
||||
|
||||
res = self.client.post(
|
||||
reverse(self.INSERTRULE_PATH, args=(policy.id,)), data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_policy_get.assert_called_once_with(helpers.IsHttpRequest(),
|
||||
policy.id)
|
||||
self.mock_rule_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
self.mock_rule_get.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), new_rule_id)
|
||||
self.mock_policy_insert_rule.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), policy.id, **data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('policy_get', 'policy_remove_rule',
|
||||
'rule_list_for_tenant', 'rule_get')})
|
||||
def test_policy_remove_rule(self):
|
||||
policy = self.fw_policies_v2.first()
|
||||
tenant_id = self.tenant.id
|
||||
rules = self.fw_rules_v2.list()
|
||||
|
||||
remove_rule_id = policy.firewall_rules[0]
|
||||
left_rule_id = policy.firewall_rules[1]
|
||||
|
||||
data = {'firewall_rule_id': remove_rule_id}
|
||||
|
||||
after_remove_policy_dict = {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
|
||||
'tenant_id': '1',
|
||||
'name': 'policy1',
|
||||
'description': 'policy description',
|
||||
'firewall_rules': [left_rule_id],
|
||||
'audited': True,
|
||||
'shared': True}
|
||||
after_remove_policy = api_fwaas_v2.Policy(after_remove_policy_dict)
|
||||
|
||||
self.mock_policy_get.return_value = policy
|
||||
self.mock_rule_list_for_tenant.return_value = rules
|
||||
self.mock_rule_get.return_value = rules[0]
|
||||
self.mock_policy_remove_rule.return_value = after_remove_policy
|
||||
|
||||
res = self.client.post(
|
||||
reverse(self.REMOVERULE_PATH, args=(policy.id,)), data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
|
||||
|
||||
self.mock_policy_get.assert_called_once_with(helpers.IsHttpRequest(),
|
||||
policy.id)
|
||||
self.mock_rule_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), tenant_id)
|
||||
self.mock_rule_get.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), remove_rule_id)
|
||||
self.mock_policy_remove_rule.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), policy.id, **data)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('rule_list_for_tenant',
|
||||
'rule_delete')})
|
||||
def test_delete_rule(self):
|
||||
rule = self.fw_rules_v2.list()[2]
|
||||
|
||||
self.mock_rule_list_for_tenant.return_value = self.fw_rules_v2.list()
|
||||
self.mock_rule_delete.return_value = None
|
||||
|
||||
form_data = {"action": "rulestable__deleterule__%s" % rule.id}
|
||||
res = self.client.post(self.INDEX_URL, form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
|
||||
self.mock_rule_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), self.tenant.id)
|
||||
self.mock_rule_delete.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), rule.id)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('policy_list_for_tenant',
|
||||
'policy_delete')})
|
||||
def test_delete_policy(self):
|
||||
policy = self.fw_policies_v2.first()
|
||||
|
||||
self.mock_policy_list_for_tenant.return_value = \
|
||||
self.fw_policies_v2.list()
|
||||
self.mock_policy_delete.return_value = None
|
||||
|
||||
form_data = {"action": "policiestable__deletepolicy__%s" % policy.id}
|
||||
res = self.client.post(self.INDEX_URL, form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
|
||||
self.mock_policy_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), self.tenant.id)
|
||||
self.mock_policy_delete.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), policy.id)
|
||||
|
||||
@helpers.create_mocks({api_fwaas_v2: ('firewall_group_list_for_tenant',
|
||||
'policy_list_for_tenant',
|
||||
'firewall_group_delete',)})
|
||||
def test_delete_firewall_group(self):
|
||||
fwl = self.firewall_groups_v2.first()
|
||||
|
||||
self.mock_firewall_group_list_for_tenant.return_value = [fwl]
|
||||
self.mock_policy_list_for_tenant.return_value = \
|
||||
self.fw_policies_v2.list()
|
||||
self.mock_firewall_group_delete.return_value = None
|
||||
|
||||
form_data = {
|
||||
"action": "FirewallGroupsTable__deletefirewallgroup__%s" %
|
||||
fwl.id}
|
||||
res = self.client.post(self.INDEX_URL, form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
|
||||
self.mock_firewall_group_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), self.tenant.id)
|
||||
self.mock_policy_list_for_tenant.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), self.tenant.id)
|
||||
self.mock_firewall_group_delete.assert_called_once_with(
|
||||
helpers.IsHttpRequest(), fwl.id)
|
@ -0,0 +1,53 @@
|
||||
# Copyright 2017, Juniper Networks, 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_fwaas_dashboard.dashboards.project.firewalls_v2 import views
|
||||
|
||||
# TODO(Sarath Mekala) : Fix 'firewall' --> 'firewallgroup' in URLs as
|
||||
# well as in other places.
|
||||
urlpatterns = [
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^\?tab=fwtabs__firewalls$',
|
||||
views.IndexView.as_view(), name='firewalls'),
|
||||
url(r'^\?tab=fwtabs__rules$', views.IndexView.as_view(), name='rules'),
|
||||
url(r'^\?tab=fwtabs__policies$',
|
||||
views.IndexView.as_view(), name='policies'),
|
||||
url(r'^addrule$', views.AddRuleView.as_view(), name='addrule'),
|
||||
url(r'^addpolicy$', views.AddPolicyView.as_view(), name='addpolicy'),
|
||||
url(r'^addfirewallgroup$',
|
||||
views.AddFirewallGroupView.as_view(),
|
||||
name='addfirewallgroup'),
|
||||
url(r'^insertrule/(?P<policy_id>[^/]+)/$',
|
||||
views.InsertRuleToPolicyView.as_view(), name='insertrule'),
|
||||
url(r'^removerule/(?P<policy_id>[^/]+)/$',
|
||||
views.RemoveRuleFromPolicyView.as_view(), name='removerule'),
|
||||
url(r'^updaterule/(?P<rule_id>[^/]+)/$',
|
||||
views.UpdateRuleView.as_view(), name='updaterule'),
|
||||
url(r'^updatepolicy/(?P<policy_id>[^/]+)/$',
|
||||
views.UpdatePolicyView.as_view(), name='updatepolicy'),
|
||||
url(r'^updatefirewall/(?P<firewall_id>[^/]+)/$',
|
||||
views.UpdateFirewallView.as_view(), name='updatefirewall'),
|
||||
url(r'^addport/(?P<firewallgroup_id>[^/]+)/$',
|
||||
views.AddPortView.as_view(), name='addport'),
|
||||
url(r'^removeport/(?P<firewallgroup_id>[^/]+)/$',
|
||||
views.RemovePortView.as_view(), name='removeport'),
|
||||
url(r'^rule/(?P<rule_id>[^/]+)/$',
|
||||
views.RuleDetailsView.as_view(), name='ruledetails'),
|
||||
url(r'^policy/(?P<policy_id>[^/]+)/$',
|
||||
views.PolicyDetailsView.as_view(), name='policydetails'),
|
||||
url(r'^firewallgroup/(?P<firewallgroup_id>[^/]+)/$',
|
||||
views.FirewallGroupDetailsView.as_view(), name='firewallgroupdetails'),
|
||||
]
|
444
neutron_fwaas_dashboard/dashboards/project/firewalls_v2/views.py
Normal file
444
neutron_fwaas_dashboard/dashboards/project/firewalls_v2/views.py
Normal file
@ -0,0 +1,444 @@
|
||||
# Copyright 2017, Juniper Networks, 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.urls import reverse
|
||||
from django.urls 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_fwaas_dashboard.api import fwaas_v2 as api_fwaas_v2
|
||||
from neutron_fwaas_dashboard.dashboards.project.firewalls_v2 \
|
||||
import forms as fw_forms
|
||||
from neutron_fwaas_dashboard.dashboards.project.firewalls_v2 \
|
||||
import tabs as fw_tabs
|
||||
from neutron_fwaas_dashboard.dashboards.project.firewalls_v2 \
|
||||
import workflows as fw_workflows
|
||||
|
||||
InsertRuleToPolicy = fw_forms.InsertRuleToPolicy
|
||||
|
||||
RemoveRuleFromPolicy = fw_forms.RemoveRuleFromPolicy
|
||||
UpdateFirewall = fw_forms.UpdateFirewall
|
||||
UpdatePolicy = fw_forms.UpdatePolicy
|
||||
UpdateRule = fw_forms.UpdateRule
|
||||
AddPort = fw_forms.AddPort
|
||||
RemovePort = fw_forms.RemovePort
|
||||
|
||||
FirewallGroupDetailsTabs = fw_tabs.FirewallGroupDetailsTabs
|
||||
FirewallGroupTabs = fw_tabs.FirewallGroupTabs
|
||||
PolicyDetailsTabs = fw_tabs.PolicyDetailsTabs
|
||||
RuleDetailsTabs = fw_tabs.RuleDetailsTabs
|
||||
|
||||
AddFirewallGroup = fw_workflows.AddFirewallGroup
|
||||
AddPolicy = fw_workflows.AddPolicy
|
||||
AddRule = fw_workflows.AddRule
|
||||
|
||||
|
||||
class IndexView(tabs.TabbedTableView):
|
||||
tab_group_class = FirewallGroupTabs
|
||||
template_name = 'project/firewalls_v2/details_tabs.html'
|
||||
page_title = _("Firewall Groups")
|
||||
|
||||
|
||||
class AddRuleView(workflows.WorkflowView):
|
||||
workflow_class = AddRule
|
||||
template_name = "project/firewalls_v2/addrule.html"
|
||||
page_title = _("Add New Rule")
|
||||
|
||||
|
||||
class AddPolicyView(workflows.WorkflowView):
|
||||
workflow_class = AddPolicy
|
||||
template_name = "project/firewalls_v2/addpolicy.html"
|
||||
page_title = _("Add New Policy")
|
||||
|
||||
|
||||
class AddFirewallGroupView(workflows.WorkflowView):
|
||||
workflow_class = AddFirewallGroup
|
||||
template_name = "project/firewalls_v2/addfirewallgroup.html"
|
||||
page_title = _("Add New Firewall Group")
|
||||
|
||||
|
||||
class RuleDetailsView(tabs.TabView):
|
||||
tab_group_class = (RuleDetailsTabs)
|
||||
template_name = 'horizon/common/_detail.html'
|
||||
page_title = "{{ rule.name|default:rule.id }}"
|
||||
failure_url = reverse_lazy('horizon:project:firewalls_v2:index')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(RuleDetailsView, self).get_context_data(**kwargs)
|
||||
rule = self.get_data()
|
||||
table = fw_tabs.RulesTable(self.request)
|
||||
breadcrumb = [
|
||||
(_("Rules"), reverse_lazy('horizon:project:firewalls_v2:rules'))]
|
||||
context["custom_breadcrumb"] = breadcrumb
|
||||
context["rule"] = rule
|
||||
context["url"] = self.failure_url
|
||||
context["actions"] = table.render_row_actions(rule)
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_data(self):
|
||||
try:
|
||||
rule_id = self.kwargs['rule_id']
|
||||
rule = api_fwaas_v2.rule_get(self.request, rule_id)
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve rule details.'),
|
||||
redirect=self.failure_url)
|
||||
return rule
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
rule = self.get_data()
|
||||
return self.tab_group_class(request, rule=rule, **kwargs)
|
||||
|
||||
|
||||
class PolicyDetailsView(tabs.TabView):
|
||||
tab_group_class = (PolicyDetailsTabs)
|
||||
template_name = 'horizon/common/_detail.html'
|
||||
page_title = "{{ policy.name|default:policy.id }}"
|
||||
failure_url = reverse_lazy('horizon:project:firewalls_v2:index')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(PolicyDetailsView, self).get_context_data(**kwargs)
|
||||
policy = self.get_data()
|
||||
table = fw_tabs.PoliciesTable(self.request)
|
||||
breadcrumb = [
|
||||
(_("Policies"),
|
||||
reverse_lazy('horizon:project:firewalls_v2:policies'))]
|
||||
context["custom_breadcrumb"] = breadcrumb
|
||||
context["policy"] = policy
|
||||
context["url"] = self.failure_url
|
||||
context["actions"] = table.render_row_actions(policy)
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_data(self):
|
||||
try:
|
||||
policy_id = self.kwargs['policy_id']
|
||||
policy = api_fwaas_v2.policy_get(self.request, policy_id)
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve policy details.'),
|
||||
redirect=self.failure_url)
|
||||
return policy
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
policy = self.get_data()
|
||||
return self.tab_group_class(request, policy=policy, **kwargs)
|
||||
|
||||
|
||||
class FirewallGroupDetailsView(tabs.TabView):
|
||||
tab_group_class = (FirewallGroupDetailsTabs)
|
||||
template_name = 'horizon/common/_detail.html'
|
||||
page_title = "{{ firewall_group.name|default:firewall_group.id }}"
|
||||
failure_url = reverse_lazy('horizon:project:firewalls_v2:index')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(FirewallGroupDetailsView, self) \
|
||||
.get_context_data(**kwargs)
|
||||
firewall_group = self.get_data()
|
||||
table = fw_tabs.FirewallGroupsTable(self.request)
|
||||
context["firewall_group"] = firewall_group
|
||||
context["url"] = self.failure_url
|
||||
context["actions"] = table.render_row_actions(firewall_group)
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_data(self):
|
||||
try:
|
||||
firewallgroup_id = self.kwargs['firewallgroup_id']
|
||||
firewall_group = api_fwaas_v2.firewall_group_get(self.request,
|
||||
firewallgroup_id)
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve firewall group details.'),
|
||||
redirect=self.failure_url)
|
||||
return firewall_group
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
firewall_group = self.get_data()
|
||||
return self.tab_group_class(request, firewallgroup=firewall_group,
|
||||
**kwargs)
|
||||
|
||||
|
||||
class UpdateRuleView(forms.ModalFormView):
|
||||
form_class = UpdateRule
|
||||
form_id = "update_rule_form"
|
||||
template_name = "project/firewalls_v2/updaterule.html"
|
||||
context_object_name = 'rule'
|
||||
submit_label = _("Save Changes")
|
||||
submit_url = "horizon:project:firewalls_v2:updaterule"
|
||||
success_url = reverse_lazy("horizon:project:firewalls_v2:index")
|
||||
page_title = _("Edit Rule {{ name }}")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UpdateRuleView, self).get_context_data(**kwargs)
|
||||
context['rule_id'] = self.kwargs['rule_id']
|
||||
args = (self.kwargs['rule_id'],)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
obj = self._get_object()
|
||||
if obj:
|
||||
context['name'] = obj.name_or_id
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def _get_object(self, *args, **kwargs):
|
||||
rule_id = self.kwargs['rule_id']
|
||||
try:
|
||||
rule = api_fwaas_v2.rule_get(self.request, rule_id)
|
||||
return rule
|
||||
except Exception:
|
||||
redirect = self.success_url
|
||||
msg = _('Unable to retrieve rule details.')
|
||||
exceptions.handle(self.request, msg, redirect=redirect)
|
||||
|
||||
def get_initial(self):
|
||||
rule = self._get_object()
|
||||
initial = rule.to_dict()
|
||||
protocol = initial['protocol']
|
||||
initial['protocol'] = protocol.upper() if protocol else 'ANY'
|
||||
initial['action'] = initial['action'].upper()
|
||||
return initial
|
||||
|
||||
|
||||
class UpdatePolicyView(forms.ModalFormView):
|
||||
form_class = UpdatePolicy
|
||||
form_id = "update_policy_form"
|
||||
template_name = "project/firewalls_v2/updatepolicy.html"
|
||||
context_object_name = 'policy'
|
||||
submit_label = _("Save Changes")
|
||||
submit_url = "horizon:project:firewalls_v2:updatepolicy"
|
||||
success_url = reverse_lazy("horizon:project:firewalls_v2:index")
|
||||
page_title = _("Edit Policy {{ name }}")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UpdatePolicyView, self).get_context_data(**kwargs)
|
||||
context["policy_id"] = self.kwargs['policy_id']
|
||||
args = (self.kwargs['policy_id'],)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
obj = self._get_object()
|
||||
if obj:
|
||||
context['name'] = obj.name_or_id
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def _get_object(self, *args, **kwargs):
|
||||
policy_id = self.kwargs['policy_id']
|
||||
try:
|
||||
policy = api_fwaas_v2.policy_get(self.request, policy_id)
|
||||
return policy
|
||||
except Exception:
|
||||
redirect = self.success_url
|
||||
msg = _('Unable to retrieve policy details.')
|
||||
exceptions.handle(self.request, msg, redirect=redirect)
|
||||
|
||||
def get_initial(self):
|
||||
policy = self._get_object()
|
||||
initial = policy.to_dict()
|
||||
return initial
|
||||
|
||||
|
||||
class UpdateFirewallView(forms.ModalFormView):
|
||||
form_class = UpdateFirewall
|
||||
form_id = "update_firewall_form"
|
||||
template_name = "project/firewalls_v2/updatefirewall.html"
|
||||
context_object_name = 'firewall'
|
||||
submit_label = _("Save Changes")
|
||||
submit_url = "horizon:project:firewalls_v2:updatefirewall"
|
||||
success_url = reverse_lazy("horizon:project:firewalls_v2:index")
|
||||
page_title = _("Edit FirewallGroup {{ name }}")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UpdateFirewallView, self).get_context_data(**kwargs)
|
||||
context["firewall_id"] = self.kwargs['firewall_id']
|
||||
args = (self.kwargs['firewall_id'],)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
obj = self._get_object()
|
||||
if obj:
|
||||
context['name'] = obj.name
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def _get_object(self, *args, **kwargs):
|
||||
fwg_id = self.kwargs['firewall_id']
|
||||
try:
|
||||
fwg = api_fwaas_v2.firewall_group_get(self.request, fwg_id)
|
||||
return fwg
|
||||
except Exception:
|
||||
redirect = self.success_url
|
||||
msg = _('Unable to retrieve firewall group details.')
|
||||
exceptions.handle(self.request, msg, redirect=redirect)
|
||||
|
||||
def get_initial(self):
|
||||
fwg = self._get_object()
|
||||
initial = fwg.to_dict()
|
||||
return initial
|
||||
|
||||
|
||||
class AddPortView(forms.ModalFormView):
|
||||
form_class = AddPort
|
||||
form_id = "update_firewall_port_form"
|
||||
template_name = "project/firewalls_v2/addport.html"
|
||||
context_object_name = 'firewallgroup'
|
||||
submit_label = _("Save Changes")
|
||||
submit_url = "horizon:project:firewalls_v2:addport"
|
||||
success_url = reverse_lazy("horizon:project:firewalls_v2:index")
|
||||
page_title = _("Add port to Firewall Group {{ name }}")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(AddPortView, self).get_context_data(**kwargs)
|
||||
context["firewallgroup_id"] = self.kwargs['firewallgroup_id']
|
||||
args = (self.kwargs['firewallgroup_id'],)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
obj = self._get_object()
|
||||
if obj:
|
||||
context['name'] = obj.name
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def _get_object(self, *args, **kwargs):
|
||||
firewallgroup_id = self.kwargs['firewallgroup_id']
|
||||
try:
|
||||
firewallgroup = api_fwaas_v2.firewall_group_get(self.request,
|
||||
firewallgroup_id)
|
||||
return firewallgroup
|
||||
except Exception:
|
||||
redirect = self.success_url
|
||||
msg = _('Unable to retrieve firewallgroup details.')
|
||||
exceptions.handle(self.request, msg, redirect=redirect)
|
||||
|
||||
def get_initial(self):
|
||||
firewallgroup = self._get_object()
|
||||
initial = firewallgroup.to_dict()
|
||||
return initial
|
||||
|
||||
|
||||
class RemovePortView(forms.ModalFormView):
|
||||
form_class = RemovePort
|
||||
form_id = "update_firewall_port_form"
|
||||
template_name = "project/firewalls_v2/removeport.html"
|
||||
context_object_name = 'firewallgroup'
|
||||
submit_label = _("Save Changes")
|
||||
submit_url = "horizon:project:firewalls_v2:removeport"
|
||||
success_url = reverse_lazy("horizon:project:firewalls_v2:index")
|
||||
page_title = _("Remove port from FirewallGroup {{ name }}")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(RemovePortView, self).get_context_data(**kwargs)
|
||||
context["firewallgroup_id"] = self.kwargs['firewallgroup_id']
|
||||
args = (self.kwargs['firewallgroup_id'],)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
obj = self._get_object()
|
||||
if obj:
|
||||
context['name'] = obj.name
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def _get_object(self, *args, **kwargs):
|
||||
firewallgroup_id = self.kwargs['firewallgroup_id']
|
||||
try:
|
||||
firewallgroup = api_fwaas_v2.firewall_group_get(self.request,
|
||||
firewallgroup_id)
|
||||
return firewallgroup
|
||||
except Exception:
|
||||
redirect = self.success_url
|
||||
msg = _('Unable to retrieve firewall group details.')
|
||||
exceptions.handle(self.request, msg, redirect=redirect)
|
||||
|
||||
def get_initial(self):
|
||||
firewallgroup = self._get_object()
|
||||
initial = firewallgroup.to_dict()
|
||||
return initial
|
||||
|
||||
|
||||
class InsertRuleToPolicyView(forms.ModalFormView):
|
||||
form_class = InsertRuleToPolicy
|
||||
form_id = "update_policy_form"
|
||||
template_name = "project/firewalls_v2/insert_rule_to_policy.html"
|
||||
context_object_name = 'policy'
|
||||
submit_url = "horizon:project:firewalls_v2:insertrule"
|
||||
submit_label = _("Save Changes")
|
||||
success_url = reverse_lazy("horizon:project:firewalls_v2:index")
|
||||
page_title = _("Insert Rule to Policy")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(InsertRuleToPolicyView,
|
||||
self).get_context_data(**kwargs)
|
||||
context["policy_id"] = self.kwargs['policy_id']
|
||||
args = (self.kwargs['policy_id'],)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
obj = self._get_object()
|
||||
if obj:
|
||||
context['name'] = obj.name_or_id
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def _get_object(self, *args, **kwargs):
|
||||
policy_id = self.kwargs['policy_id']
|
||||
try:
|
||||
policy = api_fwaas_v2.policy_get(self.request, policy_id)
|
||||
return policy
|
||||
except Exception:
|
||||
redirect = self.success_url
|
||||
msg = _('Unable to retrieve policy details.')
|
||||
exceptions.handle(self.request, msg, redirect=redirect)
|
||||
|
||||
def get_initial(self):
|
||||
policy = self._get_object()
|
||||
initial = policy.to_dict()
|
||||
initial['policy_id'] = initial['id']
|
||||
return initial
|
||||
|
||||
|
||||
class RemoveRuleFromPolicyView(forms.ModalFormView):
|
||||
form_class = RemoveRuleFromPolicy
|
||||
form_id = "update_policy_form"
|
||||
template_name = "project/firewalls_v2/remove_rule_from_policy.html"
|
||||
context_object_name = 'policy'
|
||||
submit_label = _("Save Changes")
|
||||
submit_url = "horizon:project:firewalls_v2:removerule"
|
||||
success_url = reverse_lazy("horizon:project:firewalls_v2:index")
|
||||
page_title = _("Remove Rule from Policy")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(RemoveRuleFromPolicyView,
|
||||
self).get_context_data(**kwargs)
|
||||
context["policy_id"] = self.kwargs['policy_id']
|
||||
args = (self.kwargs['policy_id'],)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
obj = self._get_object()
|
||||
if obj:
|
||||
context['name'] = obj.name_or_id
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def _get_object(self, *args, **kwargs):
|
||||
policy_id = self.kwargs['policy_id']
|
||||
try:
|
||||
policy = api_fwaas_v2.policy_get(self.request, policy_id)
|
||||
return policy
|
||||
except Exception:
|
||||
redirect = self.success_url
|
||||
msg = _('Unable to retrieve policy details.')
|
||||
exceptions.handle(self.request, msg, redirect=redirect)
|
||||
|
||||
def get_initial(self):
|
||||
policy = self._get_object()
|
||||
initial = policy.to_dict()
|
||||
initial['policy_id'] = initial['id']
|
||||
return initial
|
@ -0,0 +1,260 @@
|
||||
# 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 itertools
|
||||
|
||||
from django.template.loader import get_template
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from horizon.forms import fields
|
||||
|
||||
"""A custom Horizon Forms Select widget that displays select choices as a table
|
||||
|
||||
The widgets is meant as an optional replacement for the existing Horizon
|
||||
ThemableDynamicSelectWidget which it extends and is compatible with.
|
||||
|
||||
|
||||
Columns
|
||||
-------
|
||||
Columns are defined by setting the widgets 'column' attribute, which is
|
||||
expected to be an iterable of strings, each one corresponding to one column and
|
||||
used for that columns heading.
|
||||
|
||||
|
||||
Rows
|
||||
----
|
||||
Each row corresponds to one choice/select option with a defined value in
|
||||
each column.
|
||||
|
||||
The values displayed in each column are derived using the 'build_columns'
|
||||
attribute, which is expected to be a function that:
|
||||
|
||||
- takes a choice tuple of the form (value, label) as defined
|
||||
for the Django SelectField instances as it's only parameter
|
||||
- returns an iterable of Strings which are rendered as column
|
||||
values for the given choice row in the same order as in the
|
||||
iterable
|
||||
|
||||
The default implementation simply uses the provided value and label as separate
|
||||
column values.
|
||||
|
||||
See the default implementation and example bellow for more details.
|
||||
|
||||
|
||||
Condensed values
|
||||
----------------
|
||||
To maintain visual consistency, the currently selected value is displayed in
|
||||
the 'standard' ThemableDynamicSelectWidget HTML setup. To accommodate this, a
|
||||
condensed, single string value is created from the individual columns and
|
||||
displayed in the select box.
|
||||
|
||||
This behavior can be modified by setting the 'condense' attribute. This is
|
||||
expected to be a function that:
|
||||
|
||||
- Takes the column iterable returned by 'build_columns' function
|
||||
- Returns a single string representation of the choice
|
||||
|
||||
By default, the condensed value is created by joining all of the provided
|
||||
columns and joining them using commas as a delimiter.
|
||||
|
||||
See the default implementation and example bellow for more details.
|
||||
|
||||
|
||||
Small screen reactivity
|
||||
-----------------------
|
||||
Support for small screens (< 768px) is turned on by setting the attribute
|
||||
'alternate_xs' to True. When on, a condesned version of the popup table
|
||||
us used for small screens, where a single column is used with the condensed
|
||||
row values used instead of the full table rows.
|
||||
|
||||
The 'condense' function described above is used to construct this table.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
port_id = forms.ThemableDynamicChoiceField(
|
||||
label=_("Ports"),
|
||||
widget=TableSelectWidget(
|
||||
columns=[
|
||||
'ID',
|
||||
'Name'
|
||||
],
|
||||
build_columns=lambda choice: return (choice[1], choice[0]),
|
||||
choices=[
|
||||
('port 1', 'id1'),
|
||||
('port 2', 'id2')
|
||||
],
|
||||
alternate_xs=True,
|
||||
condense=lambda columns: return ",".join(columns)
|
||||
)
|
||||
)
|
||||
|
||||
Produces:
|
||||
|
||||
+------+--------+
|
||||
| ID | Name |
|
||||
+------+--------+
|
||||
| id1 | port 1 |
|
||||
| id2 | port 2 |
|
||||
+------+--------+
|
||||
|
||||
on normal screens and
|
||||
|
||||
+-------------+
|
||||
| ID, Name |
|
||||
+-------------+
|
||||
| id1, port 1 |
|
||||
| id2, port 2 |
|
||||
+-------------+
|
||||
|
||||
on xs screens.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class TableSelectWidget(fields.ThemableDynamicSelectWidget):
|
||||
def __init__(self,
|
||||
attrs=None,
|
||||
columns=None,
|
||||
alternate_xs=False,
|
||||
empty_text=_("No options available"),
|
||||
other_html=None,
|
||||
condense=None,
|
||||
build_columns=None, *args, **kwargs
|
||||
):
|
||||
"""Initializer for TableSelectWidget
|
||||
|
||||
:param attrs: A { attribute: value } dictionary which is attached to
|
||||
the hidden select element; see
|
||||
ThemableDynamicSelectWidget for further information
|
||||
:param columns: An iterable of column headers/names
|
||||
:param alternate_xs: A truth-y value which enables/disables an
|
||||
alternate rendering method for small screens
|
||||
:param empty_text: The text to be displayed in case no options are
|
||||
available
|
||||
:param other_html: A method for adding custom HTML to the hidden option
|
||||
HTML.
|
||||
NOTE: This mimics the behavior of
|
||||
ThemableDynamicSelectWidget and is retained to
|
||||
maintain compatibility with any related, potential
|
||||
functionality
|
||||
:param condense: A function callback that produces a condensed label
|
||||
for each option
|
||||
:param build_columns: A function used to populate the individual
|
||||
columns in the pop up table for each option
|
||||
"""
|
||||
super(TableSelectWidget, self).__init__(attrs, *args, **kwargs)
|
||||
self.columns = columns or [_('Label'), _('Value'), 'Nothing']
|
||||
|
||||
self.alternate_xs = alternate_xs
|
||||
self.empty_text = empty_text
|
||||
|
||||
if other_html:
|
||||
self.other_html = other_html
|
||||
|
||||
if condense:
|
||||
self.condense = condense
|
||||
|
||||
if build_columns:
|
||||
self.build_columns = build_columns
|
||||
|
||||
@staticmethod
|
||||
def build_columns(choice):
|
||||
"""Default column building method
|
||||
|
||||
Overwrite this method when initializing this widget or using
|
||||
self.fields[name].widget.build_columns in a parent form initialization
|
||||
to customize the behavior (see above for details)
|
||||
|
||||
:param choice:
|
||||
:return:
|
||||
"""
|
||||
return choice
|
||||
|
||||
@staticmethod
|
||||
def condense(choice_columns):
|
||||
"""The default condense method
|
||||
|
||||
Overwrite this method when initializing this widget or using
|
||||
self.fields[name].widget.condense in a parent form initialization to
|
||||
customize the behavior (see above for details)
|
||||
|
||||
:param choice_columns:
|
||||
:return:
|
||||
"""
|
||||
return " / ".join([str(c) for c in choice_columns])
|
||||
|
||||
# Implements the parent 'other_html' construction for compatibility reasons
|
||||
# Can be set in initializer to change the behavior as needed
|
||||
def other_html(self, choice):
|
||||
opt_label = choice[1]
|
||||
|
||||
other_html = self.transform_option_html_attrs(opt_label)
|
||||
data_attr_html = self.get_data_attrs(opt_label)
|
||||
|
||||
if data_attr_html:
|
||||
other_html += ' ' + data_attr_html
|
||||
|
||||
return other_html
|
||||
|
||||
def render(self, name, value, attrs=None, choices=None, renderer=None):
|
||||
new_choices = []
|
||||
initial_value = value
|
||||
|
||||
choices = choices or []
|
||||
|
||||
for opt in itertools.chain(self.choices, choices):
|
||||
other_html = self.other_html(opt)
|
||||
choice_columns = self.build_columns(opt)
|
||||
condensed_label = self.condense(choice_columns)
|
||||
|
||||
built_choice = (
|
||||
opt[0], condensed_label, choice_columns, other_html
|
||||
)
|
||||
|
||||
new_choices.append(built_choice)
|
||||
|
||||
# Initial selection
|
||||
if opt[0] == value:
|
||||
initial_value = built_choice
|
||||
|
||||
if not initial_value and new_choices:
|
||||
initial_value = new_choices[0]
|
||||
|
||||
element_id = attrs.pop('id', 'id_%s' % name)
|
||||
|
||||
# Size of individual columns in terms of the bootstrap grid - used
|
||||
# for styling purposes
|
||||
column_size = 12 // len(self.columns)
|
||||
|
||||
# Creates a single string label for all columns for use with small
|
||||
# screens
|
||||
condensed_headers = self.condense(self.columns)
|
||||
|
||||
template = get_template('project/firewalls_v2/table_select.html')
|
||||
|
||||
select_attrs = self.build_attrs(attrs)
|
||||
|
||||
context = {
|
||||
'name': name,
|
||||
'options': new_choices,
|
||||
'id': element_id,
|
||||
'value': value,
|
||||
'initial_value': initial_value,
|
||||
'select_attrs': select_attrs,
|
||||
'column_size': column_size,
|
||||
'columns': self.columns,
|
||||
'condensed_headers': condensed_headers,
|
||||
'alternate_xs': self.alternate_xs,
|
||||
'empty_text': self.empty_text
|
||||
}
|
||||
return template.render(context)
|
@ -0,0 +1,388 @@
|
||||
# Copyright 2017, Juniper Networks, 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 operator import attrgetter
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon.utils import validators
|
||||
from horizon import workflows
|
||||
import netaddr
|
||||
|
||||
from neutron_fwaas_dashboard.api import fwaas_v2 as api_fwaas_v2
|
||||
|
||||
port_validator = validators.validate_port_or_colon_separated_port_range
|
||||
|
||||
|
||||
class AddRuleAction(workflows.Action):
|
||||
name = forms.CharField(
|
||||
max_length=80,
|
||||
label=_("Name"),
|
||||
required=False)
|
||||
description = forms.CharField(
|
||||
max_length=80,
|
||||
label=_("Description"),
|
||||
required=False)
|
||||
protocol = forms.ThemableChoiceField(
|
||||
label=_("Protocol"),
|
||||
choices=[('tcp', _('TCP')),
|
||||
('udp', _('UDP')),
|
||||
('icmp', _('ICMP')),
|
||||
('any', _('ANY'))],)
|
||||
action = forms.ThemableChoiceField(
|
||||
label=_("Action"),
|
||||
choices=[('allow', _('ALLOW')),
|
||||
('deny', _('DENY')),
|
||||
('reject', _('REJECT'))],)
|
||||
source_ip_address = forms.IPField(
|
||||
label=_("Source IP Address/Subnet"),
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
required=False, mask=True)
|
||||
destination_ip_address = forms.IPField(
|
||||
label=_("Destination IP Address/Subnet"),
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
required=False, mask=True)
|
||||
source_port = forms.CharField(
|
||||
max_length=80,
|
||||
label=_("Source Port/Port Range"),
|
||||
required=False,
|
||||
validators=[port_validator])
|
||||
destination_port = forms.CharField(
|
||||
max_length=80,
|
||||
label=_("Destination Port/Port Range"),
|
||||
required=False,
|
||||
validators=[port_validator])
|
||||
ip_version = forms.ThemableChoiceField(
|
||||
label=_("IP Version"), required=False,
|
||||
choices=[('4', '4'), ('6', '6')])
|
||||
shared = forms.BooleanField(
|
||||
label=_("Shared"), initial=False, required=False)
|
||||
enabled = forms.BooleanField(
|
||||
label=_("Enabled"), initial=True, required=False)
|
||||
|
||||
def _check_ip_addr_and_ip_version(self, cleaned_data):
|
||||
ip_version = int(str(cleaned_data.get('ip_version')))
|
||||
src_ip = cleaned_data.get('source_ip_address')
|
||||
dst_ip = cleaned_data.get('destination_ip_address')
|
||||
msg = _('Source/Destination Network Address and IP version '
|
||||
'are inconsistent. Please make them consistent.')
|
||||
if (src_ip and
|
||||
netaddr.IPNetwork(src_ip).version != ip_version):
|
||||
self._errors['ip_version'] = self.error_class([msg])
|
||||
|
||||
elif (dst_ip and
|
||||
netaddr.IPNetwork(dst_ip).version != ip_version):
|
||||
self._errors['ip_version'] = self.error_class([msg])
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(AddRuleAction, self).clean()
|
||||
self._check_ip_addr_and_ip_version(cleaned_data)
|
||||
|
||||
class Meta(object):
|
||||
name = _("Rule")
|
||||
permissions = ('openstack.services.network',)
|
||||
help_text = _("Create a firewall rule.\n\n"
|
||||
"A Firewall rule is an association of the following "
|
||||
"attributes:\n\n"
|
||||
"<li>IP Addresses: The addresses from/to which the "
|
||||
"traffic filtration needs to be applied.</li>"
|
||||
"<li>IP Version: The type of IP packets (IP V4/V6) "
|
||||
"that needs to be filtered.</li>"
|
||||
"<li>Protocol: Type of packets (UDP, ICMP, TCP, Any) "
|
||||
"that needs to be checked.</li>"
|
||||
"<li>Action: Action is the type of filtration "
|
||||
"required, it can be Reject/Deny/Allow data "
|
||||
"packets.</li>\n"
|
||||
"The protocol and action fields are required, all "
|
||||
"others are optional.")
|
||||
|
||||
|
||||
class AddRuleStep(workflows.Step):
|
||||
action_class = AddRuleAction
|
||||
contributes = ("name", "description", "protocol", "action",
|
||||
"source_ip_address", "source_port",
|
||||
"destination_ip_address", "destination_port",
|
||||
"enabled", "shared", "ip_version")
|
||||
|
||||
def contribute(self, data, context):
|
||||
context = super(AddRuleStep, self).contribute(data, context)
|
||||
if data:
|
||||
if context['protocol'] == 'any':
|
||||
del context['protocol']
|
||||
for field in ['source_port',
|
||||
'destination_port',
|
||||
'source_ip_address',
|
||||
'destination_ip_address']:
|
||||
if not context[field]:
|
||||
del context[field]
|
||||
return context
|
||||
|
||||
|
||||
class AddRule(workflows.Workflow):
|
||||
slug = "addrule"
|
||||
name = _("Add Rule")
|
||||
finalize_button_name = _("Add")
|
||||
success_message = _('Added Rule "%s".')
|
||||
failure_message = _('Unable to add Rule "%s".')
|
||||
success_url = "horizon:project:firewalls_v2:index"
|
||||
default_steps = (AddRuleStep,)
|
||||
|
||||
def format_status_message(self, message):
|
||||
return message % self.context.get('name')
|
||||
|
||||
def handle(self, request, context):
|
||||
try:
|
||||
api_fwaas_v2.rule_create(request, **context)
|
||||
return True
|
||||
except Exception as e:
|
||||
msg = self.format_status_message(self.failure_message) + str(e)
|
||||
exceptions.handle(request, msg)
|
||||
return False
|
||||
|
||||
|
||||
class SelectRulesAction(workflows.Action):
|
||||
rule = forms.MultipleChoiceField(
|
||||
label=_("Rules"),
|
||||
required=False,
|
||||
widget=forms.ThemableCheckboxSelectMultiple(),
|
||||
help_text=_("Create a policy with selected rules."))
|
||||
|
||||
class Meta(object):
|
||||
name = _("Rules")
|
||||
permissions = ('openstack.services.network',)
|
||||
help_text = _("Select rules for your policy.")
|
||||
|
||||
def populate_rule_choices(self, request, context):
|
||||
try:
|
||||
tenant_id = self.request.user.tenant_id
|
||||
rules = api_fwaas_v2.rule_list_for_tenant(request, tenant_id)
|
||||
rules = sorted(rules,
|
||||
key=attrgetter('name_or_id'))
|
||||
rule_list = [(rule.id, rule.name_or_id) for rule in rules]
|
||||
except Exception as e:
|
||||
rule_list = []
|
||||
exceptions.handle(request, _('Unable to retrieve rules (%s).') % e)
|
||||
return rule_list
|
||||
|
||||
|
||||
class SelectRulesStep(workflows.Step):
|
||||
action_class = SelectRulesAction
|
||||
template_name = "project/firewalls_v2/_update_rules.html"
|
||||
contributes = ("firewall_rules",)
|
||||
|
||||
def contribute(self, data, context):
|
||||
if data:
|
||||
rules = self.workflow.request.POST.getlist("rule")
|
||||
if rules:
|
||||
rules = [r for r in rules if r]
|
||||
context['firewall_rules'] = rules
|
||||
return context
|
||||
|
||||
|
||||
class AddPolicyAction(workflows.Action):
|
||||
name = forms.CharField(max_length=80,
|
||||
label=_("Name"))
|
||||
description = forms.CharField(max_length=80,
|
||||
label=_("Description"),
|
||||
required=False)
|
||||
shared = forms.BooleanField(label=_("Shared"),
|
||||
initial=False,
|
||||
required=False)
|
||||
audited = forms.BooleanField(label=_("Audited"),
|
||||
initial=False,
|
||||
required=False)
|
||||
|
||||
class Meta(object):
|
||||
name = _("Policy")
|
||||
permissions = ('openstack.services.network',)
|
||||
help_text = _("Create a firewall policy with an ordered list "
|
||||
"of firewall rules.\n\n"
|
||||
"A firewall policy is an ordered collection of firewall "
|
||||
"rules. So if the traffic matches the first rule, the "
|
||||
"other rules are not executed. If the traffic does not "
|
||||
"match the current rule, then the next rule is "
|
||||
"executed. A firewall policy has the following "
|
||||
"attributes:\n\n"
|
||||
"<li>Shared: A firewall policy can be shared across "
|
||||
"tenants. Thus it can also be made part of an audit "
|
||||
"workflow wherein the firewall policy can be audited "
|
||||
"by the relevant entity that is authorized.</li>"
|
||||
"<li>Audited: When audited is set to True, it indicates "
|
||||
"that the firewall policy has been audited. "
|
||||
"Each time the firewall policy or the associated "
|
||||
"firewall rules are changed, this attribute will be "
|
||||
"set to False and will have to be explicitly set to "
|
||||
"True through an update operation.</li>\n"
|
||||
"The name field is required, all others are optional.")
|
||||
|
||||
|
||||
class AddPolicyStep(workflows.Step):
|
||||
action_class = AddPolicyAction
|
||||
contributes = ("name", "description", "shared", "audited")
|
||||
|
||||
def contribute(self, data, context):
|
||||
context = super(AddPolicyStep, self).contribute(data, context)
|
||||
if data:
|
||||
return context
|
||||
|
||||
|
||||
class AddPolicy(workflows.Workflow):
|
||||
slug = "addpolicy"
|
||||
name = _("Add Policy")
|
||||
finalize_button_name = _("Add")
|
||||
success_message = _('Added Policy "%s".')
|
||||
failure_message = _('Unable to add Policy "%s".')
|
||||
success_url = "horizon:project:firewalls_v2:index"
|
||||
default_steps = (AddPolicyStep, SelectRulesStep)
|
||||
|
||||
def format_status_message(self, message):
|
||||
return message % self.context.get('name')
|
||||
|
||||
def handle(self, request, context):
|
||||
try:
|
||||
api_fwaas_v2.policy_create(request, **context)
|
||||
return True
|
||||
except Exception as e:
|
||||
msg = self.format_status_message(self.failure_message) + str(e)
|
||||
exceptions.handle(request, msg)
|
||||
return False
|
||||
|
||||
|
||||
class AddFWGPortsAction(workflows.Action):
|
||||
port = forms.MultipleChoiceField(
|
||||
label=_("Ports"),
|
||||
required=False,
|
||||
widget=forms.ThemableCheckboxSelectMultiple(),
|
||||
help_text=_("Create a Firewall Group with selected ports."))
|
||||
|
||||
class Meta(object):
|
||||
name = _("Ports")
|
||||
permissions = ('openstack.services.network',)
|
||||
help_text = _("Select ports for your firewall group.")
|
||||
|
||||
def populate_port_choices(self, request, context):
|
||||
try:
|
||||
tenant_id = self.request.user.tenant_id
|
||||
ports = api_fwaas_v2.fwg_port_list_for_tenant(request, tenant_id)
|
||||
ports = sorted(ports,
|
||||
key=attrgetter('name_or_id'))
|
||||
port_list = [(port.id, port.name_or_id) for port in ports]
|
||||
except Exception as e:
|
||||
port_list = []
|
||||
exceptions.handle(request, _('Unable to retrieve ports (%s).') % e)
|
||||
return port_list
|
||||
|
||||
|
||||
class AddFWGPortsStep(workflows.Step):
|
||||
action_class = AddFWGPortsAction
|
||||
template_name = "project/firewalls_v2/_update_ports.html"
|
||||
contributes = ("ports")
|
||||
|
||||
def contribute(self, data, context):
|
||||
if data:
|
||||
ports = self.workflow.request.POST.getlist("port")
|
||||
if ports:
|
||||
ports = [r for r in ports if r != '']
|
||||
context['ports'] = ports
|
||||
else:
|
||||
context['ports'] = []
|
||||
return context
|
||||
|
||||
|
||||
class AddFirewallGroupAction(workflows.Action):
|
||||
name = forms.CharField(max_length=80,
|
||||
label=_("Name"),
|
||||
required=False)
|
||||
description = forms.CharField(max_length=80,
|
||||
label=_("Description"),
|
||||
required=False)
|
||||
ingress_firewall_policy_id = forms.ThemableChoiceField(
|
||||
label=_("Ingress Policy"),
|
||||
required=False)
|
||||
egress_firewall_policy_id = forms.ThemableChoiceField(
|
||||
label=_("Egress Policy"),
|
||||
required=False)
|
||||
admin_state_up = forms.BooleanField(
|
||||
label=_("Admin State"), initial=True, required=False)
|
||||
shared = forms.BooleanField(
|
||||
label=_("Shared"), initial=False, required=False)
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(AddFirewallGroupAction, self).__init__(request, *args, **kwargs)
|
||||
|
||||
firewall_policy_id_choices = [('', _("Select a Policy"))]
|
||||
try:
|
||||
tenant_id = self.request.user.tenant_id
|
||||
policies = api_fwaas_v2.policy_list_for_tenant(request, tenant_id)
|
||||
policies = sorted(policies, key=attrgetter('name'))
|
||||
except Exception as e:
|
||||
exceptions.handle(request,
|
||||
_('Unable to retrieve policy list (%s).') % e)
|
||||
policies = []
|
||||
for p in policies:
|
||||
firewall_policy_id_choices.append((p.id, p.name_or_id))
|
||||
self.fields['ingress_firewall_policy_id'].choices = \
|
||||
firewall_policy_id_choices
|
||||
self.fields['egress_firewall_policy_id'].choices = \
|
||||
firewall_policy_id_choices
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(AddFirewallGroupAction, self).clean()
|
||||
for field in ('ingress_firewall_policy_id',
|
||||
'egress_firewall_policy_id'):
|
||||
if not cleaned_data[field]:
|
||||
cleaned_data[field] = None
|
||||
return cleaned_data
|
||||
|
||||
class Meta(object):
|
||||
name = _("FirewallGroup")
|
||||
permissions = ('openstack.services.network',)
|
||||
help_text = _("Create a firewall group based on a policy.\n\n"
|
||||
"A firewall group represents a logical firewall "
|
||||
"resource that a tenant can instantiate and manage. "
|
||||
"A firewall group must be associated with one policy, "
|
||||
"all other fields are optional.")
|
||||
|
||||
|
||||
class AddFirewallGroupStep(workflows.Step):
|
||||
action_class = AddFirewallGroupAction
|
||||
contributes = ("name", "description", "admin_state_up", "shared",
|
||||
"ingress_firewall_policy_id",
|
||||
"egress_firewall_policy_id")
|
||||
|
||||
def contribute(self, data, context):
|
||||
context = super(AddFirewallGroupStep, self).contribute(data, context)
|
||||
return context
|
||||
|
||||
|
||||
class AddFirewallGroup(workflows.Workflow):
|
||||
slug = "addfirewallgroup"
|
||||
name = _("Add Firewall Group")
|
||||
finalize_button_name = _("Add")
|
||||
success_message = _('Added Firewall Group"%s".')
|
||||
failure_message = _('Unable to add Firewall Group "%s".')
|
||||
success_url = "horizon:project:firewalls_v2:index"
|
||||
default_steps = (AddFirewallGroupStep, AddFWGPortsStep)
|
||||
|
||||
def format_status_message(self, message):
|
||||
return message % self.context.get('name')
|
||||
|
||||
def handle(self, request, context):
|
||||
try:
|
||||
api_fwaas_v2.firewall_group_create(request, **context)
|
||||
return True
|
||||
except Exception as e:
|
||||
msg = self.format_status_message(self.failure_message) + str(e)
|
||||
exceptions.handle(request, msg)
|
||||
return False
|
@ -0,0 +1,20 @@
|
||||
# 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.
|
||||
|
||||
# FEATURE just declares this enabled file needs to be loaded.
|
||||
# This is required for ADD_INSTALLED_APPS to be processed.
|
||||
# The value itself has no meaning in the current horizon.
|
||||
FEATURE = 'neutron-fwaas-dashboard'
|
||||
|
||||
ADD_INSTALLED_APPS = ['neutron_fwaas_dashboard']
|
||||
AUTO_DISCOVER_STATIC_FILES = True
|
||||
ADD_SCSS_FILES = ['neutron_fwaas_dashboard/scss/firewalls.scss']
|
@ -0,0 +1,22 @@
|
||||
# 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 = 'firewalls_v2'
|
||||
# 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_fwaas_dashboard.dashboards.project.'
|
||||
'firewalls_v2.panel.Firewall_V2')
|
0
neutron_fwaas_dashboard/enabled/__init__.py
Normal file
0
neutron_fwaas_dashboard/enabled/__init__.py
Normal file
@ -0,0 +1,16 @@
|
||||
# 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 import settings
|
||||
|
||||
|
||||
settings.POLICY_FILES['neutron-fwaas'] = 'neutron-fwaas-policy.json'
|
0
neutron_fwaas_dashboard/locale/.placeholder
Normal file
0
neutron_fwaas_dashboard/locale/.placeholder
Normal file
649
neutron_fwaas_dashboard/locale/de/LC_MESSAGES/django.po
Normal file
649
neutron_fwaas_dashboard/locale/de/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,649 @@
|
||||
# Frank Kloeker <eumel@arcor.de>, 2016. #zanata
|
||||
# Robert Simai <robert.simai@suse.com>, 2016. #zanata
|
||||
# Andreas Jaeger <jaegerandi@gmail.com>, 2017. #zanata
|
||||
# Frank Kloeker <eumel@arcor.de>, 2017. #zanata
|
||||
# Robert Simai <robert.simai@suse.com>, 2017. #zanata
|
||||
# Andreas Jaeger <jaegerandi@gmail.com>, 2018. #zanata
|
||||
# Frank Kloeker <eumel@arcor.de>, 2018. #zanata
|
||||
# Reik Keutterling <spielkind@gmail.com>, 2018. #zanata
|
||||
# Robert Simai <robert.simai@suse.com>, 2018. #zanata
|
||||
# Andreas Jaeger <jaegerandi@gmail.com>, 2019. #zanata
|
||||
# Robert Simai <robert.simai@suse.com>, 2019. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: neutron-fwaas-dashboard VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2019-04-25 13:36+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-05-03 02:14+0000\n"
|
||||
"Last-Translator: Robert Simai <robert.simai@suse.com>\n"
|
||||
"Language-Team: German\n"
|
||||
"Language: de\n"
|
||||
"X-Generator: Zanata 4.3.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
msgid "-"
|
||||
msgstr "-"
|
||||
|
||||
msgid "ALLOW"
|
||||
msgstr "Erlauben"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "ALLOW"
|
||||
msgstr "Erlauben"
|
||||
|
||||
msgid "ANY"
|
||||
msgstr "ALLE"
|
||||
|
||||
msgid "Action"
|
||||
msgstr "Aktion"
|
||||
|
||||
msgid "Action for the firewall rule"
|
||||
msgstr "Aktion für die Firewallregel"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Active"
|
||||
msgstr "Aktiv"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "Hinzufügen"
|
||||
|
||||
msgid "Add Firewall Group"
|
||||
msgstr "Firewall-Gruppe hinzufügen"
|
||||
|
||||
msgid "Add New Firewall Group"
|
||||
msgstr "Neue Firewall-Gruppe hinzufügen"
|
||||
|
||||
msgid "Add New Policy"
|
||||
msgstr "Neue Richtlinie hinzufügen"
|
||||
|
||||
msgid "Add New Rule"
|
||||
msgstr "Neue Regel hinzufügen"
|
||||
|
||||
msgid "Add Policy"
|
||||
msgstr "Richtlinie hinzufügen"
|
||||
|
||||
msgid "Add Port"
|
||||
msgstr "Port hinzufügen"
|
||||
|
||||
msgid "Add Port to Firewall Group"
|
||||
msgstr "Port zur Firewallgruppe hinzufügen"
|
||||
|
||||
msgid "Add Rule"
|
||||
msgstr "Regel hinzufügen"
|
||||
|
||||
msgid "Add port to Firewall Group {{ name }}"
|
||||
msgstr "Port zur Firewallgruppe {{ name }} hinzufügen"
|
||||
|
||||
#, python-format
|
||||
msgid "Added Firewall Group\"%s\"."
|
||||
msgstr "Firewall-Gruppe \"%s\" hinzugefügt."
|
||||
|
||||
#, python-format
|
||||
msgid "Added Policy \"%s\"."
|
||||
msgstr "Richtlinie \"%s\" hinzugefügt."
|
||||
|
||||
#, python-format
|
||||
msgid "Added Rule \"%s\"."
|
||||
msgstr "Regel \"%s\" wurde hinzugefügt."
|
||||
|
||||
#, python-format
|
||||
msgid "Added the port(s) to the firewall group %s successfully."
|
||||
msgstr "Port(s) wurde(n) zur Firewall-Gruppe %s erfolgreich hinzugefügt."
|
||||
|
||||
msgid "Admin State"
|
||||
msgstr "Adminstatus"
|
||||
|
||||
msgid "Admin State Up"
|
||||
msgstr "Adminstatus aktiv"
|
||||
|
||||
msgid "After"
|
||||
msgstr "Nachher"
|
||||
|
||||
msgid "Audited"
|
||||
msgstr "Geprüft"
|
||||
|
||||
msgid "Available Ports"
|
||||
msgstr "Verfügbare Ports"
|
||||
|
||||
msgid "Available Rules"
|
||||
msgstr "Verfügbare Regeln"
|
||||
|
||||
msgid "Before"
|
||||
msgstr "Vorher"
|
||||
|
||||
msgid "Choose port(s) from Available Ports. "
|
||||
msgstr "Wählen Sie aus den verfügbaren Ports aus."
|
||||
|
||||
msgid ""
|
||||
"Choose rule(s) from Available Rules to Selected Rule by push button or drag "
|
||||
"and drop, you may change their order by drag and drop as well."
|
||||
msgstr ""
|
||||
"Wählen Sie aus den \"Verfügbaren Regeln\" Regel(n) aus, indem Sie den Knopf "
|
||||
"drücken oder mit Ziehen und Ablegen. Sie können auch die Reihenfolge mit "
|
||||
"Ziehen und Ablegen ändern."
|
||||
|
||||
msgid ""
|
||||
"Choose the rule you want to insert. Specify either the rule you want to "
|
||||
"insert immediately before, or the rule to insert immediately after. If both "
|
||||
"are specified, the prior takes precedence."
|
||||
msgstr ""
|
||||
"Wählen Sie die Regel aus, die Sie einfügen wollen. Spezifizieren Sie "
|
||||
"entweder die Regel unmittelbar vor der Sie einfügen wollen oder die Regel "
|
||||
"unmittelbar nach der Sie einfügen wollen. Wenn beide angegeben werden, hat "
|
||||
"die vorherige Vorrang. "
|
||||
|
||||
msgid "Choose the rule you want to remove."
|
||||
msgstr "Zu entfernende Richtlinie auswählen."
|
||||
|
||||
msgid "Create Firewall Group"
|
||||
msgstr "Firewall-Gruppe erstellen"
|
||||
|
||||
msgid "Create a Firewall Group with selected ports."
|
||||
msgstr "Erstellen einer Firewall-Gruppe mit den ausgewählten Ports."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall group based on a policy.\n"
|
||||
"\n"
|
||||
"A firewall group represents a logical firewall resource that a tenant can "
|
||||
"instantiate and manage. A firewall group must be associated with one policy, "
|
||||
"all other fields are optional."
|
||||
msgstr ""
|
||||
"Erzeugen einer Firewall-Gruppe auf Basis einer Richtlinie\n"
|
||||
"\n"
|
||||
"Eine Firewall-Gruppe repräsentiert eine logische Firewall-Ressource, die ein "
|
||||
"Mandant instanzieren und verwalten kann. Eine Firewall-Gruppe muss mit einer "
|
||||
"Richtlinie verbunden werden. Alle anderen Felder sind optional."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall policy with an ordered list of firewall rules.\n"
|
||||
"\n"
|
||||
"A firewall policy is an ordered collection of firewall rules. So if the "
|
||||
"traffic matches the first rule, the other rules are not executed. If the "
|
||||
"traffic does not match the current rule, then the next rule is executed. A "
|
||||
"firewall policy has the following attributes:\n"
|
||||
"\n"
|
||||
"<li>Shared: A firewall policy can be shared across tenants. Thus it can also "
|
||||
"be made part of an audit workflow wherein the firewall policy can be audited "
|
||||
"by the relevant entity that is authorized.</li><li>Audited: When audited is "
|
||||
"set to True, it indicates that the firewall policy has been audited. Each "
|
||||
"time the firewall policy or the associated firewall rules are changed, this "
|
||||
"attribute will be set to False and will have to be explicitly set to True "
|
||||
"through an update operation.</li>\n"
|
||||
"The name field is required, all others are optional."
|
||||
msgstr ""
|
||||
"Erzeugen einer Firewall-Richtlinie mit einer geordneten Liste von Regeln.\n"
|
||||
"\n"
|
||||
"Eine Firewall-Richtlinie ist eine geordnete Sammlung von Firewall-Regeln. "
|
||||
"Sobald eine Regel auf den Datenverkehr zutrifft, werden die weiteren Regeln "
|
||||
"nicht mehr ausgeführt. Solange die Regeln nicht zutreffen, werden weitere "
|
||||
"Regeln ausgeführt. Eine Firewall-Richtlinie hat die folgenden Attribute:\n"
|
||||
"\n"
|
||||
"<li>Geteilt/Shared: eine Firewall-Richtlinie kann mit mehreren Mandanten "
|
||||
"geteilt werden. Dadurch kann sie auch als Teil eines Audit-Workflows "
|
||||
"verwendet werden, um von einer berechtigten Einheit/Organisation/Person "
|
||||
"geprüft zu werden.</li><li>Auditiert/Audited: wenn dies auf wahr/true "
|
||||
"gesetzt ist, zeigt es an, dass die Richtlinie geprüft wurde. Jedes Mal, wenn "
|
||||
"eine Richtlinie oder eine der Regeln darin geändert wird, wird der Indikator "
|
||||
"wieder auf falsch/false gesetzt und muss durch eine Update-Operation "
|
||||
"explizit wieder auf wahr/true gesetzt werden.</li>\n"
|
||||
"Das Namensfeld ist erforderlich, alle anderen sind optional."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall rule.\n"
|
||||
"\n"
|
||||
"A Firewall rule is an association of the following attributes:\n"
|
||||
"\n"
|
||||
"<li>IP Addresses: The addresses from/to which the traffic filtration needs "
|
||||
"to be applied.</li><li>IP Version: The type of IP packets (IP V4/V6) that "
|
||||
"needs to be filtered.</li><li>Protocol: Type of packets (UDP, ICMP, TCP, "
|
||||
"Any) that needs to be checked.</li><li>Action: Action is the type of "
|
||||
"filtration required, it can be Reject/Deny/Allow data packets.</li>\n"
|
||||
"The protocol and action fields are required, all others are optional."
|
||||
msgstr ""
|
||||
"Firewall-Regel anlegen\n"
|
||||
"\n"
|
||||
"Eine Firewall-Regel bezieht sich auf die folgenden Attribute:\n"
|
||||
"\n"
|
||||
"<li>IP-Adresse: die Adresse, auf zu/von der der Datenverkehr gefiltert wird."
|
||||
"</li><li>IP-Version: der IP Pakettyp (IPV4/6) der gefiltert wird.</"
|
||||
"li><li>Protokoll: der Pakettyp (UDP, ICMP, TCP, Any) der kontrolliert wird.</"
|
||||
"li><li>Aktion: die vorhergesehene Filteraktion, möglich ist Abweisen/"
|
||||
"Verweigern/Erlauben für Datenpakete.</li>\n"
|
||||
"Die Protokoll- und Aktionsfelder sind erforderlich, andere optional."
|
||||
|
||||
msgid "Create a policy with selected rules."
|
||||
msgstr "Richtlinie mit ausgewählten Regeln erstellen."
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Created"
|
||||
msgstr "Erstellt"
|
||||
|
||||
msgid "DENY"
|
||||
msgstr "Verweigern"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "DENY"
|
||||
msgstr "Verweigern"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "DOWN"
|
||||
msgstr "INAKTIV"
|
||||
|
||||
msgid "Delete Firewall Group"
|
||||
msgid_plural "Delete Firewall Groups"
|
||||
msgstr[0] "Firewall-Gruppe löschen"
|
||||
msgstr[1] "Firewall-Gruppen löschen"
|
||||
|
||||
msgid "Delete Policy"
|
||||
msgid_plural "Delete Policies"
|
||||
msgstr[0] "Richtlinie löschen"
|
||||
msgstr[1] "Richtlinien löschen"
|
||||
|
||||
msgid "Delete Rule"
|
||||
msgid_plural "Delete Rules"
|
||||
msgstr[0] "Regel löschen"
|
||||
msgstr[1] "Regeln löschen"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr "Beschreibung:"
|
||||
|
||||
msgid "Destination IP"
|
||||
msgstr "Ziel-IP"
|
||||
|
||||
msgid "Destination IP Address"
|
||||
msgstr "Ziel-IP-Adresse"
|
||||
|
||||
msgid "Destination IP Address/Subnet"
|
||||
msgstr "Ziel-IP-Adresse oder Subnetz"
|
||||
|
||||
msgid "Destination IP address or subnet"
|
||||
msgstr "Ziel-IP-Adresse oder Subnetz"
|
||||
|
||||
msgid "Destination Port"
|
||||
msgstr "Ziel-Port"
|
||||
|
||||
msgid "Destination Port/Port Range"
|
||||
msgstr "Ziel-Port/-Portbereich"
|
||||
|
||||
msgid "Destination port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr "Ziel-Port (Ganzzahl aus [1, 65535] oder Bereich als a:b)"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Down"
|
||||
msgstr "Inaktiv"
|
||||
|
||||
msgid "Edit Firewall Group"
|
||||
msgstr "Firewall-Gruppe bearbeiten"
|
||||
|
||||
msgid "Edit FirewallGroup {{ name }}"
|
||||
msgstr "Firewall-Gruppe bearbeiten {{ name }}"
|
||||
|
||||
msgid "Edit Policy"
|
||||
msgstr "Richtlinie bearbeiten"
|
||||
|
||||
msgid "Edit Policy {{ name }}"
|
||||
msgstr "Richtlinie bearbeiten {{ name }}"
|
||||
|
||||
msgid "Edit Rule"
|
||||
msgstr "Regel bearbeiten"
|
||||
|
||||
msgid "Edit Rule {{ name }}"
|
||||
msgstr "Regel bearbeiten {{ name }}"
|
||||
|
||||
msgid "Egress Policy"
|
||||
msgstr "Austrittsrichtlinie"
|
||||
|
||||
msgid "Egress Policy ID"
|
||||
msgstr "Ausgang Richtlinien-ID"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "Aktiviert"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Error"
|
||||
msgstr "Fehler"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to add the port(s) to the firewall group %(name)s: %(reason)s"
|
||||
msgstr ""
|
||||
"Port konnte zur der Firewallgruppe %(name)s nicht hinzugefügt werden: "
|
||||
"%(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to insert rule to policy %(name)s: %(reason)s"
|
||||
msgstr "Regel konnte nicht eingefügt werden in Richtlinie %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to remove rule from policy %(name)s: %(reason)s"
|
||||
msgstr "Entfernen der Regel von Richtlinie %(name)s fehlgeschlagen: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Failed to remove the port(s) from the firewall group %(name)s: %(reason)s"
|
||||
msgstr ""
|
||||
"Port konnte von der Firewallgruppe %(name)s nicht entfernt werden: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve available rules: %s"
|
||||
msgstr "Verfügbare Regeln konnten nicht abgerufen werden: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve current rules in policy %(name)s: %(reason)s"
|
||||
msgstr ""
|
||||
"Aktuelle Regeln in Richtline %(name)s konnten nicht abgerufen werden: "
|
||||
"%(reason)s"
|
||||
|
||||
msgid "Failed to retrieve port list of the firewall group."
|
||||
msgstr "Abruf der Portliste der Firewall-Gruppe ist fehlgeschlagen."
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update firewall group %(name)s: %(reason)s"
|
||||
msgstr "Firewallgruppe %(name)s konnte nicht aktualisiert werden: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update policy %(name)s: %(reason)s"
|
||||
msgstr "Fehler beim Aktualisieren der Richtlinie %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update rule %(name)s: %(reason)s"
|
||||
msgstr "Regel %(name)s konnte nicht aktualisiert werden: %(reason)s"
|
||||
|
||||
msgid "Firewall Groups"
|
||||
msgstr "Firewall-Gruppe"
|
||||
|
||||
msgid "Firewall Policies"
|
||||
msgstr "Firewallrichtlinien"
|
||||
|
||||
msgid "Firewall Rules"
|
||||
msgstr "Firewallregeln"
|
||||
|
||||
#, python-format
|
||||
msgid "Firewall group %s was successfully updated."
|
||||
msgstr "Firewallgruppe %s wurde erfolgreich aktualisiert."
|
||||
|
||||
msgid "FirewallGroup"
|
||||
msgstr "Firewall-Gruppe"
|
||||
|
||||
msgid "ICMP"
|
||||
msgstr "ICMP"
|
||||
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
msgid "IP Version"
|
||||
msgstr "IP Version"
|
||||
|
||||
msgid "IP Version for Firewall Rule"
|
||||
msgstr "IP-Version der Firewall-Regel"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Inactive"
|
||||
msgstr "Inaktiv"
|
||||
|
||||
msgid "Ingress Policy"
|
||||
msgstr "Eingangsrichtlinie"
|
||||
|
||||
msgid "Ingress Policy ID"
|
||||
msgstr "Eingang Richtlinien-ID"
|
||||
|
||||
msgid "Insert Rule"
|
||||
msgstr "Regel einfügen"
|
||||
|
||||
msgid "Insert Rule to Policy"
|
||||
msgstr "Regel in Richtlinie hinzufügen"
|
||||
|
||||
msgid "Label"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
msgid "No options available"
|
||||
msgstr "Keine Optionen verfügbar"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Create"
|
||||
msgstr "Geplante Erstellung"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Delete"
|
||||
msgstr "Geplante Löschung"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Update"
|
||||
msgstr "Geplante Aktualisierung"
|
||||
|
||||
msgid "Policies"
|
||||
msgstr "Richtlinien"
|
||||
|
||||
msgid "Policy"
|
||||
msgstr "Richtlinie"
|
||||
|
||||
#, python-format
|
||||
msgid "Policy %s was successfully updated."
|
||||
msgstr "Richtlinie %s wurde wurde erfolgreich aktualisiert."
|
||||
|
||||
msgid "Ports"
|
||||
msgstr "Ports"
|
||||
|
||||
msgid "Project ID"
|
||||
msgstr "Projekt-ID"
|
||||
|
||||
msgid "Protocol"
|
||||
msgstr "Protokoll"
|
||||
|
||||
msgid "Protocol for the firewall rule"
|
||||
msgstr "Protokoll für die Firewallregel"
|
||||
|
||||
msgid "REJECT"
|
||||
msgstr "Abweisen"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "REJECT"
|
||||
msgstr "Abweisen"
|
||||
|
||||
msgid "Remove Port"
|
||||
msgstr "Port entfernen"
|
||||
|
||||
msgid "Remove Port from Firewall Group"
|
||||
msgstr "Port von der Firewallgruppe entfernen"
|
||||
|
||||
msgid "Remove Rule"
|
||||
msgstr "Regel entfernen"
|
||||
|
||||
msgid "Remove Rule from Policy"
|
||||
msgstr "Regel aus Richtlinie entfernen"
|
||||
|
||||
msgid "Remove port from FirewallGroup {{ name }}"
|
||||
msgstr "Port aus Firewall-Gruppe entfernen {{ name }}"
|
||||
|
||||
#, python-format
|
||||
msgid "Removed the port(s) from the firewall group %s successfully."
|
||||
msgstr "Port(s) wurde(n) von der Firewall-Gruppe %s erfolgreich entfernt."
|
||||
|
||||
msgid "Rule"
|
||||
msgstr "Regel"
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully inserted to policy %(policy)s."
|
||||
msgstr "Regel %(rule)s wurde erfolgreich in Richtlinie %(policy)s eingefügt ."
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully removed from policy %(policy)s."
|
||||
msgstr "Regel %(rule)s wurde erfolgreich aus Richtlinie %(policy)s entfernt."
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %s was successfully updated."
|
||||
msgstr "Regel %s wurde erfolgreich aktualisiert."
|
||||
|
||||
msgid "Rules"
|
||||
msgstr "Regeln"
|
||||
|
||||
msgid "Save Changes"
|
||||
msgstr "Änderungen speichern"
|
||||
|
||||
msgid "Scheduled deletion of Firewall Group"
|
||||
msgid_plural "Scheduled deletion of Firewall Groups"
|
||||
msgstr[0] "Geplante Löschung der Firewall-Gruppe"
|
||||
msgstr[1] "Geplante Löschung der Firewall-Gruppen"
|
||||
|
||||
msgid "Scheduled deletion of Policy"
|
||||
msgid_plural "Scheduled deletion of Policies"
|
||||
msgstr[0] "Geplante Löschung der Richtlinie"
|
||||
msgstr[1] "Geplante Löschung von Richtlinien"
|
||||
|
||||
msgid "Scheduled deletion of Rule"
|
||||
msgid_plural "Scheduled deletion of Rules"
|
||||
msgstr[0] "Geplante Löschung der Regel"
|
||||
msgstr[1] "Geplante Löschung von Regeln"
|
||||
|
||||
msgid "Select a Policy"
|
||||
msgstr "Richtlinie auswählen"
|
||||
|
||||
msgid "Select ports for your firewall group."
|
||||
msgstr "Wählen Sie Ports für Ihre Firewall-Gruppe."
|
||||
|
||||
msgid "Select rules for your policy."
|
||||
msgstr "Regeln für Richtlinie auswählen."
|
||||
|
||||
msgid "Selected Ports"
|
||||
msgstr "Ausgewählte Ports"
|
||||
|
||||
msgid "Selected Rules"
|
||||
msgstr "Ausgewählte Regeln"
|
||||
|
||||
msgid "Shared"
|
||||
msgstr "Geteilt"
|
||||
|
||||
msgid "Source IP"
|
||||
msgstr "Quell-IP"
|
||||
|
||||
msgid "Source IP Address"
|
||||
msgstr "Quell-IP-Adresse"
|
||||
|
||||
msgid "Source IP Address/Subnet"
|
||||
msgstr "Quell-IP-Adresse oder Subnetz"
|
||||
|
||||
msgid "Source IP address or subnet"
|
||||
msgstr "Quell-IP-Adresse oder Subnetz"
|
||||
|
||||
msgid "Source Port"
|
||||
msgstr "Quell-Port"
|
||||
|
||||
msgid "Source Port/Port Range"
|
||||
msgstr "Quell-Port/-Portbereich"
|
||||
|
||||
msgid "Source port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr "Quell-Port (Ganzzahl aus [1, 65535] oder Bereich als a:b)"
|
||||
|
||||
msgid ""
|
||||
"Source/Destination Network Address and IP version are inconsistent. Please "
|
||||
"make them consistent."
|
||||
msgstr ""
|
||||
"Quelle/Ziel Netzwekadresse und IP-Version sind nicht konsistent. Bitte "
|
||||
"ändern Sie dies."
|
||||
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
msgid "TCP"
|
||||
msgstr "TCP"
|
||||
|
||||
msgid "UDP"
|
||||
msgstr "UDP"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "UP"
|
||||
msgstr "AKTIV"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Firewall Group \"%s\"."
|
||||
msgstr "Firewall-Gruppe \"%s\" konnte nicht hinzugefügt werden."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Policy \"%s\"."
|
||||
msgstr "Richtlinie \"%s\" konnte nicht hinzugefügt werden."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Rule \"%s\"."
|
||||
msgstr "Regel \"%s\" kann nicht hinzugefügt werden"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete firewall group. %s"
|
||||
msgstr "Firewall-Gruppe kann nicht gelöscht werden: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete policy. %s"
|
||||
msgstr "Richtlinie %s konnte nicht gelöscht werden."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete rule. %s"
|
||||
msgstr "Regel %s kann nicht gelöscht werden."
|
||||
|
||||
msgid "Unable to retrieve firewall group details."
|
||||
msgstr "Firewall-Gruppendetails können nicht abgerufen werden."
|
||||
|
||||
msgid "Unable to retrieve firewall group list."
|
||||
msgstr "Firewall-Gruppenliste kann nicht abgerufen werden."
|
||||
|
||||
msgid "Unable to retrieve firewallgroup details."
|
||||
msgstr "Konnte Firewall-Gruppendetails nicht abrufen."
|
||||
|
||||
msgid "Unable to retrieve policies list."
|
||||
msgstr "Liste der Richtlinien kann nicht abgerufen werden."
|
||||
|
||||
msgid "Unable to retrieve policy details."
|
||||
msgstr "Richtliniendetails können nicht abgerufen werden."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve policy list (%s)."
|
||||
msgstr "Richtlinienliste kann nicht abgerufen werden (%s)."
|
||||
|
||||
msgid "Unable to retrieve policy list."
|
||||
msgstr "Liste der Richtlinien kann nicht abgerufen werden."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve ports (%s)."
|
||||
msgstr "Ports können nicht abgerufen werden (%s)."
|
||||
|
||||
msgid "Unable to retrieve rule details."
|
||||
msgstr "Details der Regeln können nicht abgerufen werden. "
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve rules (%s)."
|
||||
msgstr "Regeln können nicht abgerufen werden (%s)."
|
||||
|
||||
msgid "Unable to retrieve rules list."
|
||||
msgstr "Liste der Regeln kann nicht abgerufen werden."
|
||||
|
||||
msgid "Value"
|
||||
msgstr "Wert"
|
||||
|
||||
msgid "You may add ports to firewall group here."
|
||||
msgstr "Hier können Sie Ports zur Firewallgruppe hinzufügen."
|
||||
|
||||
msgid "You may remove ports from firewall group here."
|
||||
msgstr "Hier können Sie Ports von der Firewallgruppe entfernen."
|
||||
|
||||
msgid "You may update firewall group details here."
|
||||
msgstr "Hier können Sie die Firewallgruppendetails bearbeiten."
|
||||
|
||||
msgid ""
|
||||
"You may update policy details here. Use 'Insert Rule' or 'Remove Rule' links "
|
||||
"instead to insert or remove a rule."
|
||||
msgstr ""
|
||||
"Hier können Sie Richtliniendetails aktualisieren. Wählen Sie die "
|
||||
"Verknüpfungen 'Regel einfügen' oder 'Regel entfernen', um eine Regel "
|
||||
"einzufügen oder zu entfernen."
|
||||
|
||||
msgid "You may update rule details here."
|
||||
msgstr "Hier können Sie die Details der Regeln aktualisieren."
|
633
neutron_fwaas_dashboard/locale/en_GB/LC_MESSAGES/django.po
Normal file
633
neutron_fwaas_dashboard/locale/en_GB/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,633 @@
|
||||
# Andi Chandler <andi@gowling.com>, 2017. #zanata
|
||||
# Andi Chandler <andi@gowling.com>, 2018. #zanata
|
||||
# Andi Chandler <andi@gowling.com>, 2019. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: neutron-fwaas-dashboard VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2019-02-19 16:16+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-01-26 03:30+0000\n"
|
||||
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
|
||||
"Language-Team: English (United Kingdom)\n"
|
||||
"Language: en_GB\n"
|
||||
"X-Generator: Zanata 4.3.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
msgid "-"
|
||||
msgstr "-"
|
||||
|
||||
msgid "ALLOW"
|
||||
msgstr "ALLOW"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "ALLOW"
|
||||
msgstr "ALLOW"
|
||||
|
||||
msgid "ANY"
|
||||
msgstr "ANY"
|
||||
|
||||
msgid "Action"
|
||||
msgstr "Action"
|
||||
|
||||
msgid "Action for the firewall rule"
|
||||
msgstr "Action for the firewall rule"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Active"
|
||||
msgstr "Active"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "Add"
|
||||
|
||||
msgid "Add Firewall Group"
|
||||
msgstr "Add Firewall Group"
|
||||
|
||||
msgid "Add New Firewall Group"
|
||||
msgstr "Add New Firewall Group"
|
||||
|
||||
msgid "Add New Policy"
|
||||
msgstr "Add New Policy"
|
||||
|
||||
msgid "Add New Rule"
|
||||
msgstr "Add New Rule"
|
||||
|
||||
msgid "Add Policy"
|
||||
msgstr "Add Policy"
|
||||
|
||||
msgid "Add Port"
|
||||
msgstr "Add Port"
|
||||
|
||||
msgid "Add Port to Firewall Group"
|
||||
msgstr "Add Port to Firewall Group"
|
||||
|
||||
msgid "Add Rule"
|
||||
msgstr "Add Rule"
|
||||
|
||||
msgid "Add port to Firewall Group {{ name }}"
|
||||
msgstr "Add port to Firewall Group {{ name }}"
|
||||
|
||||
#, python-format
|
||||
msgid "Added Firewall Group\"%s\"."
|
||||
msgstr "Added Firewall Group\"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Added Policy \"%s\"."
|
||||
msgstr "Added Policy \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Added Rule \"%s\"."
|
||||
msgstr "Added Rule \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Added the port(s) to the firewall group %s successfully."
|
||||
msgstr "Added the port(s) to the firewall group %s successfully."
|
||||
|
||||
msgid "Admin State"
|
||||
msgstr "Admin State"
|
||||
|
||||
msgid "Admin State Up"
|
||||
msgstr "Admin State Up"
|
||||
|
||||
msgid "After"
|
||||
msgstr "After"
|
||||
|
||||
msgid "Audited"
|
||||
msgstr "Audited"
|
||||
|
||||
msgid "Available Ports"
|
||||
msgstr "Available Ports"
|
||||
|
||||
msgid "Available Rules"
|
||||
msgstr "Available Rules"
|
||||
|
||||
msgid "Before"
|
||||
msgstr "Before"
|
||||
|
||||
msgid "Choose port(s) from Available Ports. "
|
||||
msgstr "Choose port(s) from Available Ports. "
|
||||
|
||||
msgid ""
|
||||
"Choose rule(s) from Available Rules to Selected Rule by push button or drag "
|
||||
"and drop, you may change their order by drag and drop as well."
|
||||
msgstr ""
|
||||
"Choose rule(s) from Available Rules to Selected Rule by push button or drag "
|
||||
"and drop, you may change their order by drag and drop as well."
|
||||
|
||||
msgid ""
|
||||
"Choose the rule you want to insert. Specify either the rule you want to "
|
||||
"insert immediately before, or the rule to insert immediately after. If both "
|
||||
"are specified, the prior takes precedence."
|
||||
msgstr ""
|
||||
"Choose the rule you want to insert. Specify either the rule you want to "
|
||||
"insert immediately before, or the rule to insert immediately after. If both "
|
||||
"are specified, the prior takes precedence."
|
||||
|
||||
msgid "Choose the rule you want to remove."
|
||||
msgstr "Choose the rule you want to remove."
|
||||
|
||||
msgid "Create Firewall Group"
|
||||
msgstr "Create Firewall Group"
|
||||
|
||||
msgid "Create a Firewall Group with selected ports."
|
||||
msgstr "Create a Firewall Group with selected ports."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall group based on a policy.\n"
|
||||
"\n"
|
||||
"A firewall group represents a logical firewall resource that a tenant can "
|
||||
"instantiate and manage. A firewall group must be associated with one policy, "
|
||||
"all other fields are optional."
|
||||
msgstr ""
|
||||
"Create a firewall group based on a policy.\n"
|
||||
"\n"
|
||||
"A firewall group represents a logical firewall resource that a tenant can "
|
||||
"instantiate and manage. A firewall group must be associated with one policy, "
|
||||
"all other fields are optional."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall policy with an ordered list of firewall rules.\n"
|
||||
"\n"
|
||||
"A firewall policy is an ordered collection of firewall rules. So if the "
|
||||
"traffic matches the first rule, the other rules are not executed. If the "
|
||||
"traffic does not match the current rule, then the next rule is executed. A "
|
||||
"firewall policy has the following attributes:\n"
|
||||
"\n"
|
||||
"<li>Shared: A firewall policy can be shared across tenants. Thus it can also "
|
||||
"be made part of an audit workflow wherein the firewall policy can be audited "
|
||||
"by the relevant entity that is authorized.</li><li>Audited: When audited is "
|
||||
"set to True, it indicates that the firewall policy has been audited. Each "
|
||||
"time the firewall policy or the associated firewall rules are changed, this "
|
||||
"attribute will be set to False and will have to be explicitly set to True "
|
||||
"through an update operation.</li>\n"
|
||||
"The name field is required, all others are optional."
|
||||
msgstr ""
|
||||
"Create a firewall policy with an ordered list of firewall rules.\n"
|
||||
"\n"
|
||||
"A firewall policy is an ordered collection of firewall rules. So if the "
|
||||
"traffic matches the first rule, the other rules are not executed. If the "
|
||||
"traffic does not match the current rule, then the next rule is executed. A "
|
||||
"firewall policy has the following attributes:\n"
|
||||
"\n"
|
||||
"<li>Shared: A firewall policy can be shared across tenants. Thus it can also "
|
||||
"be made part of an audit workflow wherein the firewall policy can be audited "
|
||||
"by the relevant entity that is authorized.</li><li>Audited: When audited is "
|
||||
"set to True, it indicates that the firewall policy has been audited. Each "
|
||||
"time the firewall policy or the associated firewall rules are changed, this "
|
||||
"attribute will be set to False and will have to be explicitly set to True "
|
||||
"through an update operation.</li>\n"
|
||||
"The name field is required, all others are optional."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall rule.\n"
|
||||
"\n"
|
||||
"A Firewall rule is an association of the following attributes:\n"
|
||||
"\n"
|
||||
"<li>IP Addresses: The addresses from/to which the traffic filtration needs "
|
||||
"to be applied.</li><li>IP Version: The type of IP packets (IP V4/V6) that "
|
||||
"needs to be filtered.</li><li>Protocol: Type of packets (UDP, ICMP, TCP, "
|
||||
"Any) that needs to be checked.</li><li>Action: Action is the type of "
|
||||
"filtration required, it can be Reject/Deny/Allow data packets.</li>\n"
|
||||
"The protocol and action fields are required, all others are optional."
|
||||
msgstr ""
|
||||
"Create a firewall rule.\n"
|
||||
"\n"
|
||||
"A Firewall rule is an association of the following attributes:\n"
|
||||
"\n"
|
||||
"<li>IP Addresses: The addresses from/to which the traffic filtration needs "
|
||||
"to be applied.</li><li>IP Version: The type of IP packets (IP V4/V6) that "
|
||||
"needs to be filtered.</li><li>Protocol: Type of packets (UDP, ICMP, TCP, "
|
||||
"Any) that needs to be checked.</li><li>Action: Action is the type of "
|
||||
"filtration required, it can be Reject/Deny/Allow data packets.</li>\n"
|
||||
"The protocol and action fields are required, all others are optional."
|
||||
|
||||
msgid "Create a policy with selected rules."
|
||||
msgstr "Create a policy with selected rules."
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Created"
|
||||
msgstr "Created"
|
||||
|
||||
msgid "DENY"
|
||||
msgstr "DENY"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "DENY"
|
||||
msgstr "DENY"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "DOWN"
|
||||
msgstr "DOWN"
|
||||
|
||||
msgid "Delete Firewall Group"
|
||||
msgid_plural "Delete Firewall Groups"
|
||||
msgstr[0] "Delete Firewall Group"
|
||||
msgstr[1] "Delete Firewall Groups"
|
||||
|
||||
msgid "Delete Policy"
|
||||
msgid_plural "Delete Policies"
|
||||
msgstr[0] "Delete Policy"
|
||||
msgstr[1] "Delete Policies"
|
||||
|
||||
msgid "Delete Rule"
|
||||
msgid_plural "Delete Rules"
|
||||
msgstr[0] "Delete Rule"
|
||||
msgstr[1] "Delete Rules"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr "Description:"
|
||||
|
||||
msgid "Destination IP"
|
||||
msgstr "Destination IP"
|
||||
|
||||
msgid "Destination IP Address"
|
||||
msgstr "Destination IP Address"
|
||||
|
||||
msgid "Destination IP Address/Subnet"
|
||||
msgstr "Destination IP Address/Subnet"
|
||||
|
||||
msgid "Destination IP address or subnet"
|
||||
msgstr "Destination IP address or subnet"
|
||||
|
||||
msgid "Destination Port"
|
||||
msgstr "Destination Port"
|
||||
|
||||
msgid "Destination Port/Port Range"
|
||||
msgstr "Destination Port/Port Range"
|
||||
|
||||
msgid "Destination port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr "Destination port (integer in [1, 65535] or range in a:b)"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Down"
|
||||
msgstr "Down"
|
||||
|
||||
msgid "Edit Firewall Group"
|
||||
msgstr "Edit Firewall Group"
|
||||
|
||||
msgid "Edit FirewallGroup {{ name }}"
|
||||
msgstr "Edit FirewallGroup {{ name }}"
|
||||
|
||||
msgid "Edit Policy"
|
||||
msgstr "Edit Policy"
|
||||
|
||||
msgid "Edit Policy {{ name }}"
|
||||
msgstr "Edit Policy {{ name }}"
|
||||
|
||||
msgid "Edit Rule"
|
||||
msgstr "Edit Rule"
|
||||
|
||||
msgid "Edit Rule {{ name }}"
|
||||
msgstr "Edit Rule {{ name }}"
|
||||
|
||||
msgid "Egress Policy"
|
||||
msgstr "Egress Policy"
|
||||
|
||||
msgid "Egress Policy ID"
|
||||
msgstr "Egress Policy ID"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "Enabled"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to add the port(s) to the firewall group %(name)s: %(reason)s"
|
||||
msgstr "Failed to add the port(s) to the firewall group %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to insert rule to policy %(name)s: %(reason)s"
|
||||
msgstr "Failed to insert rule to policy %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to remove rule from policy %(name)s: %(reason)s"
|
||||
msgstr "Failed to remove rule from policy %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Failed to remove the port(s) from the firewall group %(name)s: %(reason)s"
|
||||
msgstr ""
|
||||
"Failed to remove the port(s) from the firewall group %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve available rules: %s"
|
||||
msgstr "Failed to retrieve available rules: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve current rules in policy %(name)s: %(reason)s"
|
||||
msgstr "Failed to retrieve current rules in policy %(name)s: %(reason)s"
|
||||
|
||||
msgid "Failed to retrieve port list of the firewall group."
|
||||
msgstr "Failed to retrieve port list of the firewall group."
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update firewall group %(name)s: %(reason)s"
|
||||
msgstr "Failed to update firewall group %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update policy %(name)s: %(reason)s"
|
||||
msgstr "Failed to update policy %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update rule %(name)s: %(reason)s"
|
||||
msgstr "Failed to update rule %(name)s: %(reason)s"
|
||||
|
||||
msgid "Firewall Groups"
|
||||
msgstr "Firewall Groups"
|
||||
|
||||
msgid "Firewall Policies"
|
||||
msgstr "Firewall Policies"
|
||||
|
||||
msgid "Firewall Rules"
|
||||
msgstr "Firewall Rules"
|
||||
|
||||
#, python-format
|
||||
msgid "Firewall group %s was successfully updated."
|
||||
msgstr "Firewall group %s was successfully updated."
|
||||
|
||||
msgid "FirewallGroup"
|
||||
msgstr "FirewallGroup"
|
||||
|
||||
msgid "ICMP"
|
||||
msgstr "ICMP"
|
||||
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
msgid "IP Version"
|
||||
msgstr "IP Version"
|
||||
|
||||
msgid "IP Version for Firewall Rule"
|
||||
msgstr "IP Version for Firewall Rule"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Inactive"
|
||||
msgstr "Inactive"
|
||||
|
||||
msgid "Ingress Policy"
|
||||
msgstr "Ingress Policy"
|
||||
|
||||
msgid "Ingress Policy ID"
|
||||
msgstr "Ingress Policy ID"
|
||||
|
||||
msgid "Insert Rule"
|
||||
msgstr "Insert Rule"
|
||||
|
||||
msgid "Insert Rule to Policy"
|
||||
msgstr "Insert Rule to Policy"
|
||||
|
||||
msgid "Label"
|
||||
msgstr "Label"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
msgid "No options available"
|
||||
msgstr "No options available"
|
||||
|
||||
msgid "None"
|
||||
msgstr "None"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Create"
|
||||
msgstr "Pending Create"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Delete"
|
||||
msgstr "Pending Delete"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Update"
|
||||
msgstr "Pending Update"
|
||||
|
||||
msgid "Policies"
|
||||
msgstr "Policies"
|
||||
|
||||
msgid "Policy"
|
||||
msgstr "Policy"
|
||||
|
||||
#, python-format
|
||||
msgid "Policy %s was successfully updated."
|
||||
msgstr "Policy %s was successfully updated."
|
||||
|
||||
msgid "Ports"
|
||||
msgstr "Ports"
|
||||
|
||||
msgid "Project ID"
|
||||
msgstr "Project ID"
|
||||
|
||||
msgid "Protocol"
|
||||
msgstr "Protocol"
|
||||
|
||||
msgid "Protocol for the firewall rule"
|
||||
msgstr "Protocol for the firewall rule"
|
||||
|
||||
msgid "REJECT"
|
||||
msgstr "REJECT"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "REJECT"
|
||||
msgstr "REJECT"
|
||||
|
||||
msgid "Remove Port"
|
||||
msgstr "Remove Port"
|
||||
|
||||
msgid "Remove Port from Firewall Group"
|
||||
msgstr "Remove Port from Firewall Group"
|
||||
|
||||
msgid "Remove Rule"
|
||||
msgstr "Remove Rule"
|
||||
|
||||
msgid "Remove Rule from Policy"
|
||||
msgstr "Remove Rule from Policy"
|
||||
|
||||
msgid "Remove port from FirewallGroup {{ name }}"
|
||||
msgstr "Remove port from FirewallGroup {{ name }}"
|
||||
|
||||
#, python-format
|
||||
msgid "Removed the port(s) from the firewall group %s successfully."
|
||||
msgstr "Removed the port(s) from the firewall group %s successfully."
|
||||
|
||||
msgid "Rule"
|
||||
msgstr "Rule"
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully inserted to policy %(policy)s."
|
||||
msgstr "Rule %(rule)s was successfully inserted to policy %(policy)s."
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully removed from policy %(policy)s."
|
||||
msgstr "Rule %(rule)s was successfully removed from policy %(policy)s."
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %s was successfully updated."
|
||||
msgstr "Rule %s was successfully updated."
|
||||
|
||||
msgid "Rules"
|
||||
msgstr "Rules"
|
||||
|
||||
msgid "Save Changes"
|
||||
msgstr "Save Changes"
|
||||
|
||||
msgid "Scheduled deletion of Firewall Group"
|
||||
msgid_plural "Scheduled deletion of Firewall Groups"
|
||||
msgstr[0] "Scheduled deletion of Firewall Group"
|
||||
msgstr[1] "Scheduled deletion of Firewall Groups"
|
||||
|
||||
msgid "Scheduled deletion of Policy"
|
||||
msgid_plural "Scheduled deletion of Policies"
|
||||
msgstr[0] "Scheduled deletion of Policy"
|
||||
msgstr[1] "Scheduled deletion of Policies"
|
||||
|
||||
msgid "Scheduled deletion of Rule"
|
||||
msgid_plural "Scheduled deletion of Rules"
|
||||
msgstr[0] "Scheduled deletion of Rule"
|
||||
msgstr[1] "Scheduled deletion of Rules"
|
||||
|
||||
msgid "Select a Policy"
|
||||
msgstr "Select a Policy"
|
||||
|
||||
msgid "Select ports for your firewall group."
|
||||
msgstr "Select ports for your firewall group."
|
||||
|
||||
msgid "Select rules for your policy."
|
||||
msgstr "Select rules for your policy."
|
||||
|
||||
msgid "Selected Ports"
|
||||
msgstr "Selected Ports"
|
||||
|
||||
msgid "Selected Rules"
|
||||
msgstr "Selected Rules"
|
||||
|
||||
msgid "Shared"
|
||||
msgstr "Shared"
|
||||
|
||||
msgid "Source IP"
|
||||
msgstr "Source IP"
|
||||
|
||||
msgid "Source IP Address"
|
||||
msgstr "Source IP Address"
|
||||
|
||||
msgid "Source IP Address/Subnet"
|
||||
msgstr "Source IP Address/Subnet"
|
||||
|
||||
msgid "Source IP address or subnet"
|
||||
msgstr "Source IP address or subnet"
|
||||
|
||||
msgid "Source Port"
|
||||
msgstr "Source Port"
|
||||
|
||||
msgid "Source Port/Port Range"
|
||||
msgstr "Source Port/Port Range"
|
||||
|
||||
msgid "Source port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr "Source port (integer in [1, 65535] or range in a:b)"
|
||||
|
||||
msgid ""
|
||||
"Source/Destination Network Address and IP version are inconsistent. Please "
|
||||
"make them consistent."
|
||||
msgstr ""
|
||||
"Source/Destination Network Address and IP version are inconsistent. Please "
|
||||
"make them consistent."
|
||||
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
msgid "TCP"
|
||||
msgstr "TCP"
|
||||
|
||||
msgid "UDP"
|
||||
msgstr "UDP"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "UP"
|
||||
msgstr "UP"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Firewall Group \"%s\"."
|
||||
msgstr "Unable to add Firewall Group \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Policy \"%s\"."
|
||||
msgstr "Unable to add Policy \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Rule \"%s\"."
|
||||
msgstr "Unable to add Rule \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete firewall group. %s"
|
||||
msgstr "Unable to delete firewall group. %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete policy. %s"
|
||||
msgstr "Unable to delete policy. %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete rule. %s"
|
||||
msgstr "Unable to delete rule. %s"
|
||||
|
||||
msgid "Unable to retrieve firewall group details."
|
||||
msgstr "Unable to retrieve firewall group details."
|
||||
|
||||
msgid "Unable to retrieve firewall group list."
|
||||
msgstr "Unable to retrieve firewall group list."
|
||||
|
||||
msgid "Unable to retrieve firewallgroup details."
|
||||
msgstr "Unable to retrieve Firewallgroup details."
|
||||
|
||||
msgid "Unable to retrieve policies list."
|
||||
msgstr "Unable to retrieve policies list."
|
||||
|
||||
msgid "Unable to retrieve policy details."
|
||||
msgstr "Unable to retrieve policy details."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve policy list (%s)."
|
||||
msgstr "Unable to retrieve policy list (%s)."
|
||||
|
||||
msgid "Unable to retrieve policy list."
|
||||
msgstr "Unable to retrieve policy list."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve ports (%s)."
|
||||
msgstr "Unable to retrieve ports (%s)."
|
||||
|
||||
msgid "Unable to retrieve rule details."
|
||||
msgstr "Unable to retrieve rule details."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve rules (%s)."
|
||||
msgstr "Unable to retrieve rules (%s)."
|
||||
|
||||
msgid "Unable to retrieve rules list."
|
||||
msgstr "Unable to retrieve rules list."
|
||||
|
||||
msgid "Value"
|
||||
msgstr "Value"
|
||||
|
||||
msgid "You may add ports to firewall group here."
|
||||
msgstr "You may add ports to firewall group here."
|
||||
|
||||
msgid "You may remove ports from firewall group here."
|
||||
msgstr "You may remove ports from firewall group here."
|
||||
|
||||
msgid "You may update firewall group details here."
|
||||
msgstr "You may update firewall group details here."
|
||||
|
||||
msgid ""
|
||||
"You may update policy details here. Use 'Insert Rule' or 'Remove Rule' links "
|
||||
"instead to insert or remove a rule."
|
||||
msgstr ""
|
||||
"You may update policy details here. Use 'Insert Rule' or 'Remove Rule' links "
|
||||
"instead to insert or remove a rule."
|
||||
|
||||
msgid "You may update rule details here."
|
||||
msgstr "You may update rule details here."
|
501
neutron_fwaas_dashboard/locale/fr/LC_MESSAGES/django.po
Normal file
501
neutron_fwaas_dashboard/locale/fr/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,501 @@
|
||||
# Adrien Cunin <adrien@adriencunin.fr>, 2016. #zanata
|
||||
# Gérald LONLAS <g.lonlas@gmail.com>, 2016. #zanata
|
||||
# Sylvie Chesneau <sissicdf@fr.ibm.com>, 2016. #zanata
|
||||
# Cédric Savignan <liced@liced.fr>, 2017. #zanata
|
||||
# JF Taltavull <jftalta@gmail.com>, 2017. #zanata
|
||||
# Loic Nicolle <loic.nicolle@orange.com>, 2017. #zanata
|
||||
# Pascal Larivée <pascal@larivee.photo>, 2017. #zanata
|
||||
# Loic Nicolle <loic.nicolle@orange.com>, 2018. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: neutron-fwaas-dashboard VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2019-02-19 16:16+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2018-03-27 03:09+0000\n"
|
||||
"Last-Translator: Loic Nicolle <loic.nicolle@orange.com>\n"
|
||||
"Language-Team: French\n"
|
||||
"Language: fr\n"
|
||||
"X-Generator: Zanata 4.3.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
|
||||
|
||||
msgid "-"
|
||||
msgstr "-"
|
||||
|
||||
msgid "ALLOW"
|
||||
msgstr "AUTORISER"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "ALLOW"
|
||||
msgstr "AUTORISER"
|
||||
|
||||
msgid "ANY"
|
||||
msgstr "TOUT"
|
||||
|
||||
msgid "Action"
|
||||
msgstr "Action"
|
||||
|
||||
msgid "Action for the firewall rule"
|
||||
msgstr "Action pour la règle de pare-feu"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Active"
|
||||
msgstr "Actif"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "Ajouter"
|
||||
|
||||
msgid "Add Firewall Group"
|
||||
msgstr "Ajouter un groupe de pare-feux"
|
||||
|
||||
msgid "Add New Policy"
|
||||
msgstr "Ajouter une nouvelle stratégie"
|
||||
|
||||
msgid "Add New Rule"
|
||||
msgstr "Ajouter une nouvelle règle"
|
||||
|
||||
msgid "Add Policy"
|
||||
msgstr "Ajouter une stratégie"
|
||||
|
||||
msgid "Add Rule"
|
||||
msgstr "Ajouter une règle"
|
||||
|
||||
#, python-format
|
||||
msgid "Added Policy \"%s\"."
|
||||
msgstr "Stratégie \"%s\" ajoutée."
|
||||
|
||||
#, python-format
|
||||
msgid "Added Rule \"%s\"."
|
||||
msgstr "Règle \"%s\" ajoutée."
|
||||
|
||||
msgid "Admin State"
|
||||
msgstr "État Administateur"
|
||||
|
||||
msgid "Admin State Up"
|
||||
msgstr "Etat Admin activé"
|
||||
|
||||
msgid "After"
|
||||
msgstr "Après"
|
||||
|
||||
msgid "Audited"
|
||||
msgstr "Audité"
|
||||
|
||||
msgid "Available Ports"
|
||||
msgstr "Ports disponibles"
|
||||
|
||||
msgid "Available Rules"
|
||||
msgstr "Règles disponibles"
|
||||
|
||||
msgid "Before"
|
||||
msgstr "Avant"
|
||||
|
||||
msgid ""
|
||||
"Choose rule(s) from Available Rules to Selected Rule by push button or drag "
|
||||
"and drop, you may change their order by drag and drop as well."
|
||||
msgstr ""
|
||||
"Choisissez une ou plusieurs règles en les faisant passer des règles "
|
||||
"disponibles aux règles sélectionnées en cliquant sur le bouton ou par "
|
||||
"glisser-déposer. Vous pouvez aussi changer l'ordre des règles par glisser-"
|
||||
"déposer."
|
||||
|
||||
msgid ""
|
||||
"Choose the rule you want to insert. Specify either the rule you want to "
|
||||
"insert immediately before, or the rule to insert immediately after. If both "
|
||||
"are specified, the prior takes precedence."
|
||||
msgstr ""
|
||||
"Choisissez la règle que vous souhaitez insérer. Spécifiez la règle qui doit "
|
||||
"précéder immédiatement votre nouvelle règle, ou la règle qui doit suivre "
|
||||
"immédiatement votre nouvelle règle. Si vous spécifiez les deux, le premier "
|
||||
"critère est prioritaire."
|
||||
|
||||
msgid "Choose the rule you want to remove."
|
||||
msgstr "Choisissez la règle que vous voulez enlever."
|
||||
|
||||
msgid "Create a Firewall Group with selected ports."
|
||||
msgstr "Créer un groupe de pare-feux avec les ports sélectionnés."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall policy with an ordered list of firewall rules.\n"
|
||||
"\n"
|
||||
"A firewall policy is an ordered collection of firewall rules. So if the "
|
||||
"traffic matches the first rule, the other rules are not executed. If the "
|
||||
"traffic does not match the current rule, then the next rule is executed. A "
|
||||
"firewall policy has the following attributes:\n"
|
||||
"\n"
|
||||
"<li>Shared: A firewall policy can be shared across tenants. Thus it can also "
|
||||
"be made part of an audit workflow wherein the firewall policy can be audited "
|
||||
"by the relevant entity that is authorized.</li><li>Audited: When audited is "
|
||||
"set to True, it indicates that the firewall policy has been audited. Each "
|
||||
"time the firewall policy or the associated firewall rules are changed, this "
|
||||
"attribute will be set to False and will have to be explicitly set to True "
|
||||
"through an update operation.</li>\n"
|
||||
"The name field is required, all others are optional."
|
||||
msgstr ""
|
||||
"Créer une stratégie de pare-feu avec une liste ordonnée de règles de pare-"
|
||||
"feu.\n"
|
||||
"\n"
|
||||
"Une stratégie de pare-feu est un ensemble ordonné de règles de pare-feu. Si "
|
||||
"le trafic correspond à la première règle, les autres règles ne sont pas "
|
||||
"exécutées. Si le trafic ne correspond pas à la règle en cours, la règle "
|
||||
"suivante est exécutée. Une stratégie de pare-feu comporte les attributs "
|
||||
"suivants :\n"
|
||||
"\n"
|
||||
"<li>Partagé (shared) : Une stratégie de pare-feu peut être partagée entre "
|
||||
"locataires. Elle peut ainsi faire partie d'un flux de travaux d'audit au "
|
||||
"sein duquel la stratégie de pare-feu peut être auditée par l'entité "
|
||||
"appropriée autorisée.</li><li>Audité (audited) : Lorsque l'attribut est "
|
||||
"défini sur True, la stratégie de pare-feu a été auditée. Chaque fois qu'une "
|
||||
"stratégie de pare-feu ou les règles de pare-feu associées sont modifiées, "
|
||||
"cet attribut est défini sur False et devra être explicitement défini avec la "
|
||||
"valeur True via une opération de mise à jour.</li>\n"
|
||||
"La zone de nom est obligatoire, toutes les autres sont facultatives."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall rule.\n"
|
||||
"\n"
|
||||
"A Firewall rule is an association of the following attributes:\n"
|
||||
"\n"
|
||||
"<li>IP Addresses: The addresses from/to which the traffic filtration needs "
|
||||
"to be applied.</li><li>IP Version: The type of IP packets (IP V4/V6) that "
|
||||
"needs to be filtered.</li><li>Protocol: Type of packets (UDP, ICMP, TCP, "
|
||||
"Any) that needs to be checked.</li><li>Action: Action is the type of "
|
||||
"filtration required, it can be Reject/Deny/Allow data packets.</li>\n"
|
||||
"The protocol and action fields are required, all others are optional."
|
||||
msgstr ""
|
||||
"Créer une règle de pare-feu.\n"
|
||||
"\n"
|
||||
"Une règle de pare-feu est une association des attributs suivants :\n"
|
||||
"\n"
|
||||
"<li>Adresses IP : Adresses depuis/vers lesquelles le filtrage du trafic doit "
|
||||
"s'appliquer.</li><li>Version d'IP : Type des paquets IP (IP V4/V6) à filtrer."
|
||||
"</li><li>Protocole : Type des paquets (UDP, ICMP, TCP, Tout) à vérifier.</"
|
||||
"li><li>Action : Type de filtrage requis ; Il peut s'agir de Rejeter/Refuser/"
|
||||
"Autoriser les paquets de données.</li>\n"
|
||||
"Les zones de protocole et d'action sont obligatoires, toutes les autres sont "
|
||||
"facultatives."
|
||||
|
||||
msgid "Create a policy with selected rules."
|
||||
msgstr "Créer une stratégie avec les règles sélectionnées."
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Created"
|
||||
msgstr "Créé"
|
||||
|
||||
msgid "DENY"
|
||||
msgstr "REFUSER"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "DENY"
|
||||
msgstr "REFUSER"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "DOWN"
|
||||
msgstr "INACTIF"
|
||||
|
||||
msgid "Delete Policy"
|
||||
msgid_plural "Delete Policies"
|
||||
msgstr[0] "Supprimer la stratégie"
|
||||
msgstr[1] "Supprimer les stratégies"
|
||||
|
||||
msgid "Delete Rule"
|
||||
msgid_plural "Delete Rules"
|
||||
msgstr[0] "Supprimer la règle"
|
||||
msgstr[1] "Supprimer les règles"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr "Description:"
|
||||
|
||||
msgid "Destination IP"
|
||||
msgstr "IP de destination"
|
||||
|
||||
msgid "Destination IP Address"
|
||||
msgstr "Adresse IP de destination"
|
||||
|
||||
msgid "Destination IP Address/Subnet"
|
||||
msgstr "Adresse IP/Sous-réseau de destination"
|
||||
|
||||
msgid "Destination IP address or subnet"
|
||||
msgstr "Adresse IP ou sous-réseau de destination"
|
||||
|
||||
msgid "Destination Port"
|
||||
msgstr "Port de destination"
|
||||
|
||||
msgid "Destination Port/Port Range"
|
||||
msgstr "Port/Plage de ports de destination"
|
||||
|
||||
msgid "Destination port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr "Port de destination (entier compris dans [1, 65535] ou plage a:b)"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Down"
|
||||
msgstr "Inactif"
|
||||
|
||||
msgid "Edit Policy"
|
||||
msgstr "Editer la stratégie"
|
||||
|
||||
msgid "Edit Policy {{ name }}"
|
||||
msgstr "Editer la stratégie {{ name }}"
|
||||
|
||||
msgid "Edit Rule"
|
||||
msgstr "Éditer la règle"
|
||||
|
||||
msgid "Edit Rule {{ name }}"
|
||||
msgstr "Editer la règle {{ name }}"
|
||||
|
||||
msgid "Egress Policy"
|
||||
msgstr "Stratégie sortante"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "Activé"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Error"
|
||||
msgstr "Erreur"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to insert rule to policy %(name)s: %(reason)s"
|
||||
msgstr "Echec d'insertion de la règle dans la stratégie %(name)s : %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to remove rule from policy %(name)s: %(reason)s"
|
||||
msgstr "Echec de retrait de la règle de la stratégie %(name)s : %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve available rules: %s"
|
||||
msgstr "Impossible de récupérer les règles disponibles : %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve current rules in policy %(name)s: %(reason)s"
|
||||
msgstr ""
|
||||
"Échec de la récupération des règles courantes de la stratégie %(name)s : "
|
||||
"%(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update policy %(name)s: %(reason)s"
|
||||
msgstr "Echec de mise à jour de la stratégie %(name)s : %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update rule %(name)s: %(reason)s"
|
||||
msgstr "Échec de la mise à jour de la règle %(name)s : %(reason)s"
|
||||
|
||||
msgid "Firewall Policies"
|
||||
msgstr "Stratégies de pare-feu"
|
||||
|
||||
msgid "Firewall Rules"
|
||||
msgstr "Règles de pare-feu"
|
||||
|
||||
msgid "ICMP"
|
||||
msgstr "ICMP"
|
||||
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
msgid "IP Version"
|
||||
msgstr "Version d'IP"
|
||||
|
||||
msgid "IP Version for Firewall Rule"
|
||||
msgstr "Version d'IP pour la règle de pare-feu"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Inactive"
|
||||
msgstr "Inactif"
|
||||
|
||||
msgid "Ingress Policy"
|
||||
msgstr "Stratégie entrante"
|
||||
|
||||
msgid "Insert Rule"
|
||||
msgstr "Insérer une règle"
|
||||
|
||||
msgid "Insert Rule to Policy"
|
||||
msgstr "Insérer une règle dans la stratégie"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Aucun"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Create"
|
||||
msgstr "Création en attente"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Delete"
|
||||
msgstr "Suppression en attente"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Update"
|
||||
msgstr "Mise à jour en attente"
|
||||
|
||||
msgid "Policies"
|
||||
msgstr "Stratégies"
|
||||
|
||||
msgid "Policy"
|
||||
msgstr "Stratégie"
|
||||
|
||||
#, python-format
|
||||
msgid "Policy %s was successfully updated."
|
||||
msgstr "La stratégie %s a été mise à jour."
|
||||
|
||||
msgid "Ports"
|
||||
msgstr "Ports"
|
||||
|
||||
msgid "Project ID"
|
||||
msgstr "Project ID"
|
||||
|
||||
msgid "Protocol"
|
||||
msgstr "Protocole"
|
||||
|
||||
msgid "Protocol for the firewall rule"
|
||||
msgstr "Protocole pour la règle de pare-feu"
|
||||
|
||||
msgid "REJECT"
|
||||
msgstr "REJETER"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "REJECT"
|
||||
msgstr "REJETER"
|
||||
|
||||
msgid "Remove Port"
|
||||
msgstr "Supprimer le port"
|
||||
|
||||
msgid "Remove Rule"
|
||||
msgstr "Retirer la règle"
|
||||
|
||||
msgid "Remove Rule from Policy"
|
||||
msgstr "Retirer une règle de la stratégie"
|
||||
|
||||
msgid "Rule"
|
||||
msgstr "Règle"
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully inserted to policy %(policy)s."
|
||||
msgstr "La règle %(rule)s a été insérée dans la stratégie %(policy)s."
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully removed from policy %(policy)s."
|
||||
msgstr "La règle %(rule)s a été retirée de la stratégie %(policy)s."
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %s was successfully updated."
|
||||
msgstr "La règle %s a été mise à jour."
|
||||
|
||||
msgid "Rules"
|
||||
msgstr "Règles"
|
||||
|
||||
msgid "Save Changes"
|
||||
msgstr "Enregistrer les changements"
|
||||
|
||||
msgid "Scheduled deletion of Policy"
|
||||
msgid_plural "Scheduled deletion of Policies"
|
||||
msgstr[0] "Suppression planifiée de la stratégie"
|
||||
msgstr[1] "Suppression planifiée des stratégies"
|
||||
|
||||
msgid "Scheduled deletion of Rule"
|
||||
msgid_plural "Scheduled deletion of Rules"
|
||||
msgstr[0] "Suppression planifiée de la règle"
|
||||
msgstr[1] "Suppression planifiée des règles"
|
||||
|
||||
msgid "Select a Policy"
|
||||
msgstr "Sélectionner une stratégie"
|
||||
|
||||
msgid "Select rules for your policy."
|
||||
msgstr "Sélectionnez des règles pour votre stratégie."
|
||||
|
||||
msgid "Selected Rules"
|
||||
msgstr "Règles sélectionnées"
|
||||
|
||||
msgid "Shared"
|
||||
msgstr "Partagé"
|
||||
|
||||
msgid "Source IP"
|
||||
msgstr "IP source"
|
||||
|
||||
msgid "Source IP Address"
|
||||
msgstr "Adresse IP source"
|
||||
|
||||
msgid "Source IP Address/Subnet"
|
||||
msgstr "Adresse IP/Sous-réseau source"
|
||||
|
||||
msgid "Source IP address or subnet"
|
||||
msgstr "Adresse IP ou sous-réseau source"
|
||||
|
||||
msgid "Source Port"
|
||||
msgstr "Port source"
|
||||
|
||||
msgid "Source Port/Port Range"
|
||||
msgstr "Port/plage de ports source"
|
||||
|
||||
msgid "Source port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr "Port source (entier compris dans [1,65535] ou plage a:b)"
|
||||
|
||||
msgid ""
|
||||
"Source/Destination Network Address and IP version are inconsistent. Please "
|
||||
"make them consistent."
|
||||
msgstr ""
|
||||
"La version d'IP et l'adresse réseau source/de destination ne sont pas "
|
||||
"cohérentes. Corrigez-les en conséquence."
|
||||
|
||||
msgid "Status"
|
||||
msgstr "Statut"
|
||||
|
||||
msgid "TCP"
|
||||
msgstr "TCP"
|
||||
|
||||
msgid "UDP"
|
||||
msgstr "UDP"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "UP"
|
||||
msgstr "ACTIF"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Policy \"%s\"."
|
||||
msgstr "Impossible d'ajouter la stratégie \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Rule \"%s\"."
|
||||
msgstr "Impossible d'ajouter la règle \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete policy. %s"
|
||||
msgstr "Impossible de supprimer la stratégie. %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete rule. %s"
|
||||
msgstr "Impossible de supprimer la règle %s"
|
||||
|
||||
msgid "Unable to retrieve policies list."
|
||||
msgstr "Impossible de récupérer la liste des stratégies."
|
||||
|
||||
msgid "Unable to retrieve policy details."
|
||||
msgstr "Impossible de récupérer les détails de la stratégie."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve policy list (%s)."
|
||||
msgstr "Impossible de récupérer la liste des stratégies (%s)."
|
||||
|
||||
msgid "Unable to retrieve policy list."
|
||||
msgstr "Impossible de récupérer la liste des stratégies."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve ports (%s)."
|
||||
msgstr "Impossible de récupérer les ports (%s)."
|
||||
|
||||
msgid "Unable to retrieve rule details."
|
||||
msgstr "Impossible de récupérer les détails de la règle."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve rules (%s)."
|
||||
msgstr "Impossible de récupérer les règles (%s)."
|
||||
|
||||
msgid "Unable to retrieve rules list."
|
||||
msgstr "Impossible de récupérer la liste des règles."
|
||||
|
||||
msgid "You may update rule details here."
|
||||
msgstr "Ici, vous pouvez mettre à jour les détails de la règle."
|
637
neutron_fwaas_dashboard/locale/id/LC_MESSAGES/django.po
Normal file
637
neutron_fwaas_dashboard/locale/id/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,637 @@
|
||||
# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
|
||||
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
|
||||
# suhartono <cloudsuhartono@gmail.com>, 2016. #zanata
|
||||
# suhartono <cloudsuhartono@gmail.com>, 2017. #zanata
|
||||
# suhartono <cloudsuhartono@gmail.com>, 2018. #zanata
|
||||
# Frank Kloeker <eumel@arcor.de>, 2019. #zanata
|
||||
# suhartono <cloudsuhartono@gmail.com>, 2019. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: neutron-fwaas-dashboard VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2019-03-27 14:25+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-04-03 11:53+0000\n"
|
||||
"Last-Translator: Frank Kloeker <eumel@arcor.de>\n"
|
||||
"Language-Team: Indonesian\n"
|
||||
"Language: id\n"
|
||||
"X-Generator: Zanata 4.3.3\n"
|
||||
"Plural-Forms: nplurals=1; plural=0\n"
|
||||
|
||||
msgid "-"
|
||||
msgstr "-"
|
||||
|
||||
msgid "ALLOW"
|
||||
msgstr "ALLOW"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "ALLOW"
|
||||
msgstr "ALLOW (mengizinkan)"
|
||||
|
||||
msgid "ANY"
|
||||
msgstr "ANY"
|
||||
|
||||
msgid "Action"
|
||||
msgstr "Action"
|
||||
|
||||
msgid "Action for the firewall rule"
|
||||
msgstr "Aksi aturan firewall"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Active"
|
||||
msgstr "Active"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "Menambahkan"
|
||||
|
||||
msgid "Add Firewall Group"
|
||||
msgstr "Menambahkan Firewall Group"
|
||||
|
||||
msgid "Add New Firewall Group"
|
||||
msgstr "Add New Firewall Group"
|
||||
|
||||
msgid "Add New Policy"
|
||||
msgstr "Menambah kebijakan baru"
|
||||
|
||||
msgid "Add New Rule"
|
||||
msgstr "Menambah aturan baru"
|
||||
|
||||
msgid "Add Policy"
|
||||
msgstr "Add Policy (tambahkan kebiijakan)"
|
||||
|
||||
msgid "Add Port"
|
||||
msgstr "Add Port"
|
||||
|
||||
msgid "Add Port to Firewall Group"
|
||||
msgstr "Tambahkan Port ke Firewall Group"
|
||||
|
||||
msgid "Add Rule"
|
||||
msgstr "Tambahkan Aturan"
|
||||
|
||||
msgid "Add port to Firewall Group {{ name }}"
|
||||
msgstr "Tambahkan port ke Firewall Group {{ name }}"
|
||||
|
||||
#, python-format
|
||||
msgid "Added Firewall Group\"%s\"."
|
||||
msgstr "Ditambahkan Firewall Group\"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Added Policy \"%s\"."
|
||||
msgstr "Kebijakan ditambahkan \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Added Rule \"%s\"."
|
||||
msgstr "Aturan ditambahkan \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Added the port(s) to the firewall group %s successfully."
|
||||
msgstr "Berhasil menambahkan port ke grup firewall %s."
|
||||
|
||||
msgid "Admin State"
|
||||
msgstr "Admin State"
|
||||
|
||||
msgid "Admin State Up"
|
||||
msgstr "Admin State Up"
|
||||
|
||||
msgid "After"
|
||||
msgstr "After (sesudah)"
|
||||
|
||||
msgid "Audited"
|
||||
msgstr "Audited"
|
||||
|
||||
msgid "Available Ports"
|
||||
msgstr "Available Ports"
|
||||
|
||||
msgid "Available Rules"
|
||||
msgstr "Available Rules"
|
||||
|
||||
msgid "Before"
|
||||
msgstr "Before (sebelum)"
|
||||
|
||||
msgid "Choose port(s) from Available Ports. "
|
||||
msgstr "Pilih port dari Available Ports. "
|
||||
|
||||
msgid ""
|
||||
"Choose rule(s) from Available Rules to Selected Rule by push button or drag "
|
||||
"and drop, you may change their order by drag and drop as well."
|
||||
msgstr ""
|
||||
"Pilih aturan dari Available Rules ke Selected Rule dengan menekan tombol "
|
||||
"atau seret dan lepaskan, Anda dapat mengubah pesanan mereka dengan drag dan "
|
||||
"drop juga."
|
||||
|
||||
msgid ""
|
||||
"Choose the rule you want to insert. Specify either the rule you want to "
|
||||
"insert immediately before, or the rule to insert immediately after. If both "
|
||||
"are specified, the prior takes precedence."
|
||||
msgstr ""
|
||||
"Pilih aturan yang ingin Anda sisipkan. Tentukan baik aturan yang ingin Anda "
|
||||
"masukkan segera sebelumnya, atau aturan untuk memasukkan segera setelahnya. "
|
||||
"Jika keduanya ditentukan, sebelumnya diutamakan."
|
||||
|
||||
msgid "Choose the rule you want to remove."
|
||||
msgstr "Pilih aturan yang ingin Anda hapus."
|
||||
|
||||
msgid "Create Firewall Group"
|
||||
msgstr "Membuat Firewall Group"
|
||||
|
||||
msgid "Create a Firewall Group with selected ports."
|
||||
msgstr "Buat Firewall Group dengan port yang dipilih."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall group based on a policy.\n"
|
||||
"\n"
|
||||
"A firewall group represents a logical firewall resource that a tenant can "
|
||||
"instantiate and manage. A firewall group must be associated with one policy, "
|
||||
"all other fields are optional."
|
||||
msgstr ""
|
||||
"Buat grup firewall berdasarkan kebijakan.\n"
|
||||
"\n"
|
||||
"Grup firewall mewakili sumber daya firewall logis dimana tenant dapat "
|
||||
"instantiate dan kelola. Grup firewall harus dikaitkan dengan satu kebijakan, "
|
||||
"semua bidang lainnya opsional."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall policy with an ordered list of firewall rules.\n"
|
||||
"\n"
|
||||
"A firewall policy is an ordered collection of firewall rules. So if the "
|
||||
"traffic matches the first rule, the other rules are not executed. If the "
|
||||
"traffic does not match the current rule, then the next rule is executed. A "
|
||||
"firewall policy has the following attributes:\n"
|
||||
"\n"
|
||||
"<li>Shared: A firewall policy can be shared across tenants. Thus it can also "
|
||||
"be made part of an audit workflow wherein the firewall policy can be audited "
|
||||
"by the relevant entity that is authorized.</li><li>Audited: When audited is "
|
||||
"set to True, it indicates that the firewall policy has been audited. Each "
|
||||
"time the firewall policy or the associated firewall rules are changed, this "
|
||||
"attribute will be set to False and will have to be explicitly set to True "
|
||||
"through an update operation.</li>\n"
|
||||
"The name field is required, all others are optional."
|
||||
msgstr ""
|
||||
"Membuat kebijakan firewall dengan daftar aturan firewall tersusun "
|
||||
"berurutan.\n"
|
||||
"\n"
|
||||
"Sebuah kebijakan firewall adalah koleksi aturan firewall berurutan. Jadi "
|
||||
"jika lalu lintas sesuai dengan aturan pertama, maka aturan lain tidak "
|
||||
"dieksekusi. Jika lalu lintas tidak sesuai dengan aturan saat ini, maka "
|
||||
"aturan berikutnya dieksekusi. Sebuah kebijakan firewall memiliki atribut "
|
||||
"sebagai berikut:\n"
|
||||
"\n"
|
||||
"<li>Shared: Sebuah kebijakan firewall dapat digunakan bersama seluruh "
|
||||
"penyewa (tenant). Dengan demikian kebijakan itu dapat juga menjadi bagian "
|
||||
"dari alur kerja pemeriksaan dimana kebijakan firewall dapat diaudit oleh "
|
||||
"entitas terkait yang berwenang.</li><li>Audited: Ketika diaudit diatur ke "
|
||||
"True, ini menunjukkan bahwa kebijakan firewall telah diaudit. Setiap kali "
|
||||
"kebijakan firewall atau aturan firewall yang terkait berubah, atribut ini "
|
||||
"akan diatur ke False dan harus secara eksplisit diatur ke True melalui "
|
||||
"operasi update.</li>\n"
|
||||
"Kolom (field) nama diperlukan, semua yang lain adalah opsional."
|
||||
|
||||
msgid ""
|
||||
"Create a firewall rule.\n"
|
||||
"\n"
|
||||
"A Firewall rule is an association of the following attributes:\n"
|
||||
"\n"
|
||||
"<li>IP Addresses: The addresses from/to which the traffic filtration needs "
|
||||
"to be applied.</li><li>IP Version: The type of IP packets (IP V4/V6) that "
|
||||
"needs to be filtered.</li><li>Protocol: Type of packets (UDP, ICMP, TCP, "
|
||||
"Any) that needs to be checked.</li><li>Action: Action is the type of "
|
||||
"filtration required, it can be Reject/Deny/Allow data packets.</li>\n"
|
||||
"The protocol and action fields are required, all others are optional."
|
||||
msgstr ""
|
||||
"Buat aturan firewall\n"
|
||||
"\n"
|
||||
"Aturan firewall adalah sebuah asosiasi atribut berikut:\n"
|
||||
"\n"
|
||||
"<li>IP Addresses: Alamat dari/ke dimana filtrasi lalu lintas perlu "
|
||||
"diterapkan.</li><li>IP Version: Tipe paket IP (IP V4/V6) yang perlu disaring."
|
||||
"</li><li>Protocol: Tipe paket (UDP, ICMP, TCP, lainnya) yang perlu diperiksa."
|
||||
"</li><li>Action: Action adalah tipe filtrasi diperlukan, dapat Reject/Deny/"
|
||||
"Allow paket data.</li>\n"
|
||||
"Protokol dan action field (kolom aksi) yang diperlukan, semua yang lain "
|
||||
"adalah opsional."
|
||||
|
||||
msgid "Create a policy with selected rules."
|
||||
msgstr "Membuat kebijakan dengan aturan yang dipilih."
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Created"
|
||||
msgstr "Created"
|
||||
|
||||
msgid "DENY"
|
||||
msgstr "DENY (menyangkal)"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "DENY"
|
||||
msgstr "DENY (menyangkal)"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "DOWN"
|
||||
msgstr "DOWN"
|
||||
|
||||
msgid "Delete Firewall Group"
|
||||
msgid_plural "Delete Firewall Groups"
|
||||
msgstr[0] "Delete Firewall Group"
|
||||
|
||||
msgid "Delete Policy"
|
||||
msgid_plural "Delete Policies"
|
||||
msgstr[0] "Delete Policy"
|
||||
|
||||
msgid "Delete Rule"
|
||||
msgid_plural "Delete Rules"
|
||||
msgstr[0] "Delete Rule"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Deskripsi"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr "Deskripsi:"
|
||||
|
||||
msgid "Destination IP"
|
||||
msgstr "IP Tujuan"
|
||||
|
||||
msgid "Destination IP Address"
|
||||
msgstr "Destination IP Address"
|
||||
|
||||
msgid "Destination IP Address/Subnet"
|
||||
msgstr "Tujuan subnet/alamat IP"
|
||||
|
||||
msgid "Destination IP address or subnet"
|
||||
msgstr "Tujuan subnet atau alamat IP"
|
||||
|
||||
msgid "Destination Port"
|
||||
msgstr "Port Tujuan"
|
||||
|
||||
msgid "Destination Port/Port Range"
|
||||
msgstr "Destination Port/Port Range (tujuan port/ kisaran port)"
|
||||
|
||||
msgid "Destination port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr ""
|
||||
"Destination (tujuan) port (integer dalam [1, 65535] atau dalam kisaran a:b)"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Down"
|
||||
msgstr "Down"
|
||||
|
||||
msgid "Edit Firewall Group"
|
||||
msgstr "Edit Firewall Group"
|
||||
|
||||
msgid "Edit FirewallGroup {{ name }}"
|
||||
msgstr "Edit FirewallGroup {{ name }}"
|
||||
|
||||
msgid "Edit Policy"
|
||||
msgstr "Ubah Kebijakan"
|
||||
|
||||
msgid "Edit Policy {{ name }}"
|
||||
msgstr "Edit Policy {{ name }}"
|
||||
|
||||
msgid "Edit Rule"
|
||||
msgstr "Ubah Aturan"
|
||||
|
||||
msgid "Edit Rule {{ name }}"
|
||||
msgstr "Edit Rule {{ name }}"
|
||||
|
||||
msgid "Egress Policy"
|
||||
msgstr "Egress Policy"
|
||||
|
||||
msgid "Egress Policy ID"
|
||||
msgstr "Egress Policy ID"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "Enabled (aktif)"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to add the port(s) to the firewall group %(name)s: %(reason)s"
|
||||
msgstr "Gagal menambahkan port(s) ke firewall group %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to insert rule to policy %(name)s: %(reason)s"
|
||||
msgstr "Gagal untuk memasukkan aturan kebijakan %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to remove rule from policy %(name)s: %(reason)s"
|
||||
msgstr "Gagal menghapus aturan dari kebijakan %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Failed to remove the port(s) from the firewall group %(name)s: %(reason)s"
|
||||
msgstr "Gagal menghapus port(s) dari firewall group %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve available rules: %s"
|
||||
msgstr "Gagal mengambil aturan yang tersedia: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve current rules in policy %(name)s: %(reason)s"
|
||||
msgstr "Gagal mengambil aturan saat ini dalam kebijakan %(name)s: %(reason)s"
|
||||
|
||||
msgid "Failed to retrieve port list of the firewall group."
|
||||
msgstr "Gagal mengambil daftar port dari grup firewall."
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update firewall group %(name)s: %(reason)s"
|
||||
msgstr "Gagal memperbarui grup firewall %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update policy %(name)s: %(reason)s"
|
||||
msgstr "Gagal memperbarui kebijakan %(name)s: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update rule %(name)s: %(reason)s"
|
||||
msgstr "Gagal memperbarui aturan %(name)s: %(reason)s"
|
||||
|
||||
msgid "Firewall Groups"
|
||||
msgstr "Firewall Groups"
|
||||
|
||||
msgid "Firewall Policies"
|
||||
msgstr "Firewall Policies (kebijakan firewall)"
|
||||
|
||||
msgid "Firewall Rules"
|
||||
msgstr " Firewall Rules (aturan firewall)"
|
||||
|
||||
#, python-format
|
||||
msgid "Firewall group %s was successfully updated."
|
||||
msgstr "Grup firewall %s berhasil diperbarui."
|
||||
|
||||
msgid "FirewallGroup"
|
||||
msgstr "FirewallGroup"
|
||||
|
||||
msgid "ICMP"
|
||||
msgstr "ICMP"
|
||||
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
msgid "IP Version"
|
||||
msgstr "IP Version"
|
||||
|
||||
msgid "IP Version for Firewall Rule"
|
||||
msgstr "IP Version untuk Firewall Rule"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Inactive"
|
||||
msgstr "Inactive"
|
||||
|
||||
msgid "Ingress Policy"
|
||||
msgstr "Ingress Policy"
|
||||
|
||||
msgid "Ingress Policy ID"
|
||||
msgstr "Ingress Policy ID"
|
||||
|
||||
msgid "Insert Rule"
|
||||
msgstr "Insert Rule (menyisipkan aturan)"
|
||||
|
||||
msgid "Insert Rule to Policy"
|
||||
msgstr "Sisipkan aturan ke kebijakan"
|
||||
|
||||
msgid "Label"
|
||||
msgstr "Label"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
msgid "No options available"
|
||||
msgstr "Tidak ada opsi yang tersedia"
|
||||
|
||||
msgid "None"
|
||||
msgstr "None"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Create"
|
||||
msgstr "Pending Create"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Delete"
|
||||
msgstr "Pending Delete"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Update"
|
||||
msgstr "Pending Update"
|
||||
|
||||
msgid "Policies"
|
||||
msgstr "Kebijakan"
|
||||
|
||||
msgid "Policy"
|
||||
msgstr "Policy (kebijakan)"
|
||||
|
||||
#, python-format
|
||||
msgid "Policy %s was successfully updated."
|
||||
msgstr "Kebijakan %s telah berhasil diperbarui."
|
||||
|
||||
msgid "Ports"
|
||||
msgstr "Ports"
|
||||
|
||||
msgid "Project ID"
|
||||
msgstr "Project ID"
|
||||
|
||||
msgid "Protocol"
|
||||
msgstr "Protocol"
|
||||
|
||||
msgid "Protocol for the firewall rule"
|
||||
msgstr "Protokol untuk aturan firewall"
|
||||
|
||||
msgid "REJECT"
|
||||
msgstr "REJECT (menolak)"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "REJECT"
|
||||
msgstr "REJECT (menolak)"
|
||||
|
||||
msgid "Remove Port"
|
||||
msgstr "Remove Port"
|
||||
|
||||
msgid "Remove Port from Firewall Group"
|
||||
msgstr "Hapus Port dari Firewall Group"
|
||||
|
||||
msgid "Remove Rule"
|
||||
msgstr "Remove Rule (hapus aturan)"
|
||||
|
||||
msgid "Remove Rule from Policy"
|
||||
msgstr "Buang aturan dari kebijakan"
|
||||
|
||||
msgid "Remove port from FirewallGroup {{ name }}"
|
||||
msgstr "Hapus port dari FirewallGroup {{ name }}"
|
||||
|
||||
#, python-format
|
||||
msgid "Removed the port(s) from the firewall group %s successfully."
|
||||
msgstr "Port berhasil dihapus dari firewall group %s ."
|
||||
|
||||
msgid "Rule"
|
||||
msgstr "Aturan"
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully inserted to policy %(policy)s."
|
||||
msgstr "Aturan %(rule)s berhasil dimasukkan ke kebijakan %(policy)s."
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully removed from policy %(policy)s."
|
||||
msgstr "Aturan %(rule)s berhasil dihapus dari kebijakan %(policy)s."
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %s was successfully updated."
|
||||
msgstr "Aturan %s telah berhasil diperbarui."
|
||||
|
||||
msgid "Rules"
|
||||
msgstr "Aturan"
|
||||
|
||||
msgid "Save Changes"
|
||||
msgstr "Simpan perubahan"
|
||||
|
||||
msgid "Scheduled deletion of Firewall Group"
|
||||
msgid_plural "Scheduled deletion of Firewall Groups"
|
||||
msgstr[0] "Scheduled deletion of Firewall Group"
|
||||
|
||||
msgid "Scheduled deletion of Policy"
|
||||
msgid_plural "Scheduled deletion of Policies"
|
||||
msgstr[0] "Scheduled deletion of Policy"
|
||||
|
||||
msgid "Scheduled deletion of Rule"
|
||||
msgid_plural "Scheduled deletion of Rules"
|
||||
msgstr[0] "Scheduled deletion of Rule"
|
||||
|
||||
msgid "Select a Policy"
|
||||
msgstr "Pilih kebijakan "
|
||||
|
||||
msgid "Select ports for your firewall group."
|
||||
msgstr "Pilih port untuk grup firewall Anda."
|
||||
|
||||
msgid "Select rules for your policy."
|
||||
msgstr "Pilih aturan untuk kebijakan Anda."
|
||||
|
||||
msgid "Selected Ports"
|
||||
msgstr "Selected Ports"
|
||||
|
||||
msgid "Selected Rules"
|
||||
msgstr "Selected Rules"
|
||||
|
||||
msgid "Shared"
|
||||
msgstr "Shared"
|
||||
|
||||
msgid "Source IP"
|
||||
msgstr "Source IP (IP sumber)"
|
||||
|
||||
msgid "Source IP Address"
|
||||
msgstr "Source IP Address"
|
||||
|
||||
msgid "Source IP Address/Subnet"
|
||||
msgstr "Source (asal) subnet/alamat IP"
|
||||
|
||||
msgid "Source IP address or subnet"
|
||||
msgstr "Source (asal) subnet atau alamat IP"
|
||||
|
||||
msgid "Source Port"
|
||||
msgstr "Port Sumber"
|
||||
|
||||
msgid "Source Port/Port Range"
|
||||
msgstr "Source Port/Port Range (asal port/ kisaran port)"
|
||||
|
||||
msgid "Source port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr "Source (asal) port (integer dalam [1, 65535] atau dalam kisaran a:b)"
|
||||
|
||||
msgid ""
|
||||
"Source/Destination Network Address and IP version are inconsistent. Please "
|
||||
"make them consistent."
|
||||
msgstr ""
|
||||
"Sumber/tujuan alamat jaringan dan IP versi tidak konsisten. Harap membuat "
|
||||
"mereka konsisten."
|
||||
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
msgid "TCP"
|
||||
msgstr "TCP"
|
||||
|
||||
msgid "UDP"
|
||||
msgstr "UDP"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "UP"
|
||||
msgstr "UP"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Firewall Group \"%s\"."
|
||||
msgstr "Tidak dapat menambahkan Firewall Group \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Policy \"%s\"."
|
||||
msgstr "Tidak dapat menambahkan kebijakan \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Rule \"%s\"."
|
||||
msgstr "Tidak dapat menambahkan Aturan \"%s\"."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete firewall group. %s"
|
||||
msgstr "Tidak dapat menghapus firewall group. %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete policy. %s"
|
||||
msgstr "Tidak dapat menghapus kebijakan. %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete rule. %s"
|
||||
msgstr "Tidak dapat menghapus aturan. %s"
|
||||
|
||||
msgid "Unable to retrieve firewall group details."
|
||||
msgstr "Tidak dapat mengambil detail grup firewall."
|
||||
|
||||
msgid "Unable to retrieve firewall group list."
|
||||
msgstr "Tidak dapat mengambil daftar grup firewall."
|
||||
|
||||
msgid "Unable to retrieve firewallgroup details."
|
||||
msgstr "Tidak dapat mengambil rincian firewallgroup."
|
||||
|
||||
msgid "Unable to retrieve policies list."
|
||||
msgstr "Tidak dapat mengambil daftar kebijakan."
|
||||
|
||||
msgid "Unable to retrieve policy details."
|
||||
msgstr "Tidak dapat mengambil rincian kebijakan."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve policy list (%s)."
|
||||
msgstr "Tidak dapat mengambil daftar kebijakan (%s)."
|
||||
|
||||
msgid "Unable to retrieve policy list."
|
||||
msgstr "Tidak dapat mengambil daftar kebijakan."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve ports (%s)."
|
||||
msgstr "Tidak dapat mengambil port (%s)."
|
||||
|
||||
msgid "Unable to retrieve rule details."
|
||||
msgstr "Tidak dapat mengambil rincian aturan."
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve rules (%s)."
|
||||
msgstr "Tidak dapat mengambil peraturan (%s)."
|
||||
|
||||
msgid "Unable to retrieve rules list."
|
||||
msgstr "Tidak dapat mengambil daftar aturan."
|
||||
|
||||
msgid "Value"
|
||||
msgstr "Value"
|
||||
|
||||
msgid "You may add ports to firewall group here."
|
||||
msgstr "Anda dapat menambahkan port ke grup firewall di sini."
|
||||
|
||||
msgid "You may remove ports from firewall group here."
|
||||
msgstr "Anda dapat menghapus port dari grup firewall di sini."
|
||||
|
||||
msgid "You may update firewall group details here."
|
||||
msgstr "Anda dapat memperbarui rincian grup firewall di sini."
|
||||
|
||||
msgid ""
|
||||
"You may update policy details here. Use 'Insert Rule' or 'Remove Rule' links "
|
||||
"instead to insert or remove a rule."
|
||||
msgstr ""
|
||||
"Anda dapat memperbarui rincian kebijakan di sini. Gunakan tautan 'Insert "
|
||||
"Rule' atau 'Remove Rule' sebagai gantinya untuk memasukkan atau menghapus "
|
||||
"aturan."
|
||||
|
||||
msgid "You may update rule details here."
|
||||
msgstr "Anda dapat memperbarui detail aturan di sini."
|
633
neutron_fwaas_dashboard/locale/ja/LC_MESSAGES/django.po
Normal file
633
neutron_fwaas_dashboard/locale/ja/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,633 @@
|
||||
# Akihiro Motoki <amotoki@gmail.com>, 2017. #zanata
|
||||
# Yuko Katabami <yukokatabami@gmail.com>, 2018. #zanata
|
||||
# Takashi Kuroda <tkuroda@redhat.com>, 2019. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: neutron-fwaas-dashboard VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2019-03-19 10:41+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-03-20 03:16+0000\n"
|
||||
"Last-Translator: Takashi Kuroda <tkuroda@redhat.com>\n"
|
||||
"Language-Team: Japanese\n"
|
||||
"Language: ja\n"
|
||||
"X-Generator: Zanata 4.3.3\n"
|
||||
"Plural-Forms: nplurals=1; plural=0\n"
|
||||
|
||||
msgid "-"
|
||||
msgstr "-"
|
||||
|
||||
msgid "ALLOW"
|
||||
msgstr "ALLOW"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "ALLOW"
|
||||
msgstr "ALLOW"
|
||||
|
||||
msgid "ANY"
|
||||
msgstr "ANY"
|
||||
|
||||
msgid "Action"
|
||||
msgstr "アクション"
|
||||
|
||||
msgid "Action for the firewall rule"
|
||||
msgstr "ファイアウォールルールのアクション"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Active"
|
||||
msgstr "稼働中"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "追加"
|
||||
|
||||
msgid "Add Firewall Group"
|
||||
msgstr "ファイアウォールグループの追加"
|
||||
|
||||
msgid "Add New Firewall Group"
|
||||
msgstr "ファイアウォールグループの追加"
|
||||
|
||||
msgid "Add New Policy"
|
||||
msgstr "ポリシーの追加"
|
||||
|
||||
msgid "Add New Rule"
|
||||
msgstr "ルールの追加"
|
||||
|
||||
msgid "Add Policy"
|
||||
msgstr "ポリシーの追加"
|
||||
|
||||
msgid "Add Port"
|
||||
msgstr "ポートの追加"
|
||||
|
||||
msgid "Add Port to Firewall Group"
|
||||
msgstr "ファイアウォールグループへのポートの追加"
|
||||
|
||||
msgid "Add Rule"
|
||||
msgstr "ルールの追加"
|
||||
|
||||
msgid "Add port to Firewall Group {{ name }}"
|
||||
msgstr "ファイアウォールグループ {{ name }} へのポートの追加"
|
||||
|
||||
#, python-format
|
||||
msgid "Added Firewall Group\"%s\"."
|
||||
msgstr "ファイアウォールグループ \"%s\" を追加しました。"
|
||||
|
||||
#, python-format
|
||||
msgid "Added Policy \"%s\"."
|
||||
msgstr "ポリシー \"%s\" を追加しました。"
|
||||
|
||||
#, python-format
|
||||
msgid "Added Rule \"%s\"."
|
||||
msgstr "ルール \"%s\" を追加しました。"
|
||||
|
||||
#, python-format
|
||||
msgid "Added the port(s) to the firewall group %s successfully."
|
||||
msgstr "ポートを正常にファイアウォールグループ %s に追加しました。"
|
||||
|
||||
msgid "Admin State"
|
||||
msgstr "管理状態"
|
||||
|
||||
msgid "Admin State Up"
|
||||
msgstr "管理状態有効"
|
||||
|
||||
msgid "After"
|
||||
msgstr "後に挿入"
|
||||
|
||||
msgid "Audited"
|
||||
msgstr "監査対象 (Audited)"
|
||||
|
||||
msgid "Available Ports"
|
||||
msgstr "利用可能なポート"
|
||||
|
||||
msgid "Available Rules"
|
||||
msgstr "利用可能なルール"
|
||||
|
||||
msgid "Before"
|
||||
msgstr "前に挿入"
|
||||
|
||||
msgid "Choose port(s) from Available Ports. "
|
||||
msgstr "以下の利用可能なポートからポートを選択してください。"
|
||||
|
||||
msgid ""
|
||||
"Choose rule(s) from Available Rules to Selected Rule by push button or drag "
|
||||
"and drop, you may change their order by drag and drop as well."
|
||||
msgstr ""
|
||||
"利用可能なルールから選択済みルールに、ボタンを押すかドラッグアンドドロップす"
|
||||
"ることでルールを選択します。ドラッグアンドドロップでルールの順番を変更するこ"
|
||||
"ともできます。"
|
||||
|
||||
msgid ""
|
||||
"Choose the rule you want to insert. Specify either the rule you want to "
|
||||
"insert immediately before, or the rule to insert immediately after. If both "
|
||||
"are specified, the prior takes precedence."
|
||||
msgstr ""
|
||||
"挿入するルールを選択してください。ルールをどのルールの直前、または直後に挿入"
|
||||
"するかを指定してください。両方指定した場合は指定したルールの直前に挿入されま"
|
||||
"す。"
|
||||
|
||||
msgid "Choose the rule you want to remove."
|
||||
msgstr "削除するルールを選択してください。"
|
||||
|
||||
msgid "Create Firewall Group"
|
||||
msgstr "ファイアウォールグループの作成"
|
||||
|
||||
msgid "Create a Firewall Group with selected ports."
|
||||
msgstr "ポートを選択してファイアウォールグループを作成します。"
|
||||
|
||||
msgid ""
|
||||
"Create a firewall group based on a policy.\n"
|
||||
"\n"
|
||||
"A firewall group represents a logical firewall resource that a tenant can "
|
||||
"instantiate and manage. A firewall group must be associated with one policy, "
|
||||
"all other fields are optional."
|
||||
msgstr ""
|
||||
"ポリシーに基づいてファイアウォールグループを作成します。\n"
|
||||
"\n"
|
||||
"ファイアウォールグループは、テナントがインスタンス化して管理することのできる"
|
||||
"論理的なファイアウォールリソースを表します。1 つのファイアウォールグループは "
|
||||
"1 つのポリシーと関連付けられる必要があり、他のフィールドはすべて省略可能で"
|
||||
"す。"
|
||||
|
||||
msgid ""
|
||||
"Create a firewall policy with an ordered list of firewall rules.\n"
|
||||
"\n"
|
||||
"A firewall policy is an ordered collection of firewall rules. So if the "
|
||||
"traffic matches the first rule, the other rules are not executed. If the "
|
||||
"traffic does not match the current rule, then the next rule is executed. A "
|
||||
"firewall policy has the following attributes:\n"
|
||||
"\n"
|
||||
"<li>Shared: A firewall policy can be shared across tenants. Thus it can also "
|
||||
"be made part of an audit workflow wherein the firewall policy can be audited "
|
||||
"by the relevant entity that is authorized.</li><li>Audited: When audited is "
|
||||
"set to True, it indicates that the firewall policy has been audited. Each "
|
||||
"time the firewall policy or the associated firewall rules are changed, this "
|
||||
"attribute will be set to False and will have to be explicitly set to True "
|
||||
"through an update operation.</li>\n"
|
||||
"The name field is required, all others are optional."
|
||||
msgstr ""
|
||||
"ファイアウォールルールの順序付きリストでファイアウォールポリシーを作成しま"
|
||||
"す。\n"
|
||||
"\n"
|
||||
"ファイアウォールポリシーは、ファイアウォールルールの順序付きコレクションなの"
|
||||
"で、トラフィックが最初のルールに一致した場合には、他のルールは実行されませ"
|
||||
"ん。トラフィックが現在のルールに一致しない場合には、次のルールが実行されま"
|
||||
"す。ファイアウォールポリシーには、以下の属性があります。\n"
|
||||
"\n"
|
||||
"<li>共有: ファイアウォールポリシーをテナント間で共有できます。そのため、承認"
|
||||
"済みの関連エンティティーによってファイアウォールポリシーを監査することができ"
|
||||
"る監査ワークフローの一部にすることも可能です。</li><li>監査: 監査が True に設"
|
||||
"定されている場合には、ファイアウォールポリシーが監査されることを意味します。"
|
||||
"ファイアウォールポリシーまたは関連付けられたファイアウォールルールが変更され"
|
||||
"るたびに、この属性は False に設定され、更新操作で明示的に True に設定する必要"
|
||||
"があります。</li>\n"
|
||||
"名前のフィールドは入力する必要があり、その他のフィールドはすべて省略可能で"
|
||||
"す。"
|
||||
|
||||
msgid ""
|
||||
"Create a firewall rule.\n"
|
||||
"\n"
|
||||
"A Firewall rule is an association of the following attributes:\n"
|
||||
"\n"
|
||||
"<li>IP Addresses: The addresses from/to which the traffic filtration needs "
|
||||
"to be applied.</li><li>IP Version: The type of IP packets (IP V4/V6) that "
|
||||
"needs to be filtered.</li><li>Protocol: Type of packets (UDP, ICMP, TCP, "
|
||||
"Any) that needs to be checked.</li><li>Action: Action is the type of "
|
||||
"filtration required, it can be Reject/Deny/Allow data packets.</li>\n"
|
||||
"The protocol and action fields are required, all others are optional."
|
||||
msgstr ""
|
||||
"ファイアウォールルールを作成します。\n"
|
||||
"\n"
|
||||
"ファイアウォールルールは、以下の属性の組み合わせです。\n"
|
||||
"\n"
|
||||
"<li>IP アドレス: トラフィックフィルターを適用する必要があるアドレス (送信元/"
|
||||
"送信先) です。</li><li>IP バージョン: フィルタリングする必要がある IP パケッ"
|
||||
"トの種別 (IP V4/V6) です。</li><li>プロトコル: チェックされる必要があるパケッ"
|
||||
"トの種別 (UDP、ICMP、TCP、Any) です。</li><li>アクション: アクションは必要な"
|
||||
"フィルターの種別で、データパケットを REJECT/DENY/ALLOW できます。</li>\n"
|
||||
"プロトコルとアクションは必須項目であり、他のフィールドはすべて省略可能です。"
|
||||
|
||||
msgid "Create a policy with selected rules."
|
||||
msgstr "ルールを選択してポリシーを作成します。"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Created"
|
||||
msgstr "作成済み"
|
||||
|
||||
msgid "DENY"
|
||||
msgstr "DENY"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "DENY"
|
||||
msgstr "DENY"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "DOWN"
|
||||
msgstr "DOWN"
|
||||
|
||||
msgid "Delete Firewall Group"
|
||||
msgid_plural "Delete Firewall Groups"
|
||||
msgstr[0] "ファイアウォールグループの削除"
|
||||
|
||||
msgid "Delete Policy"
|
||||
msgid_plural "Delete Policies"
|
||||
msgstr[0] "ポリシーの削除"
|
||||
|
||||
msgid "Delete Rule"
|
||||
msgid_plural "Delete Rules"
|
||||
msgstr[0] "ルールの削除"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "説明"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr "説明:"
|
||||
|
||||
msgid "Destination IP"
|
||||
msgstr "宛先 IP アドレス"
|
||||
|
||||
msgid "Destination IP Address"
|
||||
msgstr "宛先 IP アドレス"
|
||||
|
||||
msgid "Destination IP Address/Subnet"
|
||||
msgstr "宛先 IP アドレス/サブネット"
|
||||
|
||||
msgid "Destination IP address or subnet"
|
||||
msgstr "宛先 IP アドレスまたはサブネット"
|
||||
|
||||
msgid "Destination Port"
|
||||
msgstr "宛先ポート番号"
|
||||
|
||||
msgid "Destination Port/Port Range"
|
||||
msgstr "宛先ポート/ポートの範囲"
|
||||
|
||||
msgid "Destination port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr "宛先ポート ([1, 65535] の整数か a:b 形式の範囲)"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Down"
|
||||
msgstr "停止中"
|
||||
|
||||
msgid "Edit Firewall Group"
|
||||
msgstr "ファイアウォールグループの編集"
|
||||
|
||||
msgid "Edit FirewallGroup {{ name }}"
|
||||
msgstr "ファイアウォールグループ {{ name }} の編集"
|
||||
|
||||
msgid "Edit Policy"
|
||||
msgstr "ポリシーの編集"
|
||||
|
||||
msgid "Edit Policy {{ name }}"
|
||||
msgstr "ポリシー {{ name }} の編集"
|
||||
|
||||
msgid "Edit Rule"
|
||||
msgstr "ルールの編集"
|
||||
|
||||
msgid "Edit Rule {{ name }}"
|
||||
msgstr "ルール {{ name }} の編集"
|
||||
|
||||
msgid "Egress Policy"
|
||||
msgstr "送信ポリシー"
|
||||
|
||||
msgid "Egress Policy ID"
|
||||
msgstr "送信ポリシー ID"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "有効"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Error"
|
||||
msgstr "エラー"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to add the port(s) to the firewall group %(name)s: %(reason)s"
|
||||
msgstr ""
|
||||
"ポートのファイアウォールグループ %(name)s への追加に失敗しました: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to insert rule to policy %(name)s: %(reason)s"
|
||||
msgstr "ポリシー %(name)s へのルールの挿入に失敗しました: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to remove rule from policy %(name)s: %(reason)s"
|
||||
msgstr "ポリシー %(name)s からのルールの削除に失敗しました: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Failed to remove the port(s) from the firewall group %(name)s: %(reason)s"
|
||||
msgstr ""
|
||||
"ポートのファイアウォールグループ %(name)s からの削除に失敗しました: "
|
||||
"%(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve available rules: %s"
|
||||
msgstr "利用可能なルールの取得に失敗しました: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to retrieve current rules in policy %(name)s: %(reason)s"
|
||||
msgstr "ポリシー %(name)s の現在のルールの取得に失敗しました: %(reason)s"
|
||||
|
||||
msgid "Failed to retrieve port list of the firewall group."
|
||||
msgstr "ファイアウォールグループのポート一覧を取得できません。"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update firewall group %(name)s: %(reason)s"
|
||||
msgstr "ファイアウォールグループ %(name)s の更新に失敗しました: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update policy %(name)s: %(reason)s"
|
||||
msgstr "ポリシー %(name)s の更新に失敗しました: %(reason)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Failed to update rule %(name)s: %(reason)s"
|
||||
msgstr "ルール %(name)s の更新に失敗しました: %(reason)s"
|
||||
|
||||
msgid "Firewall Groups"
|
||||
msgstr "ファイアウォールグループ"
|
||||
|
||||
msgid "Firewall Policies"
|
||||
msgstr "ファイアウォールポリシー"
|
||||
|
||||
msgid "Firewall Rules"
|
||||
msgstr "ファイアウォールルール"
|
||||
|
||||
#, python-format
|
||||
msgid "Firewall group %s was successfully updated."
|
||||
msgstr "ファイアウォールグループ %s が正常に更新されました。"
|
||||
|
||||
msgid "FirewallGroup"
|
||||
msgstr "ファイアウォールグループ"
|
||||
|
||||
msgid "ICMP"
|
||||
msgstr "ICMP"
|
||||
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
msgid "IP Version"
|
||||
msgstr "IP バージョン"
|
||||
|
||||
msgid "IP Version for Firewall Rule"
|
||||
msgstr "ファイアウォールルールの IP バージョン"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Inactive"
|
||||
msgstr "非稼働"
|
||||
|
||||
msgid "Ingress Policy"
|
||||
msgstr "受信ポリシー"
|
||||
|
||||
msgid "Ingress Policy ID"
|
||||
msgstr "受信ポリシー ID"
|
||||
|
||||
msgid "Insert Rule"
|
||||
msgstr "ルールの挿入"
|
||||
|
||||
msgid "Insert Rule to Policy"
|
||||
msgstr "ポリシーへのルールの挿入"
|
||||
|
||||
msgid "Label"
|
||||
msgstr "ラベル"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "名前"
|
||||
|
||||
msgid "No options available"
|
||||
msgstr "利用可能なオプションはありません"
|
||||
|
||||
msgid "None"
|
||||
msgstr "なし"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Create"
|
||||
msgstr "作成待ち"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Delete"
|
||||
msgstr "削除待ち"
|
||||
|
||||
msgctxt "Current status of a Firewall Group"
|
||||
msgid "Pending Update"
|
||||
msgstr "更新待ち"
|
||||
|
||||
msgid "Policies"
|
||||
msgstr "ポリシー"
|
||||
|
||||
msgid "Policy"
|
||||
msgstr "ポリシー"
|
||||
|
||||
#, python-format
|
||||
msgid "Policy %s was successfully updated."
|
||||
msgstr "ポリシー %s が正常に更新されました。"
|
||||
|
||||
msgid "Ports"
|
||||
msgstr "ポート"
|
||||
|
||||
msgid "Project ID"
|
||||
msgstr "プロジェクト ID"
|
||||
|
||||
msgid "Protocol"
|
||||
msgstr "プロトコル"
|
||||
|
||||
msgid "Protocol for the firewall rule"
|
||||
msgstr "ファイアウォールルールのプロトコル"
|
||||
|
||||
msgid "REJECT"
|
||||
msgstr "REJECT"
|
||||
|
||||
msgctxt "Action Name of a Firewall Rule"
|
||||
msgid "REJECT"
|
||||
msgstr "REJECT"
|
||||
|
||||
msgid "Remove Port"
|
||||
msgstr "ポートの削除"
|
||||
|
||||
msgid "Remove Port from Firewall Group"
|
||||
msgstr "ファイアウォールグループからのポートの削除"
|
||||
|
||||
msgid "Remove Rule"
|
||||
msgstr "ルールの削除"
|
||||
|
||||
msgid "Remove Rule from Policy"
|
||||
msgstr "ポリシーからのルールの削除"
|
||||
|
||||
msgid "Remove port from FirewallGroup {{ name }}"
|
||||
msgstr "ファイアウォールグループ {{ name }} からのポートの削除"
|
||||
|
||||
#, python-format
|
||||
msgid "Removed the port(s) from the firewall group %s successfully."
|
||||
msgstr "ポートを正常にファイアウォールグループ %s から削除しました。"
|
||||
|
||||
msgid "Rule"
|
||||
msgstr "ルール"
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully inserted to policy %(policy)s."
|
||||
msgstr "ルール %(rule)s のポリシー %(policy)s への挿入に成功しました。"
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %(rule)s was successfully removed from policy %(policy)s."
|
||||
msgstr "ポリシー %(policy)s からのルール %(rule)s の削除に成功しました。"
|
||||
|
||||
#, python-format
|
||||
msgid "Rule %s was successfully updated."
|
||||
msgstr "ルール %s が正常に更新されました。"
|
||||
|
||||
msgid "Rules"
|
||||
msgstr "ルール"
|
||||
|
||||
msgid "Save Changes"
|
||||
msgstr "変更の保存"
|
||||
|
||||
msgid "Scheduled deletion of Firewall Group"
|
||||
msgid_plural "Scheduled deletion of Firewall Groups"
|
||||
msgstr[0] "ファイアウォールグループの削除を予約しました"
|
||||
|
||||
msgid "Scheduled deletion of Policy"
|
||||
msgid_plural "Scheduled deletion of Policies"
|
||||
msgstr[0] "ポリシーの削除を予約しました"
|
||||
|
||||
msgid "Scheduled deletion of Rule"
|
||||
msgid_plural "Scheduled deletion of Rules"
|
||||
msgstr[0] "ルールの削除を予約しました"
|
||||
|
||||
msgid "Select a Policy"
|
||||
msgstr "ポリシーを選択してください"
|
||||
|
||||
msgid "Select ports for your firewall group."
|
||||
msgstr "ファイアウォールグループを適用するポートを選択してください。"
|
||||
|
||||
msgid "Select rules for your policy."
|
||||
msgstr "ポリシーに追加するルールの選択"
|
||||
|
||||
msgid "Selected Ports"
|
||||
msgstr "選択済みポート"
|
||||
|
||||
msgid "Selected Rules"
|
||||
msgstr "選択済みのルール"
|
||||
|
||||
msgid "Shared"
|
||||
msgstr "共有"
|
||||
|
||||
msgid "Source IP"
|
||||
msgstr "送信元 IP"
|
||||
|
||||
msgid "Source IP Address"
|
||||
msgstr "送信元 IP アドレス"
|
||||
|
||||
msgid "Source IP Address/Subnet"
|
||||
msgstr "送信元 IP アドレス/サブネット"
|
||||
|
||||
msgid "Source IP address or subnet"
|
||||
msgstr "送信元 IP アドレスまたはサブネット"
|
||||
|
||||
msgid "Source Port"
|
||||
msgstr "送信元ポート番号"
|
||||
|
||||
msgid "Source Port/Port Range"
|
||||
msgstr "送信元ポート/ポートの範囲"
|
||||
|
||||
msgid "Source port (integer in [1, 65535] or range in a:b)"
|
||||
msgstr "送信元ポート ([1, 65535] の整数か a:b 形式の範囲)"
|
||||
|
||||
msgid ""
|
||||
"Source/Destination Network Address and IP version are inconsistent. Please "
|
||||
"make them consistent."
|
||||
msgstr ""
|
||||
"送信元 / 送信先のネットワークアドレスと IP バージョンが一致していません。これ"
|
||||
"らを一致させてください。"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "ステータス"
|
||||
|
||||
msgid "TCP"
|
||||
msgstr "TCP"
|
||||
|
||||
msgid "UDP"
|
||||
msgstr "UDP"
|
||||
|
||||
msgctxt "Admin state of a Firewall Group"
|
||||
msgid "UP"
|
||||
msgstr "UP"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Firewall Group \"%s\"."
|
||||
msgstr "ファイアウォールグループ \"%s\" を追加できません。"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Policy \"%s\"."
|
||||
msgstr "ポリシー \"%s\" を追加できません。"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to add Rule \"%s\"."
|
||||
msgstr "ルール \"%s\" を追加できません。"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete firewall group. %s"
|
||||
msgstr "ファイアウォールグループを削除できません: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete policy. %s"
|
||||
msgstr "ポリシーを削除できません: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to delete rule. %s"
|
||||
msgstr "ルールを削除できません: %s"
|
||||
|
||||
msgid "Unable to retrieve firewall group details."
|
||||
msgstr "ファイアウォールグループの詳細を取得できません。"
|
||||
|
||||
msgid "Unable to retrieve firewall group list."
|
||||
msgstr "ファイアウォールグループの一覧を取得できません。"
|
||||
|
||||
msgid "Unable to retrieve firewallgroup details."
|
||||
msgstr "ファイアウォールグループの詳細を取得できません。"
|
||||
|
||||
msgid "Unable to retrieve policies list."
|
||||
msgstr "ポリシー一覧を取得できません。"
|
||||
|
||||
msgid "Unable to retrieve policy details."
|
||||
msgstr "ポリシーの詳細を取得できません。"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve policy list (%s)."
|
||||
msgstr "ポリシー覧を取得できません (%s)"
|
||||
|
||||
msgid "Unable to retrieve policy list."
|
||||
msgstr "ポリシー一覧を取得できません。"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve ports (%s)."
|
||||
msgstr "ポートを取得できません (%s)"
|
||||
|
||||
msgid "Unable to retrieve rule details."
|
||||
msgstr "ルールの詳細を取得できません。"
|
||||
|
||||
#, python-format
|
||||
msgid "Unable to retrieve rules (%s)."
|
||||
msgstr "ルール一覧を取得できません (%s)"
|
||||
|
||||
msgid "Unable to retrieve rules list."
|
||||
msgstr "ルール一覧を取得できません。"
|
||||
|
||||
msgid "Value"
|
||||
msgstr "値"
|
||||
|
||||
msgid "You may add ports to firewall group here."
|
||||