Prepare initial sandbox for neutron-dynamic-routing
This patch-set prepares the basic code structure with all the tools required for running static and unit tests. Note: All the imported code from the seed repo is being removed temporarily and will be added after the required re-factoring needed as per the new repo in the subsequent patch-sets. Co-Authored-By: Ryan Tidwell <ryan.tidwell@hpe.com> Implements: blueprint bgp-spinout Partial-Bug: #1560003 Change-Id: I9bff3d916279c4f335b309e7a2c2e943ac6f6cdechanges/26/309326/7
parent
8ff4499030
commit
4ba80f3f1c
@ -0,0 +1,7 @@
|
||||
[run]
|
||||
branch = True
|
||||
source = neutron_dynamic_routing
|
||||
# omit = neutron_dynamic_routing/tests/*
|
||||
|
||||
[report]
|
||||
ignore_errors = True
|
@ -0,0 +1,32 @@
|
||||
AUTHORS
|
||||
build/*
|
||||
build-stamp
|
||||
ChangeLog
|
||||
cover/
|
||||
covhtml/
|
||||
dist/
|
||||
doc/build
|
||||
*.DS_Store
|
||||
*.pyc
|
||||
neutron.egg-info/
|
||||
neutron_dynamic_routing.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
|
||||
!/.testr.conf
|
||||
|
||||
# Files created by releasenotes build
|
||||
releasenotes/build
|
@ -1,4 +1,4 @@
|
||||
[gerrit]
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=stackforge/neutron-dynamic-routing.git
|
||||
project=openstack/neutron-dynamic-routing.git
|
||||
|
@ -0,0 +1,3 @@
|
||||
# Format is:
|
||||
# <preferred e-mail> <other e-mail 1>
|
||||
# <preferred e-mail> <other e-mail 2>
|
@ -0,0 +1,133 @@
|
||||
# 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.
|
||||
#
|
||||
# Note the 'openstack' below is intended to match only
|
||||
# neutron.openstack.common. If we ever have another 'openstack'
|
||||
# dirname, then we'll need to expand the ignore features in pylint :/
|
||||
ignore=.git,tests,openstack
|
||||
|
||||
[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 lowecased 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 openstack.common.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
|
@ -0,0 +1,8 @@
|
||||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
|
||||
OS_LOG_CAPTURE=1 \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
@ -0,0 +1,4 @@
|
||||
Please see the Neutron CONTRIBUTING.rst file for how to contribute to
|
||||
neutron-dynamic-routing:
|
||||
|
||||
`Neutron CONTRIBUTING.rst <http://git.openstack.org/cgit/openstack/neutron/tree/CONTRIBUTING.rst>`_
|
@ -0,0 +1,7 @@
|
||||
Neutron Dynamic Routing Style Commandments
|
||||
==========================================
|
||||
|
||||
Please see the Neutron HACKING.rst file for style commandments for
|
||||
neutron-dynamic-routing:
|
||||
|
||||
`Neutron HACKING.rst <http://git.openstack.org/cgit/openstack/neutron/tree/HACKING.rst>`_
|
@ -0,0 +1,176 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
@ -0,0 +1,9 @@
|
||||
include AUTHORS
|
||||
include README.rst
|
||||
include ChangeLog
|
||||
include LICENSE
|
||||
|
||||
exclude .gitignore
|
||||
exclude .gitreview
|
||||
|
||||
global-exclude *.pyc
|
@ -0,0 +1,18 @@
|
||||
Welcome!
|
||||
========
|
||||
|
||||
This package contains the code for the Neutron dynamic routing. This package
|
||||
requires Neutron to run.
|
||||
|
||||
External Resources:
|
||||
===================
|
||||
|
||||
The homepage for Neutron is: http://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:
|
||||
<http://git.openstack.org/cgit/openstack/neutron-dynamic-routing>.
|
||||
|
||||
Please refer to Neutron documentation for more information:
|
||||
`Neutron README.rst <http://git.openstack.org/cgit/openstack/neutron/tree/README.rst>`_
|
@ -0,0 +1,8 @@
|
||||
Testing Neutron Dynamic Routing
|
||||
===============================
|
||||
|
||||
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-dynamic-routing as well:
|
||||
|
||||
`Neutron TESTING.rst <http://git.openstack.org/cgit/openstack/neutron/tree/TESTING.rst>`_
|
@ -1,29 +0,0 @@
|
||||
function configure_bgp_service_plugin {
|
||||
_neutron_service_plugin_class_add "bgp"
|
||||
}
|
||||
|
||||
function configure_bgp {
|
||||
configure_bgp_service_plugin
|
||||
}
|
||||
|
||||
function configure_bgp_dragent {
|
||||
cp $NEUTRON_DIR/etc/bgp_dragent.ini.sample $Q_BGP_DRAGENT_CONF_FILE
|
||||
|
||||
iniset $Q_BGP_DRAGENT_CONF_FILE DEFAULT verbose True
|
||||
iniset $Q_BGP_DRAGENT_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
|
||||
if [ -n "$BGP_ROUTER_ID" ]; then
|
||||
iniset $Q_BGP_DRAGENT_CONF_FILE BGP bgp_router_id $BGP_ROUTER_ID
|
||||
fi
|
||||
if [ -z "$BGP_SPEAKER_DRIVER" ]; then
|
||||
BGP_SPEAKER_DRIVER=$RYU_BGP_SPEAKER_DRIVER
|
||||
fi
|
||||
iniset $Q_BGP_DRAGENT_CONF_FILE BGP bgp_speaker_driver $BGP_SPEAKER_DRIVER
|
||||
}
|
||||
|
||||
function start_bgp_dragent {
|
||||
run_process q-bgp-agt "$AGENT_BGP_BINARY --config-file $NEUTRON_CONF --config-file /$Q_BGP_DRAGENT_CONF_FILE"
|
||||
}
|
||||
|
||||
function stop_bgp_dragent {
|
||||
stop_process q-bgp-agt
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
LIBDIR=$DEST/neutron/devstack/lib
|
||||
|
||||
source $LIBDIR/bgp
|
||||
source $LIBDIR/flavors
|
||||
source $LIBDIR/l2_agent
|
||||
source $LIBDIR/l2_agent_sriovnicswitch
|
||||
source $LIBDIR/ml2
|
||||
source $LIBDIR/qos
|
||||
|
||||
if [[ "$1" == "stack" ]]; then
|
||||
case "$2" in
|
||||
install)
|
||||
if is_service_enabled q-flavors; then
|
||||
configure_flavors
|
||||
fi
|
||||
if is_service_enabled q-qos; then
|
||||
configure_qos
|
||||
fi
|
||||
if is_service_enabled q-bgp; then
|
||||
configure_bgp
|
||||
fi
|
||||
;;
|
||||
post-config)
|
||||
if is_service_enabled q-agt; then
|
||||
configure_l2_agent
|
||||
fi
|
||||
if is_service_enabled q-bgp && is_service_enabled q-bgp-agt; then
|
||||
configure_bgp_dragent
|
||||
fi
|
||||
#Note: sriov agent should run with OVS or linux bridge agent
|
||||
#because they are the mechanisms that bind the DHCP and router ports.
|
||||
#Currently devstack lacks the option to run two agents on the same node.
|
||||
#Therefore we create new service, q-sriov-agt, and the q-agt should be OVS
|
||||
#or linux bridge.
|
||||
if is_service_enabled q-sriov-agt; then
|
||||
configure_$Q_PLUGIN
|
||||
configure_l2_agent
|
||||
configure_l2_agent_sriovnicswitch
|
||||
fi
|
||||
;;
|
||||
extra)
|
||||
if is_service_enabled q-sriov-agt; then
|
||||
start_l2_agent_sriov
|
||||
fi
|
||||
if is_service_enabled q-bgp && is_service_enabled q-bgp-agt; then
|
||||
start_bgp_dragent
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
elif [[ "$1" == "unstack" ]]; then
|
||||
if is_service_enabled q-sriov-agt; then
|
||||
stop_l2_agent_sriov
|
||||
fi
|
||||
if is_service_enabled q-bgp && is_service_enabled q-bgp-agt; then
|
||||
stop_bgp_dragent
|
||||
fi
|
||||
fi
|
@ -1,8 +0,0 @@
|
||||
L2_AGENT_EXTENSIONS=${L2_AGENT_EXTENSIONS:-}
|
||||
|
||||
#BGP binary and config information
|
||||
AGENT_BGP_BINARY=${AGENT_BGP_BINARY:-"$NEUTRON_BIN_DIR/neutron-bgp-dragent"}
|
||||
Q_BGP_DRAGENT_CONF_FILE=${Q_BGP_DRAGENT_CONF_FILE:-"$NEUTRON_CONF_DIR/bgp_dragent.ini"}
|
||||
BGP_ROUTER_ID=${BGP_ROUTER_ID:-}
|
||||
|
||||
RYU_BGP_SPEAKER_DRIVER="neutron.services.bgp.driver.ryu.driver.RyuBgpDriver"
|
@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
# -- 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 = [
|
||||
'sphinx.ext.autodoc',
|
||||
#'sphinx.ext.intersphinx',
|
||||
'oslosphinx'
|
||||
]
|
||||
|
||||
# autodoc generation is a bit aggressive and a nuisance when doing heavy
|
||||
# text edit cycles.
|
||||
# execute "export SPHINX_DEBUG=1" in your terminal to disable
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'neutron-dynamic-routing'
|
||||
copyright = u'2013, OpenStack Foundation'
|
||||
|
||||
# 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
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# -- 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'
|
||||
# html_static_path = ['static']
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = '%sdoc' % project
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass
|
||||
# [howto/manual]).
|
||||
latex_documents = [
|
||||
('index',
|
||||
'%s.tex' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation', 'manual'),
|
||||
]
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
#intersphinx_mapping = {'http://docs.python.org/': None}
|
@ -0,0 +1,4 @@
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
.. include:: ../../CONTRIBUTING.rst
|
@ -0,0 +1,43 @@
|
||||
..
|
||||
Copyright 2016 Huawei India Pvt Ltd. 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.
|
||||
|
||||
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.)
|
||||
|
||||
Welcome to neutron-dynamic-routing's documentation!
|
||||
===================================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
readme
|
||||
installation
|
||||
usage
|
||||
contributing
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
@ -0,0 +1,12 @@
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
At the command line::
|
||||
|
||||
$ pip install neutron-dynamic-routing
|
||||
|
||||
Or, if you have virtualenvwrapper installed::
|
||||
|
||||
$ mkvirtualenv neutron-dynamic-routing
|
||||
$ pip install neutron-dynamic-routing
|
@ -0,0 +1 @@
|
||||
.. include:: ../../README.rst
|
@ -0,0 +1,7 @@
|
||||
========
|
||||
Usage
|
||||
========
|
||||
|
||||
To use neutron-dynamic-routing in a project::
|
||||
|
||||
import neutron_dynamic_routing
|
@ -1,7 +0,0 @@
|
||||
[DEFAULT]
|
||||
output_file = etc/bgp_dragent.ini.sample
|
||||
wrap_width = 79
|
||||
|
||||
namespace = neutron.base.agent
|
||||
namespace = neutron.bgp.agent
|
||||
namespace = oslo.log
|
@ -1,238 +0,0 @@
|
||||
{
|
||||
"context_is_admin": "role:admin",
|
||||
"owner": "tenant_id:%(tenant_id)s",
|
||||
"admin_or_owner": "rule:context_is_admin or rule:owner",
|
||||
"context_is_advsvc": "role:advsvc",
|
||||
"admin_or_network_owner": "rule:context_is_admin or tenant_id:%(network:tenant_id)s",
|
||||
"admin_owner_or_network_owner": "rule:owner or rule:admin_or_network_owner",
|
||||
"admin_only": "rule:context_is_admin",
|
||||
"regular_user": "",
|
||||
"shared": "field:networks:shared=True",
|
||||
"shared_firewalls": "field:firewalls:shared=True",
|
||||
"shared_firewall_policies": "field:firewall_policies:shared=True",
|
||||
"shared_subnetpools": "field:subnetpools:shared=True",
|
||||
"shared_address_scopes": "field:address_scopes:shared=True",
|
||||
"external": "field:networks:router:external=True",
|
||||
"default": "rule:admin_or_owner",
|
||||
|
||||
"create_subnet": "rule:admin_or_network_owner",
|
||||
"get_subnet": "rule:admin_or_owner or rule:shared",
|
||||
"update_subnet": "rule:admin_or_network_owner",
|
||||
"delete_subnet": "rule:admin_or_network_owner",
|
||||
|
||||
"create_subnetpool": "",
|
||||
"create_subnetpool:shared": "rule:admin_only",
|
||||
"create_subnetpool:is_default": "rule:admin_only",
|
||||
"get_subnetpool": "rule:admin_or_owner or rule:shared_subnetpools",
|
||||
"update_subnetpool": "rule:admin_or_owner",
|
||||
"update_subnetpool:is_default": "rule:admin_only",
|
||||
"delete_subnetpool": "rule:admin_or_owner",
|
||||
|
||||
"create_address_scope": "",
|
||||
"create_address_scope:shared": "rule:admin_only",
|
||||
"get_address_scope": "rule:admin_or_owner or rule:shared_address_scopes",
|
||||
"update_address_scope": "rule:admin_or_owner",
|
||||
"update_address_scope:shared": "rule:admin_only",
|
||||
"delete_address_scope": "rule:admin_or_owner",
|
||||
|
||||
"create_network": "",
|
||||
"get_network": "rule:admin_or_owner or rule:shared or rule:external or rule:context_is_advsvc",
|
||||
"get_network:router:external": "rule:regular_user",
|
||||
"get_network:segments": "rule:admin_only",
|
||||
"get_network:provider:network_type": "rule:admin_only",
|
||||
"get_network:provider:physical_network": "rule:admin_only",
|
||||
"get_network:provider:segmentation_id": "rule:admin_only",
|
||||
"get_network:queue_id": "rule:admin_only",
|
||||
"get_network_ip_availabilities": "rule:admin_only",
|
||||
"get_network_ip_availability": "rule:admin_only",
|
||||
"create_network:shared": "rule:admin_only",
|
||||
"create_network:router:external": "rule:admin_only",
|
||||
"create_network:is_default": "rule:admin_only",
|
||||
"create_network:segments": "rule:admin_only",
|
||||
"create_network:provider:network_type": "rule:admin_only",
|
||||
"create_network:provider:physical_network": "rule:admin_only",
|
||||
"create_network:provider:segmentation_id": "rule:admin_only",
|
||||
"update_network": "rule:admin_or_owner",
|
||||
"update_network:segments": "rule:admin_only",
|
||||
"update_network:shared": "rule:admin_only",
|
||||
"update_network:provider:network_type": "rule:admin_only",
|
||||
"update_network:provider:physical_network": "rule:admin_only",
|
||||
"update_network:provider:segmentation_id": "rule:admin_only",
|
||||
"update_network:router:external": "rule:admin_only",
|
||||
"delete_network": "rule:admin_or_owner",
|
||||
|
||||
"network_device": "field:port:device_owner=~^network:",
|
||||
"create_port": "",
|
||||
"create_port:device_owner": "not rule:network_device or rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||
"create_port:mac_address": "rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||
"create_port:fixed_ips": "rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||
"create_port:port_security_enabled": "rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||
"create_port:binding:host_id": "rule:admin_only",
|
||||
"create_port:binding:profile": "rule:admin_only",
|
||||
"create_port:mac_learning_enabled": "rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||
"create_port:allowed_address_pairs": "rule:admin_or_network_owner",
|
||||
"get_port": "rule:context_is_advsvc or rule:admin_owner_or_network_owner",
|
||||
"get_port:queue_id": "rule:admin_only",
|
||||
"get_port:binding:vif_type": "rule:admin_only",
|
||||
"get_port:binding:vif_details": "rule:admin_only",
|
||||
"get_port:binding:host_id": "rule:admin_only",
|
||||
"get_port:binding:profile": "rule:admin_only",
|
||||
"update_port": "rule:admin_or_owner or rule:context_is_advsvc",
|
||||
"update_port:device_owner": "not rule:network_device or rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||
"update_port:mac_address": "rule:admin_only or rule:context_is_advsvc",
|
||||
"update_port:fixed_ips": "rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||
"update_port:port_security_enabled": "rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||
"update_port:binding:host_id": "rule:admin_only",
|
||||
"update_port:binding:profile": "rule:admin_only",
|
||||
"update_port:mac_learning_enabled": "rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||
"update_port:allowed_address_pairs": "rule:admin_or_network_owner",
|
||||
"delete_port": "rule:context_is_advsvc or rule:admin_owner_or_network_owner",
|
||||
|
||||
"get_router:ha": "rule:admin_only",
|
||||
"create_router": "rule:regular_user",
|
||||
"create_router:external_gateway_info:enable_snat": "rule:admin_only",
|
||||
"create_router:distributed": "rule:admin_only",
|
||||
"create_router:ha": "rule:admin_only",
|
||||
"get_router": "rule:admin_or_owner",
|
||||
"get_router:distributed": "rule:admin_only",
|
||||
"update_router:external_gateway_info:enable_snat": "rule:admin_only",
|
||||
"update_router:distributed": "rule:admin_only",
|
||||
"update_router:ha": "rule:admin_only",
|
||||
"delete_router": "rule:admin_or_owner",
|
||||
|
||||
"add_router_interface": "rule:admin_or_owner",
|
||||
"remove_router_interface": "rule:admin_or_owner",
|
||||
|
||||
"create_router:external_gateway_info:external_fixed_ips": "rule:admin_only",
|
||||
"update_router:external_gateway_info:external_fixed_ips": "rule:admin_only",
|
||||
|
||||
"create_firewall": "",
|
||||
"get_firewall": "rule:admin_or_owner",
|
||||
"create_firewall:shared": "rule:admin_only",
|
||||
"get_firewall:shared": "rule:admin_only",
|
||||
"update_firewall": "rule:admin_or_owner",
|
||||
"update_firewall:shared": "rule:admin_only",
|
||||
"delete_firewall": "rule:admin_or_owner",
|
||||
|
||||
"create_firewall_policy": "",
|
||||
"get_firewall_policy": "rule:admin_or_owner or rule:shared_firewall_policies",
|
||||
"create_firewall_policy:shared": "rule:admin_or_owner",
|
||||
"update_firewall_policy": "rule:admin_or_owner",
|
||||
"delete_firewall_policy": "rule:admin_or_owner",
|
||||
|
||||
"insert_rule": "rule:admin_or_owner",
|
||||
"remove_rule": "rule:admin_or_owner",
|
||||
|
||||
"create_firewall_rule": "",
|
||||
"get_firewall_rule": "rule:admin_or_owner or rule:shared_firewalls",
|
||||
"update_firewall_rule": "rule:admin_or_owner",
|
||||
"delete_firewall_rule": "rule:admin_or_owner",
|
||||
|
||||
"create_qos_queue": "rule:admin_only",
|
||||
"get_qos_queue": "rule:admin_only",
|
||||
|
||||
"update_agent": "rule:admin_only",
|
||||
"delete_agent": "rule:admin_only",
|
||||
"get_agent": "rule:admin_only",
|
||||
|
||||
"create_dhcp-network": "rule:admin_only",
|
||||
"delete_dhcp-network": "rule:admin_only",
|
||||
"get_dhcp-networks": "rule:admin_only",
|
||||
"create_l3-router": "rule:admin_only",
|
||||
"delete_l3-router": "rule:admin_only",
|
||||
"get_l3-routers": "rule:admin_only",
|
||||
"get_dhcp-agents": "rule:admin_only",
|
||||
"get_l3-agents": "rule:admin_only",
|
||||
"get_loadbalancer-agent": "rule:admin_only",
|
||||
"get_loadbalancer-pools": "rule:admin_only",
|
||||
"get_agent-loadbalancers": "rule:admin_only",
|
||||
"get_loadbalancer-hosting-agent": "rule:admin_only",
|
||||
|
||||
"create_floatingip": "rule:regular_user",
|
||||
"create_floatingip:floating_ip_address": "rule:admin_only",
|
||||
"update_floatingip": "rule:admin_or_owner",
|
||||
"delete_floatingip": "rule:admin_or_owner",
|
||||
"get_floatingip": "rule:admin_or_owner",
|
||||
|
||||
"create_network_profile": "rule:admin_only",
|
||||
"update_network_profile": "rule:admin_only",
|
||||
"delete_network_profile": "rule:admin_only",
|
||||
"get_network_profiles": "",
|
||||
"get_network_profile": "",
|
||||
"update_policy_profiles": "rule:admin_only",
|
||||
"get_policy_profiles": "",
|
||||
"get_policy_profile": "",
|
||||
|
||||
"create_metering_label": "rule:admin_only",
|
||||
"delete_metering_label": "rule:admin_only",
|
||||
"get_metering_label": "rule:admin_only",
|
||||
|
||||
"create_metering_label_rule": "rule:admin_only",
|
||||
"delete_metering_label_rule": "rule:admin_only",
|
||||
"get_metering_label_rule": "rule:admin_only",
|
||||
|
||||
"get_service_provider": "rule:regular_user",
|
||||
"get_lsn": "rule:admin_only",
|
||||
"create_lsn": "rule:admin_only",
|
||||
|
||||
"create_flavor": "rule:admin_only",
|
||||
"update_flavor": "rule:admin_only",
|
||||
"delete_flavor": "rule:admin_only",
|
||||
"get_flavors": "rule:regular_user",
|
||||
"get_flavor": "rule:regular_user",
|
||||
"create_service_profile": "rule:admin_only",
|
||||
"update_service_profile": "rule:admin_only",
|
||||
"delete_service_profile": "rule:admin_only",
|
||||
"get_service_profiles": "rule:admin_only",
|
||||
"get_service_profile": "rule:admin_only",
|
||||
|
||||
"get_policy": "rule:regular_user",
|
||||
"create_policy": "rule:admin_only",
|
||||
"update_policy": "rule:admin_only",
|
||||
"delete_policy": "rule:admin_only",
|
||||
"get_policy_bandwidth_limit_rule": "rule:regular_user",
|
||||
"create_policy_bandwidth_limit_rule": "rule:admin_only",
|
||||
"delete_policy_bandwidth_limit_rule": "rule:admin_only",
|
||||
"update_policy_bandwidth_limit_rule": "rule:admin_only",
|
||||
"get_policy_dscp_marking_rule": "rule:regular_user",
|
||||
"create_policy_dscp_marking_rule": "rule:admin_only",
|
||||
"delete_policy_dscp_marking_rule": "rule:admin_only",
|
||||
"update_policy_dscp_marking_rule": "rule:admin_only",
|
||||
"get_rule_type": "rule:regular_user",
|
||||
|
||||
"restrict_wildcard": "(not field:rbac_policy:target_tenant=*) or rule:admin_only",
|
||||
"create_rbac_policy": "",
|
||||
"create_rbac_policy:target_tenant": "rule:restrict_wildcard",
|
||||
"update_rbac_policy": "rule:admin_or_owner",
|
||||
"update_rbac_policy:target_tenant": "rule:restrict_wildcard and rule:admin_or_owner",
|
||||
"get_rbac_policy": "rule:admin_or_owner",
|
||||
"delete_rbac_policy": "rule:admin_or_owner",
|
||||
|
||||
"create_flavor_service_profile": "rule:admin_only",
|
||||
"delete_flavor_service_profile": "rule:admin_only",
|
||||
"get_flavor_service_profile": "rule:regular_user",
|
||||
"get_auto_allocated_topology": "rule:admin_or_owner",
|
||||
|
||||
"get_bgp_speaker": "rule:admin_only",
|
||||
"create_bgp_speaker": "rule:admin_only",
|
||||
"update_bgp_speaker": "rule:admin_only",
|
||||
"delete_bgp_speaker": "rule:admin_only",
|
||||
|
||||
"get_bgp_peer": "rule:admin_only",
|
||||
"create_bgp_peer": "rule:admin_only",
|
||||
"update_bgp_peer": "rule:admin_only",
|
||||
"delete_bgp_peer": "rule:admin_only",
|
||||
|
||||
"add_bgp_peer": "rule:admin_only",
|
||||
"remove_bgp_peer": "rule:admin_only",
|
||||
|
||||
"add_gateway_network": "rule:admin_only",
|
||||
"remove_gateway_network": "rule:admin_only",
|
||||
|
||||
"get_advertised_routes":"rule:admin_only",
|
||||
|
||||
"add_bgp_speaker_to_dragent": "rule:admin_only",
|
||||
"remove_bgp_speaker_from_dragent": "rule:admin_only",
|
||||
"list_bgp_speaker_on_dragent": "rule:admin_only",
|
||||
"list_dragent_hosting_bgp_speaker": "rule:admin_only"
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
# Copyright 2016 Huawei Technologies India Pvt. Ltd.
|
||||
#
|
||||
# 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_messaging
|
||||
|
||||
from neutron.common import rpc as n_rpc
|
||||
from neutron.services.bgp.common import constants as bgp_consts
|
||||
|
||||
|
||||
class BgpDrAgentNotifyApi(object):
|
||||
"""API for plugin to notify BGP DrAgent.
|
||||
|
||||
This class implements the client side of an rpc interface. The server side
|
||||
is neutron.services.bgp_speaker.agent.bgp_dragent.BgpDrAgent. For more
|
||||
information about rpc interfaces, please see doc/source/devref/rpc_api.rst.
|
||||
"""
|
||||
|
||||
def __init__(self, topic=bgp_consts.BGP_DRAGENT):
|
||||
target = oslo_messaging.Target(topic=topic, version='1.0')
|
||||
self.client = n_rpc.get_client(target)
|
||||
self.topic = topic
|
||||
|
||||
def bgp_routes_advertisement(self, context, bgp_speaker_id,
|
||||
routes, host):
|
||||
"""Tell BgpDrAgent to begin advertising the given route.
|
||||
|
||||
Invoked on FIP association, adding router port to a tenant network,
|
||||
and new DVR port-host bindings, and subnet creation(?).
|
||||
"""
|
||||
self._notification_host_cast(context, 'bgp_routes_advertisement_end',
|
||||
{'advertise_routes': {'speaker_id': bgp_speaker_id,
|
||||
'routes': routes}}, host)
|
||||
|
||||
def bgp_routes_withdrawal(self, context, bgp_speaker_id,
|
||||
routes, host):
|
||||
"""Tell BgpDrAgent to stop advertising the given route.
|
||||
|
||||
Invoked on FIP disassociation, removal of a router port on a
|
||||
network, and removal of DVR port-host binding, and subnet delete(?).
|
||||
"""
|
||||
self._notification_host_cast(context, 'bgp_routes_withdrawal_end',
|
||||
{'withdraw_routes': {'speaker_id': bgp_speaker_id,
|
||||
'routes': routes}}, host)
|
||||
|
||||
def bgp_peer_disassociated(self, context, bgp_speaker_id,
|
||||
bgp_peer_ip, host):
|
||||
"""Tell BgpDrAgent about a new BGP Peer association.
|
||||
|
||||
This effectively tells the BgpDrAgent to stop a peering session.
|
||||
"""
|
||||
self._notification_host_cast(context, 'bgp_peer_disassociation_end',
|
||||
{'bgp_peer': {'speaker_id': bgp_speaker_id,
|
||||
'peer_ip': bgp_peer_ip}}, host)
|
||||
|
||||
def bgp_peer_associated(self, context, bgp_speaker_id,
|
||||
bgp_peer_id, host):
|
||||
"""Tell BgpDrAgent about a BGP Peer disassociation.
|
||||
|
||||
This effectively tells the bgp_dragent to open a peering session.
|
||||
"""
|
||||
self._notification_host_cast(context, 'bgp_peer_association_end',
|
||||
{'bgp_peer': {'speaker_id': bgp_speaker_id,
|
||||
'peer_id': bgp_peer_id}}, host)
|
||||
|
||||
def bgp_speaker_created(self, context, bgp_speaker_id, host):
|
||||
"""Tell BgpDrAgent about the creation of a BGP Speaker.
|
||||
|
||||
Because a BGP Speaker can be created with BgpPeer binding in place,
|
||||
we need to inform the BgpDrAgent of a new BGP Speaker in case a
|
||||
peering session needs to opened immediately.
|
||||
"""
|
||||
self._notification_host_cast(context, 'bgp_speaker_create_end',
|
||||
{'bgp_speaker': {'id': bgp_speaker_id}}, host)
|
||||
|
||||
def bgp_speaker_removed(self, context, bgp_speaker_id, host):
|
||||
"""Tell BgpDrAgent about the removal of a BGP Speaker.
|
||||
|
||||
Because a BGP Speaker can be removed with BGP Peer binding in
|
||||
place, we need to inform the BgpDrAgent of the removal of a
|
||||
BGP Speaker in case peering sessions need to be stopped.
|
||||
"""
|
||||
self._notification_host_cast(context, 'bgp_speaker_remove_end',
|
||||
{'bgp_speaker': {'id': bgp_speaker_id}}, host)
|
||||
|
||||
def _notification_host_cast(self, context, method, payload, host):
|
||||
"""Send payload to BgpDrAgent in the cast mode"""
|
||||
cctxt = self.client.prepare(topic=self.topic, server=host)
|
||||
cctxt.cast(context, method, payload=payload)
|
||||
|
||||
def _notification_host_call(self, context, method, payload, host):
|
||||
"""Send payload to BgpDrAgent in the call mode"""
|
||||
cctxt = self.client.prepare(topic=self.topic, server=host)
|
||||
cctxt.call(context, method, payload=payload)
|
@ -1,65 +0,0 @@
|
||||
# Copyright 2016 Huawei Technologies India Pvt. Ltd.
|
||||
#
|
||||
# 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_messaging
|
||||
|
||||
from neutron.extensions import bgp as bgp_ext
|
||||
from neutron import manager
|
||||
|
||||
|
||||
class BgpSpeakerRpcCallback(object):
|
||||
"""BgpDrAgent RPC callback in plugin implementations.
|
||||
|
||||
This class implements the server side of an RPC interface.
|
||||
The client side of this interface can be found in
|
||||
neutron.services.bgp_speaker.agent.bgp_dragent.BgpDrPluginApi.
|
||||
For more information about changing RPC interfaces,
|
||||
see doc/source/devref/rpc_api.rst.
|
||||
"""
|
||||
|
||||
# API version history:
|
||||
# 1.0 BGPDRPluginApi BASE_RPC_API_VERSION
|
||||
target = oslo_messaging.Target(version='1.0')
|
||||
|
||||
@property
|
||||
def plugin(self):
|
||||
if not hasattr(self, '_plugin'):
|
||||
self._plugin = manager.NeutronManager.get_service_plugins().get(
|
||||
bgp_ext.BGP_EXT_ALIAS)
|
||||
return self._plugin
|
||||
|
||||
def get_bgp_speaker_info(self, context, bgp_speaker_id):
|
||||
"""Return BGP Speaker details such as peer list and local_as.
|
||||
|
||||
Invoked by the BgpDrAgent to lookup the details of a BGP Speaker.
|
||||
"""
|
||||
return self.plugin.get_bgp_speaker_with_advertised_routes(
|
||||
context, bgp_speaker_id)
|
||||
|
||||
def get_bgp_peer_info(self, context, bgp_peer_id):
|
||||
"""Return BgpPeer details such as IP, remote_as, and credentials.
|
||||
|
||||
Invoked by the BgpDrAgent to lookup the details of a BGP peer.
|
||||
"""
|
||||
return self.plugin.get_bgp_peer(context, bgp_peer_id,
|
||||
['peer_ip', 'remote_as',
|
||||
'auth_type', 'password'])
|
||||
|
||||
def get_bgp_speakers(self, context, host=None, **kwargs):
|
||||
"""Returns the list of all BgpSpeakers.
|
||||
|
||||
Typically invoked by the BgpDrAgent as part of its bootstrap process.
|
||||
"""
|
||||
return self.plugin.get_bgp_speakers_for_agent_host(context, host)
|
@ -1,20 +0,0 @@
|
||||
# Copyright 2016 Huawei Technologies India Pvt. Ltd.
|
||||
#
|
||||
# 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.services.bgp.agent import entry as bgp_dragent
|
||||
|
||||
|
||||
def main():
|
||||
bgp_dragent.main()
|
File diff suppressed because it is too large
Load Diff
@ -1,215 +0,0 @@
|
||||
# Copyright 2016 Huawei Technologies India Pvt. Ltd.
|
||||
# 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_config import cfg
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_log import log as logging
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
from sqlalchemy.orm import exc
|
||||
|
||||
from neutron._i18n import _
|
||||
from neutron._i18n import _LW
|
||||
from neutron.db import agents_db
|
||||
from neutron.db import agentschedulers_db as as_db
|
||||
from neutron.db import model_base
|
||||
from neutron.extensions import bgp_dragentscheduler as bgp_dras_ext
|
||||
from neutron.services.bgp.common import constants as bgp_consts
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
BGP_DRAGENT_SCHEDULER_OPTS = [
|
||||
cfg.StrOpt(
|
||||
'bgp_drscheduler_driver',
|
||||
default='neutron.services.bgp.scheduler'
|
||||
'.bgp_dragent_scheduler.ChanceScheduler',
|
||||
help=_('Driver used for scheduling BGP speakers to BGP DrAgent'))
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(BGP_DRAGENT_SCHEDULER_OPTS)
|
||||
|
||||
|
||||
class BgpSpeakerDrAgentBinding(model_base.BASEV2):
|
||||
"""Represents a mapping between BGP speaker and BGP DRAgent"""
|
||||
|
||||
__tablename__ = 'bgp_speaker_dragent_bindings'
|
||||
|
||||
bgp_speaker_id = sa.Column(sa.String(length=36),
|
||||
sa.ForeignKey("bgp_speakers.id",
|
||||
ondelete='CASCADE'),
|
||||
nullable=False)
|
||||
dragent = orm.relation(agents_db.Agent)
|
||||
agent_id = sa.Column(sa.String(length=36),
|
||||
sa.ForeignKey("agents.id",
|
||||
ondelete='CASCADE'),
|
||||
primary_key=True)
|
||||
|
||||
|
||||
class BgpDrAgentSchedulerDbMixin(bgp_dras_ext.BgpDrSchedulerPluginBase,
|
||||
as_db.AgentSchedulerDbMixin):
|
||||
|
||||
bgp_drscheduler = None
|
||||
|
||||
def schedule_unscheduled_bgp_speakers(self, context, host):
|
||||
if self.bgp_drscheduler:
|
||||
return self.bgp_drscheduler.schedule_unscheduled_bgp_speakers(
|
||||
context, host)
|
||||
else:
|
||||
LOG.warning(_LW("Cannot schedule BgpSpeaker to DrAgent. "
|
||||
"Reason: No scheduler registered."))
|
||||
|
||||
def schedule_bgp_speaker(self, context, created_bgp_speaker):
|
||||
if self.bgp_drscheduler:
|
||||
agents = self.bgp_drscheduler.schedule(context,
|
||||
created_bgp_speaker)
|
||||
for agent in agents:
|
||||
self._bgp_rpc.bgp_speaker_created(context,
|
||||
created_bgp_speaker['id'],
|
||||
agent.host)
|
||||
else:
|
||||
LOG.warning(_LW("Cannot schedule BgpSpeaker to DrAgent. "
|
||||
"Reason: No scheduler registered."))
|
||||
|
||||
def add_bgp_speaker_to_dragent(self, context, agent_id, speaker_id):
|
||||
"""Associate a BgpDrAgent with a BgpSpeaker."""
|
||||
try:
|
||||
self._save_bgp_speaker_dragent_binding(context,
|
||||
agent_id,
|
||||
speaker_id)
|
||||
except db_exc.DBDuplicateEntry:
|
||||
raise bgp_dras_ext.DrAgentAssociationError(
|
||||
agent_id=agent_id)
|
||||
|
||||
LOG.debug('BgpSpeaker %(bgp_speaker_id)s added to '
|
||||
'BgpDrAgent %(agent_id)s',
|
||||
{'bgp_speaker_id': speaker_id, 'agent_id': agent_id})
|
||||
|
||||
def _save_bgp_speaker_dragent_binding(self, context,
|
||||
agent_id, speaker_id):
|
||||
with context.session.begin(subtransactions=True):
|
||||
agent_db = self._get_agent(context, agent_id)
|
||||
agent_up = agent_db['admin_state_up']
|
||||
is_agent_bgp = (agent_db['agent_type'] ==
|
||||
bgp_consts.AGENT_TYPE_BGP_ROUTING)
|
||||
if not is_agent_bgp or not agent_up:
|
||||
raise bgp_dras_ext.DrAgentInvalid(id=agent_id)
|
||||
|
||||
binding = BgpSpeakerDrAgentBinding()
|
||||
binding.bgp_speaker_id = speaker_id
|
||||
binding.agent_id = agent_id
|
||||
context.session.add(binding)
|
||||
|
||||
self._bgp_rpc.bgp_speaker_created(context, speaker_id, agent_db.host)
|
||||
|
||||
def remove_bgp_speaker_from_dragent(self, context, agent_id, speaker_id):
|
||||
with context.session.begin(subtransactions=True):
|
||||
agent_db = self._get_agent(context, agent_id)
|
||||
is_agent_bgp = (agent_db['agent_type'] ==
|
||||
bgp_consts.AGENT_TYPE_BGP_ROUTING)
|
||||
if not is_agent_bgp:
|
||||
raise bgp_dras_ext.DrAgentInvalid(id=agent_id)
|
||||
|
||||
query = context.session.query(BgpSpeakerDrAgentBinding)
|
||||
query = query.filter_by(bgp_speaker_id=speaker_id,
|
||||
agent_id=agent_id)
|
||||
|
||||
num_deleted = query.delete()
|
||||
if not num_deleted:
|
||||
raise bgp_dras_ext.DrAgentNotHostingBgpSpeaker(
|
||||
bgp_speaker_id=speaker_id,
|
||||
agent_id=agent_id)
|
||||
LOG.debug('BgpSpeaker %(bgp_speaker_id)s removed from '
|
||||
'BgpDrAgent %(agent_id)s',
|
||||
{'bgp_speaker_id': speaker_id,
|
||||
'agent_id': agent_id})
|
||||
|
||||
self._bgp_rpc.bgp_speaker_removed(context, speaker_id, agent_db.host)
|
||||
|
||||
def get_dragents_hosting_bgp_speakers(self, context, bgp_speaker_ids,
|
||||
active=None, admin_state_up=None):
|
||||
query = context.session.query(BgpSpeakerDrAgentBinding)
|
||||
query = query.options(orm.contains_eager(
|
||||
BgpSpeakerDrAgentBinding.dragent))
|
||||
query = query.join(BgpSpeakerDrAgentBinding.dragent)
|
||||
|
||||
if len(bgp_speaker_ids) == 1:
|
||||
query = query.filter(
|
||||
BgpSpeakerDrAgentBinding.bgp_speaker_id == (
|
||||
bgp_speaker_ids[0]))
|
||||
elif bgp_speaker_ids:
|
||||
query = query.filter(
|
||||
BgpSpeakerDrAgentBinding.bgp_speaker_id in bgp_speaker_ids)
|
||||
if admin_state_up is not None:
|
||||
query = query.filter(agents_db.Agent.admin_state_up ==
|
||||
admin_state_up)
|
||||
|
||||
return [binding.dragent
|
||||
for binding in query
|
||||
if as_db.AgentSchedulerDbMixin.is_eligible_agent(
|
||||
active, binding.dragent)]
|
||||
|
||||
def get_dragent_bgp_speaker_bindings(self, context):
|
||||
return context.session.query(BgpSpeakerDrAgentBinding).all()
|
||||
|
||||
def list_dragent_hosting_bgp_speaker(self, context, speaker_id):
|
||||
dragents = self.get_dragents_hosting_bgp_speakers(context,
|
||||
[speaker_id])
|
||||
agent_ids = [dragent.id for dragent in dragents]
|
||||
if not agent_ids:
|
||||
return {'agents': []}
|
||||
return {'agents': self.get_agents(context, filters={'id': agent_ids})}
|
||||
|
||||
def list_bgp_speaker_on_dragent(self, context, agent_id):
|
||||
query = context.session.query(BgpSpeakerDrAgentBinding.bgp_speaker_id)
|
||||
query = query.filter_by(agent_id=agent_id)
|
||||
|
||||
bgp_speaker_ids = [item[0] for item in query]
|
||||
if not bgp_speaker_ids:
|
||||
# Exception will be thrown if the requested agent does not exist.
|
||||
self._get_agent(context, agent_id)
|
||||
return {'bgp_speakers': []}
|
||||
return {'bgp_speakers':
|
||||
self.get_bgp_speakers(context,
|
||||
filters={'id': bgp_speaker_ids})}
|
||||
|
||||
def get_bgp_speakers_for_agent_host(self, context, host):
|
||||
agent = self._get_agent_by_type_and_host(
|
||||
context, bgp_consts.AGENT_TYPE_BGP_ROUTING, host)
|
||||
if not agent.admin_state_up:
|
||||
return {}
|
||||
|
||||
query = context.session.query(BgpSpeakerDrAgentBinding)
|
||||
query = query.filter(BgpSpeakerDrAgentBinding.agent_id == agent.id)
|
||||
try:
|
||||
binding = query.one()
|
||||
except exc.NoResultFound:
|
||||
return []
|
||||
bgp_speaker = self.get_bgp_speaker_with_advertised_routes(
|
||||
context, binding['bgp_speaker_id'])
|
||||
return [bgp_speaker]
|
||||
|
||||
def get_bgp_speaker_by_speaker_id(self, context, bgp_speaker_id):
|
||||
try:
|
||||
return self.get_bgp_speaker(context, bgp_speaker_id)
|
||||
except exc.NoResultFound:
|
||||
return {}
|
||||
|
||||
def get_bgp_peer_by_peer_id(self, context, bgp_peer_id):
|
||||
try:
|
||||
return self.get_bgp_peer(context, bgp_peer_id)
|
||||
except exc.NoResultFound:
|
||||
return {}
|
@ -1,105 +0,0 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# 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 dynamic routing model data
|
||||
|
||||
Revision ID: 15be73214821
|
||||
Create Date: 2015-07-29 13:16:08.604175
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '15be73214821'
|
||||
down_revision = '19f26505c74f'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
|
||||
op.create_table(
|
||||
'bgp_speakers',
|
||||
sa.Column('id', sa.String(length=36),
|
||||
nullable=False),
|
||||
sa.Column('name', sa.String(length=255),
|
||||
nullable=False),
|
||||
sa.Column('local_as', sa.Integer, nullable=False,
|
||||
autoincrement=False),
|
||||
sa.Column('ip_version', sa.Integer, nullable=False,
|
||||
autoincrement=False),
|
||||
sa.Column('tenant_id',
|
||||
sa.String(length=255),
|
||||
nullable=True,
|
||||
index=True),
|
||||
sa.Column('advertise_floating_ip_host_routes', sa.Boolean(),
|
||||
nullable=False),
|
||||
sa.Column('advertise_tenant_networks', sa.Boolean(),
|
||||
nullable=False),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'bgp_peers',
|
||||
sa.Column('id', sa.String(length=36),
|
||||
nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('auth_type', sa.String(length=16), nullable=False),
|
||||
sa.Column('password', sa.String(length=255), nullable=True),
|
||||
sa.Column('peer_ip',
|
||||
sa.String(length=64),
|
||||
nullable=False),
|
||||
sa.Column('remote_as', sa.Integer, nullable=False,
|
||||
autoincrement=False),
|
||||
sa.Column('tenant_id',
|
||||
sa.String(length=255),
|
||||
nullable=True,
|
||||
index=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'bgp_speaker_network_bindings',
|
||||
sa.Column('bgp_speaker_id',
|
||||
sa.String(length=36),
|
||||
nullable=False),
|
||||
sa.Column('network_id',
|
||||
sa.String(length=36),
|
||||
nullable=True),
|
||||
sa.Column('ip_version', sa.Integer, nullable=False,
|
||||
autoincrement=False),
|
||||
sa.ForeignKeyConstraint(['bgp_speaker_id'],
|
||||
['bgp_speakers.id'],
|
||||
ondelete='CASCADE'),
|
||||
sa.ForeignKeyConstraint(['network_id'],
|
||||
['networks.id'],
|
||||
ondelete='CASCADE'),
|
||||
sa.PrimaryKeyConstraint('network_id', 'bgp_speaker_id', 'ip_version')
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'bgp_speaker_peer_bindings',
|
||||
sa.Column('bgp_speaker_id',
|
||||
sa.String(length=36),
|
||||
nullable=False),
|
||||
sa.Column('bgp_peer_id',
|
||||
sa.String(length=36),
|
||||
nullable=False),
|
||||
sa.ForeignKeyConstraint(['bgp_speaker_id'], ['bgp_speakers.id'],
|
||||
ondelete='CASCADE'),
|
||||
sa.ForeignKeyConstraint(['bgp_peer_id'], ['bgp_peers.id'],
|
||||
ondelete='CASCADE'),
|
||||
sa.PrimaryKeyConstraint('bgp_speaker_id', 'bgp_peer_id')
|
||||
)
|
@ -1,46 +0,0 @@
|
||||
# Copyright 2016 Huawei Technologies India Pvt. Ltd.
|
||||
#
|
||||
# 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_bgp_dragent_model_data
|
||||
|
||||
Revision ID: b4caf27aae4
|
||||
Revises: 15be7321482
|
||||
Create Date: 2015-08-20 17:05:31.038704
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'b4caf27aae4'
|
||||
down_revision = '15be73214821'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
|
||||
op.create_table(
|
||||
'bgp_speaker_dragent_bindings',
|
||||
sa.Column('agent_id',
|
||||
sa.String(length=36),
|
||||
primary_key=True),
|
||||
sa.Column('bgp_speaker_id',
|
||||
sa.String(length=36),
|
||||
nullable=False),
|
||||
sa.ForeignKeyConstraint(['agent_id'], ['agents.id'],
|
||||
ondelete='CASCADE'),
|
||||
sa.ForeignKeyConstraint(['bgp_speaker_id'], ['bgp_speakers.id'],
|
||||
ondelete='CASCADE'),
|
||||
)
|
@ -1,65 +0,0 @@
|
||||
# Copyright (c) 2014 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.
|
||||
|
||||
"""
|
||||
The module provides all database models at current HEAD.
|
||||
|
||||
Its purpose is to create comparable metadata with current database schema.
|
||||
Based on this comparison database can be healed with healing migration.
|
||||
|
||||
"""
|
||||
|
||||
from neutron.db import address_scope_db # noqa
|
||||
from neutron.db import agents_db # noqa
|
||||
from neutron.db import agentschedulers_db # noqa
|
||||
from neutron.db import allowedaddresspairs_db # noqa
|
||||
from neutron.db import bgp_db # noqa
|
||||
from neutron.db import bgp_dragentscheduler_db # noqa
|
||||
from neutron.db import dns_db # noqa
|
||||
from neutron.db import dvr_mac_db # noqa
|
||||
from neutron.db import external_net_db # noqa
|
||||
from neutron.db import extradhcpopt_db # noqa
|
||||
from neutron.db import extraroute_db # noqa
|
||||
from neutron.db import flavors_db # noqa
|
||||
from neutron.db import l3_agentschedulers_db # noqa
|
||||
from neutron.db import l3_attrs_db # noqa
|
||||
from neutron.db import l3_db # noqa
|
||||