Retire neutron-fwaas project
Governance change is proposed at [1] and project config patch is proposed at [2] [1] https://review.opendev.org/735828 [2] https://review.opendev.org/#/c/735812/ Change-Id: I561504160e5548c54d1af31821c3366ab34cf0ec
This commit is contained in:
parent
94c0d54ded
commit
caae7b6a6f
@ -1,7 +0,0 @@
|
|||||||
[run]
|
|
||||||
branch = True
|
|
||||||
source = neutron_fwaas
|
|
||||||
omit = neutron_fwaas/tests/*
|
|
||||||
|
|
||||||
[report]
|
|
||||||
ignore_errors = True
|
|
37
.gitignore
vendored
37
.gitignore
vendored
@ -1,37 +0,0 @@
|
|||||||
AUTHORS
|
|
||||||
build/*
|
|
||||||
build-stamp
|
|
||||||
ChangeLog
|
|
||||||
cover/
|
|
||||||
covhtml/
|
|
||||||
dist/
|
|
||||||
doc/build
|
|
||||||
doc/source/_static/config_samples/*.sample
|
|
||||||
doc/source/_static/*.policy.yaml.sample
|
|
||||||
doc/source/contributor/api/
|
|
||||||
etc/*.sample
|
|
||||||
*.DS_Store
|
|
||||||
*.pyc
|
|
||||||
neutron.egg-info/
|
|
||||||
neutron_fwaas.egg-info/
|
|
||||||
neutron/vcsversion.py
|
|
||||||
neutron/versioninfo
|
|
||||||
pbr*.egg/
|
|
||||||
run_tests.err.log
|
|
||||||
run_tests.log
|
|
||||||
setuptools*.egg/
|
|
||||||
subunit.log
|
|
||||||
*.mo
|
|
||||||
*.sw?
|
|
||||||
*~
|
|
||||||
/.*
|
|
||||||
!/.coveragerc
|
|
||||||
!/.gitignore
|
|
||||||
!/.gitreview
|
|
||||||
!/.mailmap
|
|
||||||
!/.pylintrc
|
|
||||||
!/.zuul.yaml
|
|
||||||
!/.stestr.conf
|
|
||||||
|
|
||||||
# Files created by releasenotes build
|
|
||||||
releasenotes/build
|
|
11
.mailmap
11
.mailmap
@ -1,11 +0,0 @@
|
|||||||
# Format is:
|
|
||||||
# <preferred e-mail> <other e-mail 1>
|
|
||||||
# <preferred e-mail> <other e-mail 2>
|
|
||||||
lawrancejing <lawrancejing@gmail.com> <liuqing@windawn.com>
|
|
||||||
Jiajun Liu <jiajun@unitedstack.com> <iamljj@gmail.com>
|
|
||||||
Zhongyue Luo <zhongyue.nah@intel.com> <lzyeval@gmail.com>
|
|
||||||
Kun Huang <gareth@unitedstack.com> <academicgareth@gmail.com>
|
|
||||||
Zhenguo Niu <zhenguo@unitedstack.com> <Niu.ZGlinux@gmail.com>
|
|
||||||
Isaku Yamahata <isaku.yamahata@intel.com> <isaku.yamahata@gmail.com>
|
|
||||||
Isaku Yamahata <isaku.yamahata@intel.com> <yamahata@private.email.ne.jp>
|
|
||||||
Morgan Fainberg <morgan.fainberg@gmail.com> <m@metacloud.com>
|
|
130
.pylintrc
130
.pylintrc
@ -1,130 +0,0 @@
|
|||||||
# The format of this file isn't really documented; just use --generate-rcfile
|
|
||||||
[MASTER]
|
|
||||||
# Add <file or directory> to the black list. It should be a base name, not a
|
|
||||||
# path. You may set this option multiple times.
|
|
||||||
#
|
|
||||||
ignore=.git,tests
|
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
|
||||||
# NOTE(gus): This is a long list. A number of these are important and
|
|
||||||
# should be re-enabled once the offending code is fixed (or marked
|
|
||||||
# with a local disable)
|
|
||||||
disable=
|
|
||||||
# "F" Fatal errors that prevent further processing
|
|
||||||
import-error,
|
|
||||||
# "I" Informational noise
|
|
||||||
locally-disabled,
|
|
||||||
# "E" Error for important programming issues (likely bugs)
|
|
||||||
access-member-before-definition,
|
|
||||||
bad-super-call,
|
|
||||||
maybe-no-member,
|
|
||||||
no-member,
|
|
||||||
no-method-argument,
|
|
||||||
no-self-argument,
|
|
||||||
not-callable,
|
|
||||||
no-value-for-parameter,
|
|
||||||
super-on-old-class,
|
|
||||||
too-few-format-args,
|
|
||||||
# "W" Warnings for stylistic problems or minor programming issues
|
|
||||||
abstract-method,
|
|
||||||
anomalous-backslash-in-string,
|
|
||||||
anomalous-unicode-escape-in-string,
|
|
||||||
arguments-differ,
|
|
||||||
attribute-defined-outside-init,
|
|
||||||
bad-builtin,
|
|
||||||
bad-indentation,
|
|
||||||
broad-except,
|
|
||||||
dangerous-default-value,
|
|
||||||
deprecated-lambda,
|
|
||||||
duplicate-key,
|
|
||||||
expression-not-assigned,
|
|
||||||
fixme,
|
|
||||||
global-statement,
|
|
||||||
global-variable-not-assigned,
|
|
||||||
logging-not-lazy,
|
|
||||||
no-init,
|
|
||||||
non-parent-init-called,
|
|
||||||
pointless-string-statement,
|
|
||||||
protected-access,
|
|
||||||
redefined-builtin,
|
|
||||||
redefined-outer-name,
|
|
||||||
redefine-in-handler,
|
|
||||||
signature-differs,
|
|
||||||
star-args,
|
|
||||||
super-init-not-called,
|
|
||||||
unnecessary-lambda,
|
|
||||||
unnecessary-pass,
|
|
||||||
unpacking-non-sequence,
|
|
||||||
unreachable,
|
|
||||||
unused-argument,
|
|
||||||
unused-import,
|
|
||||||
unused-variable,
|
|
||||||
# TODO(dougwig) - disable nonstandard-exception while we have neutron_lib shims
|
|
||||||
nonstandard-exception,
|
|
||||||
# "C" Coding convention violations
|
|
||||||
bad-continuation,
|
|
||||||
invalid-name,
|
|
||||||
missing-docstring,
|
|
||||||
old-style-class,
|
|
||||||
superfluous-parens,
|
|
||||||
# "R" Refactor recommendations
|
|
||||||
abstract-class-little-used,
|
|
||||||
abstract-class-not-used,
|
|
||||||
duplicate-code,
|
|
||||||
interface-not-implemented,
|
|
||||||
no-self-use,
|
|
||||||
too-few-public-methods,
|
|
||||||
too-many-ancestors,
|
|
||||||
too-many-arguments,
|
|
||||||
too-many-branches,
|
|
||||||
too-many-instance-attributes,
|
|
||||||
too-many-lines,
|
|
||||||
too-many-locals,
|
|
||||||
too-many-public-methods,
|
|
||||||
too-many-return-statements,
|
|
||||||
too-many-statements
|
|
||||||
|
|
||||||
[BASIC]
|
|
||||||
# Variable names can be 1 to 31 characters long, with lowercase and underscores
|
|
||||||
variable-rgx=[a-z_][a-z0-9_]{0,30}$
|
|
||||||
|
|
||||||
# Argument names can be 2 to 31 characters long, with lowercase and underscores
|
|
||||||
argument-rgx=[a-z_][a-z0-9_]{1,30}$
|
|
||||||
|
|
||||||
# Method names should be at least 3 characters long
|
|
||||||
# and be lowercased with underscores
|
|
||||||
method-rgx=([a-z_][a-z0-9_]{2,}|setUp|tearDown)$
|
|
||||||
|
|
||||||
# Module names matching neutron-* are ok (files in bin/)
|
|
||||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|(neutron-[a-z0-9_-]+))$
|
|
||||||
|
|
||||||
# Don't require docstrings on tests.
|
|
||||||
no-docstring-rgx=((__.*__)|([tT]est.*)|setUp|tearDown)$
|
|
||||||
|
|
||||||
[FORMAT]
|
|
||||||
# Maximum number of characters on a single line.
|
|
||||||
max-line-length=79
|
|
||||||
|
|
||||||
[VARIABLES]
|
|
||||||
# List of additional names supposed to be defined in builtins. Remember that
|
|
||||||
# you should avoid to define new builtins when possible.
|
|
||||||
# _ is used by our localization
|
|
||||||
additional-builtins=_
|
|
||||||
|
|
||||||
[CLASSES]
|
|
||||||
# List of interface methods to ignore, separated by a comma.
|
|
||||||
ignore-iface-methods=
|
|
||||||
|
|
||||||
[IMPORTS]
|
|
||||||
# Deprecated modules which should not be used, separated by a comma
|
|
||||||
deprecated-modules=
|
|
||||||
# should use oslo_serialization.jsonutils
|
|
||||||
json
|
|
||||||
|
|
||||||
[TYPECHECK]
|
|
||||||
# List of module names for which member attributes should not be checked
|
|
||||||
ignored-modules=six.moves,_MovedItems
|
|
||||||
|
|
||||||
[REPORTS]
|
|
||||||
# Tells whether to display a full report or only the messages
|
|
||||||
reports=no
|
|
@ -1,3 +0,0 @@
|
|||||||
[DEFAULT]
|
|
||||||
test_path=${OS_TEST_PATH:-./neutron_fwaas/tests/unit}
|
|
||||||
top_dir=./
|
|
72
.zuul.yaml
72
.zuul.yaml
@ -1,72 +0,0 @@
|
|||||||
- project:
|
|
||||||
templates:
|
|
||||||
- check-requirements
|
|
||||||
- openstack-cover-jobs-neutron
|
|
||||||
- openstack-lower-constraints-jobs-neutron
|
|
||||||
- openstack-python3-ussuri-jobs-neutron
|
|
||||||
- periodic-stable-jobs-neutron
|
|
||||||
- publish-openstack-docs-pti
|
|
||||||
- release-notes-jobs-python3
|
|
||||||
check:
|
|
||||||
jobs:
|
|
||||||
- neutron-fwaas-functional
|
|
||||||
- neutron-tempest-plugin-fwaas
|
|
||||||
- neutron-fwaas-v2-dsvm-tempest-multinode:
|
|
||||||
voting: false
|
|
||||||
gate:
|
|
||||||
jobs:
|
|
||||||
- neutron-fwaas-functional
|
|
||||||
- neutron-tempest-plugin-fwaas
|
|
||||||
experimental:
|
|
||||||
jobs:
|
|
||||||
- neutron-fwaas-fullstack
|
|
||||||
|
|
||||||
- job:
|
|
||||||
name: neutron-fwaas-functional
|
|
||||||
parent: neutron-functional
|
|
||||||
vars:
|
|
||||||
project_name: neutron-fwaas
|
|
||||||
|
|
||||||
- job:
|
|
||||||
name: neutron-fwaas-fullstack
|
|
||||||
parent: neutron-fullstack
|
|
||||||
vars:
|
|
||||||
project_name: neutron-fwaas
|
|
||||||
|
|
||||||
- job:
|
|
||||||
name: neutron-fwaas-v2-dsvm-tempest-multinode
|
|
||||||
parent: tempest-multinode-full-py3
|
|
||||||
roles:
|
|
||||||
- zuul: openstack/devstack
|
|
||||||
required-projects:
|
|
||||||
- openstack/devstack-gate
|
|
||||||
- openstack/neutron
|
|
||||||
- openstack/neutron-fwaas
|
|
||||||
- openstack/neutron-tempest-plugin
|
|
||||||
- openstack/tempest
|
|
||||||
vars:
|
|
||||||
tox_envlist: all-plugin
|
|
||||||
tempest_test_regex: ^neutron_tempest_plugin\.fwaas
|
|
||||||
devstack_plugins:
|
|
||||||
neutron: https://opendev.org/openstack/neutron.git
|
|
||||||
neutron-fwaas: https://opendev.org/openstack/neutron-fwaas.git
|
|
||||||
neutron-tempest-plugin: https://opendev.org/openstack/neutron-tempest-plugin.git
|
|
||||||
devstack_services:
|
|
||||||
q-fwaas-v2: true
|
|
||||||
devstack_localrc:
|
|
||||||
NETWORK_API_EXTENSIONS: "agent,binding,dhcp_agent_scheduler,external-net,ext-gw-mode,extra_dhcp_opts,quotas,router,security-group,subnet_allocation,network-ip-availability,auto-allocated-topology,timestamp_core,tag,service-type,rbac-policies,standard-attr-description,pagination,sorting,project-id,fwaas_v2"
|
|
||||||
group-vars:
|
|
||||||
subnode:
|
|
||||||
devstack_services:
|
|
||||||
q-agt: true
|
|
||||||
devstack_localrc:
|
|
||||||
USE_PYTHON3: true
|
|
||||||
devstack_local_conf:
|
|
||||||
post-config:
|
|
||||||
# NOTE(slaweq): We can get rid of this hardcoded absolute path when
|
|
||||||
# devstack-tempest job will be switched to use lib/neutron instead of
|
|
||||||
# lib/neutron-legacy
|
|
||||||
"/$NEUTRON_CORE_PLUGIN_CONF":
|
|
||||||
ovs:
|
|
||||||
tunnel_bridge: br-tun
|
|
||||||
bridge_mappings: public:br-ex
|
|
@ -1,4 +0,0 @@
|
|||||||
Please see the Neutron CONTRIBUTING.rst file for how to contribute to
|
|
||||||
neutron-fwaas:
|
|
||||||
|
|
||||||
`Neutron CONTRIBUTING.rst <https://opendev.org/openstack/neutron/src/branch/master/CONTRIBUTING.rst>`_
|
|
@ -1,7 +0,0 @@
|
|||||||
Neutron FWaaS Style Commandments
|
|
||||||
================================
|
|
||||||
|
|
||||||
Please see the Neutron HACKING.rst file for style commandments for
|
|
||||||
neutron-fwaas:
|
|
||||||
|
|
||||||
`Neutron HACKING.rst <https://opendev.org/openstack/neutron/src/branch/master/HACKING.rst>`_
|
|
176
LICENSE
176
LICENSE
@ -1,176 +0,0 @@
|
|||||||
|
|
||||||
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.
|
|
||||||
|
|
44
README.rst
44
README.rst
@ -1,38 +1,10 @@
|
|||||||
========================
|
This project is no longer maintained.
|
||||||
Team and repository tags
|
|
||||||
========================
|
|
||||||
|
|
||||||
.. image:: https://governance.openstack.org/tc/badges/neutron-fwaas.svg
|
The contents of this repository are still available in the Git
|
||||||
:target: https://governance.openstack.org/tc/reference/tags/index.html
|
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".
|
||||||
|
|
||||||
.. Change things from this point on
|
For any further questions, please email
|
||||||
|
openstack-discuss@lists.openstack.org or join #openstack-dev on
|
||||||
.. warning::
|
Freenode.
|
||||||
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.
|
|
||||||
|
|
||||||
Welcome!
|
|
||||||
========
|
|
||||||
|
|
||||||
This package contains the code for the Neutron Firewall as a Service
|
|
||||||
(FWaaS) service. This package requires Neutron to run.
|
|
||||||
|
|
||||||
External Resources:
|
|
||||||
===================
|
|
||||||
|
|
||||||
The homepage for Neutron is: https://launchpad.net/neutron. Use this
|
|
||||||
site for asking for help, and filing bugs. We use a single Launchpad
|
|
||||||
page for all Neutron projects.
|
|
||||||
|
|
||||||
Code is available on git.openstack.org at:
|
|
||||||
<https://opendev.org/openstack/neutron-fwaas>.
|
|
||||||
|
|
||||||
Please refer to Neutron documentation for more information:
|
|
||||||
`Neutron README.rst <https://opendev.org/openstack/neutron/src/branch/master/README.rst>`_
|
|
||||||
|
|
||||||
Get release notes:
|
|
||||||
`Neutron FWaaS Release Notes <https://docs.openstack.org/releasenotes/neutron-fwaas/>`_
|
|
||||||
|
12
TESTING.rst
12
TESTING.rst
@ -1,12 +0,0 @@
|
|||||||
Testing Neutron FWaaS
|
|
||||||
=====================
|
|
||||||
|
|
||||||
Please see the TESTING.rst file for the Neutron project itself. This will have
|
|
||||||
the latest up to date instructions for how to test Neutron, and will
|
|
||||||
be applicable to neutron-fwaas as well:
|
|
||||||
|
|
||||||
`Neutron TESTING.rst <https://opendev.org/openstack/neutron/src/branch/master/TESTING.rst>`_
|
|
||||||
|
|
||||||
For instructions on how to use FWaaS with devstack, look at:
|
|
||||||
|
|
||||||
`Neutron-FWaaS DevStack <https://opendev.org/openstack/neutron-fwaas/src/branch/master/devstack/README.rst>`_
|
|
10
bindep.txt
10
bindep.txt
@ -1,10 +0,0 @@
|
|||||||
# This file contains runtime (non-python) dependencies
|
|
||||||
# More info at: http://docs.openstack.org/infra/bindep/readme.html
|
|
||||||
|
|
||||||
# MySQL and PostgreSQL databases since some jobs are set up in
|
|
||||||
# OpenStack infra that need these like
|
|
||||||
libpq-dev [test]
|
|
||||||
|
|
||||||
# Packages required e.g. in functional tests
|
|
||||||
libnetfilter-log1 [platform:dpkg platform:suse]
|
|
||||||
libnetfilter-log [platform:rpm !platform:suse]
|
|
@ -1,30 +0,0 @@
|
|||||||
=========================
|
|
||||||
neutron-fwaas in DevStack
|
|
||||||
=========================
|
|
||||||
|
|
||||||
This is setup as a DevStack plugin. For more information on DevStack plugins,
|
|
||||||
see the `DevStack Plugins documentation
|
|
||||||
<https://docs.openstack.org/devstack/latest/plugins.html>`_.
|
|
||||||
|
|
||||||
Please note that the old 'q-fwaas' keyword still exists, You can specify
|
|
||||||
enable_service q-fwaas or enable_service q-fwaas-v2 in local.conf
|
|
||||||
|
|
||||||
How to run FWaaS V2 in DevStack
|
|
||||||
===============================
|
|
||||||
|
|
||||||
Add the following to the localrc section of your local.conf to configure
|
|
||||||
FWaaS v2.
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[[local|localrc]]
|
|
||||||
enable_plugin neutron-fwaas https://git.openstack.org/openstack/neutron-fwaas
|
|
||||||
|
|
||||||
To check a specific patchset that is currently under development, use a form
|
|
||||||
like the below example, which is checking out change 214350 patch set 14 for
|
|
||||||
testing.
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[[local|localrc]]
|
|
||||||
enable_plugin neutron-fwaas https://review.openstack.org/p/openstack/neutron-fwaas refs/changes/50/214350/14
|
|
@ -1,16 +0,0 @@
|
|||||||
# This file was shamelessly stolen from the neutron repository here:
|
|
||||||
# https://opendev.org/openstack/neutron/src/branch/master/devstack/lib/l2_agent
|
|
||||||
|
|
||||||
function plugin_agent_add_l2_agent_extension {
|
|
||||||
local l2_agent_extension=$1
|
|
||||||
if [[ -z "$L2_AGENT_EXTENSIONS" ]]; then
|
|
||||||
L2_AGENT_EXTENSIONS=$l2_agent_extension
|
|
||||||
elif [[ ! ,${L2_AGENT_EXTENSIONS}, =~ ,${l2_agent_extension}, ]]; then
|
|
||||||
L2_AGENT_EXTENSIONS+=",$l2_agent_extension"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function configure_l2_agent {
|
|
||||||
iniset /$Q_PLUGIN_CONF_FILE agent extensions "$L2_AGENT_EXTENSIONS"
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
# This file is completely based on one in the neutron repository here:
|
|
||||||
# https://opendev.org/openstack/neutron/src/branch/master/devstack/lib/l2_agent
|
|
||||||
|
|
||||||
function plugin_agent_add_l3_agent_extension {
|
|
||||||
local l3_agent_extension=$1
|
|
||||||
if [[ -z "$L3_AGENT_EXTENSIONS" ]]; then
|
|
||||||
L3_AGENT_EXTENSIONS=$l3_agent_extension
|
|
||||||
elif [[ ! ,${L3_AGENT_EXTENSIONS}, =~ ,${l3_agent_extension}, ]]; then
|
|
||||||
L3_AGENT_EXTENSIONS+=",$l3_agent_extension"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function configure_l3_agent {
|
|
||||||
iniset $Q_L3_CONF_FILE agent extensions "$L3_AGENT_EXTENSIONS"
|
|
||||||
}
|
|
@ -1,145 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
# Dependencies:
|
|
||||||
#
|
|
||||||
# ``functions`` file
|
|
||||||
# ``DEST`` must be defined
|
|
||||||
|
|
||||||
# Save trace setting
|
|
||||||
XTRACE=$(set +o | grep xtrace)
|
|
||||||
set +o xtrace
|
|
||||||
|
|
||||||
# Source in L2 and L3 agent extension management
|
|
||||||
LIBDIR=$DEST/neutron-fwaas/devstack/lib
|
|
||||||
source $LIBDIR/l2_agent
|
|
||||||
source $LIBDIR/l3_agent
|
|
||||||
|
|
||||||
function install_fwaas() {
|
|
||||||
# Install the service.
|
|
||||||
:
|
|
||||||
setup_develop $DEST/neutron-fwaas
|
|
||||||
if is_ubuntu; then
|
|
||||||
install_package libnetfilter-log1
|
|
||||||
else
|
|
||||||
# EPEL
|
|
||||||
install_package libnetfilter_log
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function configure_fwaas_v2() {
|
|
||||||
# Add conf file
|
|
||||||
cp $NEUTRON_FWAAS_DIR/etc/neutron_fwaas.conf.sample $NEUTRON_FWAAS_CONF
|
|
||||||
neutron_server_config_add $NEUTRON_FWAAS_CONF
|
|
||||||
inicomment $NEUTRON_FWAAS_CONF service_providers service_provider
|
|
||||||
iniadd $NEUTRON_FWAAS_CONF service_providers service_provider $NEUTRON_FWAAS_SERVICE_PROVIDERV2
|
|
||||||
|
|
||||||
neutron_fwaas_configure_driver fwaas_v2
|
|
||||||
if is_service_enabled q-l3; then
|
|
||||||
iniset_multiline $Q_L3_CONF_FILE fwaas agent_version v2
|
|
||||||
iniset_multiline $Q_L3_CONF_FILE fwaas driver $FWAAS_DRIVER_V2
|
|
||||||
fi
|
|
||||||
if is_service_enabled q-agt; then
|
|
||||||
# TODO(hoangcx) we can remove the slashes below once neutron-legacy has gone
|
|
||||||
iniset /$NEUTRON_CORE_PLUGIN_CONF fwaas firewall_l2_driver $FW_L2_DRIVER
|
|
||||||
iniset /$NEUTRON_CORE_PLUGIN_CONF agent extensions fwaas_v2
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function configure_l3_log_fwaas_v2(){
|
|
||||||
if is_service_enabled q-l3; then
|
|
||||||
iniadd $Q_L3_CONF_FILE agent extensions fwaas_v2_log
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function neutron_fwaas_generate_config_files {
|
|
||||||
(cd $NEUTRON_FWAAS_DIR && exec ./tools/generate_config_file_samples.sh)
|
|
||||||
}
|
|
||||||
|
|
||||||
function init_fwaas() {
|
|
||||||
# Initialize and start the service.
|
|
||||||
:
|
|
||||||
# Using sudo to gain the root privilege to be able to copy file to rootwrap.d
|
|
||||||
sudo cp $DEST/neutron-fwaas/etc/neutron/rootwrap.d/fwaas-privsep.filters /etc/neutron/rootwrap.d/fwaas-privsep.filters
|
|
||||||
}
|
|
||||||
|
|
||||||
function shutdown_fwaas() {
|
|
||||||
# Shut the service down.
|
|
||||||
:
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanup_fwaas() {
|
|
||||||
# Cleanup the service.
|
|
||||||
:
|
|
||||||
if is_ubuntu; then
|
|
||||||
uninstall_package libnetfilter-log1
|
|
||||||
else
|
|
||||||
# EPEL
|
|
||||||
uninstall_package libnetfilter_log
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function neutron_fwaas_configure_common {
|
|
||||||
neutron_service_plugin_class_add $FWAAS_PLUGIN_V2
|
|
||||||
}
|
|
||||||
|
|
||||||
function neutron_fwaas_configure_driver {
|
|
||||||
if is_service_enabled q-l3; then
|
|
||||||
plugin_agent_add_l3_agent_extension $1
|
|
||||||
configure_l3_agent
|
|
||||||
iniset_multiline $Q_L3_CONF_FILE fwaas enabled True
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# check for service enabled
|
|
||||||
if is_service_enabled q-svc neutron-api && is_service_enabled q-fwaas q-fwaas-v2 neutron-fwaas-v2; then
|
|
||||||
|
|
||||||
if [[ "$1" == "stack" && "$2" == "install" ]]; then
|
|
||||||
# Perform installation of service source
|
|
||||||
echo_summary "Installing neutron-fwaas"
|
|
||||||
install_fwaas
|
|
||||||
|
|
||||||
elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
|
|
||||||
# Configure after the other layer 1 and 2 services have been configured
|
|
||||||
neutron_fwaas_configure_common
|
|
||||||
neutron_fwaas_generate_config_files
|
|
||||||
echo_summary "Configuring neutron-fwaas for FWaaS v2"
|
|
||||||
configure_fwaas_v2
|
|
||||||
if is_service_enabled q-log neutron-log; then
|
|
||||||
echo_summary "Configuring FwaaS V2 packet log for l3 extension"
|
|
||||||
configure_l3_log_fwaas_v2
|
|
||||||
fi
|
|
||||||
|
|
||||||
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
|
|
||||||
# Initialize and start the neutron-fwaas service
|
|
||||||
echo_summary "Initializing neutron-fwaas"
|
|
||||||
init_fwaas
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$1" == "unstack" ]]; then
|
|
||||||
# Shut down neutron-fwaas services
|
|
||||||
# no-op
|
|
||||||
shutdown_fwaas
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$1" == "clean" ]]; then
|
|
||||||
# Remove state and transient data
|
|
||||||
# Remember clean.sh first calls unstack.sh
|
|
||||||
# no-op
|
|
||||||
cleanup_fwaas
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Restore xtrace
|
|
||||||
$XTRACE
|
|
@ -1,12 +0,0 @@
|
|||||||
FWAAS_DRIVER_V2=${FWAAS_DRIVER_V2:-iptables_v2}
|
|
||||||
FW_L2_DRIVER=${FW_L2_DRIVER:-noop}
|
|
||||||
FWAAS_PLUGIN_V2=${FWAAS_PLUGIN:-firewall_v2}
|
|
||||||
|
|
||||||
NEUTRON_FWAAS_DIR=$DEST/neutron-fwaas
|
|
||||||
NEUTRON_FWAAS_CONF_FILE=neutron_fwaas.conf
|
|
||||||
|
|
||||||
NEUTRON_FWAAS_CONF=$NEUTRON_CONF_DIR/$NEUTRON_FWAAS_CONF_FILE
|
|
||||||
|
|
||||||
NEUTRON_FWAAS_SERVICE_PROVIDERV2=${NEUTRON_FWAAS_SERVICE_PROVIDERV2:-FIREWALL_V2:fwaas_db:neutron_fwaas.services.firewall.service_drivers.agents.agents.FirewallAgentDriver:default}
|
|
||||||
|
|
||||||
enable_service q-fwaas-v2
|
|
@ -1,8 +0,0 @@
|
|||||||
# The order of packages is significant, because pip processes them in the order
|
|
||||||
# of appearance. Changing the order has an impact on the overall integration
|
|
||||||
# process, which may cause wedges in the gate later.
|
|
||||||
sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
|
|
||||||
sphinxcontrib-apidoc>=0.2.0 # BSD
|
|
||||||
sphinxmark>=0.1.14 # Apache-2.0
|
|
||||||
openstackdocstheme>=1.18.1 # Apache-2.0
|
|
||||||
reno>=2.5.0 # Apache-2.0
|
|
@ -1,311 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2010 OpenStack Foundation.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
#
|
|
||||||
# Keystone documentation build configuration file, created by
|
|
||||||
# sphinx-quickstart on Tue May 18 13:50:15 2010.
|
|
||||||
#
|
|
||||||
# This file is execfile()'d with the current directory set to it's 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
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
ROOT_DIR = os.path.abspath(os.path.join(BASE_DIR, "..", ".."))
|
|
||||||
sys.path.insert(0, ROOT_DIR)
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
|
||||||
extensions = ['sphinxcontrib.apidoc',
|
|
||||||
'sphinx.ext.coverage',
|
|
||||||
'sphinx.ext.ifconfig',
|
|
||||||
'sphinx.ext.graphviz',
|
|
||||||
'sphinx.ext.todo',
|
|
||||||
'oslo_config.sphinxext',
|
|
||||||
'oslo_config.sphinxconfiggen',
|
|
||||||
'oslo_policy.sphinxext',
|
|
||||||
'oslo_policy.sphinxpolicygen',
|
|
||||||
'openstackdocstheme',]
|
|
||||||
|
|
||||||
try:
|
|
||||||
import openstackdocstheme
|
|
||||||
extensions.append('openstackdocstheme')
|
|
||||||
except ImportError:
|
|
||||||
openstackdocstheme = None
|
|
||||||
|
|
||||||
todo_include_todos = True
|
|
||||||
|
|
||||||
# sphinxcontrib.apidoc options
|
|
||||||
apidoc_module_dir = '../../neutron_fwaas'
|
|
||||||
apidoc_output_dir = 'contributor/api'
|
|
||||||
# TODO(hoangcx): remove 'services/logapi/*' and
|
|
||||||
# 'services/firewall/fwaas_plugin_v2.py' after the next neutron release
|
|
||||||
# (current release is Rocky-3)
|
|
||||||
|
|
||||||
# NOTE(longkb): Due to libnetfilter_log library is not installed in sphinx-docs
|
|
||||||
# gate, so we would like to ignore 'privileged/netfilter_log/*'.
|
|
||||||
|
|
||||||
apidoc_excluded_paths = [
|
|
||||||
'db/migration/alembic_migrations/*',
|
|
||||||
'privileged/netfilter_log/*',
|
|
||||||
'services/firewall/fwaas_plugin_v2.py',
|
|
||||||
'services/logapi/*',
|
|
||||||
'setup.py',
|
|
||||||
'tests/*',
|
|
||||||
'tests']
|
|
||||||
apidoc_separate_modules = True
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = []
|
|
||||||
|
|
||||||
# The suffix of source filenames.
|
|
||||||
source_suffix = '.rst'
|
|
||||||
|
|
||||||
# The encoding of source files.
|
|
||||||
#source_encoding = 'utf-8'
|
|
||||||
|
|
||||||
# The master toctree document.
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
# General information about the project.
|
|
||||||
project = u'Neutron FWaaS'
|
|
||||||
copyright = u'2011-present, OpenStack Foundation.'
|
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
|
||||||
# |version| and |release|, also used in various other places throughout the
|
|
||||||
# built documents.
|
|
||||||
#
|
|
||||||
# Version info
|
|
||||||
from neutron_fwaas.version import version_info as neutron_fwaas_version
|
|
||||||
release = neutron_fwaas_version.release_string()
|
|
||||||
# The short X.Y version.
|
|
||||||
version = neutron_fwaas_version.version_string()
|
|
||||||
|
|
||||||
# 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 documents that shouldn't be included in the build.
|
|
||||||
# unused_docs = []
|
|
||||||
|
|
||||||
# List of directories, relative to source directory, that shouldn't be searched
|
|
||||||
# for source files.
|
|
||||||
exclude_trees = []
|
|
||||||
|
|
||||||
# The reST default role (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 = True
|
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
|
||||||
pygments_style = 'sphinx'
|
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
|
||||||
modindex_common_prefix = ['neutron_fwaas.']
|
|
||||||
|
|
||||||
# -- Options for man page output --------------------------------------------
|
|
||||||
|
|
||||||
# Grouping the document tree for man pages.
|
|
||||||
# List of tuples 'sourcefile', 'target', u'title', u'Authors name', 'manual'
|
|
||||||
|
|
||||||
#man_pages = [
|
|
||||||
# ('man/neutron-server', 'neutron-server', u'Neutron Server',
|
|
||||||
# [u'OpenStack'], 1)
|
|
||||||
#]
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output -------------------------------------------------
|
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
|
||||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
|
||||||
# html_theme_path = ["."]
|
|
||||||
# html_theme = '_theme'
|
|
||||||
if openstackdocstheme is not None:
|
|
||||||
html_theme = 'openstackdocs'
|
|
||||||
else:
|
|
||||||
html_theme = 'default'
|
|
||||||
|
|
||||||
# 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 = {}
|
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory.
|
|
||||||
#html_theme_path = ['_theme']
|
|
||||||
|
|
||||||
# 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 = ['_static']
|
|
||||||
|
|
||||||
# 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'
|
|
||||||
html_last_updated_fmt = '%Y-%m-%d %H:%M'
|
|
||||||
|
|
||||||
# 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_use_modindex = 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, 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 = ''
|
|
||||||
|
|
||||||
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
|
||||||
#html_file_suffix = ''
|
|
||||||
|
|
||||||
# Output file base name for HTML help builder.
|
|
||||||
#htmlhelp_basename = 'neutrondoc'
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for LaTeX output ------------------------------------------------
|
|
||||||
|
|
||||||
# The paper size ('letter' or 'a4').
|
|
||||||
#latex_paper_size = 'letter'
|
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
|
||||||
#latex_font_size = '10pt'
|
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
|
||||||
# (source start file, target name, title, author,
|
|
||||||
# documentclass [howto/manual]).
|
|
||||||
latex_documents = [
|
|
||||||
('index', 'doc-neutron-fwaas.tex',
|
|
||||||
u'Neutron Firewall-as-s-Service Documentation',
|
|
||||||
u'Neutron development team', 'manual'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
|
||||||
# the title page.
|
|
||||||
#latex_logo = None
|
|
||||||
|
|
||||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
|
||||||
# not chapters.
|
|
||||||
#latex_use_parts = False
|
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
|
||||||
#latex_preamble = ''
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#latex_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#latex_use_modindex = True
|
|
||||||
|
|
||||||
# Disable usage of xindy https://bugzilla.redhat.com/show_bug.cgi?id=1643664
|
|
||||||
latex_use_xindy = False
|
|
||||||
|
|
||||||
latex_domain_indices = False
|
|
||||||
|
|
||||||
latex_elements = {
|
|
||||||
'makeindex': '',
|
|
||||||
'printindex': '',
|
|
||||||
'preamble': r'\setcounter{tocdepth}{3}',
|
|
||||||
}
|
|
||||||
|
|
||||||
# -- Options for openstackdocstheme -------------------------------------------
|
|
||||||
repository_name = 'openstack/neutron-fwaas'
|
|
||||||
bug_project = 'neutron'
|
|
||||||
bug_tag = 'doc'
|
|
||||||
|
|
||||||
# -- Options for oslo_config.sphinxconfiggen ---------------------------------
|
|
||||||
|
|
||||||
_config_generator_config_files = [
|
|
||||||
'fwaas_driver.ini',
|
|
||||||
'neutron_fwaas.conf',
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def _get_config_generator_config_definition(conf):
|
|
||||||
config_file_path = '../../etc/oslo-config-generator/%s' % conf
|
|
||||||
# oslo_config.sphinxconfiggen appends '.conf.sample' to the filename,
|
|
||||||
# strip file extentension (.conf or .ini).
|
|
||||||
output_file_path = '_static/config_samples/%s' % conf.rsplit('.', 1)[0]
|
|
||||||
return (config_file_path, output_file_path)
|
|
||||||
|
|
||||||
|
|
||||||
config_generator_config_file = [
|
|
||||||
_get_config_generator_config_definition(conf)
|
|
||||||
for conf in _config_generator_config_files
|
|
||||||
]
|
|
||||||
|
|
||||||
# -- Options for oslo_policy.sphinxpolicygen ---------------------------------
|
|
||||||
|
|
||||||
policy_generator_config_file = '../../etc/oslo-policy-generator/policy.conf'
|
|
||||||
sample_policy_basename = '_static/neutron-fwaas'
|
|
@ -1,6 +0,0 @@
|
|||||||
================
|
|
||||||
fwaas_driver.ini
|
|
||||||
================
|
|
||||||
|
|
||||||
.. show-options::
|
|
||||||
:config-file: etc/oslo-config-generator/fwaas_driver.ini
|
|
@ -1,41 +0,0 @@
|
|||||||
.. _configuring:
|
|
||||||
|
|
||||||
=================================
|
|
||||||
Neutron FWaaS Configuration Guide
|
|
||||||
=================================
|
|
||||||
|
|
||||||
This section provides a list of all possible options for each
|
|
||||||
configuration file.
|
|
||||||
|
|
||||||
Configuration
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Neutron FWaaS uses the following configuration files for its various services.
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
neutron_fwaas
|
|
||||||
fwaas_driver
|
|
||||||
|
|
||||||
The following are sample configuration files for Neutron FWaaS and utilities.
|
|
||||||
These are generated from code and reflect the current state of code
|
|
||||||
in the neutron-fwaas repository.
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:glob:
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
samples/*
|
|
||||||
|
|
||||||
Policy
|
|
||||||
------
|
|
||||||
|
|
||||||
Neutron FWaaS, like most OpenStack projects, uses a policy language to restrict
|
|
||||||
permissions on REST API actions.
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
Policy Reference <policy>
|
|
||||||
Sample Policy File <policy-sample>
|
|
@ -1,6 +0,0 @@
|
|||||||
==================
|
|
||||||
neutron_fwaas.conf
|
|
||||||
==================
|
|
||||||
|
|
||||||
.. show-options::
|
|
||||||
:config-file: etc/oslo-config-generator/neutron_fwaas.conf
|
|
@ -1,16 +0,0 @@
|
|||||||
================================
|
|
||||||
Sample Neutron FWaaS Policy File
|
|
||||||
================================
|
|
||||||
|
|
||||||
The following is a sample neutron-fwaas policy file for adaptation and use.
|
|
||||||
|
|
||||||
The sample policy can also be viewed in :download:`file form
|
|
||||||
</_static/neutron-fwaas.policy.yaml.sample>`.
|
|
||||||
|
|
||||||
.. important::
|
|
||||||
|
|
||||||
The sample policy file is auto-generated from neutron-fwaas when this
|
|
||||||
documentation is built. You must ensure your version of neutron-fwaas
|
|
||||||
matches the version of this documentation.
|
|
||||||
|
|
||||||
.. literalinclude:: /_static/neutron-fwaas.policy.yaml.sample
|
|
@ -1,9 +0,0 @@
|
|||||||
======================
|
|
||||||
neutron-fwaas policies
|
|
||||||
======================
|
|
||||||
|
|
||||||
The following is an overview of all available policies in neutron-fwaas.
|
|
||||||
For a sample configuration file, refer to :doc:`/configuration/policy-sample`.
|
|
||||||
|
|
||||||
.. show-policy::
|
|
||||||
:config-file: etc/oslo-policy-generator/policy.conf
|
|
@ -1,8 +0,0 @@
|
|||||||
=======================
|
|
||||||
Sample fwaas_driver.ini
|
|
||||||
=======================
|
|
||||||
|
|
||||||
This sample configuration can also be viewed in `the raw format
|
|
||||||
<../../_static/config_samples/fwaas_driver.conf.sample>`_.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../_static/config_samples/fwaas_driver.conf.sample
|
|
@ -1,8 +0,0 @@
|
|||||||
=========================
|
|
||||||
Sample neutron_fwaas.conf
|
|
||||||
=========================
|
|
||||||
|
|
||||||
This sample configuration can also be viewed in `the raw format
|
|
||||||
<../../_static/config_samples/neutron_fwaas.conf.sample>`_.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../_static/config_samples/neutron_fwaas.conf.sample
|
|
@ -1,28 +0,0 @@
|
|||||||
=============================
|
|
||||||
Contributing to neutron-fwaas
|
|
||||||
=============================
|
|
||||||
|
|
||||||
If you would like to contribute to the development of OpenStack, you must
|
|
||||||
follow the steps documented at:
|
|
||||||
https://docs.openstack.org/infra/manual/developers.html
|
|
||||||
|
|
||||||
Once those steps have been completed, changes to OpenStack should be submitted
|
|
||||||
for review via the Gerrit tool, following the workflow documented at:
|
|
||||||
https://docs.openstack.org/infra/manual/developers.html#development-workflow
|
|
||||||
|
|
||||||
Pull requests submitted through GitHub will be ignored.
|
|
||||||
|
|
||||||
Bugs should be filed on Launchpad in the 'neutron' project:
|
|
||||||
https://bugs.launchpad.net/neutron
|
|
||||||
|
|
||||||
To get in touch with the neutron-fwaas community,
|
|
||||||
look at the following resources:
|
|
||||||
|
|
||||||
- Join the #openstack-fwaas IRC channel on Freenode. This is where the
|
|
||||||
FireWall-as-a-Service team is available for discussion.
|
|
||||||
- Join the `FireWall-as-a-Service weekly IRC meeting
|
|
||||||
<http://eavesdrop.openstack.org/#Firewall_as_a_Service_(FWaaS)_Team_Meeting>`_
|
|
||||||
where the status of new initiatives and bugs is discussed.
|
|
||||||
|
|
||||||
These are a great places to get recommendations on where to start contributing
|
|
||||||
to neutron-fwaas.
|
|
@ -1 +0,0 @@
|
|||||||
.. include:: ../../../devstack/README.rst
|
|
@ -1,7 +0,0 @@
|
|||||||
FireWall as a Service V2
|
|
||||||
========================
|
|
||||||
|
|
||||||
The `FireWall as a Service API V2
|
|
||||||
<https://specs.openstack.org/openstack/neutron-specs/specs/newton/fwaas-api-2.0.html>`_
|
|
||||||
specification lists the changes that together compose FWaaS V2. These changes
|
|
||||||
are not fully implemented.
|
|
@ -1,17 +0,0 @@
|
|||||||
=================
|
|
||||||
Contributor Guide
|
|
||||||
=================
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
contributing
|
|
||||||
fwaas_v2
|
|
||||||
devstack
|
|
||||||
|
|
||||||
.. API reference contains a lot of sections, toctree with maxdepth 1 is used.
|
|
||||||
.. toctree::
|
|
||||||
:glob:
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
modules
|
|
@ -1,19 +0,0 @@
|
|||||||
================
|
|
||||||
Module Reference
|
|
||||||
================
|
|
||||||
|
|
||||||
.. The module reference is rendered in HTML version much much better.
|
|
||||||
PDF version is not good for reading due to page width, lack of TOC
|
|
||||||
in subsections and so on, so we skip the module reference in PDF version.
|
|
||||||
|
|
||||||
.. only:: html
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
:glob:
|
|
||||||
|
|
||||||
api/*
|
|
||||||
|
|
||||||
.. only:: latex
|
|
||||||
|
|
||||||
See the online version of this document for the module reference.
|
|
@ -1,27 +0,0 @@
|
|||||||
===========================
|
|
||||||
neutron-fwaas documentation
|
|
||||||
===========================
|
|
||||||
|
|
||||||
.. 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.
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:glob:
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
install/index
|
|
||||||
configuration/index
|
|
||||||
contributor/index
|
|
||||||
|
|
||||||
.. only:: html
|
|
||||||
|
|
||||||
.. rubric:: Indices and tables
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
||||||
* :ref:`modindex`
|
|
||||||
* :ref:`search`
|
|
@ -1,39 +0,0 @@
|
|||||||
..
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
Convention for heading levels in Neutron devref:
|
|
||||||
======= Heading 0 (reserved for the title in a document)
|
|
||||||
------- Heading 1
|
|
||||||
~~~~~~~ Heading 2
|
|
||||||
+++++++ Heading 3
|
|
||||||
''''''' Heading 4
|
|
||||||
(Avoid deeper levels because they do not render well.)
|
|
||||||
|
|
||||||
|
|
||||||
============
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
At the command line::
|
|
||||||
|
|
||||||
$ pip install neutron-fwaas
|
|
||||||
|
|
||||||
Or, if you have virtualenvwrapper installed::
|
|
||||||
|
|
||||||
$ mkvirtualenv neutron-fwaas
|
|
||||||
$ pip install neutron-fwaas
|
|
||||||
|
|
||||||
For information on what to do with FWaaS once it is installed, please check the
|
|
||||||
Networking Guide `Firewall-as-a-Service (FWaaS) v2 scenario <https://docs.openstack.org/neutron/latest/admin/fwaas-v2-scenario.html>`_ or
|
|
||||||
the `Firewall-as-a-Service (FWaaS) v1 scenario <https://docs.openstack.org/neutron/latest/admin/fwaas-v1-scenario.html>`_.
|
|
@ -1,9 +0,0 @@
|
|||||||
To generate the sample neutron-fwaas configuration files, run the following
|
|
||||||
command from the top level of the neutron-fwaas directory:
|
|
||||||
|
|
||||||
tox -e genconfig
|
|
||||||
|
|
||||||
If a 'tox' environment is unavailable, then you can run the following script
|
|
||||||
instead to generate the configuration files:
|
|
||||||
|
|
||||||
./tools/generate_config_file_samples.sh
|
|
@ -1,7 +0,0 @@
|
|||||||
# neutron-fwaas privsep filters
|
|
||||||
|
|
||||||
# This file should be owned by (and only-writeable by) the root user
|
|
||||||
|
|
||||||
[Filters]
|
|
||||||
|
|
||||||
privsep-rootwrap: PathFilter, privsep-helper, root, privsep-helper, --config-file, /etc/(?!\.\.).*, --privsep_context, neutron_fwaas.privileged.default
|
|
@ -1,5 +0,0 @@
|
|||||||
[DEFAULT]
|
|
||||||
output_file = etc/fwaas_driver.ini.sample
|
|
||||||
wrap_width = 79
|
|
||||||
|
|
||||||
namespace = firewall.agent
|
|
@ -1,6 +0,0 @@
|
|||||||
[DEFAULT]
|
|
||||||
output_file = etc/neutron_fwaas.conf.sample
|
|
||||||
wrap_width = 79
|
|
||||||
|
|
||||||
namespace = neutron.fwaas
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
[DEFAULT]
|
|
||||||
output_file = etc/policy.yaml.sample
|
|
||||||
namespace = neutron-fwaas
|
|
@ -1,147 +0,0 @@
|
|||||||
alabaster==0.7.10
|
|
||||||
alembic==0.8.10
|
|
||||||
amqp==2.1.1
|
|
||||||
appdirs==1.4.3
|
|
||||||
Babel==2.3.4
|
|
||||||
beautifulsoup4==4.6.0
|
|
||||||
cachetools==2.0.0
|
|
||||||
cffi==1.7.0
|
|
||||||
chardet==3.0.4
|
|
||||||
cliff==2.8.0
|
|
||||||
cmd2==0.8.0
|
|
||||||
contextlib2==0.4.0
|
|
||||||
coverage==4.0
|
|
||||||
debtcollector==1.2.0
|
|
||||||
decorator==3.4.0
|
|
||||||
deprecation==1.0
|
|
||||||
doc8==0.6.0
|
|
||||||
docutils==0.11
|
|
||||||
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-import-order==0.12
|
|
||||||
flake8==2.6.2
|
|
||||||
future==0.16.0
|
|
||||||
futurist==1.2.0
|
|
||||||
greenlet==0.4.10
|
|
||||||
hacking==1.1.0
|
|
||||||
httplib2==0.9.1
|
|
||||||
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
|
|
||||||
keystonemiddleware==4.17.0
|
|
||||||
kombu==4.0.0
|
|
||||||
linecache2==1.0.0
|
|
||||||
logutils==0.3.5
|
|
||||||
Mako==0.4.0
|
|
||||||
MarkupSafe==1.0
|
|
||||||
mccabe==0.2.1
|
|
||||||
mock==2.0.0
|
|
||||||
monotonic==0.6
|
|
||||||
mox3==0.20.0
|
|
||||||
msgpack-python==0.4.0
|
|
||||||
munch==2.1.0
|
|
||||||
netaddr==0.7.18
|
|
||||||
netifaces==0.10.4
|
|
||||||
neutron-lib==1.26.0
|
|
||||||
neutron==14.0.0.0b3
|
|
||||||
openstackdocstheme==1.18.1
|
|
||||||
openstacksdk==0.11.2
|
|
||||||
os-client-config==1.28.0
|
|
||||||
os-ken==0.3.0
|
|
||||||
os-service-types==1.2.0
|
|
||||||
os-xenapi==0.3.1
|
|
||||||
osc-lib==1.8.0
|
|
||||||
oslo.cache==1.26.0
|
|
||||||
oslo.concurrency==3.26.0
|
|
||||||
oslo.config==5.2.0
|
|
||||||
oslo.context==2.19.2
|
|
||||||
oslo.db==4.37.0
|
|
||||||
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.privsep==1.32.0
|
|
||||||
oslo.reports==1.18.0
|
|
||||||
oslo.rootwrap==5.8.0
|
|
||||||
oslo.serialization==2.18.0
|
|
||||||
oslo.service==1.24.0
|
|
||||||
oslo.utils==3.33.0
|
|
||||||
oslo.versionedobjects==1.31.2
|
|
||||||
oslotest==3.2.0
|
|
||||||
osprofiler==1.4.0
|
|
||||||
ovs==2.8.0
|
|
||||||
ovsdbapp==0.9.1
|
|
||||||
Paste==2.0.2
|
|
||||||
PasteDeploy==1.5.0
|
|
||||||
pbr==4.0.0
|
|
||||||
pecan==1.3.2
|
|
||||||
pep8==1.5.7
|
|
||||||
pika-pool==0.1.3
|
|
||||||
pika==0.10.0
|
|
||||||
positional==1.2.1
|
|
||||||
prettytable==0.7.2
|
|
||||||
psutil==3.2.2
|
|
||||||
psycopg2==2.7.3
|
|
||||||
pycadf==1.1.0
|
|
||||||
pycodestyle==2.4.0
|
|
||||||
pycparser==2.18
|
|
||||||
pyflakes==0.8.1
|
|
||||||
Pygments==2.2.0
|
|
||||||
pyinotify==0.9.6
|
|
||||||
PyMySQL==0.7.6
|
|
||||||
pyparsing==2.1.0
|
|
||||||
pyperclip==1.5.27
|
|
||||||
pyroute2==0.5.3
|
|
||||||
python-dateutil==2.5.3
|
|
||||||
python-designateclient==2.7.0
|
|
||||||
python-editor==1.0.3
|
|
||||||
python-keystoneclient==3.8.0
|
|
||||||
python-mimeparse==1.6.0
|
|
||||||
python-neutronclient==6.7.0
|
|
||||||
python-novaclient==9.1.0
|
|
||||||
python-subunit==1.0.0
|
|
||||||
pytz==2013.6
|
|
||||||
PyYAML==3.12
|
|
||||||
pyzmq==14.3.1
|
|
||||||
reno==2.5.0
|
|
||||||
repoze.lru==0.7
|
|
||||||
requests-mock==1.2.0
|
|
||||||
requests==2.14.2
|
|
||||||
requestsexceptions==1.2.0
|
|
||||||
restructuredtext-lint==1.1.1
|
|
||||||
rfc3986==0.3.1
|
|
||||||
Routes==2.3.1
|
|
||||||
simplejson==3.5.1
|
|
||||||
six==1.10.0
|
|
||||||
snowballstemmer==1.2.1
|
|
||||||
sphinx==1.6.5
|
|
||||||
sqlalchemy-migrate==0.11.0
|
|
||||||
SQLAlchemy==1.2.0
|
|
||||||
sqlparse==0.2.2
|
|
||||||
statsd==3.2.1
|
|
||||||
stestr==1.0.0
|
|
||||||
stevedore==1.20.0
|
|
||||||
Tempita==0.5.2
|
|
||||||
tenacity==3.2.1
|
|
||||||
testrepository==0.0.18
|
|
||||||
testresources==2.0.0
|
|
||||||
testscenarios==0.4
|
|
||||||
testtools==2.2.0
|
|
||||||
tinyrpc==0.6
|
|
||||||
traceback2==1.4.0
|
|
||||||
unittest2==1.1.0
|
|
||||||
vine==1.1.4
|
|
||||||
waitress==1.1.0
|
|
||||||
WebOb==1.8.2
|
|
||||||
WebTest==2.0.27
|
|
||||||
wrapt==1.7.0
|
|
@ -1,24 +0,0 @@
|
|||||||
# Copyright 2011 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.
|
|
||||||
|
|
||||||
import gettext
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
gettext.install('neutron', unicode=1)
|
|
||||||
else:
|
|
||||||
gettext.install('neutron')
|
|
@ -1,32 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
import oslo_i18n
|
|
||||||
|
|
||||||
DOMAIN = "neutron_fwaas"
|
|
||||||
|
|
||||||
_translators = oslo_i18n.TranslatorFactory(domain=DOMAIN)
|
|
||||||
|
|
||||||
# The primary translation function using the well-known name "_"
|
|
||||||
_ = _translators.primary
|
|
||||||
|
|
||||||
# The contextual translation function using the name "_C"
|
|
||||||
_C = _translators.contextual_form
|
|
||||||
|
|
||||||
# The plural translation function using the name "_P"
|
|
||||||
_P = _translators.plural_form
|
|
||||||
|
|
||||||
|
|
||||||
def get_available_languages():
|
|
||||||
return oslo_i18n.get_available_languages(DOMAIN)
|
|
@ -1,40 +0,0 @@
|
|||||||
# Copyright 2019 Red Hat 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 neutron_lib.utils import upgrade_checks as base_checks
|
|
||||||
from oslo_config import cfg
|
|
||||||
from oslo_upgradecheck import upgradecheck
|
|
||||||
|
|
||||||
from neutron_fwaas._i18n import _
|
|
||||||
|
|
||||||
|
|
||||||
class Checks(base_checks.BaseChecks):
|
|
||||||
|
|
||||||
def get_checks(self):
|
|
||||||
return [
|
|
||||||
(_("Check FWaaS v1"), self.fwaas_v1_check)
|
|
||||||
]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def fwaas_v1_check(checker):
|
|
||||||
fwaas_v1_names = [
|
|
||||||
'firewall',
|
|
||||||
'neutron_fwaas.services.firewall.fwaas_plugin:FirewallPlugin']
|
|
||||||
for name in fwaas_v1_names:
|
|
||||||
if name in cfg.CONF.service_plugins:
|
|
||||||
return upgradecheck.Result(
|
|
||||||
upgradecheck.Code.FAILURE,
|
|
||||||
_("FWaaS v1 is removed. "
|
|
||||||
"FWaaS v2 should be used instead."))
|
|
||||||
return upgradecheck.Result(upgradecheck.Code.SUCCESS)
|
|
@ -1,136 +0,0 @@
|
|||||||
# 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 neutron.common import config
|
|
||||||
from neutron.db import models_v2
|
|
||||||
from oslo_config import cfg
|
|
||||||
from oslo_db.sqlalchemy import enginefacade
|
|
||||||
from oslo_log import log as logging
|
|
||||||
|
|
||||||
from neutron_fwaas.db.firewall import firewall_db as firewall_db_v1
|
|
||||||
from neutron_fwaas.db.firewall.v2 import firewall_db_v2
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_conf():
|
|
||||||
cli_opts = [
|
|
||||||
cfg.StrOpt('neutron-db-connection',
|
|
||||||
required=True,
|
|
||||||
help=_('neutron database connection string')),
|
|
||||||
]
|
|
||||||
conf = cfg.CONF
|
|
||||||
conf.register_cli_opts(cli_opts)
|
|
||||||
conf()
|
|
||||||
|
|
||||||
|
|
||||||
def migrate_fwaas_v1_to_v2(db_session):
|
|
||||||
# the entire migration process will be done under the same transaction to
|
|
||||||
# allow full rollback in case of error
|
|
||||||
with db_session.begin(subtransactions=True):
|
|
||||||
# Read all V1 policies
|
|
||||||
v1_policies = db_session.query(firewall_db_v1.FirewallPolicy)
|
|
||||||
|
|
||||||
for v1_pol in v1_policies:
|
|
||||||
LOG.info("Migrating FWaaS V1 policy %s", v1_pol.id)
|
|
||||||
# read the rules of this policy
|
|
||||||
v1_rules = db_session.query(firewall_db_v1.FirewallRule).filter_by(
|
|
||||||
firewall_policy_id=v1_pol.id).all()
|
|
||||||
# Create the V2 policy
|
|
||||||
v2_pol = firewall_db_v2.FirewallPolicy(
|
|
||||||
id=v1_pol.id,
|
|
||||||
tenant_id=v1_pol.tenant_id,
|
|
||||||
name=v1_pol.name,
|
|
||||||
description=v1_pol.description,
|
|
||||||
shared=v1_pol.shared,
|
|
||||||
audited=v1_pol.audited,
|
|
||||||
rule_count=len(v1_rules))
|
|
||||||
db_session.add(v2_pol)
|
|
||||||
|
|
||||||
# Add the rules and associate them with the policy
|
|
||||||
for v1_rule in v1_rules:
|
|
||||||
LOG.info("Migrating FWaaS V1 rule %s", v1_rule.id)
|
|
||||||
v2_rule = firewall_db_v2.FirewallRuleV2(
|
|
||||||
id=v1_rule.id,
|
|
||||||
name=v1_rule.name,
|
|
||||||
description=v1_rule.description,
|
|
||||||
tenant_id=v1_rule.tenant_id,
|
|
||||||
shared=v1_rule.shared,
|
|
||||||
protocol=v1_rule.protocol,
|
|
||||||
ip_version=v1_rule.ip_version,
|
|
||||||
source_ip_address=v1_rule.source_ip_address,
|
|
||||||
destination_ip_address=v1_rule.destination_ip_address,
|
|
||||||
source_port_range_min=v1_rule.source_port_range_min,
|
|
||||||
source_port_range_max=v1_rule.source_port_range_max,
|
|
||||||
destination_port_range_min=(
|
|
||||||
v1_rule.destination_port_range_min),
|
|
||||||
destination_port_range_max=(
|
|
||||||
v1_rule.destination_port_range_max),
|
|
||||||
action=v1_rule.action,
|
|
||||||
enabled=v1_rule.enabled)
|
|
||||||
db_session.add(v2_rule)
|
|
||||||
v2_link = firewall_db_v2.FirewallPolicyRuleAssociation(
|
|
||||||
firewall_policy_id=v1_pol.id,
|
|
||||||
firewall_rule_id=v1_rule.id,
|
|
||||||
position=v1_rule.position)
|
|
||||||
db_session.add(v2_link)
|
|
||||||
|
|
||||||
# Read all V1 firewalls
|
|
||||||
v1_fws = db_session.query(firewall_db_v1.Firewall)
|
|
||||||
for v1_fw in v1_fws:
|
|
||||||
LOG.info("Migrating FWaaS V1 firewall %s", v1_fw.id)
|
|
||||||
# create the V2 firewall group
|
|
||||||
v2_fw_group = firewall_db_v2.FirewallGroup(
|
|
||||||
id=v1_fw.id,
|
|
||||||
name=v1_fw.name,
|
|
||||||
description=v1_fw.description,
|
|
||||||
tenant_id=v1_fw.tenant_id,
|
|
||||||
shared=v1_fw.shared,
|
|
||||||
admin_state_up=v1_fw.admin_state_up,
|
|
||||||
status=v1_fw.status,
|
|
||||||
ingress_firewall_policy_id=v1_fw.firewall_policy_id,
|
|
||||||
egress_firewall_policy_id=v1_fw.firewall_policy_id)
|
|
||||||
db_session.add(v2_fw_group)
|
|
||||||
|
|
||||||
# for every router in the V1 Firewall router association, add all
|
|
||||||
# its interface ports to the V2 FirewallGroupPortAssociation
|
|
||||||
v1_routers = db_session.query(
|
|
||||||
firewall_db_v1.FirewallRouterAssociation).filter_by(
|
|
||||||
fw_id=v1_fw.id)
|
|
||||||
for v1_router in v1_routers:
|
|
||||||
rtr_id = v1_router.router_id
|
|
||||||
LOG.info("Migrating FWaaS V1 %s router %s", v1_fw.id, rtr_id)
|
|
||||||
if_ports = db_session.query(models_v2.Port).filter_by(
|
|
||||||
device_id=rtr_id,
|
|
||||||
device_owner="network:router_interface")
|
|
||||||
for port in if_ports:
|
|
||||||
fw_port = firewall_db_v2.FirewallGroupPortAssociation(
|
|
||||||
firewall_group_id=v2_fw_group.id,
|
|
||||||
port_id=port.id)
|
|
||||||
db_session.add(fw_port)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# Initialize the cli options
|
|
||||||
setup_conf()
|
|
||||||
config.setup_logging()
|
|
||||||
|
|
||||||
# Get the neutron DB session
|
|
||||||
neutron_context_manager = enginefacade.transaction_context()
|
|
||||||
neutron_context_manager.configure(
|
|
||||||
connection=cfg.CONF.neutron_db_connection)
|
|
||||||
n_session_maker = neutron_context_manager.writer.get_sessionmaker()
|
|
||||||
n_session = n_session_maker(autocommit=True)
|
|
||||||
|
|
||||||
# Run DB migration
|
|
||||||
migrate_fwaas_v1_to_v2(n_session)
|
|
||||||
LOG.info("DB migration done.")
|
|
@ -1,24 +0,0 @@
|
|||||||
# Copyright 2018 Fujitsu Limited.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from neutron_lib import exceptions as n_exc
|
|
||||||
|
|
||||||
from neutron_fwaas._i18n import _
|
|
||||||
|
|
||||||
|
|
||||||
# TODO(annp): migrate to neutron-lib after Queen release
|
|
||||||
class FirewallGroupPortNotSupported(n_exc.Conflict):
|
|
||||||
message = _("Port %(port_id)s is not supported by firewall driver "
|
|
||||||
"'%(driver_name)s'.")
|
|
@ -1,42 +0,0 @@
|
|||||||
# Copyright 2015 Cisco Systems, Inc
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
FIREWALL = 'FIREWALL'
|
|
||||||
FIREWALL_V2 = 'FIREWALL_V2'
|
|
||||||
|
|
||||||
# Constants for "topics"
|
|
||||||
FIREWALL_PLUGIN = 'q-firewall-plugin'
|
|
||||||
FW_AGENT = 'firewall_agent'
|
|
||||||
FIREWALL_RULE_LIST = 'firewall_rule_list'
|
|
||||||
|
|
||||||
# V2 Constants
|
|
||||||
DEFAULT_FWG = 'default'
|
|
||||||
DEFAULT_FWP_INGRESS = 'default ingress'
|
|
||||||
DEFAULT_FWP_EGRESS = 'default egress'
|
|
||||||
|
|
||||||
# Firewall group events for agent-side
|
|
||||||
DELETE_FWG = 'delete_firewall_group'
|
|
||||||
UPDATE_FWG = 'update_firewall_group'
|
|
||||||
CREATE_FWG = 'create_firewall_group'
|
|
||||||
|
|
||||||
# Port events for L2 agent extension
|
|
||||||
HANDLE_PORT = 'handle_port'
|
|
||||||
DELETE_PORT = 'delete_port'
|
|
||||||
|
|
||||||
# Resource name
|
|
||||||
|
|
||||||
FIREWALL_GROUP = 'firewall_group'
|
|
||||||
FIREWALL_RULE = 'firewall_rule'
|
|
||||||
FIREWALL_POLICY = 'firewall_policy'
|
|
@ -1,17 +0,0 @@
|
|||||||
# 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 neutron_fwaas.db.firewall.v2 import firewall_db_v2
|
|
||||||
|
|
||||||
FIREWALL_GROUP = firewall_db_v2.FirewallGroup
|
|
||||||
FIREWALL_POLICY = firewall_db_v2.FirewallPolicy
|
|
||||||
FIREWALL_RULE = firewall_db_v2.FirewallRuleV2
|
|
@ -1,89 +0,0 @@
|
|||||||
# Copyright 2013 Big Switch Networks, Inc.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from neutron_lib.db import model_base
|
|
||||||
import sqlalchemy as sa
|
|
||||||
from sqlalchemy.ext.orderinglist import ordering_list
|
|
||||||
from sqlalchemy import orm
|
|
||||||
|
|
||||||
|
|
||||||
# Note(annp): Keep firewall db v1 structure for migration
|
|
||||||
class FirewallRule(model_base.BASEV2, model_base.HasId, model_base.HasProject):
|
|
||||||
"""Represents a Firewall rule."""
|
|
||||||
__tablename__ = 'firewall_rules'
|
|
||||||
__table_args__ = ({'mysql_collate': 'utf8_bin'})
|
|
||||||
name = sa.Column(sa.String(255))
|
|
||||||
description = sa.Column(sa.String(1024))
|
|
||||||
firewall_policy_id = sa.Column(sa.String(36),
|
|
||||||
sa.ForeignKey('firewall_policies.id'),
|
|
||||||
nullable=True)
|
|
||||||
shared = sa.Column(sa.Boolean)
|
|
||||||
protocol = sa.Column(sa.String(40))
|
|
||||||
ip_version = sa.Column(sa.Integer, nullable=False)
|
|
||||||
source_ip_address = sa.Column(sa.String(46))
|
|
||||||
destination_ip_address = sa.Column(sa.String(46))
|
|
||||||
source_port_range_min = sa.Column(sa.Integer)
|
|
||||||
source_port_range_max = sa.Column(sa.Integer)
|
|
||||||
destination_port_range_min = sa.Column(sa.Integer)
|
|
||||||
destination_port_range_max = sa.Column(sa.Integer)
|
|
||||||
action = sa.Column(sa.Enum('allow', 'deny', 'reject',
|
|
||||||
name='firewallrules_action'))
|
|
||||||
enabled = sa.Column(sa.Boolean)
|
|
||||||
position = sa.Column(sa.Integer)
|
|
||||||
|
|
||||||
|
|
||||||
class Firewall(model_base.BASEV2, model_base.HasId, model_base.HasProject):
|
|
||||||
"""Represents a Firewall resource."""
|
|
||||||
__tablename__ = 'firewalls'
|
|
||||||
__table_args__ = ({'mysql_collate': 'utf8_bin'})
|
|
||||||
name = sa.Column(sa.String(255))
|
|
||||||
description = sa.Column(sa.String(1024))
|
|
||||||
shared = sa.Column(sa.Boolean)
|
|
||||||
admin_state_up = sa.Column(sa.Boolean)
|
|
||||||
status = sa.Column(sa.String(16))
|
|
||||||
firewall_policy_id = sa.Column(sa.String(36),
|
|
||||||
sa.ForeignKey('firewall_policies.id'),
|
|
||||||
nullable=True)
|
|
||||||
|
|
||||||
|
|
||||||
class FirewallPolicy(model_base.BASEV2, model_base.HasId,
|
|
||||||
model_base.HasProject):
|
|
||||||
"""Represents a Firewall Policy resource."""
|
|
||||||
__tablename__ = 'firewall_policies'
|
|
||||||
__table_args__ = ({'mysql_collate': 'utf8_bin'})
|
|
||||||
name = sa.Column(sa.String(255))
|
|
||||||
description = sa.Column(sa.String(1024))
|
|
||||||
shared = sa.Column(sa.Boolean)
|
|
||||||
firewall_rules = orm.relationship(
|
|
||||||
FirewallRule,
|
|
||||||
backref=orm.backref('firewall_policies', cascade='all, delete'),
|
|
||||||
order_by='FirewallRule.position',
|
|
||||||
collection_class=ordering_list('position', count_from=1))
|
|
||||||
audited = sa.Column(sa.Boolean)
|
|
||||||
firewalls = orm.relationship(Firewall, backref='firewall_policies')
|
|
||||||
|
|
||||||
|
|
||||||
class FirewallRouterAssociation(model_base.BASEV2):
|
|
||||||
|
|
||||||
"""Tracks FW Router Association"""
|
|
||||||
|
|
||||||
__tablename__ = 'firewall_router_associations'
|
|
||||||
|
|
||||||
fw_id = sa.Column(sa.String(36),
|
|
||||||
sa.ForeignKey('firewalls.id', ondelete="CASCADE"),
|
|
||||||
primary_key=True)
|
|
||||||
router_id = sa.Column(sa.String(36),
|
|
||||||
sa.ForeignKey('routers.id', ondelete="CASCADE"),
|
|
||||||
primary_key=True)
|
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
|||||||
Generic single-database configuration.
|
|
@ -1,86 +0,0 @@
|
|||||||
# Copyright 2014 OpenStack Foundation
|
|
||||||
#
|
|
||||||
# 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 logging import config as logging_config
|
|
||||||
|
|
||||||
from alembic import context
|
|
||||||
from neutron_lib.db import model_base
|
|
||||||
from oslo_config import cfg
|
|
||||||
from oslo_db.sqlalchemy import session
|
|
||||||
import sqlalchemy as sa
|
|
||||||
from sqlalchemy import event
|
|
||||||
|
|
||||||
|
|
||||||
MYSQL_ENGINE = None
|
|
||||||
FWAAS_VERSION_TABLE = 'alembic_version_fwaas'
|
|
||||||
config = context.config
|
|
||||||
neutron_config = config.neutron_config
|
|
||||||
logging_config.fileConfig(config.config_file_name)
|
|
||||||
target_metadata = model_base.BASEV2.metadata
|
|
||||||
|
|
||||||
|
|
||||||
def set_mysql_engine():
|
|
||||||
try:
|
|
||||||
mysql_engine = neutron_config.command.mysql_engine
|
|
||||||
except cfg.NoSuchOptError:
|
|
||||||
mysql_engine = None
|
|
||||||
|
|
||||||
global MYSQL_ENGINE
|
|
||||||
MYSQL_ENGINE = (mysql_engine or
|
|
||||||
model_base.BASEV2.__table_args__['mysql_engine'])
|
|
||||||
|
|
||||||
|
|
||||||
def run_migrations_offline():
|
|
||||||
set_mysql_engine()
|
|
||||||
|
|
||||||
kwargs = dict()
|
|
||||||
if neutron_config.database.connection:
|
|
||||||
kwargs['url'] = neutron_config.database.connection
|
|
||||||
else:
|
|
||||||
kwargs['dialect_name'] = neutron_config.database.engine
|
|
||||||
kwargs['version_table'] = FWAAS_VERSION_TABLE
|
|
||||||
context.configure(**kwargs)
|
|
||||||
|
|
||||||
with context.begin_transaction():
|
|
||||||
context.run_migrations()
|
|
||||||
|
|
||||||
|
|
||||||
@event.listens_for(sa.Table, 'after_parent_attach')
|
|
||||||
def set_storage_engine(target, parent):
|
|
||||||
if MYSQL_ENGINE:
|
|
||||||
target.kwargs['mysql_engine'] = MYSQL_ENGINE
|
|
||||||
|
|
||||||
|
|
||||||
def run_migrations_online():
|
|
||||||
set_mysql_engine()
|
|
||||||
engine = session.create_engine(neutron_config.database.connection)
|
|
||||||
|
|
||||||
connection = engine.connect()
|
|
||||||
context.configure(
|
|
||||||
connection=connection,
|
|
||||||
target_metadata=target_metadata,
|
|
||||||
version_table=FWAAS_VERSION_TABLE
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
with context.begin_transaction():
|
|
||||||
context.run_migrations()
|
|
||||||
finally:
|
|
||||||
connection.close()
|
|
||||||
engine.dispose()
|
|
||||||
|
|
||||||
|
|
||||||
if context.is_offline_mode():
|
|
||||||
run_migrations_offline()
|
|
||||||
else:
|
|
||||||
run_migrations_online()
|
|
@ -1,36 +0,0 @@
|
|||||||
# Copyright ${create_date.year} <PUT YOUR NAME/COMPANY HERE>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""${message}
|
|
||||||
|
|
||||||
Revision ID: ${up_revision}
|
|
||||||
Revises: ${down_revision}
|
|
||||||
Create Date: ${create_date}
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = ${repr(up_revision)}
|
|
||||||
down_revision = ${repr(down_revision)}
|
|
||||||
% if branch_labels:
|
|
||||||
branch_labels = ${repr(branch_labels)}
|
|
||||||
%endif
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
${imports if imports else ""}
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
${upgrades if upgrades else "pass"}
|
|
@ -1,35 +0,0 @@
|
|||||||
# Copyright 2015 OpenStack Foundation
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""add_index_tenant_id
|
|
||||||
|
|
||||||
Revision ID: 4202e3047e47
|
|
||||||
Revises: start_neutron_fwaas
|
|
||||||
Create Date: 2015-02-10 17:17:47.846764
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '4202e3047e47'
|
|
||||||
down_revision = 'start_neutron_fwaas'
|
|
||||||
|
|
||||||
TABLES = ['firewall_rules', 'firewalls', 'firewall_policies']
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
for table in TABLES:
|
|
||||||
op.create_index(op.f('ix_%s_tenant_id' % table),
|
|
||||||
table, ['tenant_id'], unique=False)
|
|
@ -1,62 +0,0 @@
|
|||||||
# Copyright 2014 OpenStack Foundation
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""FWaaS router insertion
|
|
||||||
|
|
||||||
Revision ID: 540142f314f4
|
|
||||||
Revises: 4202e3047e47
|
|
||||||
Create Date: 2015-02-06 17:02:24.279337
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
from sqlalchemy.engine import reflection
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '540142f314f4'
|
|
||||||
down_revision = '4202e3047e47'
|
|
||||||
|
|
||||||
SQL_STATEMENT = (
|
|
||||||
"insert into firewall_router_associations "
|
|
||||||
"select "
|
|
||||||
"f.id as fw_id, r.id as router_id "
|
|
||||||
"from firewalls f, routers r "
|
|
||||||
"where "
|
|
||||||
"f.tenant_id=r.%s"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
op.create_table('firewall_router_associations',
|
|
||||||
sa.Column('fw_id', sa.String(length=36), nullable=False),
|
|
||||||
sa.Column('router_id', sa.String(length=36), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['fw_id'], ['firewalls.id'],
|
|
||||||
ondelete='CASCADE'),
|
|
||||||
sa.ForeignKeyConstraint(['router_id'], ['routers.id'],
|
|
||||||
ondelete='CASCADE'),
|
|
||||||
sa.PrimaryKeyConstraint('fw_id', 'router_id'),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Depending on when neutron-fwaas is installed with neutron, this script
|
|
||||||
# may be run before or after the neutron core tables have had their
|
|
||||||
# tenant_id columns renamed to project_id. Account for both scenarios.
|
|
||||||
bind = op.get_bind()
|
|
||||||
insp = reflection.Inspector.from_engine(bind)
|
|
||||||
columns = insp.get_columns('routers')
|
|
||||||
if 'tenant_id' in [c['name'] for c in columns]:
|
|
||||||
op.execute(SQL_STATEMENT % 'tenant_id')
|
|
||||||
else:
|
|
||||||
op.execute(SQL_STATEMENT % 'project_id')
|
|
@ -1,45 +0,0 @@
|
|||||||
# Copyright 2015 OpenStack Foundation
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""cisco_csr_fwaas
|
|
||||||
|
|
||||||
Revision ID: 796c68dffbb
|
|
||||||
Revises: 540142f314f4
|
|
||||||
Create Date: 2015-02-02 13:11:55.184112
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '796c68dffbb'
|
|
||||||
down_revision = '540142f314f4'
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade(active_plugins=None, options=None):
|
|
||||||
|
|
||||||
op.create_table('cisco_firewall_associations',
|
|
||||||
sa.Column('fw_id', sa.String(length=36), nullable=False),
|
|
||||||
sa.Column('port_id', sa.String(length=36), nullable=True),
|
|
||||||
sa.Column('direction', sa.String(length=16), nullable=True),
|
|
||||||
sa.Column('acl_id', sa.String(length=36), nullable=True),
|
|
||||||
sa.Column('router_id', sa.String(length=36), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['fw_id'], ['firewalls.id'],
|
|
||||||
ondelete='CASCADE'),
|
|
||||||
sa.ForeignKeyConstraint(['port_id'], ['ports.id'],
|
|
||||||
ondelete='CASCADE'),
|
|
||||||
sa.PrimaryKeyConstraint('fw_id')
|
|
||||||
)
|
|
@ -1 +0,0 @@
|
|||||||
fd38cd995cc0
|
|
@ -1 +0,0 @@
|
|||||||
f24e0d5e5bff
|
|
@ -1,29 +0,0 @@
|
|||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""kilo
|
|
||||||
|
|
||||||
Revision ID: kilo
|
|
||||||
Revises: 796c68dffbb
|
|
||||||
Create Date: 2015-04-16 00:00:00.000000
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'kilo'
|
|
||||||
down_revision = '796c68dffbb'
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
"""A no-op migration for marking the Kilo release."""
|
|
||||||
pass
|
|
@ -1,38 +0,0 @@
|
|||||||
# Copyright 2015 Red Hat 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""Initial Liberty no-op script.
|
|
||||||
|
|
||||||
Revision ID: 67c8e8d61d5
|
|
||||||
Revises: kilo
|
|
||||||
Create Date: 2015-07-28 22:18:13.330846
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from neutron.db import migration
|
|
||||||
from neutron_lib.db import constants
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '67c8e8d61d5'
|
|
||||||
down_revision = 'kilo'
|
|
||||||
branch_labels = (constants.CONTRACT_BRANCH,)
|
|
||||||
|
|
||||||
# milestone identifier, used by neutron-db-manage
|
|
||||||
neutron_milestone = [migration.LIBERTY]
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
pass
|
|
@ -1,47 +0,0 @@
|
|||||||
# Copyright 2015 NEC Corporation. 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.
|
|
||||||
|
|
||||||
"""add reject rule
|
|
||||||
|
|
||||||
Revision ID: 4b47ea298795
|
|
||||||
Revises: c40fbb377ad
|
|
||||||
Create Date: 2015-04-15 04:19:57.324584
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
from neutron.db import migration
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '4b47ea298795'
|
|
||||||
down_revision = 'c40fbb377ad'
|
|
||||||
|
|
||||||
# milestone identifier, used by neutron-db-manage
|
|
||||||
neutron_milestone = [migration.LIBERTY, migration.MITAKA]
|
|
||||||
|
|
||||||
|
|
||||||
new_action = sa.Enum('allow', 'deny', 'reject', name='firewallrules_action')
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# NOTE: postgresql have a builtin ENUM type, so just altering the
|
|
||||||
# column won't works
|
|
||||||
# https://bitbucket.org/zzzeek/alembic/issues/270/altering-enum-type
|
|
||||||
# alter_enum that was already invented for such case in neutron
|
|
||||||
# https://github.com/openstack/neutron/blob/master/neutron/db/migration/__init__.py
|
|
||||||
|
|
||||||
migration.alter_enum(
|
|
||||||
'firewall_rules', 'action', enum_type=new_action, nullable=True)
|
|
@ -1,34 +0,0 @@
|
|||||||
# Copyright 2015 Red Hat 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""Initial Liberty no-op script.
|
|
||||||
|
|
||||||
Revision ID: c40fbb377ad
|
|
||||||
Revises: kilo
|
|
||||||
Create Date: 2015-07-28 22:18:13.321233
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from neutron_lib.db import constants
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'c40fbb377ad'
|
|
||||||
down_revision = 'kilo'
|
|
||||||
branch_labels = (constants.EXPAND_BRANCH,)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
pass
|
|
@ -1,49 +0,0 @@
|
|||||||
#Copyright 2015 OpenStack Foundation
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""fw_table_alter script to make <name> column case sensitive
|
|
||||||
|
|
||||||
Revision ID: 458aa42b14b
|
|
||||||
Revises: 67c8e8d61d5
|
|
||||||
Create Date: 2015-09-16 11:47:43.061649
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
|
|
||||||
from neutron.db import migration
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '458aa42b14b'
|
|
||||||
down_revision = '67c8e8d61d5'
|
|
||||||
|
|
||||||
# milestone identifier, used by neutron-db-manage
|
|
||||||
neutron_milestone = [migration.MITAKA]
|
|
||||||
|
|
||||||
|
|
||||||
FW_TAB_NAME = ['firewall_rules', 'firewall_policies', 'firewalls']
|
|
||||||
SQL_STATEMENT_UPDATE_CMD = (
|
|
||||||
"alter table %s "
|
|
||||||
"modify name varchar(255) "
|
|
||||||
"CHARACTER SET utf8 COLLATE utf8_bin"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
context = op.get_context()
|
|
||||||
if context.bind.dialect.name == 'mysql':
|
|
||||||
for table in FW_TAB_NAME:
|
|
||||||
op.execute(SQL_STATEMENT_UPDATE_CMD % table)
|
|
@ -1,143 +0,0 @@
|
|||||||
# Copyright 2016 <PUT YOUR NAME/COMPANY HERE>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""rename tenant to project
|
|
||||||
|
|
||||||
Revision ID: f83a0b2964d0
|
|
||||||
Revises: 458aa42b14b
|
|
||||||
Create Date: 2016-07-14 13:11:53.112622
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
from sqlalchemy.engine import reflection
|
|
||||||
|
|
||||||
from neutron.db import migration
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'f83a0b2964d0'
|
|
||||||
down_revision = '458aa42b14b'
|
|
||||||
|
|
||||||
# milestone identifier, used by neutron-db-manage
|
|
||||||
neutron_milestone = [migration.NEWTON]
|
|
||||||
|
|
||||||
_INSPECTOR = None
|
|
||||||
|
|
||||||
|
|
||||||
def get_inspector():
|
|
||||||
"""Reuse inspector"""
|
|
||||||
|
|
||||||
global _INSPECTOR
|
|
||||||
|
|
||||||
if _INSPECTOR:
|
|
||||||
return _INSPECTOR
|
|
||||||
|
|
||||||
else:
|
|
||||||
bind = op.get_bind()
|
|
||||||
_INSPECTOR = reflection.Inspector.from_engine(bind)
|
|
||||||
|
|
||||||
return _INSPECTOR
|
|
||||||
|
|
||||||
|
|
||||||
def get_tables():
|
|
||||||
"""
|
|
||||||
Returns hardcoded list of tables which have ``tenant_id`` column.
|
|
||||||
|
|
||||||
The list is hardcoded to match the state of the schema when this
|
|
||||||
upgrade script is run.
|
|
||||||
"""
|
|
||||||
|
|
||||||
tables = [
|
|
||||||
'firewalls',
|
|
||||||
'firewall_policies',
|
|
||||||
'firewall_rules',
|
|
||||||
]
|
|
||||||
|
|
||||||
return tables
|
|
||||||
|
|
||||||
|
|
||||||
def get_columns(table):
|
|
||||||
"""Returns list of columns for given table."""
|
|
||||||
inspector = get_inspector()
|
|
||||||
return inspector.get_columns(table)
|
|
||||||
|
|
||||||
|
|
||||||
def get_data():
|
|
||||||
"""Returns combined list of tuples: [(table, column)].
|
|
||||||
|
|
||||||
The list is built from tables with a tenant_id column.
|
|
||||||
"""
|
|
||||||
|
|
||||||
output = []
|
|
||||||
tables = get_tables()
|
|
||||||
for table in tables:
|
|
||||||
columns = get_columns(table)
|
|
||||||
|
|
||||||
for column in columns:
|
|
||||||
if column['name'] == 'tenant_id':
|
|
||||||
output.append((table, column))
|
|
||||||
|
|
||||||
return output
|
|
||||||
|
|
||||||
|
|
||||||
def alter_column(table, column):
|
|
||||||
old_name = 'tenant_id'
|
|
||||||
new_name = 'project_id'
|
|
||||||
|
|
||||||
op.alter_column(
|
|
||||||
table_name=table,
|
|
||||||
column_name=old_name,
|
|
||||||
new_column_name=new_name,
|
|
||||||
existing_type=column['type'],
|
|
||||||
existing_nullable=column['nullable']
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def recreate_index(index, table_name):
|
|
||||||
old_name = index['name']
|
|
||||||
new_name = old_name.replace('tenant', 'project')
|
|
||||||
|
|
||||||
op.drop_index(op.f(old_name), table_name)
|
|
||||||
op.create_index(new_name, table_name, ['project_id'])
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
"""Code reused from
|
|
||||||
|
|
||||||
Change-Id: I87a8ef342ccea004731ba0192b23a8e79bc382dc
|
|
||||||
"""
|
|
||||||
|
|
||||||
inspector = get_inspector()
|
|
||||||
|
|
||||||
data = get_data()
|
|
||||||
for table, column in data:
|
|
||||||
alter_column(table, column)
|
|
||||||
|
|
||||||
indexes = inspector.get_indexes(table)
|
|
||||||
for index in indexes:
|
|
||||||
if 'tenant_id' in index['name']:
|
|
||||||
recreate_index(index, table)
|
|
||||||
|
|
||||||
|
|
||||||
def contract_creation_exceptions():
|
|
||||||
"""Special migration for the blueprint to support Keystone V3.
|
|
||||||
We drop all tenant_id columns and create project_id columns instead.
|
|
||||||
"""
|
|
||||||
return {
|
|
||||||
sa.Column: ['.'.join([table, 'project_id']) for table in get_tables()],
|
|
||||||
sa.Index: get_tables()
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
# Copyright 2016 OpenStack Foundation
|
|
||||||
#
|
|
||||||
# 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 v2.0
|
|
||||||
|
|
||||||
Revision ID: d6a12e637e28
|
|
||||||
Revises: 4b47ea298795
|
|
||||||
Create Date: 2016-06-08 19:57:13.848855
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
from sqlalchemy.dialects import postgresql
|
|
||||||
|
|
||||||
from neutron.db import migration
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'd6a12e637e28'
|
|
||||||
down_revision = '4b47ea298795'
|
|
||||||
|
|
||||||
# milestone identifier, used by neutron-db-manage
|
|
||||||
neutron_milestone = [migration.NEWTON]
|
|
||||||
|
|
||||||
|
|
||||||
def get_enum():
|
|
||||||
engine = op.get_bind().engine
|
|
||||||
# In PostgreSQL types created separately, so if type was already created in
|
|
||||||
# 4b47ea298795_add_reject_rule it should be created one time.
|
|
||||||
# Use parameter create_type=False for that.
|
|
||||||
if engine.name == 'postgresql':
|
|
||||||
return postgresql.ENUM('allow', 'deny', 'reject',
|
|
||||||
name='firewallrules_action',
|
|
||||||
create_type=False)
|
|
||||||
else:
|
|
||||||
return sa.Enum('allow', 'deny', 'reject',
|
|
||||||
name='firewallrules_action')
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
|
|
||||||
op.create_table(
|
|
||||||
'firewall_policies_v2',
|
|
||||||
sa.Column('id', sa.String(length=36), primary_key=True),
|
|
||||||
sa.Column('name', sa.String(length=255)),
|
|
||||||
sa.Column('description', sa.String(length=1024)),
|
|
||||||
sa.Column('project_id', sa.String(length=255), index=True),
|
|
||||||
sa.Column('audited', sa.Boolean),
|
|
||||||
sa.Column('public', sa.Boolean),
|
|
||||||
sa.Column('rule_count', sa.Integer))
|
|
||||||
|
|
||||||
op.create_table(
|
|
||||||
'firewall_rules_v2',
|
|
||||||
sa.Column('id', sa.String(length=36), primary_key=True),
|
|
||||||
sa.Column('name', sa.String(length=255)),
|
|
||||||
sa.Column('description', sa.String(length=1024)),
|
|
||||||
sa.Column('project_id', sa.String(length=255), index=True),
|
|
||||||
sa.Column('protocol', sa.String(length=40)),
|
|
||||||
sa.Column('ip_version', sa.Integer),
|
|
||||||
sa.Column('source_ip_address', sa.String(length=46)),
|
|
||||||
sa.Column('destination_ip_address', sa.String(length=46)),
|
|
||||||
sa.Column('source_port_range_min', sa.Integer),
|
|
||||||
sa.Column('source_port_range_max', sa.Integer),
|
|
||||||
sa.Column('destination_port_range_min', sa.Integer),
|
|
||||||
sa.Column('destination_port_range_max', sa.Integer),
|
|
||||||
sa.Column('action', get_enum()),
|
|
||||||
sa.Column('public', sa.Boolean),
|
|
||||||
sa.Column('enabled', sa.Boolean))
|
|
||||||
|
|
||||||
op.create_table(
|
|
||||||
'firewall_groups_v2',
|
|
||||||
sa.Column('id', sa.String(length=36), primary_key=True),
|
|
||||||
sa.Column('name', sa.String(length=255)),
|
|
||||||
sa.Column('description', sa.String(length=1024)),
|
|
||||||
sa.Column('project_id', sa.String(length=255), index=True),
|
|
||||||
sa.Column('status', sa.String(length=16)),
|
|
||||||
sa.Column('admin_state_up', sa.Boolean),
|
|
||||||
sa.Column('public', sa.Boolean),
|
|
||||||
sa.Column('egress_firewall_policy_id', sa.String(length=36),
|
|
||||||
sa.ForeignKey('firewall_policies_v2.id')),
|
|
||||||
sa.Column('ingress_firewall_policy_id', sa.String(length=36),
|
|
||||||
sa.ForeignKey('firewall_policies_v2.id')))
|
|
||||||
|
|
||||||
op.create_table(
|
|
||||||
'firewall_group_port_associations_v2',
|
|
||||||
sa.Column('firewall_group_id', sa.String(length=36),
|
|
||||||
sa.ForeignKey('firewall_groups_v2.id', ondelete='CASCADE')),
|
|
||||||
sa.Column('port_id', sa.String(length=36),
|
|
||||||
sa.ForeignKey('ports.id', ondelete='CASCADE'))
|
|
||||||
)
|
|
||||||
|
|
||||||
op.create_table(
|
|
||||||
'firewall_policy_rule_associations_v2',
|
|
||||||
sa.Column('firewall_policy_id', sa.String(length=36),
|
|
||||||
sa.ForeignKey('firewall_policies_v2.id', ondelete='CASCADE'),
|
|
||||||
nullable=False, primary_key=True),
|
|
||||||
sa.Column('firewall_rule_id', sa.String(length=36),
|
|
||||||
sa.ForeignKey('firewall_rules_v2.id', ondelete='CASCADE'),
|
|
||||||
nullable=False, primary_key=True),
|
|
||||||
sa.Column('position', sa.Integer))
|
|
@ -1,37 +0,0 @@
|
|||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""change shared attribute for firewall resource
|
|
||||||
|
|
||||||
Revision ID: fd38cd995cc0
|
|
||||||
Revises: f83a0b2964d0
|
|
||||||
Create Date: 2017-03-31 14:22:21.063392
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'fd38cd995cc0'
|
|
||||||
down_revision = 'f83a0b2964d0'
|
|
||||||
depends_on = ('d6a12e637e28',)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
op.alter_column('firewall_rules_v2', 'public', new_column_name='shared',
|
|
||||||
existing_type=sa.Boolean)
|
|
||||||
op.alter_column('firewall_groups_v2', 'public', new_column_name='shared',
|
|
||||||
existing_type=sa.Boolean)
|
|
||||||
op.alter_column('firewall_policies_v2', 'public', new_column_name='shared',
|
|
||||||
existing_type=sa.Boolean)
|
|
@ -1,67 +0,0 @@
|
|||||||
# Copyright 2017 FUJITSU LIMITED
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""create_default_firewall_groups_table
|
|
||||||
|
|
||||||
Revision ID: 876782258a43
|
|
||||||
Revises: d6a12e637e28
|
|
||||||
Create Date: 2017-01-26 23:47:42.795504
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
from neutron_lib.db import constants as db_constants
|
|
||||||
from neutron_lib import exceptions
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
from neutron_fwaas._i18n import _
|
|
||||||
from neutron_fwaas.common import fwaas_constants as const
|
|
||||||
from neutron_fwaas.common import resources
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '876782258a43'
|
|
||||||
down_revision = 'd6a12e637e28'
|
|
||||||
|
|
||||||
|
|
||||||
class DuplicateDefaultFirewallGroup(exceptions.Conflict):
|
|
||||||
message = _("Duplicate Firewall group found named '%s'. "
|
|
||||||
"Database cannot be upgraded. Please, remove all duplicates "
|
|
||||||
"before upgrading the database.") % const.DEFAULT_FWG
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
op.create_table(
|
|
||||||
'default_firewall_groups',
|
|
||||||
sa.Column('project_id',
|
|
||||||
sa.String(length=db_constants.PROJECT_ID_FIELD_SIZE),
|
|
||||||
nullable=False),
|
|
||||||
sa.Column('firewall_group_id',
|
|
||||||
sa.String(length=db_constants.UUID_FIELD_SIZE),
|
|
||||||
nullable=False),
|
|
||||||
sa.PrimaryKeyConstraint('project_id'),
|
|
||||||
sa.ForeignKeyConstraint(['firewall_group_id'],
|
|
||||||
['firewall_groups_v2.id'], ondelete="CASCADE"))
|
|
||||||
|
|
||||||
|
|
||||||
def check_sanity(connection):
|
|
||||||
# check for already existing firewall groups with name == DEFAULT_FWG
|
|
||||||
insp = sa.engine.reflection.Inspector.from_engine(connection)
|
|
||||||
if 'firewall_groups_v2' not in insp.get_table_names():
|
|
||||||
return []
|
|
||||||
session = sa.orm.Session(bind=connection.connect())
|
|
||||||
default_fwg = session.query(resources.FIREWALL_GROUP.name).filter(
|
|
||||||
resources.FIREWALL_GROUP.name == const.DEFAULT_FWG).first()
|
|
||||||
if default_fwg:
|
|
||||||
raise DuplicateDefaultFirewallGroup()
|
|
@ -1,71 +0,0 @@
|
|||||||
# Copyright 2017 Fujitsu Limited
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""uniq_firewallgroupportassociation0port
|
|
||||||
|
|
||||||
Revision ID: f24e0d5e5bff
|
|
||||||
Revises: 876782258a43
|
|
||||||
Create Date: 2017-11-08 15:55:40.990272
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
from neutron_lib import exceptions
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
from neutron._i18n import _
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'f24e0d5e5bff'
|
|
||||||
down_revision = '876782258a43'
|
|
||||||
|
|
||||||
|
|
||||||
fwg_port_association = sa.Table(
|
|
||||||
'firewall_group_port_associations_v2', sa.MetaData(),
|
|
||||||
sa.Column('firewall_group_id', sa.String(36)),
|
|
||||||
sa.Column('port_id', sa.String(36)))
|
|
||||||
|
|
||||||
|
|
||||||
class DuplicatePortRecordinFirewallGroupPortAssociation(exceptions.Conflict):
|
|
||||||
message = _("Duplicate port(s) %(port_id)s records exist in"
|
|
||||||
"firewall_group_port_associations_v2 table. Database cannot"
|
|
||||||
"be upgraded. Please remove all duplicated records before"
|
|
||||||
"upgrading the database.")
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
op.create_unique_constraint(
|
|
||||||
'uniq_firewallgroupportassociation0port_id',
|
|
||||||
'firewall_group_port_associations_v2',
|
|
||||||
['port_id'])
|
|
||||||
|
|
||||||
|
|
||||||
def check_sanity(connection):
|
|
||||||
duplicated_port_ids = (
|
|
||||||
get_duplicate_port_records_in_fwg_port_association(connection))
|
|
||||||
if duplicated_port_ids:
|
|
||||||
raise DuplicatePortRecordinFirewallGroupPortAssociation(
|
|
||||||
port_id=",".join(duplicated_port_ids))
|
|
||||||
|
|
||||||
|
|
||||||
def get_duplicate_port_records_in_fwg_port_association(connection):
|
|
||||||
insp = sa.engine.reflection.Inspector.from_engine(connection)
|
|
||||||
if 'firewall_group_port_associations_v2' not in insp.get_table_names():
|
|
||||||
return []
|
|
||||||
session = sa.orm.Session(bind=connection.connect())
|
|
||||||
query = (session.query(fwg_port_association.c.port_id)
|
|
||||||
.group_by(fwg_port_association.c.port_id)
|
|
||||||
.having(sa.func.count() > 1)).all()
|
|
||||||
return [q[0] for q in query]
|
|
@ -1,30 +0,0 @@
|
|||||||
# Copyright 2014 OpenStack Foundation
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""start neutron-fwaas chain
|
|
||||||
|
|
||||||
Revision ID: start_neutron_fwaas
|
|
||||||
Revises: None
|
|
||||||
Create Date: 2014-12-09 18:42:08.262632
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'start_neutron_fwaas'
|
|
||||||
down_revision = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
pass
|
|
@ -1,17 +0,0 @@
|
|||||||
# 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 neutron_lib.db import model_base
|
|
||||||
|
|
||||||
|
|
||||||
def get_metadata():
|
|
||||||
return model_base.BASEV2.metadata
|
|
@ -1,302 +0,0 @@
|
|||||||
# Copyright (c) 2016 Mirantis, Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import abc
|
|
||||||
|
|
||||||
from debtcollector import moves
|
|
||||||
from neutron.api.v2 import resource_helper
|
|
||||||
from neutron_lib.api.definitions import constants as api_const
|
|
||||||
from neutron_lib.api.definitions import firewall_v2
|
|
||||||
from neutron_lib.api import extensions
|
|
||||||
from neutron_lib.exceptions import firewall_v2 as f_exc
|
|
||||||
from neutron_lib.services import base as service_base
|
|
||||||
from oslo_config import cfg
|
|
||||||
import six
|
|
||||||
|
|
||||||
from neutron_fwaas._i18n import _
|
|
||||||
from neutron_fwaas.common import fwaas_constants
|
|
||||||
|
|
||||||
|
|
||||||
FirewallGroupNotFound = moves.moved_class(
|
|
||||||
f_exc.FirewallGroupNotFound, 'FirewallGroupNotFound', __name__)
|
|
||||||
FirewallGroupInUse = moves.moved_class(
|
|
||||||
f_exc.FirewallGroupInUse, 'FirewallGroupInUse', __name__)
|
|
||||||
FirewallGroupInPendingState = moves.moved_class(
|
|
||||||
f_exc.FirewallGroupInPendingState, 'FirewallGroupInPendingState', __name__)
|
|
||||||
FirewallGroupPortInvalid = moves.moved_class(
|
|
||||||
f_exc.FirewallGroupPortInvalid, 'FirewallGroupPortInvalid', __name__)
|
|
||||||
FirewallGroupPortInvalidProject = moves.moved_class(
|
|
||||||
f_exc.FirewallGroupPortInvalidProject, 'FirewallGroupPortInvalidProject',
|
|
||||||
__name__)
|
|
||||||
FirewallGroupPortInUse = moves.moved_class(
|
|
||||||
f_exc.FirewallGroupPortInUse, 'FirewallGroupPortInUse', __name__)
|
|
||||||
FirewallPolicyNotFound = moves.moved_class(
|
|
||||||
f_exc.FirewallPolicyNotFound, 'FirewallPolicyNotFound', __name__)
|
|
||||||
FirewallPolicyInUse = moves.moved_class(
|
|
||||||
f_exc.FirewallPolicyInUse, 'FirewallPolicyInUse', __name__)
|
|
||||||
FirewallPolicyConflict = moves.moved_class(
|
|
||||||
f_exc.FirewallPolicyConflict, 'FirewallPolicyConflict', __name__)
|
|
||||||
FirewallRuleSharingConflict = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleSharingConflict, 'FirewallRuleSharingConflict',
|
|
||||||
__name__)
|
|
||||||
FirewallPolicySharingConflict = moves.moved_class(
|
|
||||||
f_exc.FirewallPolicySharingConflict, 'FirewallPolicySharingConflict',
|
|
||||||
__name__)
|
|
||||||
FirewallRuleNotFound = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleNotFound, 'FirewallRuleNotFound', __name__)
|
|
||||||
FirewallRuleInUse = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleInUse, 'FirewallRuleInUse', __name__)
|
|
||||||
FirewallRuleNotAssociatedWithPolicy = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleNotAssociatedWithPolicy,
|
|
||||||
'FirewallRuleNotAssociatedWithPolicy',
|
|
||||||
__name__)
|
|
||||||
FirewallRuleInvalidProtocol = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleInvalidProtocol, 'FirewallRuleInvalidProtocol',
|
|
||||||
__name__)
|
|
||||||
FirewallRuleInvalidAction = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleInvalidAction, 'FirewallRuleInvalidAction',
|
|
||||||
__name__)
|
|
||||||
FirewallRuleInvalidICMPParameter = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleInvalidICMPParameter,
|
|
||||||
'FirewallRuleInvalidICMPParameter', __name__)
|
|
||||||
FirewallRuleWithPortWithoutProtocolInvalid = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleWithPortWithoutProtocolInvalid,
|
|
||||||
'FirewallRuleWithPortWithoutProtocolInvalid', __name__)
|
|
||||||
FirewallRuleInvalidPortValue = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleInvalidPortValue, 'FirewallRuleInvalidPortValue',
|
|
||||||
__name__)
|
|
||||||
FirewallRuleInfoMissing = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleInfoMissing, 'FirewallRuleInfoMissing', __name__)
|
|
||||||
FirewallIpAddressConflict = moves.moved_class(
|
|
||||||
f_exc.FirewallIpAddressConflict, 'FirewallIpAddressConflict', __name__)
|
|
||||||
FirewallInternalDriverError = moves.moved_class(
|
|
||||||
f_exc.FirewallInternalDriverError, 'FirewallInternalDriverError', __name__)
|
|
||||||
FirewallRuleConflict = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleConflict, 'FirewallRuleConflict', __name__)
|
|
||||||
FirewallRuleAlreadyAssociated = moves.moved_class(
|
|
||||||
f_exc.FirewallRuleAlreadyAssociated, 'FirewallRuleAlreadyAssociated',
|
|
||||||
__name__)
|
|
||||||
|
|
||||||
default_fwg_rules_opts = [
|
|
||||||
cfg.StrOpt('ingress_action',
|
|
||||||
default=api_const.FWAAS_DENY,
|
|
||||||
help=_('Firewall group rule action allow or '
|
|
||||||
'deny or reject for ingress. '
|
|
||||||
'Default is deny.')),
|
|
||||||
cfg.StrOpt('ingress_source_ipv4_address',
|
|
||||||
default=None,
|
|
||||||
help=_('IPv4 source address for ingress '
|
|
||||||
'(address or address/netmask). '
|
|
||||||
'Default is None.')),
|
|
||||||
cfg.StrOpt('ingress_source_ipv6_address',
|
|
||||||
default=None,
|
|
||||||
help=_('IPv6 source address for ingress '
|
|
||||||
'(address or address/netmask). '
|
|
||||||
'Default is None.')),
|
|
||||||
cfg.StrOpt('ingress_source_port',
|
|
||||||
default=None,
|
|
||||||
help=_('Source port number or range '
|
|
||||||
'(min:max) for ingress. '
|
|
||||||
'Default is None.')),
|
|
||||||
cfg.StrOpt('ingress_destination_ipv4_address',
|
|
||||||
default=None,
|
|
||||||
help=_('IPv4 destination address for ingress '
|
|
||||||
'(address or address/netmask). '
|
|
||||||
'Default is None.')),
|
|
||||||
cfg.StrOpt('ingress_destination_ipv6_address',
|
|
||||||
default=None,
|
|
||||||
help=_('IPv6 destination address for ingress '
|
|
||||||
'(address or address/netmask). '
|
|
||||||
'Default is deny.')),
|
|
||||||
cfg.StrOpt('ingress_destination_port',
|
|
||||||
default=None,
|
|
||||||
help=_('Destination port number or range '
|
|
||||||
'(min:max) for ingress. '
|
|
||||||
'Default is None.')),
|
|
||||||
cfg.StrOpt('egress_action',
|
|
||||||
default=api_const.FWAAS_ALLOW,
|
|
||||||
help=_('Firewall group rule action allow or '
|
|
||||||
'deny or reject for egress. '
|
|
||||||
'Default is allow.')),
|
|
||||||
cfg.StrOpt('egress_source_ipv4_address',
|
|
||||||
default=None,
|
|
||||||
help=_('IPv4 source address for egress '
|
|
||||||
'(address or address/netmask). '
|
|
||||||
'Default is None.')),
|
|
||||||
cfg.StrOpt('egress_source_ipv6_address',
|
|
||||||
default=None,
|
|
||||||
help=_('IPv6 source address for egress '
|
|
||||||
'(address or address/netmask). '
|
|
||||||
'Default is deny.')),
|
|
||||||
cfg.StrOpt('egress_source_port',
|
|
||||||
default=None,
|
|
||||||
help=_('Source port number or range '
|
|
||||||
'(min:max) for egress. '
|
|
||||||
'Default is None.')),
|
|
||||||
cfg.StrOpt('egress_destination_ipv4_address',
|
|
||||||
default=None,
|
|
||||||
help=_('IPv4 destination address for egress '
|
|
||||||
'(address or address/netmask). '
|
|
||||||
'Default is deny.')),
|
|
||||||
cfg.StrOpt('egress_destination_ipv6_address',
|
|
||||||
default=None,
|
|
||||||
help=_('IPv6 destination address for egress '
|
|
||||||
'(address or address/netmask). '
|
|
||||||
'Default is deny.')),
|
|
||||||
cfg.StrOpt('egress_destination_port',
|
|
||||||
default=None,
|
|
||||||
help=_('Destination port number or range '
|
|
||||||
'(min:max) for egress. '
|
|
||||||
'Default is None.')),
|
|
||||||
cfg.BoolOpt('shared',
|
|
||||||
default=False,
|
|
||||||
help=_('Firewall group rule shared. '
|
|
||||||
'Default is False.')),
|
|
||||||
cfg.StrOpt('protocol',
|
|
||||||
default=None,
|
|
||||||
help=_('Network protocols (tcp, udp, ...). '
|
|
||||||
'Default is None.')),
|
|
||||||
cfg.BoolOpt('enabled',
|
|
||||||
default=True,
|
|
||||||
help=_('Firewall group rule enabled. '
|
|
||||||
'Default is True.')),
|
|
||||||
]
|
|
||||||
firewall_quota_opts = [
|
|
||||||
cfg.IntOpt('quota_firewall_group',
|
|
||||||
default=10,
|
|
||||||
help=_('Number of firewall groups allowed per tenant. '
|
|
||||||
'A negative value means unlimited.')),
|
|
||||||
cfg.IntOpt('quota_firewall_policy',
|
|
||||||
default=10,
|
|
||||||
help=_('Number of firewall policies allowed per tenant. '
|
|
||||||
'A negative value means unlimited.')),
|
|
||||||
cfg.IntOpt('quota_firewall_rule',
|
|
||||||
default=100,
|
|
||||||
help=_('Number of firewall rules allowed per tenant. '
|
|
||||||
'A negative value means unlimited.')),
|
|
||||||
]
|
|
||||||
cfg.CONF.register_opts(default_fwg_rules_opts, 'default_fwg_rules')
|
|
||||||
cfg.CONF.register_opts(firewall_quota_opts, 'QUOTAS')
|
|
||||||
|
|
||||||
|
|
||||||
# TODO(Reedip): Remove the convert_to functionality after bug1706061 is fixed.
|
|
||||||
def convert_to_string(value):
|
|
||||||
if value is not None:
|
|
||||||
return str(value)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
firewall_v2.RESOURCE_ATTRIBUTE_MAP[api_const.FIREWALL_RULES][
|
|
||||||
'source_port']['convert_to'] = convert_to_string
|
|
||||||
firewall_v2.RESOURCE_ATTRIBUTE_MAP[api_const.FIREWALL_RULES][
|
|
||||||
'destination_port']['convert_to'] = convert_to_string
|
|
||||||
|
|
||||||
|
|
||||||
class Firewall_v2(extensions.APIExtensionDescriptor):
|
|
||||||
api_definition = firewall_v2
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_resources(cls):
|
|
||||||
special_mappings = {'firewall_policies': 'firewall_policy'}
|
|
||||||
plural_mappings = resource_helper.build_plural_mappings(
|
|
||||||
special_mappings, firewall_v2.RESOURCE_ATTRIBUTE_MAP)
|
|
||||||
return resource_helper.build_resource_info(
|
|
||||||
plural_mappings, firewall_v2.RESOURCE_ATTRIBUTE_MAP,
|
|
||||||
fwaas_constants.FIREWALL_V2, action_map=firewall_v2.ACTION_MAP,
|
|
||||||
register_quota=True)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_plugin_interface(cls):
|
|
||||||
return Firewallv2PluginBase
|
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
|
||||||
class Firewallv2PluginBase(service_base.ServicePluginBase):
|
|
||||||
|
|
||||||
def get_plugin_type(self):
|
|
||||||
return fwaas_constants.FIREWALL_V2
|
|
||||||
|
|
||||||
def get_plugin_description(self):
|
|
||||||
return 'Firewall Service v2 Plugin'
|
|
||||||
|
|
||||||
# Firewall Group
|
|
||||||
@abc.abstractmethod
|
|
||||||
def create_firewall_group(self, context, firewall_group):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def delete_firewall_group(self, context, id):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def get_firewall_group(self, context, id, fields=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def get_firewall_groups(self, context, filters=None, fields=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def update_firewall_group(self, context, id, firewall_group):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Firewall Policy
|
|
||||||
@abc.abstractmethod
|
|
||||||
def create_firewall_policy(self, context, firewall_policy):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def delete_firewall_policy(self, context, id):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def get_firewall_policy(self, context, id, fields=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def get_firewall_policies(self, context, filters=None, fields=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def update_firewall_policy(self, context, id, firewall_policy):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Firewall Rule
|
|
||||||
@abc.abstractmethod
|
|
||||||
def create_firewall_rule(self, context, firewall_rule):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def delete_firewall_rule(self, context, id):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def get_firewall_rule(self, context, id, fields=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def get_firewall_rules(self, context, filters=None, fields=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def update_firewall_rule(self, context, id, firewall_rule):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def insert_rule(self, context, id, rule_info):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def remove_rule(self, context, id, rule_info):
|
|
||||||
pass
|
|
@ -1,36 +0,0 @@
|
|||||||
# 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 neutron.conf.services.provider_configuration
|
|
||||||
|
|
||||||
import neutron_fwaas.services.firewall.service_drivers.agents.\
|
|
||||||
firewall_agent_api
|
|
||||||
import neutron_fwaas.extensions.firewall_v2
|
|
||||||
|
|
||||||
|
|
||||||
def list_agent_opts():
|
|
||||||
return [
|
|
||||||
('fwaas',
|
|
||||||
neutron_fwaas.services.firewall.service_drivers.agents.
|
|
||||||
firewall_agent_api.FWaaSOpts),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def list_opts():
|
|
||||||
return [
|
|
||||||
('quotas',
|
|
||||||
neutron_fwaas.extensions.firewall_v2.firewall_quota_opts),
|
|
||||||
('service_providers',
|
|
||||||
neutron.conf.services.provider_configuration.serviceprovider_opts),
|
|
||||||
('default_fwg_rules',
|
|
||||||
neutron_fwaas.extensions.firewall_v2.default_fwg_rules_opts),
|
|
||||||
]
|
|
@ -1,25 +0,0 @@
|
|||||||
# 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 neutron_fwaas.policies import firewall_group
|
|
||||||
from neutron_fwaas.policies import firewall_policy
|
|
||||||
from neutron_fwaas.policies import firewall_rule
|
|
||||||
|
|
||||||
|
|
||||||
def list_rules():
|
|
||||||
return itertools.chain(
|
|
||||||
firewall_group.list_rules(),
|
|
||||||
firewall_policy.list_rules(),
|
|
||||||
firewall_rule.list_rules(),
|
|
||||||
)
|
|
@ -1,17 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
|
|
||||||
# TODO(amotoki): Define these in neutron or neutron-lib
|
|
||||||
RULE_ADMIN_OR_OWNER = 'rule:admin_or_owner'
|
|
||||||
RULE_ADMIN_ONLY = 'rule:admin_only'
|
|
||||||
RULE_ANY = 'rule:regular_user'
|
|
@ -1,113 +0,0 @@
|
|||||||
# 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 oslo_policy import policy
|
|
||||||
|
|
||||||
from neutron_fwaas.policies import base
|
|
||||||
|
|
||||||
|
|
||||||
rules = [
|
|
||||||
policy.RuleDefault(
|
|
||||||
'shared_firewall_groups',
|
|
||||||
'field:firewall_groups:shared=True',
|
|
||||||
'Definition of shared firewall groups'
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'create_firewall_group',
|
|
||||||
base.RULE_ANY,
|
|
||||||
'Create a firewall group',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'POST',
|
|
||||||
'path': '/fwaas/firewall_groups',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'update_firewall_group',
|
|
||||||
base.RULE_ADMIN_OR_OWNER,
|
|
||||||
'Update a firewall group',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'PUT',
|
|
||||||
'path': '/fwaas/firewall_groups/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'delete_firewall_group',
|
|
||||||
base.RULE_ADMIN_OR_OWNER,
|
|
||||||
'Delete a firewall group',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'DELETE',
|
|
||||||
'path': '/fwaas/firewall_groups/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'create_firewall_group:shared',
|
|
||||||
base.RULE_ADMIN_ONLY,
|
|
||||||
'Create a shared firewall group',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'POST',
|
|
||||||
'path': '/fwaas/firewall_groups',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'update_firewall_group:shared',
|
|
||||||
base.RULE_ADMIN_ONLY,
|
|
||||||
'Update ``shared`` attribute of a firewall group',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'PUT',
|
|
||||||
'path': '/fwaas/firewall_groups/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
# TODO(amotoki): Drop this rule as it has no effect.
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'delete_firewall_group:shared',
|
|
||||||
base.RULE_ADMIN_ONLY,
|
|
||||||
'Delete a shared firewall group',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'DELETE',
|
|
||||||
'path': '/fwaas/firewall_groups/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'get_firewall_group',
|
|
||||||
'rule:admin_or_owner or rule:shared_firewall_groups',
|
|
||||||
'Get firewall groups',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'GET',
|
|
||||||
'path': '/fwaas/firewall_groups',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'method': 'GET',
|
|
||||||
'path': '/fwaas/firewall_groups/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def list_rules():
|
|
||||||
return rules
|
|
@ -1,113 +0,0 @@
|
|||||||
# 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 oslo_policy import policy
|
|
||||||
|
|
||||||
from neutron_fwaas.policies import base
|
|
||||||
|
|
||||||
|
|
||||||
rules = [
|
|
||||||
policy.RuleDefault(
|
|
||||||
'shared_firewall_policies',
|
|
||||||
'field:firewall_policies:shared=True',
|
|
||||||
'Definition of shared firewall policies'
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'create_firewall_policy',
|
|
||||||
base.RULE_ANY,
|
|
||||||
'Create a firewall policy',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'POST',
|
|
||||||
'path': '/fwaas/firewall_policies',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'update_firewall_policy',
|
|
||||||
base.RULE_ADMIN_OR_OWNER,
|
|
||||||
'Update a firewall policy',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'PUT',
|
|
||||||
'path': '/fwaas/firewall_policies/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'delete_firewall_policy',
|
|
||||||
base.RULE_ADMIN_OR_OWNER,
|
|
||||||
'Delete a firewall policy',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'DELETE',
|
|
||||||
'path': '/fwaas/firewall_policies/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'create_firewall_policy:shared',
|
|
||||||
base.RULE_ADMIN_ONLY,
|
|
||||||
'Create a shared firewall policy',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'POST',
|
|
||||||
'path': '/fwaas/firewall_policies',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'update_firewall_policy:shared',
|
|
||||||
base.RULE_ADMIN_ONLY,
|
|
||||||
'Update ``shared`` attribute of a firewall policy',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'PUT',
|
|
||||||
'path': '/fwaas/firewall_policies/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
# TODO(amotoki): Drop this rule as it has no effect.
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'delete_firewall_policy:shared',
|
|
||||||
base.RULE_ADMIN_ONLY,
|
|
||||||
'Delete a shread firewall policy',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'DELETE',
|
|
||||||
'path': '/fwaas/firewall_policies/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'get_firewall_policy',
|
|
||||||
'rule:admin_or_owner or rule:shared_firewall_policies',
|
|
||||||
'Get firewall policies',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'GET',
|
|
||||||
'path': '/fwaas/firewall_policies',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'method': 'GET',
|
|
||||||
'path': '/fwaas/firewall_policies/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def list_rules():
|
|
||||||
return rules
|
|
@ -1,136 +0,0 @@
|
|||||||
# 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 oslo_policy import policy
|
|
||||||
|
|
||||||
from neutron_fwaas.policies import base
|
|
||||||
|
|
||||||
|
|
||||||
rules = [
|
|
||||||
policy.RuleDefault(
|
|
||||||
'shared_firewall_rules',
|
|
||||||
'field:firewall_rules:shared=True',
|
|
||||||
'Definition of shared firewall rules'
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'create_firewall_rule',
|
|
||||||
base.RULE_ANY,
|
|
||||||
'Create a firewall rule',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'POST',
|
|
||||||
'path': '/fwaas/firewall_rules',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'update_firewall_rule',
|
|
||||||
base.RULE_ADMIN_OR_OWNER,
|
|
||||||
'Update a firewall rule',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'PUT',
|
|
||||||
'path': '/fwaas/firewall_rules/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'delete_firewall_rule',
|
|
||||||
base.RULE_ADMIN_OR_OWNER,
|
|
||||||
'Delete a firewall rule',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'DELETE',
|
|
||||||
'path': '/fwaas/firewall_rules/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'create_firewall_rule:shared',
|
|
||||||
base.RULE_ADMIN_ONLY,
|
|
||||||
'Create a shared firewall rule',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'POST',
|
|
||||||
'path': '/fwaas/firewall_rules',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'update_firewall_rule:shared',
|
|
||||||
base.RULE_ADMIN_ONLY,
|
|
||||||
'Update ``shared`` attribute of a firewall rule',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'PUT',
|
|
||||||
'path': '/fwaas/firewall_rules/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
# TODO(amotoki): Drop this rule as it has no effect.
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'delete_firewall_rule:shared',
|
|
||||||
base.RULE_ADMIN_ONLY,
|
|
||||||
'Delete a shread firewall rule',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'DELETE',
|
|
||||||
'path': '/fwaas/firewall_rules/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'get_firewall_rule',
|
|
||||||
'rule:admin_or_owner or rule:shared_firewall_rules',
|
|
||||||
'Get firewall rules',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'GET',
|
|
||||||
'path': '/fwaas/firewall_rules',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'method': 'GET',
|
|
||||||
'path': '/fwaas/firewall_rules/{id}',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'insert_rule',
|
|
||||||
base.RULE_ADMIN_OR_OWNER,
|
|
||||||
'Insert rule into a firewall policy',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'PUT',
|
|
||||||
'path': '/fwaas/firewall_policies/{id}/insert_rule',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
policy.DocumentedRuleDefault(
|
|
||||||
'remove_rule',
|
|
||||||
base.RULE_ADMIN_OR_OWNER,
|
|
||||||
'Remove rule from a firewall policy',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
'method': 'PUT',
|
|
||||||
'path': '/fwaas/firewall_policies/{id}/remove_rule',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def list_rules():
|
|
||||||
return rules
|
|
@ -1,29 +0,0 @@
|
|||||||
# Copyright (c) 2017 Thales Services SAS
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from oslo_privsep import capabilities as c
|
|
||||||
from oslo_privsep import priv_context
|
|
||||||
|
|
||||||
# It is expected that most (if not all) neutron-fwaas operations can be
|
|
||||||
# executed with these privileges.
|
|
||||||
default = priv_context.PrivContext(
|
|
||||||
__name__,
|
|
||||||
cfg_section='privsep',
|
|
||||||
pypath=__name__ + '.default',
|
|
||||||
# TODO(gus): CAP_SYS_ADMIN is required (only?) for manipulating
|
|
||||||
# network namespaces. SYS_ADMIN is a lot of scary powers, so
|
|
||||||
# consider breaking this out into a separate minimal context.
|
|
||||||
capabilities=[c.CAP_SYS_ADMIN, c.CAP_NET_ADMIN],
|
|
||||||
)
|
|
@ -1,331 +0,0 @@
|
|||||||
# Copyright (c) 2018 Fujitsu Limited
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
import multiprocessing
|
|
||||||
import socket
|
|
||||||
import struct
|
|
||||||
import time
|
|
||||||
|
|
||||||
import cffi
|
|
||||||
import eventlet
|
|
||||||
from eventlet.green import zmq
|
|
||||||
from neutron_lib.utils import runtime
|
|
||||||
from os_ken.lib import addrconv
|
|
||||||
from os_ken.lib.packet import arp
|
|
||||||
from os_ken.lib.packet import ether_types
|
|
||||||
from os_ken.lib.packet import ethernet
|
|
||||||
from os_ken.lib.packet import ipv4
|
|
||||||
from os_ken.lib.packet import ipv6
|
|
||||||
from oslo_log import log as logging
|
|
||||||
from oslo_serialization import jsonutils
|
|
||||||
from oslo_utils import encodeutils
|
|
||||||
from oslo_utils import excutils
|
|
||||||
|
|
||||||
from neutron_fwaas._i18n import _
|
|
||||||
from neutron_fwaas import privileged
|
|
||||||
from neutron_fwaas.privileged import utils as fwaas_utils
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# TODO(annp): consider to make a pub-sub pattern which allows other logging
|
|
||||||
# driver like snat log can consume libnetfilter_log
|
|
||||||
|
|
||||||
NETFILTER_LOG = 'netfilter_log'
|
|
||||||
ADDR_IPC = "ipc:///var/run/nflog"
|
|
||||||
CDEF = '''
|
|
||||||
typedef unsigned char u_int8_t;
|
|
||||||
typedef unsigned short int u_int16_t;
|
|
||||||
typedef unsigned int u_int32_t;
|
|
||||||
|
|
||||||
struct nfulnl_msg_packet_hdr {
|
|
||||||
u_int16_t hw_protocol; // hw protocol (network order)
|
|
||||||
u_int8_t hook; // netfilter hook
|
|
||||||
u_int8_t _pad;
|
|
||||||
};
|
|
||||||
|
|
||||||
int nflog_fd(struct nflog_handle *h);
|
|
||||||
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
|
|
||||||
|
|
||||||
struct nflog_handle *nflog_open(void);
|
|
||||||
int nflog_close(struct nflog_handle *h);
|
|
||||||
int nflog_bind_pf(struct nflog_handle *h, u_int16_t pf);
|
|
||||||
int nflog_unbind_pf(struct nflog_handle *h, u_int16_t pf);
|
|
||||||
struct nflog_g_handle *nflog_bind_group(struct nflog_handle *h, u_int16_t num);
|
|
||||||
int nflog_unbind_group(struct nflog_g_handle *gh);
|
|
||||||
|
|
||||||
static const u_int8_t NFULNL_COPY_PACKET;
|
|
||||||
|
|
||||||
int nflog_set_mode(struct nflog_g_handle *gh, u_int8_t mode, unsigned int len);
|
|
||||||
int nflog_set_timeout(struct nflog_g_handle *gh, u_int32_t timeout);
|
|
||||||
int nflog_set_flags(struct nflog_g_handle *gh, u_int16_t flags);
|
|
||||||
int nflog_set_qthresh(struct nflog_g_handle *gh, u_int32_t qthresh);
|
|
||||||
int nflog_set_nlbufsiz(struct nflog_g_handle *gh, u_int32_t nlbufsiz);
|
|
||||||
|
|
||||||
typedef int nflog_callback(struct nflog_g_handle *gh,
|
|
||||||
struct nfgenmsg *nfmsg, struct nflog_data *nfd, void *data);
|
|
||||||
int nflog_callback_register(
|
|
||||||
struct nflog_g_handle *gh, nflog_callback *cb, void *data);
|
|
||||||
int nflog_handle_packet(struct nflog_handle *h, char *buf, int len);
|
|
||||||
|
|
||||||
struct nfulnl_msg_packet_hdr *nflog_get_msg_packet_hdr(
|
|
||||||
struct nflog_data *nfad);
|
|
||||||
|
|
||||||
u_int16_t nflog_get_hwtype(struct nflog_data *nfad);
|
|
||||||
u_int16_t nflog_get_msg_packet_hwhdrlen(struct nflog_data *nfad);
|
|
||||||
char *nflog_get_msg_packet_hwhdr(struct nflog_data *nfad);
|
|
||||||
u_int32_t nflog_get_nfmark(struct nflog_data *nfad);
|
|
||||||
int nflog_get_timestamp(struct nflog_data *nfad, struct timeval *tv);
|
|
||||||
u_int32_t nflog_get_indev(struct nflog_data *nfad);
|
|
||||||
u_int32_t nflog_get_physindev(struct nflog_data *nfad);
|
|
||||||
u_int32_t nflog_get_outdev(struct nflog_data *nfad);
|
|
||||||
u_int32_t nflog_get_physoutdev(struct nflog_data *nfad);
|
|
||||||
struct nfulnl_msg_packet_hw *nflog_get_packet_hw(struct nflog_data *nfad);
|
|
||||||
|
|
||||||
int nflog_get_payload(struct nflog_data *nfad, char **data);
|
|
||||||
|
|
||||||
char *nflog_get_prefix(struct nflog_data *nfad);
|
|
||||||
'''
|
|
||||||
|
|
||||||
ffi = None
|
|
||||||
libnflog = None
|
|
||||||
|
|
||||||
|
|
||||||
def init_library():
|
|
||||||
"""Load libnetfilter_log library"""
|
|
||||||
|
|
||||||
global ffi
|
|
||||||
global libnflog
|
|
||||||
if not ffi:
|
|
||||||
ffi = cffi.FFI()
|
|
||||||
ffi.cdef(CDEF)
|
|
||||||
if not libnflog:
|
|
||||||
try:
|
|
||||||
libnflog = ffi.dlopen(NETFILTER_LOG)
|
|
||||||
except OSError:
|
|
||||||
msg = "Could not found libnetfilter-log"
|
|
||||||
raise Exception(msg)
|
|
||||||
|
|
||||||
return ffi, libnflog
|
|
||||||
|
|
||||||
|
|
||||||
ffi, libnflog = init_library()
|
|
||||||
|
|
||||||
|
|
||||||
def _payload(nfa):
|
|
||||||
buf = ffi.new('char **')
|
|
||||||
pkt_len = libnflog.nflog_get_payload(nfa, buf)
|
|
||||||
if pkt_len <= 0:
|
|
||||||
return None
|
|
||||||
return ffi.buffer(buf[0], pkt_len)[:]
|
|
||||||
|
|
||||||
|
|
||||||
def decode(nfa):
|
|
||||||
"""This function analyses nflog packet by using os-ken packet library."""
|
|
||||||
|
|
||||||
prefix = ffi.string(libnflog.nflog_get_prefix(nfa))
|
|
||||||
packet_hdr = libnflog.nflog_get_msg_packet_hdr(nfa)
|
|
||||||
hw_proto = socket.ntohs(packet_hdr.hw_protocol)
|
|
||||||
|
|
||||||
msg = ''
|
|
||||||
msg_packet_hwhdr = libnflog.nflog_get_msg_packet_hwhdr(nfa)
|
|
||||||
if msg_packet_hwhdr != ffi.NULL:
|
|
||||||
packet_hwhdr = ffi.string(msg_packet_hwhdr)
|
|
||||||
if len(packet_hwhdr) >= 12:
|
|
||||||
dst, src = struct.unpack_from('!6s6s', packet_hwhdr)
|
|
||||||
# Dump ethernet packet to get mac addresses
|
|
||||||
eth = ethernet.ethernet(addrconv.mac.bin_to_text(dst),
|
|
||||||
addrconv.mac.bin_to_text(src),
|
|
||||||
ethertype=hw_proto)
|
|
||||||
msg = str(eth)
|
|
||||||
|
|
||||||
# Dump IP packet
|
|
||||||
pkt = _payload(nfa)
|
|
||||||
if hw_proto == ether_types.ETH_TYPE_IP:
|
|
||||||
ip_pkt, proto, data = ipv4.ipv4().parser(pkt)
|
|
||||||
msg += str(ip_pkt)
|
|
||||||
proto_pkt, a, b = proto.parser(data)
|
|
||||||
msg += str(proto_pkt)
|
|
||||||
elif hw_proto == ether_types.ETH_TYPE_IPV6:
|
|
||||||
ip_pkt, proto, data = ipv6.ipv6().parser(pkt)
|
|
||||||
proto_pkt, a, b = proto.parser(data)
|
|
||||||
msg += str(proto_pkt)
|
|
||||||
elif hw_proto == ether_types.ETH_TYPE_ARP:
|
|
||||||
ip_pkt, proto, data = arp.arp().parser(pkt)
|
|
||||||
msg += str(ip_pkt)
|
|
||||||
else:
|
|
||||||
msg += "Does not support hw_proto: " + str(hw_proto)
|
|
||||||
|
|
||||||
return {'prefix': encodeutils.safe_decode(prefix),
|
|
||||||
'msg': encodeutils.safe_decode(msg)}
|
|
||||||
|
|
||||||
|
|
||||||
class NFLogWrapper(object):
|
|
||||||
"""A wrapper for libnetfilter_log api"""
|
|
||||||
|
|
||||||
_instance = None
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.nflog_g_hanldes = {}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
@runtime.synchronized("nflog-wrapper")
|
|
||||||
def _create_instance(cls):
|
|
||||||
if not cls.has_instance():
|
|
||||||
cls._instance = cls()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def has_instance(cls):
|
|
||||||
return cls._instance is not None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def clear_instance(cls):
|
|
||||||
cls._instance = None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_instance(cls):
|
|
||||||
# double checked locking
|
|
||||||
if not cls.has_instance():
|
|
||||||
cls._create_instance()
|
|
||||||
return cls._instance
|
|
||||||
|
|
||||||
def open(self):
|
|
||||||
self.nflog_handle = libnflog.nflog_open()
|
|
||||||
if not self.nflog_handle:
|
|
||||||
msg = _("Could not open nflog handle")
|
|
||||||
raise Exception(msg)
|
|
||||||
self._bind_pf()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
if self.nflog_handle:
|
|
||||||
libnflog.nflog_close(self.nflog_handle)
|
|
||||||
|
|
||||||
def bind_group(self, group):
|
|
||||||
g_handle = libnflog.nflog_bind_group(self.nflog_handle, group)
|
|
||||||
if g_handle:
|
|
||||||
self.nflog_g_hanldes[group] = g_handle
|
|
||||||
self._set_mode(g_handle, 0x2, 0xffff)
|
|
||||||
self._set_callback(g_handle, self.cb)
|
|
||||||
|
|
||||||
def _bind_pf(self):
|
|
||||||
for pf in (socket.AF_INET, socket.AF_INET6):
|
|
||||||
libnflog.nflog_unbind_pf(self.nflog_handle, pf)
|
|
||||||
libnflog.nflog_bind_pf(self.nflog_handle, pf)
|
|
||||||
|
|
||||||
def unbind_group(self, group):
|
|
||||||
try:
|
|
||||||
g_handle = self.nflog_g_hanldes[group]
|
|
||||||
if g_handle:
|
|
||||||
libnflog.nflog_unbind_group(g_handle)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _set_mode(self, g_handle, mode, len):
|
|
||||||
ret = libnflog.nflog_set_mode(g_handle, mode, len)
|
|
||||||
if ret != 0:
|
|
||||||
msg = _("Could not set mode for nflog")
|
|
||||||
raise Exception(msg)
|
|
||||||
|
|
||||||
@ffi.callback("nflog_callback")
|
|
||||||
def cb(gh, nfmsg, nfa, data):
|
|
||||||
ev = decode(nfa)
|
|
||||||
msg = jsonutils.dumps(ev) + '\n'
|
|
||||||
ctx = zmq.Context(1)
|
|
||||||
pub = ctx.socket(zmq.XREQ)
|
|
||||||
pub.bind(ADDR_IPC)
|
|
||||||
pub.send(msg.encode('utf-8'))
|
|
||||||
pub.close()
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def _set_callback(self, g_handle, cb):
|
|
||||||
|
|
||||||
ret = libnflog.nflog_callback_register(g_handle, cb, ffi.NULL)
|
|
||||||
if ret != 0:
|
|
||||||
msg = _("Could not set callback for nflog")
|
|
||||||
raise Exception(msg)
|
|
||||||
|
|
||||||
def run_loop(self):
|
|
||||||
fd = libnflog.nflog_fd(self.nflog_handle)
|
|
||||||
buff = ffi.new('char[]', 4096)
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
pkt_len = libnflog.recv(fd, buff, 4096, 0)
|
|
||||||
except OSError as err:
|
|
||||||
# No buffer space available
|
|
||||||
if err.errno == 11:
|
|
||||||
continue
|
|
||||||
msg = _("Unknown exception")
|
|
||||||
raise Exception(msg)
|
|
||||||
if pkt_len > 0:
|
|
||||||
libnflog.nflog_handle_packet(self.nflog_handle, buff, pkt_len)
|
|
||||||
time.sleep(1.0)
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
nflog_process = multiprocessing.Process(target=self.run_loop)
|
|
||||||
nflog_process.daemon = True
|
|
||||||
nflog_process.start()
|
|
||||||
return nflog_process.pid
|
|
||||||
|
|
||||||
|
|
||||||
@privileged.default.entrypoint
|
|
||||||
def run_nflog(namespace=None, group=0):
|
|
||||||
"""Run a nflog process under a namespace
|
|
||||||
|
|
||||||
This process will listen nflog packets, which are sent from kernel to
|
|
||||||
userspace. Then it decode these packets and send it to IPC address for log
|
|
||||||
application.
|
|
||||||
"""
|
|
||||||
|
|
||||||
with fwaas_utils.in_namespace(namespace):
|
|
||||||
try:
|
|
||||||
handle = NFLogWrapper.get_instance()
|
|
||||||
handle.open()
|
|
||||||
handle.bind_group(group)
|
|
||||||
pid = handle.start()
|
|
||||||
except Exception:
|
|
||||||
with excutils.save_and_reraise_exception():
|
|
||||||
LOG.exception("NFLOG thread died of an exception")
|
|
||||||
try:
|
|
||||||
handle.unbind_group(group)
|
|
||||||
handle.close()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
return pid
|
|
||||||
|
|
||||||
|
|
||||||
class NFLogApp(object):
|
|
||||||
"""Log application for handling nflog packets"""
|
|
||||||
|
|
||||||
callback = None
|
|
||||||
|
|
||||||
def register_packet_handler(self, caller):
|
|
||||||
self.callback = caller
|
|
||||||
|
|
||||||
def unregister_packet_handler(self):
|
|
||||||
self.callback = None
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
def loop():
|
|
||||||
while True:
|
|
||||||
if self.callback:
|
|
||||||
ctx = zmq.Context(1)
|
|
||||||
sub = ctx.socket(zmq.XREQ)
|
|
||||||
sub.connect(ADDR_IPC)
|
|
||||||
msg = sub.recv()
|
|
||||||
if len(msg):
|
|
||||||
self.callback(jsonutils.loads(msg))
|
|
||||||
sub.close()
|
|
||||||
time.sleep(1.0)
|
|
||||||
# Spawn loop
|
|
||||||
eventlet.spawn_n(loop)
|
|
@ -1,86 +0,0 @@
|
|||||||
# Copyright (c) 2017 Fujitsu Limited
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Some parts are based on python-conntrack:
|
|
||||||
# Copyright (c) 2009-2011,2015 Andrew Grigorev <andrew@ei-grad.ru>
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
import socket
|
|
||||||
|
|
||||||
|
|
||||||
CONNTRACK = 0
|
|
||||||
|
|
||||||
NFCT_O_PLAIN = 0
|
|
||||||
|
|
||||||
NFCT_OF_TIME_BIT = 1
|
|
||||||
NFCT_OF_TIME = 1 << NFCT_OF_TIME_BIT
|
|
||||||
|
|
||||||
NFCT_Q_DESTROY = 2
|
|
||||||
NFCT_Q_FLUSH = 4
|
|
||||||
NFCT_Q_DUMP = 5
|
|
||||||
NFCT_T_DESTROY_BIT = 2
|
|
||||||
NFCT_T_DESTROY = 1 << NFCT_T_DESTROY_BIT
|
|
||||||
|
|
||||||
ATTR_IPV4_SRC = 0
|
|
||||||
ATTR_IPV4_DST = 1
|
|
||||||
ATTR_IPV6_SRC = 4
|
|
||||||
ATTR_IPV6_DST = 5
|
|
||||||
ATTR_PORT_SRC = 8
|
|
||||||
ATTR_PORT_DST = 9
|
|
||||||
ATTR_ICMP_TYPE = 12
|
|
||||||
ATTR_ICMP_CODE = 13
|
|
||||||
ATTR_ICMP_ID = 14
|
|
||||||
ATTR_L3PROTO = 15
|
|
||||||
ATTR_L4PROTO = 17
|
|
||||||
|
|
||||||
NFCT_T_NEW_BIT = 0
|
|
||||||
NFCT_T_NEW = 1 << NFCT_T_NEW_BIT
|
|
||||||
NFCT_T_UPDATE_BIT = 1
|
|
||||||
NFCT_T_UPDATE = 1 << NFCT_T_UPDATE_BIT
|
|
||||||
NFCT_T_DESTROY_BIT = 2
|
|
||||||
NFCT_T_DESTROY = 1 << NFCT_T_DESTROY_BIT
|
|
||||||
|
|
||||||
NFCT_T_ALL = NFCT_T_NEW | NFCT_T_UPDATE | NFCT_T_DESTROY
|
|
||||||
|
|
||||||
NFCT_CB_CONTINUE = 1
|
|
||||||
NFCT_CB_FAILURE = -1
|
|
||||||
|
|
||||||
NFNL_SUBSYS_CTNETLINK = 0
|
|
||||||
|
|
||||||
BUFFER = 1024
|
|
||||||
# IPv6 address memory buffer
|
|
||||||
ADDR_BUFFER_6 = 16
|
|
||||||
ADDR_BUFFER_4 = 4
|
|
||||||
|
|
||||||
IPVERSION_SOCKET = {4: socket.AF_INET, 6: socket.AF_INET6}
|
|
||||||
IPVERSION_BUFFER = {4: ADDR_BUFFER_4, 6: ADDR_BUFFER_6}
|
|
@ -1,314 +0,0 @@
|
|||||||
# Copyright (c) 2017 Fujitsu Limited
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Some parts are based on python-conntrack:
|
|
||||||
# Copyright (c) 2009-2011,2015 Andrew Grigorev <andrew@ei-grad.ru>
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
import ctypes
|
|
||||||
from ctypes import util
|
|
||||||
|
|
||||||
from oslo_log import log as logging
|
|
||||||
|
|
||||||
from neutron_lib import constants
|
|
||||||
|
|
||||||
from neutron_fwaas import privileged
|
|
||||||
from neutron_fwaas.privileged import netlink_constants as nl_constants
|
|
||||||
from neutron_fwaas.privileged import utils as fwaas_utils
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
nfct_lib = util.find_library('netfilter_conntrack')
|
|
||||||
nfct = ctypes.CDLL(nfct_lib)
|
|
||||||
libc = ctypes.CDLL(util.find_library('libc.so.6'))
|
|
||||||
|
|
||||||
# In unit tests the actual nfct library may not be installed, and since we
|
|
||||||
# don't make actual calls to it we don't want to add a hard dependency.
|
|
||||||
if nfct_lib:
|
|
||||||
# It's important that the types be defined properly on all of the functions
|
|
||||||
# we call from nfct, otherwise pointers can be truncated and cause
|
|
||||||
# segfaults.
|
|
||||||
nfct.nfct_set_attr.argtypes = [ctypes.c_void_p,
|
|
||||||
ctypes.c_int,
|
|
||||||
ctypes.c_void_p]
|
|
||||||
nfct.nfct_set_attr_u8.argtypes = [ctypes.c_void_p,
|
|
||||||
ctypes.c_int,
|
|
||||||
ctypes.c_uint8]
|
|
||||||
nfct.nfct_set_attr_u16.argtypes = [ctypes.c_void_p,
|
|
||||||
ctypes.c_int,
|
|
||||||
ctypes.c_uint16]
|
|
||||||
nfct.nfct_snprintf.argtypes = [ctypes.c_char_p,
|
|
||||||
ctypes.c_uint,
|
|
||||||
ctypes.c_void_p,
|
|
||||||
ctypes.c_uint,
|
|
||||||
ctypes.c_uint,
|
|
||||||
ctypes.c_uint]
|
|
||||||
nfct.nfct_new.restype = ctypes.c_void_p
|
|
||||||
nfct.nfct_destroy.argtypes = [ctypes.c_void_p]
|
|
||||||
nfct.nfct_query.argtypes = [ctypes.c_void_p,
|
|
||||||
ctypes.c_int,
|
|
||||||
ctypes.c_void_p]
|
|
||||||
nfct.nfct_callback_register.argtypes = [ctypes.c_void_p,
|
|
||||||
ctypes.c_int,
|
|
||||||
ctypes.c_void_p,
|
|
||||||
ctypes.c_void_p]
|
|
||||||
nfct.nfct_open.restype = ctypes.c_void_p
|
|
||||||
nfct.nfct_close.argtypes = [ctypes.c_void_p]
|
|
||||||
|
|
||||||
|
|
||||||
IP_VERSIONS = [constants.IP_VERSION_4, constants.IP_VERSION_6]
|
|
||||||
DATA_CALLBACK = None
|
|
||||||
|
|
||||||
ATTR_POSITIONS = {
|
|
||||||
'icmp': [('type', 6), ('code', 7), ('src', 4), ('dst', 5), ('id', 8)],
|
|
||||||
'icmpv6': [('type', 6), ('code', 7), ('src', 4), ('dst', 5), ('id', 8)],
|
|
||||||
'tcp': [('sport', 7), ('dport', 8), ('src', 5), ('dst', 6)],
|
|
||||||
'udp': [('sport', 6), ('dport', 7), ('src', 4), ('dst', 5)]
|
|
||||||
}
|
|
||||||
|
|
||||||
TARGET = {'src': {4: nl_constants.ATTR_IPV4_SRC,
|
|
||||||
6: nl_constants.ATTR_IPV6_SRC},
|
|
||||||
'dst': {4: nl_constants.ATTR_IPV4_DST,
|
|
||||||
6: nl_constants.ATTR_IPV6_DST},
|
|
||||||
'ipversion': {4: nl_constants.ATTR_L3PROTO,
|
|
||||||
6: nl_constants.ATTR_L3PROTO},
|
|
||||||
'protocol': {4: nl_constants.ATTR_L4PROTO,
|
|
||||||
6: nl_constants.ATTR_L4PROTO},
|
|
||||||
'code': {4: nl_constants.ATTR_ICMP_CODE,
|
|
||||||
6: nl_constants.ATTR_ICMP_CODE},
|
|
||||||
'type': {4: nl_constants.ATTR_ICMP_TYPE,
|
|
||||||
6: nl_constants.ATTR_ICMP_TYPE},
|
|
||||||
'id': {4: nl_constants.ATTR_ICMP_ID,
|
|
||||||
6: nl_constants.ATTR_ICMP_ID},
|
|
||||||
'sport': {4: nl_constants.ATTR_PORT_SRC,
|
|
||||||
6: nl_constants.ATTR_PORT_SRC},
|
|
||||||
'dport': {4: nl_constants.ATTR_PORT_DST,
|
|
||||||
6: nl_constants.ATTR_PORT_DST}}
|
|
||||||
|
|
||||||
NFCT_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int,
|
|
||||||
ctypes.c_void_p, ctypes.c_void_p)
|
|
||||||
|
|
||||||
|
|
||||||
class ConntrackOpenFailedExit(SystemExit):
|
|
||||||
"""Raised if we fail to open a new conntrack or conntrack handler"""
|
|
||||||
|
|
||||||
|
|
||||||
class ConntrackManager(object):
|
|
||||||
def __init__(self, family_socket=None):
|
|
||||||
self.family_socket = family_socket
|
|
||||||
self.set_functions = {
|
|
||||||
'src': {4: nfct.nfct_set_attr,
|
|
||||||
6: nfct.nfct_set_attr},
|
|
||||||
'dst': {4: nfct.nfct_set_attr,
|
|
||||||
6: nfct.nfct_set_attr},
|
|
||||||
'ipversion': {4: nfct.nfct_set_attr_u8,
|
|
||||||
6: nfct.nfct_set_attr_u8},
|
|
||||||
'protocol': {4: nfct.nfct_set_attr_u8,
|
|
||||||
6: nfct.nfct_set_attr_u8},
|
|
||||||
'type': {4: nfct.nfct_set_attr_u8,
|
|
||||||
6: nfct.nfct_set_attr_u8},
|
|
||||||
'code': {4: nfct.nfct_set_attr_u8,
|
|
||||||
6: nfct.nfct_set_attr_u8},
|
|
||||||
'id': {4: nfct.nfct_set_attr_u16,
|
|
||||||
6: nfct.nfct_set_attr_u16},
|
|
||||||
'sport': {4: nfct.nfct_set_attr_u16,
|
|
||||||
6: nfct.nfct_set_attr_u16},
|
|
||||||
'dport': {4: nfct.nfct_set_attr_u16,
|
|
||||||
6: nfct.nfct_set_attr_u16}, }
|
|
||||||
|
|
||||||
self.converters = {'src': bytes,
|
|
||||||
'dst': bytes,
|
|
||||||
'ipversion': nl_constants.IPVERSION_SOCKET.get,
|
|
||||||
'protocol': constants.IP_PROTOCOL_MAP.get,
|
|
||||||
'code': int,
|
|
||||||
'type': int,
|
|
||||||
'id': libc.htons,
|
|
||||||
'sport': libc.htons,
|
|
||||||
'dport': libc.htons, }
|
|
||||||
|
|
||||||
def list_entries(self):
|
|
||||||
entries = []
|
|
||||||
raw_entry = ctypes.create_string_buffer(nl_constants.BUFFER)
|
|
||||||
|
|
||||||
@NFCT_CALLBACK
|
|
||||||
def callback(type_, conntrack, data):
|
|
||||||
nfct.nfct_snprintf(raw_entry, nl_constants.BUFFER,
|
|
||||||
conntrack, type_,
|
|
||||||
nl_constants.NFCT_O_PLAIN,
|
|
||||||
nl_constants.NFCT_OF_TIME)
|
|
||||||
entries.append(raw_entry.value.decode('utf-8'))
|
|
||||||
return nl_constants.NFCT_CB_CONTINUE
|
|
||||||
|
|
||||||
self._callback_register(nl_constants.NFCT_T_ALL,
|
|
||||||
callback, DATA_CALLBACK)
|
|
||||||
|
|
||||||
data_ref = self._get_ref(self.family_socket or
|
|
||||||
nl_constants.IPVERSION_SOCKET[4])
|
|
||||||
self._query(nl_constants.NFCT_Q_DUMP, data_ref)
|
|
||||||
return entries
|
|
||||||
|
|
||||||
def delete_entries(self, entries):
|
|
||||||
conntrack = nfct.nfct_new()
|
|
||||||
try:
|
|
||||||
for entry in entries:
|
|
||||||
self._set_attributes(conntrack, entry)
|
|
||||||
self._query(nl_constants.NFCT_Q_DESTROY, conntrack)
|
|
||||||
except Exception as e:
|
|
||||||
msg = "Failed to delete conntrack entries %s" % e
|
|
||||||
LOG.critical(msg)
|
|
||||||
raise ConntrackOpenFailedExit(msg)
|
|
||||||
finally:
|
|
||||||
nfct.nfct_destroy(conntrack)
|
|
||||||
|
|
||||||
def flush_entries(self):
|
|
||||||
data_ref = self._get_ref(self.family_socket or
|
|
||||||
nl_constants.IPVERSION_SOCKET[4])
|
|
||||||
self._query(nl_constants.NFCT_Q_FLUSH, data_ref)
|
|
||||||
|
|
||||||
def _query(self, query_type, query_data):
|
|
||||||
result = nfct.nfct_query(self.conntrack_handler, query_type,
|
|
||||||
query_data)
|
|
||||||
if result == nl_constants.NFCT_CB_FAILURE:
|
|
||||||
LOG.warning("Netlink query failed")
|
|
||||||
|
|
||||||
def _convert_text_to_binary(self, source, addr_family):
|
|
||||||
dest = ctypes.create_string_buffer(
|
|
||||||
nl_constants.IPVERSION_BUFFER[addr_family])
|
|
||||||
libc.inet_pton(nl_constants.IPVERSION_SOCKET[addr_family],
|
|
||||||
source.encode('utf-8'), dest)
|
|
||||||
return dest.raw
|
|
||||||
|
|
||||||
def _set_attributes(self, conntrack, entry):
|
|
||||||
ipversion = entry.get('ipversion', 4)
|
|
||||||
for attr, value in entry.items():
|
|
||||||
set_function = self.set_functions[attr][ipversion]
|
|
||||||
target = TARGET[attr][ipversion]
|
|
||||||
converter = self.converters[attr]
|
|
||||||
if attr in ['src', 'dst']:
|
|
||||||
# convert src and dst of IPv4 and IPv6 into same format
|
|
||||||
value = self._convert_text_to_binary(value, ipversion)
|
|
||||||
set_function(conntrack, target, converter(value))
|
|
||||||
|
|
||||||
def _callback_register(self, message_type, callback_func, data):
|
|
||||||
nfct.nfct_callback_register(self.conntrack_handler,
|
|
||||||
message_type, callback_func, data)
|
|
||||||
|
|
||||||
def _get_ref(self, data):
|
|
||||||
return ctypes.byref(ctypes.c_int(data))
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
self.conntrack_handler = nfct.nfct_open(
|
|
||||||
nl_constants.CONNTRACK,
|
|
||||||
nl_constants.NFNL_SUBSYS_CTNETLINK)
|
|
||||||
if not self.conntrack_handler:
|
|
||||||
msg = "Failed to open new conntrack handler"
|
|
||||||
LOG.critical(msg)
|
|
||||||
raise ConntrackOpenFailedExit(msg)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __exit__(self, *args):
|
|
||||||
nfct.nfct_close(self.conntrack_handler)
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_entry(entry, ipversion):
|
|
||||||
"""Parse entry from text to Python tuple
|
|
||||||
|
|
||||||
:param entry: conntrack entry in text
|
|
||||||
:param ipversion: ipversion 4 or 6
|
|
||||||
:return: conntrack entry in Python tuple
|
|
||||||
example: (4, 'tcp', '1', '2', '1.1.1.1', '2.2.2.2')
|
|
||||||
The attributes are ordered to be easy to compare with other entries
|
|
||||||
and compare with firewall rule
|
|
||||||
"""
|
|
||||||
protocol = entry[1]
|
|
||||||
parsed_entry = [ipversion, protocol]
|
|
||||||
for attr, position in ATTR_POSITIONS[protocol]:
|
|
||||||
val = entry[position].partition('=')[2]
|
|
||||||
parsed_entry.append(int(val) if attr in ['sport', 'dport', 'type',
|
|
||||||
'code', 'id'] else val)
|
|
||||||
return tuple(parsed_entry)
|
|
||||||
|
|
||||||
|
|
||||||
@privileged.default.entrypoint
|
|
||||||
def flush_entries(namespace=None):
|
|
||||||
"""Delete all conntrack entries
|
|
||||||
|
|
||||||
:param namespace: namespace to delete conntrack entries
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
with fwaas_utils.in_namespace(namespace):
|
|
||||||
for ipversion in IP_VERSIONS:
|
|
||||||
with ConntrackManager(nl_constants.IPVERSION_SOCKET[ipversion]) \
|
|
||||||
as conntrack:
|
|
||||||
conntrack.flush_entries()
|
|
||||||
|
|
||||||
|
|
||||||
@privileged.default.entrypoint
|
|
||||||
def list_entries(namespace=None):
|
|
||||||
"""List and parse all conntrack entries
|
|
||||||
|
|
||||||
:param namespace: namespace to get conntrack entries
|
|
||||||
:return: sorted list of conntrack entries in Python tuple
|
|
||||||
example: [(4, 'icmp', '8', '0', '1.1.1.1', '2.2.2.2', '1234'),
|
|
||||||
(4, 'tcp', '1', '2', '1.1.1.1', '2.2.2.2')]
|
|
||||||
"""
|
|
||||||
parsed_entries = []
|
|
||||||
with fwaas_utils.in_namespace(namespace):
|
|
||||||
for ipversion in IP_VERSIONS:
|
|
||||||
with ConntrackManager(nl_constants.IPVERSION_SOCKET[ipversion]) \
|
|
||||||
as conntrack:
|
|
||||||
raw_entries = conntrack.list_entries()
|
|
||||||
for raw_entry in raw_entries:
|
|
||||||
parsed_entry = _parse_entry(raw_entry.split(), ipversion)
|
|
||||||
parsed_entries.append(parsed_entry)
|
|
||||||
return sorted(parsed_entries)
|
|
||||||
|
|
||||||
|
|
||||||
@privileged.default.entrypoint
|
|
||||||
def delete_entries(entries, namespace=None):
|
|
||||||
"""Delete selected entries
|
|
||||||
|
|
||||||
:param entries: list of parsed (as tuple) entries to delete
|
|
||||||
:param namespace: namespace to delete conntrack entries
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
entry_args = []
|
|
||||||
for entry in entries:
|
|
||||||
entry_arg = {'ipversion': entry[0], 'protocol': entry[1]}
|
|
||||||
for idx, attr in enumerate(ATTR_POSITIONS[entry_arg['protocol']]):
|
|
||||||
entry_arg[attr[0]] = entry[idx + 2]
|
|
||||||
entry_args.append(entry_arg)
|
|
||||||
|
|
||||||
with fwaas_utils.in_namespace(namespace):
|
|
||||||
with ConntrackManager() as conntrack:
|
|
||||||
conntrack.delete_entries(entry_args)
|
|
@ -1,29 +0,0 @@
|
|||||||
# Copyright (c) 2017 Thales Services SAS
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from oslo_utils import uuidutils
|
|
||||||
from pyroute2 import netns as pynetns
|
|
||||||
|
|
||||||
from neutron_fwaas import privileged
|
|
||||||
|
|
||||||
|
|
||||||
# TODO(cby): move this method in neutron.tests.functional.privileged associated
|
|
||||||
# to a new privsep context.
|
|
||||||
@privileged.default.entrypoint
|
|
||||||
def dummy():
|
|
||||||
"""This method aim is to validate that we can use privsep in functests."""
|
|
||||||
namespace = 'dummy-%s' % uuidutils.generate_uuid()
|
|
||||||
pynetns.create(namespace)
|
|
||||||
pynetns.remove(namespace)
|
|
@ -1,39 +0,0 @@
|
|||||||
# Copyright (c) 2017 Thales Services SAS
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
import pyroute2
|
|
||||||
|
|
||||||
from neutron_fwaas import privileged
|
|
||||||
from neutron_fwaas.privileged import utils
|
|
||||||
|
|
||||||
|
|
||||||
def _get_ifname(link):
|
|
||||||
attr_dict = dict(link['attrs'])
|
|
||||||
return attr_dict['IFLA_IFNAME']
|
|
||||||
|
|
||||||
|
|
||||||
def list_interface_names():
|
|
||||||
iproute = pyroute2.IPRoute()
|
|
||||||
result = iproute.get_links()
|
|
||||||
return [_get_ifname(link) for link in result]
|
|
||||||
|
|
||||||
|
|
||||||
@privileged.default.entrypoint
|
|
||||||
def get_in_namespace_interfaces(namespace):
|
|
||||||
before = list_interface_names()
|
|
||||||
with utils.in_namespace(namespace):
|
|
||||||
inside = list_interface_names()
|
|
||||||
after = list_interface_names()
|
|
||||||
return before, inside, after
|
|
@ -1,58 +0,0 @@
|
|||||||
# Copyright (c) 2017 Thales Services SAS
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
import contextlib
|
|
||||||
import os
|
|
||||||
|
|
||||||
from oslo_log import log as logging
|
|
||||||
from pyroute2 import netns as pynetns
|
|
||||||
|
|
||||||
from neutron_fwaas._i18n import _
|
|
||||||
|
|
||||||
|
|
||||||
PROCESS_NETNS = '/proc/self/ns/net'
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class BackInNamespaceExit(SystemExit):
|
|
||||||
"""Raised if we fail to moved back process in its original namespace."""
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def in_namespace(namespace):
|
|
||||||
"""Move current process in a specific namespace.
|
|
||||||
|
|
||||||
This contextmanager moves current process in a specific namespace and
|
|
||||||
ensures to move it back in original namespace or kills it if we fail to
|
|
||||||
move back in original namespace.
|
|
||||||
"""
|
|
||||||
if not namespace:
|
|
||||||
yield
|
|
||||||
return
|
|
||||||
|
|
||||||
org_netns_fd = os.open(PROCESS_NETNS, os.O_RDONLY)
|
|
||||||
pynetns.setns(namespace)
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
finally:
|
|
||||||
try:
|
|
||||||
# NOTE(cby): this code is not executed only if we fail to
|
|
||||||
# move in target namespace
|
|
||||||
pynetns.setns(org_netns_fd)
|
|
||||||
except Exception as e:
|
|
||||||
msg = _('Failed to move back in original netns: %s') % e
|
|
||||||
LOG.critical(msg)
|
|
||||||
raise BackInNamespaceExit(msg)
|
|
@ -1,429 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
from neutron.db import servicetype_db as st_db
|
|
||||||
from neutron import service
|
|
||||||
from neutron.services import provider_configuration as provider_conf
|
|
||||||
from neutron.services import service_base
|
|
||||||
from neutron_lib.api.definitions import firewall_v2
|
|
||||||
from neutron_lib.api.definitions import portbindings as pb_def
|
|
||||||
from neutron_lib.api import validators
|
|
||||||
from neutron_lib.callbacks import events
|
|
||||||
from neutron_lib.callbacks import registry
|
|
||||||
from neutron_lib.callbacks import resources
|
|
||||||
from neutron_lib import constants as nl_constants
|
|
||||||
from neutron_lib.exceptions import firewall_v2 as f_exc
|
|
||||||
from neutron_lib.plugins import constants as plugin_const
|
|
||||||
from neutron_lib.plugins import directory
|
|
||||||
from oslo_log import helpers as log_helpers
|
|
||||||
from oslo_log import log as logging
|
|
||||||
|
|
||||||
from neutron_fwaas.common import exceptions
|
|
||||||
from neutron_fwaas.common import fwaas_constants
|
|
||||||
from neutron_fwaas.extensions.firewall_v2 import Firewallv2PluginBase
|
|
||||||
from neutron_fwaas.services.firewall.service_drivers import driver_api
|
|
||||||
from neutron_fwaas.services.logapi.agents.drivers.iptables \
|
|
||||||
import driver as logging_driver
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@registry.has_registry_receivers
|
|
||||||
class FirewallPluginV2(Firewallv2PluginBase):
|
|
||||||
"""Firewall v2 Neutron service plugin class"""
|
|
||||||
|
|
||||||
supported_extension_aliases = [firewall_v2.ALIAS]
|
|
||||||
path_prefix = firewall_v2.API_PREFIX
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(FirewallPluginV2, self).__init__()
|
|
||||||
"""Do the initialization for the firewall service plugin here."""
|
|
||||||
# Initialize the Firewall v2 service plugin
|
|
||||||
service_type_manager = st_db.ServiceTypeManager.get_instance()
|
|
||||||
service_type_manager.add_provider_configuration(
|
|
||||||
fwaas_constants.FIREWALL_V2,
|
|
||||||
provider_conf.ProviderConfiguration('neutron_fwaas'))
|
|
||||||
|
|
||||||
# Load the default driver
|
|
||||||
drivers, default_provider = service_base.load_drivers(
|
|
||||||
fwaas_constants.FIREWALL_V2, self)
|
|
||||||
LOG.info("Firewall v2 Service Plugin using Service Driver: %s",
|
|
||||||
default_provider)
|
|
||||||
|
|
||||||
if len(drivers) > 1:
|
|
||||||
LOG.warning("Multiple drivers configured for Firewall v2, "
|
|
||||||
"although running multiple drivers in parallel is "
|
|
||||||
"not yet supported")
|
|
||||||
|
|
||||||
self.driver_name = default_provider
|
|
||||||
self.driver = drivers[default_provider]
|
|
||||||
|
|
||||||
# start rpc listener if driver required
|
|
||||||
if isinstance(self.driver, driver_api.FirewallDriverRPCMixin):
|
|
||||||
rpc_worker = service.RpcWorker([self], worker_process_count=0)
|
|
||||||
self.add_worker(rpc_worker)
|
|
||||||
|
|
||||||
log_plugin = directory.get_plugin(plugin_const.LOG_API)
|
|
||||||
logging_driver.register()
|
|
||||||
# If log_plugin was loaded before firewall plugin
|
|
||||||
if log_plugin:
|
|
||||||
# Register logging driver with LoggingServiceDriverManager again
|
|
||||||
log_plugin.driver_manager.register_driver(logging_driver.DRIVER)
|
|
||||||
|
|
||||||
def start_rpc_listeners(self):
|
|
||||||
return self.driver.start_rpc_listener()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def _core_plugin(self):
|
|
||||||
return directory.get_plugin()
|
|
||||||
|
|
||||||
def _ensure_update_firewall_group(self, context, fwg_id):
|
|
||||||
"""Checks if the firewall group can be updated
|
|
||||||
|
|
||||||
Raises FirewallGroupInPendingState if the firewall group is in pending
|
|
||||||
state.
|
|
||||||
:param context: neutron context
|
|
||||||
:param fwg_id: firewall group ID to check
|
|
||||||
:return: Firewall group dict
|
|
||||||
"""
|
|
||||||
fwg = self.get_firewall_group(context, fwg_id)
|
|
||||||
if fwg['status'] in [nl_constants.PENDING_CREATE,
|
|
||||||
nl_constants.PENDING_UPDATE,
|
|
||||||
nl_constants.PENDING_DELETE]:
|
|
||||||
raise f_exc.FirewallGroupInPendingState(
|
|
||||||
firewall_id=fwg_id, pending_state=fwg['status'])
|
|
||||||
return fwg
|
|
||||||
|
|
||||||
def _ensure_update_firewall_policy(self, context, fwp_id):
|
|
||||||
"""Checks if the firewall policy can be updated
|
|
||||||
|
|
||||||
Fetch firewall group associated to the policy and checks if they can be
|
|
||||||
updated.
|
|
||||||
:param context: neutron context
|
|
||||||
:param fwp_id: firewall policy ID to check
|
|
||||||
"""
|
|
||||||
fwp = self.get_firewall_policy(context, fwp_id)
|
|
||||||
ing_fwg_ids, eg_fwg_ids = self._get_fwgs_with_policy(context, fwp)
|
|
||||||
for fwg_id in list(set(ing_fwg_ids + eg_fwg_ids)):
|
|
||||||
self._ensure_update_firewall_group(context, fwg_id)
|
|
||||||
|
|
||||||
def _ensure_update_firewall_rule(self, context, fwr_id):
|
|
||||||
"""Checks if the firewall rule can be updated
|
|
||||||
|
|
||||||
Fetch firewall policy associated to the rule and checks if they can be
|
|
||||||
updated.
|
|
||||||
:param context: neutron context
|
|
||||||
:param fwr_id: firewall policy ID to check
|
|
||||||
"""
|
|
||||||
fwr = self.get_firewall_rule(context, fwr_id)
|
|
||||||
fwp_ids = self._get_policies_with_rule(context, fwr)
|
|
||||||
for fwp_id in fwp_ids:
|
|
||||||
self._ensure_update_firewall_policy(context, fwp_id)
|
|
||||||
|
|
||||||
def _validate_firewall_policies_for_firewall_group(self, context, fwg):
|
|
||||||
"""Validate firewall group and policy owner
|
|
||||||
|
|
||||||
Check if the firewall policy is not shared, it have the same project
|
|
||||||
owner than the friewall group.
|
|
||||||
:param context: neutron context
|
|
||||||
:param fwg: firewall group to validate
|
|
||||||
"""
|
|
||||||
for policy_type in ['ingress_firewall_policy_id',
|
|
||||||
'egress_firewall_policy_id']:
|
|
||||||
if fwg.get(policy_type):
|
|
||||||
fwp = self.get_firewall_policy(context, fwg[policy_type])
|
|
||||||
if fwg['tenant_id'] != fwp['tenant_id'] and not fwp['shared']:
|
|
||||||
raise f_exc.FirewallPolicyConflict(
|
|
||||||
firewall_policy_id=fwg[policy_type])
|
|
||||||
|
|
||||||
def _validate_ports_for_firewall_group(self, context, tenant_id,
|
|
||||||
fwg_ports):
|
|
||||||
"""Validate firewall group associated ports
|
|
||||||
|
|
||||||
Check if the firewall group associated ports have the same project
|
|
||||||
owner and is router interface type or a compute layer 2 and supported
|
|
||||||
by the firewall driver
|
|
||||||
:param context: neutron context
|
|
||||||
:param tenant_id: firewall group project ID
|
|
||||||
:param fwg_ports: firewall group associated ports
|
|
||||||
"""
|
|
||||||
# TODO(sridar): elevated context and do we want to use public ?
|
|
||||||
for port_id in fwg_ports:
|
|
||||||
port = self._core_plugin.get_port(context, port_id)
|
|
||||||
|
|
||||||
if port['tenant_id'] != tenant_id:
|
|
||||||
raise f_exc.FirewallGroupPortInvalidProject(
|
|
||||||
port_id=port_id, project_id=port['tenant_id'])
|
|
||||||
device_owner = port.get('device_owner', '')
|
|
||||||
if device_owner in nl_constants.ROUTER_INTERFACE_OWNERS:
|
|
||||||
if not self.driver.is_supported_l3_port(port):
|
|
||||||
raise exceptions.FirewallGroupPortNotSupported(
|
|
||||||
driver_name=self.driver_name, port_id=port_id)
|
|
||||||
elif device_owner.startswith(
|
|
||||||
nl_constants.DEVICE_OWNER_COMPUTE_PREFIX):
|
|
||||||
if not self._is_supported_l2_port(context, port_id):
|
|
||||||
raise exceptions.FirewallGroupPortNotSupported(
|
|
||||||
driver_name=self.driver_name, port_id=port_id)
|
|
||||||
else:
|
|
||||||
raise f_exc.FirewallGroupPortInvalid(port_id=port_id)
|
|
||||||
|
|
||||||
def _is_supported_l2_port(self, context, port_id):
|
|
||||||
"""Whether this l2 port is supported"""
|
|
||||||
|
|
||||||
# Re-fetch to get up-to-date data from db
|
|
||||||
port = self._core_plugin.get_port(context, id=port_id)
|
|
||||||
|
|
||||||
# Skip port binding is unbound or failed
|
|
||||||
if port[pb_def.VIF_TYPE] in [pb_def.VIF_TYPE_UNBOUND,
|
|
||||||
pb_def.VIF_TYPE_BINDING_FAILED]:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return self.driver.is_supported_l2_port(port)
|
|
||||||
|
|
||||||
def _validate_if_firewall_group_on_ports(self, context, firewall_group,
|
|
||||||
id=None):
|
|
||||||
"""Validate if ports are not associated with any firewall_group.
|
|
||||||
|
|
||||||
If any of the ports in the list is already associated with
|
|
||||||
a firewall group, raise an exception else just return.
|
|
||||||
:param context: neutron context
|
|
||||||
:param fwg: firewall group to validate
|
|
||||||
"""
|
|
||||||
if 'ports' not in firewall_group or not firewall_group['ports']:
|
|
||||||
return
|
|
||||||
|
|
||||||
filters = {
|
|
||||||
'tenant_id': [firewall_group['tenant_id']],
|
|
||||||
'ports': firewall_group['ports'],
|
|
||||||
}
|
|
||||||
ports_in_use = set()
|
|
||||||
for fwg in self.get_firewall_groups(context, filters=filters):
|
|
||||||
if id is not None and fwg['id'] == id:
|
|
||||||
continue
|
|
||||||
ports_in_use |= set(fwg.get('ports', [])) & \
|
|
||||||
set(firewall_group['ports'])
|
|
||||||
if ports_in_use:
|
|
||||||
raise f_exc.FirewallGroupPortInUse(port_ids=list(ports_in_use))
|
|
||||||
|
|
||||||
def _get_fwgs_with_policy(self, context, firewall_policy):
|
|
||||||
"""List firewall group IDs which use a firewall policy
|
|
||||||
|
|
||||||
List all firewall group IDs which have the given firewall policy as
|
|
||||||
ingress or egress.
|
|
||||||
:param context: neutron context
|
|
||||||
:param firewall_policy: firewall policy to filter
|
|
||||||
"""
|
|
||||||
filters = {
|
|
||||||
'tenant_id': [firewall_policy['tenant_id']],
|
|
||||||
'ingress_firewall_policy_id': [firewall_policy['id']],
|
|
||||||
}
|
|
||||||
ingress_fwp_ids = [fwg['id']
|
|
||||||
for fwg in self.get_firewall_groups(
|
|
||||||
context, filters=filters)]
|
|
||||||
|
|
||||||
filters = {
|
|
||||||
'tenant_id': [firewall_policy['tenant_id']],
|
|
||||||
'egress_firewall_policy_id': [firewall_policy['id']],
|
|
||||||
}
|
|
||||||
egress_fwp_ids = [fwg['id']
|
|
||||||
for fwg in self.get_firewall_groups(
|
|
||||||
context, filters=filters)]
|
|
||||||
|
|
||||||
return ingress_fwp_ids, egress_fwp_ids
|
|
||||||
|
|
||||||
def _get_policies_with_rule(self, context, firewall_rule):
|
|
||||||
filters = {
|
|
||||||
'tenant_id': [firewall_rule['tenant_id']],
|
|
||||||
'firewall_rules': [firewall_rule['id']],
|
|
||||||
}
|
|
||||||
return [fwp['id'] for fwp in self.get_firewall_policies(
|
|
||||||
context, filters=filters)]
|
|
||||||
|
|
||||||
def _validate_insert_remove_rule_request(self, rule_info):
|
|
||||||
"""Validate rule_info dict
|
|
||||||
|
|
||||||
Check that all mandatory fields are present, otherwise raise
|
|
||||||
proper exception.
|
|
||||||
"""
|
|
||||||
if not rule_info or 'firewall_rule_id' not in rule_info:
|
|
||||||
raise f_exc.FirewallRuleInfoMissing()
|
|
||||||
# Validator doesn't return anything if the check passes
|
|
||||||
if validators.validate_uuid(rule_info['firewall_rule_id']):
|
|
||||||
raise f_exc.FirewallRuleNotFound(
|
|
||||||
firewall_rule_id=rule_info['firewall_rule_id'])
|
|
||||||
|
|
||||||
@registry.receives(resources.PORT, [events.AFTER_UPDATE])
|
|
||||||
def handle_update_port(self, resource, event, trigger, **kwargs):
|
|
||||||
updated_port = kwargs['port']
|
|
||||||
if not updated_port['device_owner'].startswith(
|
|
||||||
nl_constants.DEVICE_OWNER_COMPUTE_PREFIX):
|
|
||||||
return
|
|
||||||
|
|
||||||
if (kwargs.get('original_port')[pb_def.VIF_TYPE] !=
|
|
||||||
pb_def.VIF_TYPE_UNBOUND):
|
|
||||||
# Checking newly vm port binding allows us to avoid call to DB
|
|
||||||
# when a port update_event like restart, setting name, etc...
|
|
||||||
# Moreover, that will help us in case of tenant admin wants to
|
|
||||||
# only attach security group to vm port.
|
|
||||||
return
|
|
||||||
|
|
||||||
context = kwargs['context']
|
|
||||||
port_id = updated_port['id']
|
|
||||||
# Check port is supported by firewall driver
|
|
||||||
if not self._is_supported_l2_port(context, port_id):
|
|
||||||
return
|
|
||||||
|
|
||||||
project_id = updated_port['project_id']
|
|
||||||
fwgs = self.get_firewall_groups(
|
|
||||||
context,
|
|
||||||
filters={
|
|
||||||
'tenant_id': [project_id],
|
|
||||||
'name': [fwaas_constants.DEFAULT_FWG],
|
|
||||||
},
|
|
||||||
fields=['id', 'ports'],
|
|
||||||
)
|
|
||||||
if len(fwgs) != 1:
|
|
||||||
# Cannot found default Firewall Group, abandon
|
|
||||||
LOG.warning("Cannot found default firewall group of project %s",
|
|
||||||
project_id)
|
|
||||||
return
|
|
||||||
default_fwg = fwgs[0]
|
|
||||||
|
|
||||||
# Add default firewall group to the port
|
|
||||||
port_ids = default_fwg.get('ports', []) + [port_id]
|
|
||||||
try:
|
|
||||||
self.update_firewall_group(context, default_fwg['id'],
|
|
||||||
{'firewall_group': {'ports': port_ids}})
|
|
||||||
except f_exc.FirewallGroupPortInUse:
|
|
||||||
LOG.warning("Port %s has been already associated with default "
|
|
||||||
"firewall group %s and skip association", port_id,
|
|
||||||
default_fwg['id'])
|
|
||||||
|
|
||||||
# Firewall Group
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def create_firewall_group(self, context, firewall_group):
|
|
||||||
firewall_group = firewall_group['firewall_group']
|
|
||||||
ports = firewall_group.get('ports', [])
|
|
||||||
|
|
||||||
self._validate_firewall_policies_for_firewall_group(context,
|
|
||||||
firewall_group)
|
|
||||||
# Validate ports owner type and project
|
|
||||||
self._validate_ports_for_firewall_group(context,
|
|
||||||
firewall_group['tenant_id'],
|
|
||||||
ports)
|
|
||||||
|
|
||||||
self._validate_if_firewall_group_on_ports(context, firewall_group)
|
|
||||||
|
|
||||||
return self.driver.create_firewall_group(context, firewall_group)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def delete_firewall_group(self, context, id):
|
|
||||||
# if no such group exists -> don't raise an exception according to
|
|
||||||
# 80fe2ba1, return None
|
|
||||||
try:
|
|
||||||
fwg = self.get_firewall_group(context, id)
|
|
||||||
except f_exc.FirewallGroupNotFound:
|
|
||||||
return
|
|
||||||
|
|
||||||
if fwg['status'] == nl_constants.ACTIVE:
|
|
||||||
raise f_exc.FirewallGroupInUse(firewall_id=id)
|
|
||||||
|
|
||||||
self.driver.delete_firewall_group(context, id)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def get_firewall_group(self, context, id, fields=None):
|
|
||||||
return self.driver.get_firewall_group(context, id, fields=fields)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def get_firewall_groups(self, context, filters=None, fields=None):
|
|
||||||
return self.driver.get_firewall_groups(context, filters, fields)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def update_firewall_group(self, context, id, firewall_group):
|
|
||||||
firewall_group = firewall_group['firewall_group']
|
|
||||||
ports = firewall_group.get('ports', [])
|
|
||||||
|
|
||||||
old_firewall_group = self._ensure_update_firewall_group(context, id)
|
|
||||||
firewall_group['tenant_id'] = old_firewall_group['tenant_id']
|
|
||||||
|
|
||||||
self._validate_firewall_policies_for_firewall_group(context,
|
|
||||||
firewall_group)
|
|
||||||
# Validate ports owner type and project
|
|
||||||
self._validate_ports_for_firewall_group(context,
|
|
||||||
firewall_group['tenant_id'],
|
|
||||||
ports)
|
|
||||||
self._validate_if_firewall_group_on_ports(context, firewall_group,
|
|
||||||
id=id)
|
|
||||||
|
|
||||||
return self.driver.update_firewall_group(context, id, firewall_group)
|
|
||||||
|
|
||||||
# Firewall Policy
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def create_firewall_policy(self, context, firewall_policy):
|
|
||||||
firewall_policy = firewall_policy['firewall_policy']
|
|
||||||
return self.driver.create_firewall_policy(context, firewall_policy)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def delete_firewall_policy(self, context, id):
|
|
||||||
self.driver.delete_firewall_policy(context, id)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def get_firewall_policy(self, context, id, fields=None):
|
|
||||||
return self.driver.get_firewall_policy(context, id, fields)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def get_firewall_policies(self, context, filters=None, fields=None):
|
|
||||||
return self.driver.get_firewall_policies(context, filters, fields)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def update_firewall_policy(self, context, id, firewall_policy):
|
|
||||||
firewall_policy = firewall_policy['firewall_policy']
|
|
||||||
self._ensure_update_firewall_policy(context, id)
|
|
||||||
return self.driver.update_firewall_policy(context, id, firewall_policy)
|
|
||||||
|
|
||||||
# Firewall Rule
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def create_firewall_rule(self, context, firewall_rule):
|
|
||||||
firewall_rule = firewall_rule['firewall_rule']
|
|
||||||
return self.driver.create_firewall_rule(context, firewall_rule)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def delete_firewall_rule(self, context, id):
|
|
||||||
self.driver.delete_firewall_rule(context, id)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def get_firewall_rule(self, context, id, fields=None):
|
|
||||||
return self.driver.get_firewall_rule(context, id, fields)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def get_firewall_rules(self, context, filters=None, fields=None):
|
|
||||||
return self.driver.get_firewall_rules(context, filters, fields)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def update_firewall_rule(self, context, id, firewall_rule):
|
|
||||||
firewall_rule = firewall_rule['firewall_rule']
|
|
||||||
self._ensure_update_firewall_rule(context, id)
|
|
||||||
return self.driver.update_firewall_rule(context, id, firewall_rule)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def insert_rule(self, context, policy_id, rule_info):
|
|
||||||
self._ensure_update_firewall_policy(context, policy_id)
|
|
||||||
self._validate_insert_remove_rule_request(rule_info)
|
|
||||||
return self.driver.insert_rule(context, policy_id, rule_info)
|
|
||||||
|
|
||||||
@log_helpers.log_method_call
|
|
||||||
def remove_rule(self, context, policy_id, rule_info):
|
|
||||||
self._ensure_update_firewall_policy(context, policy_id)
|
|
||||||
self._validate_insert_remove_rule_request(rule_info)
|
|
||||||
return self.driver.remove_rule(context, policy_id, rule_info)
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user