├── .coveragerc ├── .gitignore ├── .gitreview ├── .mailmap ├── .pre-commit-config.yaml ├── .pylintrc ├── .stestr.conf ├── .zuul.yaml ├── CONTRIBUTING.rst ├── HACKING.rst ├── LICENSE ├── MANIFEST.in ├── README.rst ├── TESTING.rst ├── devstack ├── README.rst ├── lib │ └── dr ├── plugin.sh └── settings ├── doc ├── requirements.txt └── source │ ├── _static │ └── .placeholder │ ├── admin │ ├── agent-scheduler.rst │ ├── bgp-speaker.rst │ ├── index.rst │ ├── route-advertisement.rst │ └── system-design.rst │ ├── cli │ ├── bgp-peer.rst │ ├── bgp-speaker.rst │ ├── dynamic-routing-agent.rst │ └── index.rst │ ├── conf.py │ ├── configuration │ ├── bgp_dragent.rst │ ├── index.rst │ ├── policy-sample.rst │ ├── policy.rst │ └── samples │ │ └── bgp_dragent.rst │ ├── contributor │ ├── contributing.rst │ ├── dragent-drivers.rst │ ├── index.rst │ └── testing.rst │ ├── index.rst │ ├── install │ ├── index.rst │ └── usecase-ipv6.rst │ └── reference │ └── index.rst ├── etc ├── README.txt ├── oslo-config-generator │ └── bgp_dragent.ini └── oslo-policy-generator │ └── policy.conf ├── neutron_dynamic_routing ├── __init__.py ├── _i18n.py ├── api │ ├── __init__.py │ └── rpc │ │ ├── __init__.py │ │ ├── agentnotifiers │ │ ├── __init__.py │ │ └── bgp_dr_rpc_agent_api.py │ │ ├── callbacks │ │ ├── __init__.py │ │ └── resources.py │ │ └── handlers │ │ ├── __init__.py │ │ └── bgp_speaker_rpc.py ├── cmd │ ├── __init__.py │ └── eventlet │ │ ├── __init__.py │ │ └── agents │ │ ├── __init__.py │ │ └── bgp_dragent.py ├── db │ ├── __init__.py │ ├── bgp_db.py │ ├── bgp_dragentscheduler_db.py │ └── migration │ │ ├── README │ │ ├── __init__.py │ │ ├── alembic_migrations │ │ ├── __init__.py │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── CONTRACT_HEAD │ │ │ ├── EXPAND_HEAD │ │ │ ├── newton │ │ │ ├── contract │ │ │ │ ├── 4cf8bc3edb66_rename_tenant_to_project.py │ │ │ │ └── 61cc795e43e8_initial.py │ │ │ └── expand │ │ │ │ └── f399fa0f5f25_initial.py │ │ │ ├── queens │ │ │ └── contract │ │ │ │ └── a589fdb5724c_change_size_of_as_number.py │ │ │ └── start_neutron_dynamic_routing.py │ │ └── models │ │ ├── __init__.py │ │ └── head.py ├── extensions │ ├── __init__.py │ ├── bgp.py │ ├── bgp_4byte_asn.py │ └── bgp_dragentscheduler.py ├── policies │ ├── __init__.py │ ├── bgp_dragent.py │ ├── bgp_peer.py │ └── bgp_speaker.py ├── services │ ├── __init__.py │ └── bgp │ │ ├── __init__.py │ │ ├── agent │ │ ├── __init__.py │ │ ├── bgp_dragent.py │ │ ├── config.py │ │ ├── driver │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── exceptions.py │ │ │ ├── os_ken │ │ │ │ ├── __init__.py │ │ │ │ └── driver.py │ │ │ └── utils.py │ │ └── entry.py │ │ ├── bgp_plugin.py │ │ ├── common │ │ ├── __init__.py │ │ ├── constants.py │ │ └── opts.py │ │ └── scheduler │ │ ├── __init__.py │ │ └── bgp_dragent_scheduler.py ├── tests │ ├── __init__.py │ ├── common │ │ ├── __init__.py │ │ └── helpers.py │ ├── functional │ │ ├── __init__.py │ │ └── services │ │ │ ├── __init__.py │ │ │ └── bgp │ │ │ ├── __init__.py │ │ │ └── scheduler │ │ │ ├── __init__.py │ │ │ └── test_bgp_dragent_scheduler.py │ └── unit │ │ ├── __init__.py │ │ ├── api │ │ ├── __init__.py │ │ └── rpc │ │ │ ├── __init__.py │ │ │ ├── agentnotifiers │ │ │ ├── __init__.py │ │ │ └── test_bgp_dr_rpc_agent_api.py │ │ │ └── handlers │ │ │ ├── __init__.py │ │ │ └── test_bgp_speaker_rpc.py │ │ ├── db │ │ ├── __init__.py │ │ ├── test_bgp_db.py │ │ └── test_bgp_dragentscheduler_db.py │ │ └── services │ │ ├── __init__.py │ │ └── bgp │ │ ├── __init__.py │ │ ├── agent │ │ ├── __init__.py │ │ └── test_bgp_dragent.py │ │ ├── driver │ │ ├── __init__.py │ │ ├── os_ken │ │ │ ├── __init__.py │ │ │ └── test_driver.py │ │ └── test_utils.py │ │ ├── scheduler │ │ ├── __init__.py │ │ └── test_bgp_dragent_scheduler.py │ │ └── test_bgp_plugin.py └── version.py ├── pyproject.toml ├── releasenotes ├── notes │ ├── .placeholder │ ├── add-static-scheduler-a3b0f54b964ae306.yaml │ ├── drop-py27-support-795303ca12cccd34.yaml │ ├── drop-py39-a9a5f0b7addc2f12.yaml │ ├── drop-python-3-6-and-3-7-efc3424202bf3f90.yaml │ ├── dvr-aware-announcements-24bfcb8fee87161d.yaml │ ├── fix-address-scope-calculation-c8ac84662a6547bd.yaml │ ├── mp-bgp-support-d408e8569e94d07f.yaml │ ├── rehome-dynamic-routing-apidef-d656e3273baac4e8.yaml │ ├── rpc-workers-4941f3b9136418df.yaml │ ├── sqlalchemy-20-abaa3d2895131ab4.yaml │ ├── static-scheduler-2288b8173f9357a6.yaml │ └── support-4byte-asn-d89d7100c0890ebf.yaml └── source │ ├── 2023.1.rst │ ├── 2023.2.rst │ ├── 2024.1.rst │ ├── 2024.2.rst │ ├── 2025.1.rst │ ├── README.rst │ ├── _static │ └── .placeholder │ ├── _templates │ └── .placeholder │ ├── conf.py │ ├── index.rst │ ├── queens.rst │ ├── rocky.rst │ ├── stein.rst │ ├── train.rst │ ├── unreleased.rst │ ├── ussuri.rst │ ├── victoria.rst │ ├── wallaby.rst │ ├── xena.rst │ ├── yoga.rst │ └── zed.rst ├── requirements.txt ├── setup.cfg ├── setup.py ├── test-requirements.txt ├── tools ├── check_unit_test_structure.sh ├── clean.sh └── generate_config_file_samples.sh └── tox.ini /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | source = neutron_dynamic_routing 4 | omit = neutron_dynamic_routing/tests/* 5 | 6 | [report] 7 | ignore_errors = True 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | AUTHORS 2 | build/* 3 | build-stamp 4 | ChangeLog 5 | cover/ 6 | covhtml/ 7 | dist/ 8 | doc/build 9 | doc/source/_static/config_samples/*.sample 10 | doc/source/_static/*.policy.yaml.sample 11 | etc/*.sample 12 | *.DS_Store 13 | *.pyc 14 | neutron.egg-info/ 15 | neutron_dynamic_routing.egg-info/ 16 | neutron/vcsversion.py 17 | neutron/versioninfo 18 | pbr*.egg/ 19 | run_tests.err.log 20 | run_tests.log 21 | setuptools*.egg/ 22 | subunit.log 23 | *.mo 24 | *.sw? 25 | *~ 26 | /.* 27 | !/.coveragerc 28 | !/.gitignore 29 | !/.gitreview 30 | !/.mailmap 31 | !/.pylintrc 32 | !/.stestr.conf 33 | !/.zuul.yaml 34 | 35 | # Files created by releasenotes build 36 | releasenotes/build 37 | -------------------------------------------------------------------------------- /.gitreview: -------------------------------------------------------------------------------- 1 | [gerrit] 2 | host=review.opendev.org 3 | port=29418 4 | project=openstack/neutron-dynamic-routing.git 5 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | # Format is: 2 | # 3 | # 4 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | default_language_version: 3 | # force all unspecified python hooks to run python3 4 | python: python3 5 | repos: 6 | - repo: https://github.com/pre-commit/pre-commit-hooks 7 | rev: v4.5.0 8 | hooks: 9 | - id: trailing-whitespace 10 | - id: mixed-line-ending 11 | args: ['--fix', 'lf'] 12 | exclude: '.*\.(svg)$' 13 | - id: check-byte-order-marker 14 | - id: check-executables-have-shebangs 15 | - id: check-merge-conflict 16 | - id: debug-statements 17 | - id: check-yaml 18 | - repo: https://github.com/lucas-c/pre-commit-hooks 19 | rev: v1.5.4 20 | hooks: 21 | - id: remove-tabs 22 | exclude: '.*\.(svg)$' 23 | - repo: https://opendev.org/openstack/hacking 24 | rev: 6.1.0 25 | hooks: 26 | - id: hacking 27 | additional_dependencies: ['neutron-lib'] 28 | exclude: '^(doc|releasenotes|tools)/.*$' 29 | - repo: local 30 | hooks: 31 | - id: flake8 32 | name: flake8 33 | additional_dependencies: 34 | - hacking>=6.1.0,<6.2.0 35 | language: python 36 | entry: flake8 37 | files: '^.*\.py$' 38 | exclude: '^(doc|releasenotes|tools)/.*$' 39 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | # The format of this file isn't really documented; just use --generate-rcfile 2 | [MASTER] 3 | # Add to the black list. It should be a base name, not a 4 | # path. You may set this option multiple times. 5 | # 6 | ignore=.git,tests 7 | 8 | [MESSAGES CONTROL] 9 | # NOTE(gus): This is a long list. A number of these are important and 10 | # should be re-enabled once the offending code is fixed (or marked 11 | # with a local disable) 12 | disable= 13 | # "F" Fatal errors that prevent further processing 14 | import-error, 15 | # "I" Informational noise 16 | locally-disabled, 17 | # "E" Error for important programming issues (likely bugs) 18 | access-member-before-definition, 19 | bad-super-call, 20 | maybe-no-member, 21 | no-member, 22 | no-method-argument, 23 | no-self-argument, 24 | not-callable, 25 | no-value-for-parameter, 26 | super-on-old-class, 27 | too-few-format-args, 28 | # "W" Warnings for stylistic problems or minor programming issues 29 | abstract-method, 30 | anomalous-backslash-in-string, 31 | anomalous-unicode-escape-in-string, 32 | arguments-differ, 33 | attribute-defined-outside-init, 34 | bad-builtin, 35 | bad-indentation, 36 | broad-except, 37 | dangerous-default-value, 38 | deprecated-lambda, 39 | duplicate-key, 40 | expression-not-assigned, 41 | fixme, 42 | global-statement, 43 | global-variable-not-assigned, 44 | logging-not-lazy, 45 | no-init, 46 | pointless-string-statement, 47 | protected-access, 48 | redefined-builtin, 49 | redefined-outer-name, 50 | redefine-in-handler, 51 | signature-differs, 52 | star-args, 53 | super-init-not-called, 54 | unnecessary-lambda, 55 | unnecessary-pass, 56 | unpacking-non-sequence, 57 | unreachable, 58 | unused-argument, 59 | unused-import, 60 | unused-variable, 61 | # TODO(dougwig) - disable nonstandard-exception while we have neutron_lib shims 62 | nonstandard-exception, 63 | # "C" Coding convention violations 64 | bad-continuation, 65 | invalid-name, 66 | missing-docstring, 67 | old-style-class, 68 | superfluous-parens, 69 | # "R" Refactor recommendations 70 | abstract-class-little-used, 71 | abstract-class-not-used, 72 | duplicate-code, 73 | interface-not-implemented, 74 | no-self-use, 75 | too-few-public-methods, 76 | too-many-ancestors, 77 | too-many-arguments, 78 | too-many-branches, 79 | too-many-instance-attributes, 80 | too-many-lines, 81 | too-many-locals, 82 | too-many-public-methods, 83 | too-many-return-statements, 84 | too-many-statements 85 | 86 | [BASIC] 87 | # Variable names can be 1 to 31 characters long, with lowercase and underscores 88 | variable-rgx=[a-z_][a-z0-9_]{0,30}$ 89 | 90 | # Argument names can be 2 to 31 characters long, with lowercase and underscores 91 | argument-rgx=[a-z_][a-z0-9_]{1,30}$ 92 | 93 | # Method names should be at least 3 characters long 94 | # and be lowecased with underscores 95 | method-rgx=([a-z_][a-z0-9_]{2,}|setUp|tearDown)$ 96 | 97 | # Module names matching neutron-* are ok (files in bin/) 98 | module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|(neutron-[a-z0-9_-]+))$ 99 | 100 | # Don't require docstrings on tests. 101 | no-docstring-rgx=((__.*__)|([tT]est.*)|setUp|tearDown)$ 102 | 103 | [FORMAT] 104 | # Maximum number of characters on a single line. 105 | max-line-length=79 106 | 107 | [VARIABLES] 108 | # List of additional names supposed to be defined in builtins. Remember that 109 | # you should avoid to define new builtins when possible. 110 | # _ is used by our localization 111 | additional-builtins=_ 112 | 113 | [CLASSES] 114 | # List of interface methods to ignore, separated by a comma. 115 | ignore-iface-methods= 116 | 117 | [IMPORTS] 118 | # Deprecated modules which should not be used, separated by a comma 119 | deprecated-modules= 120 | # should use oslo_serialization.jsonutils 121 | json 122 | 123 | [TYPECHECK] 124 | # List of module names for which member attributes should not be checked 125 | ignored-modules= 126 | 127 | [REPORTS] 128 | # Tells whether to display a full report or only the messages 129 | reports=no 130 | -------------------------------------------------------------------------------- /.stestr.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | test_path=${OS_TEST_PATH:-./neutron_dynamic_routing/tests/unit} 3 | top_dir=./ 4 | -------------------------------------------------------------------------------- /.zuul.yaml: -------------------------------------------------------------------------------- 1 | - job: 2 | name: neutron-dynamic-routing-static 3 | parent: neutron-tempest-plugin-dynamic-routing 4 | vars: 5 | devstack_localrc: 6 | BGP_SCHEDULER_DRIVER: neutron_dynamic_routing.services.bgp.scheduler.bgp_dragent_scheduler.StaticScheduler 7 | devstack_local_conf: 8 | test-config: 9 | $TEMPEST_CONFIG: 10 | neutron_plugin_options: 11 | bgp_schedule_speakers_to_agents: true 12 | 13 | - job: 14 | name: neutron-dynamic-routing-functional 15 | parent: neutron-functional 16 | vars: 17 | project_name: neutron-dynamic-routing-functional 18 | tox_envlist: functional 19 | # NOTE(amotoki): neutron-functional sets tox_install_siblings to false. 20 | # This needs to be true so that neutron from its repo is installed into 21 | # tox env. 22 | # We need to check tox_install_siblings false is required 23 | # in neutron-functional job. 24 | tox_install_siblings: true 25 | 26 | - project: 27 | templates: 28 | - check-requirements 29 | - openstack-cover-jobs-neutron 30 | - openstack-python3-jobs-neutron 31 | - publish-openstack-docs-pti 32 | - release-notes-jobs-python3 33 | check: 34 | jobs: 35 | - neutron-dynamic-routing-functional 36 | - neutron-dynamic-routing-static 37 | - neutron-tempest-plugin-dynamic-routing 38 | gate: 39 | jobs: 40 | - neutron-dynamic-routing-functional 41 | - neutron-tempest-plugin-dynamic-routing 42 | experimental: 43 | jobs: 44 | - openstack-tox-py312-with-oslo-master 45 | periodic-weekly: 46 | jobs: 47 | - openstack-tox-py312 48 | - openstack-tox-py312-with-oslo-master 49 | - neutron-tempest-plugin-dynamic-routing 50 | - neutron-dynamic-routing-functional 51 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | Please see the Neutron CONTRIBUTING.rst file for how to contribute to 2 | neutron-dynamic-routing: 3 | 4 | `Neutron CONTRIBUTING.rst `_ 5 | -------------------------------------------------------------------------------- /HACKING.rst: -------------------------------------------------------------------------------- 1 | Neutron Dynamic Routing Style Commandments 2 | ========================================== 3 | 4 | Please see the Neutron HACKING.rst file for style commandments for 5 | neutron-dynamic-routing: 6 | 7 | `Neutron HACKING.rst `_ 8 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS 2 | include README.rst 3 | include ChangeLog 4 | include LICENSE 5 | 6 | exclude .gitignore 7 | exclude .gitreview 8 | 9 | global-exclude *.pyc 10 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Team and repository tags 2 | ======================== 3 | 4 | .. image:: http://governance.openstack.org/badges/neutron-dynamic-routing.svg 5 | :target: http://governance.openstack.org/reference/tags/index.html 6 | 7 | .. Change things from this point on 8 | 9 | This package contains neutron-dynamic-routing code which depends upon neutron 10 | and it's related libraries to run. 11 | 12 | Project Resources 13 | ================= 14 | 15 | The homepage for Neutron is: https://launchpad.net/neutron. Use this 16 | site for asking for help, and filing bugs. We use a single launchpad 17 | page for all Neutron projects. 18 | 19 | Code is available on opendev.org at: 20 | https://opendev.org/openstack/neutron-dynamic-routing 21 | 22 | Refer to Neutron documentation for more information: 23 | `Neutron README.rst `_ 24 | 25 | Release notes for the project can be found at: 26 | https://docs.openstack.org/releasenotes/neutron-dynamic-routing/ 27 | -------------------------------------------------------------------------------- /TESTING.rst: -------------------------------------------------------------------------------- 1 | Testing Neutron Dynamic Routing 2 | =============================== 3 | 4 | Please see the TESTING.rst file for the Neutron project itself. This will have 5 | the latest up to date instructions for how to test Neutron, and will 6 | be applicable to neutron-dynamic-routing as well: 7 | 8 | `Neutron TESTING.rst `_ 9 | -------------------------------------------------------------------------------- /devstack/README.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Enabling in Devstack 3 | ====================== 4 | 5 | 1. Download devstack:: 6 | 7 | git clone https://opendev.org/openstack/devstack.git 8 | 9 | 2. Add neutron-dynamic-routing to devstack. The minimal set of critical local.conf 10 | additions are following:: 11 | 12 | cd devstack 13 | cat << EOF > local.conf 14 | > [[local|localrc]] 15 | > enable_plugin neutron-dynamic-routing https://opendev.org/openstack/neutron-dynamic-routing 16 | > EOF 17 | 18 | 3. run devstack:: 19 | 20 | ./stack.sh 21 | 22 | Notes: 23 | 24 | 1. In the default case, neutron-dynamic-routing is installed in allinone mode. 25 | In multiple nodes environment, for controller node:: 26 | 27 | cd devstack 28 | cat << EOF > local.conf 29 | > [[local|localrc]] 30 | > enable_plugin neutron-dynamic-routing https://opendev.org/openstack/neutron-dynamic-routing 31 | > DR_MODE=dr_plugin 32 | > EOF 33 | 34 | For the nodes where you want to run dr-agent:: 35 | 36 | cd devstack 37 | cat << EOF > local.conf 38 | > [[local|localrc]] 39 | > enable_plugin neutron-dynamic-routing https://opendev.org/openstack/neutron-dynamic-routing 40 | > DR_MODE=dr_agent 41 | > EOF 42 | 43 | 2. In the default case, protocol BGP is enabled for neutron-dynamic-routing. 44 | You can change "DR_SUPPORTED_PROTOCOLS" in "devstack/settings" to protocols wanted. 45 | 46 | -------------------------------------------------------------------------------- /devstack/lib/dr: -------------------------------------------------------------------------------- 1 | function is_protocol_enabled { 2 | local enabled=1 3 | local protocol=$1 4 | for temp in $DR_SUPPORTED_PROTOCOLS ;do 5 | if [ $protocol == $temp ] ; then 6 | enabled=0 7 | fi 8 | done 9 | 10 | return $enabled 11 | } 12 | 13 | 14 | ############################## 15 | # BGP Section # 16 | ############################## 17 | 18 | function configure_dr_agent_bgp_config { 19 | cp $NEUTRON_DYNAMIC_ROUTING_DIR/etc/bgp_dragent.ini.sample $DR_AGENT_BGP_CONF_FILE 20 | iniset $DR_AGENT_BGP_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL 21 | iniset $DR_AGENT_BGP_CONF_FILE bgp bgp_router_id $BGP_ROUTER_ID 22 | } 23 | 24 | function configure_dr_agent_bgp_driver { 25 | if [ -z "$BGP_SPEAKER_DRIVER" ] ; then 26 | BGP_SPEAKER_DRIVER=$OSKEN_BGP_SPEAKER_DRIVER 27 | fi 28 | iniset $DR_AGENT_BGP_CONF_FILE bgp bgp_speaker_driver $BGP_SPEAKER_DRIVER 29 | } 30 | 31 | function configure_dr_agent_scheduler_driver { 32 | if [ -n "$BGP_SCHEDULER_DRIVER" ] ; then 33 | iniset $NEUTRON_CONF DEFAULT bgp_drscheduler_driver $BGP_SCHEDULER_DRIVER 34 | fi 35 | } 36 | 37 | ############################# 38 | # Stack Install Section # 39 | ############################# 40 | 41 | #This API will be called for phase "install" 42 | 43 | function dr_install { 44 | # Install os-ken from git to test latest/in-review code 45 | if use_library_from_git "os-ken"; then 46 | git_clone_by_name "os-ken" 47 | setup_dev_lib "os-ken" 48 | fi 49 | 50 | setup_develop $NEUTRON_DYNAMIC_ROUTING_DIR 51 | } 52 | 53 | ############################# 54 | # Stack Post-config Section # 55 | ############################# 56 | 57 | #This API will be called for phase "post-config" 58 | function dr_generate_config_files { 59 | (cd $NEUTRON_DYNAMIC_ROUTING_DIR && exec ./tools/generate_config_file_samples.sh) 60 | } 61 | 62 | function dr_post_configure { 63 | if is_service_enabled q-dr neutron-dr && is_service_enabled q-svc neutron-api; then 64 | if is_protocol_enabled BGP; then 65 | neutron_service_plugin_class_add $BGP_PLUGIN 66 | fi 67 | fi 68 | if is_service_enabled q-dr-agent neutron-dr-agent; then 69 | dr_generate_config_files 70 | if is_protocol_enabled BGP; then 71 | configure_dr_agent_bgp_config 72 | configure_dr_agent_bgp_driver 73 | configure_dr_agent_scheduler_driver 74 | fi 75 | fi 76 | } 77 | 78 | ############################# 79 | # Stack Extra Section # 80 | ############################# 81 | 82 | #This API will be called for phase "extra" 83 | function start_dr_agent { 84 | local process="$DR_AGENT_BINARY --config-file $NEUTRON_CONF " 85 | local bgp_parameter 86 | if is_protocol_enabled BGP; then 87 | bgp_parameter="--config-file $DR_AGENT_BGP_CONF_FILE" 88 | fi 89 | 90 | agent_process=$process$bgp_parameter 91 | if is_neutron_legacy_enabled; then 92 | if is_service_enabled q-dr-agent; then 93 | run_process q-dr-agent "$agent_process" 94 | fi 95 | else 96 | if is_service_enabled neutron-dr-agent; then 97 | run_process neutron-dr-agent "$agent_process" 98 | fi 99 | fi 100 | } 101 | 102 | ############################# 103 | # Unstack Section # 104 | ############################# 105 | 106 | #This API will be called for unstack 107 | function stop_dr_agent { 108 | if is_neutron_legacy_enabled; then 109 | stop_process q-dr-agent 110 | else 111 | stop_process neutron-dr-agent 112 | fi 113 | } 114 | -------------------------------------------------------------------------------- /devstack/plugin.sh: -------------------------------------------------------------------------------- 1 | LIBDIR=$NEUTRON_DYNAMIC_ROUTING_DIR/devstack/lib 2 | 3 | source $LIBDIR/dr 4 | 5 | if [[ "$1" == "stack" ]]; then 6 | case "$2" in 7 | install) 8 | echo_summary "Installing neutron-dynamic-routing" 9 | dr_install 10 | ;; 11 | post-config) 12 | echo_summary "Configuring neutron-dynamic-routing" 13 | dr_post_configure 14 | ;; 15 | extra) 16 | echo_summary "Launching neutron-dynamic-routing agent" 17 | start_dr_agent 18 | ;; 19 | esac 20 | elif [[ "$1" == "unstack" ]]; then 21 | echo_summary "Uninstalling neutron-dynamic-routing" 22 | stop_dr_agent 23 | fi 24 | -------------------------------------------------------------------------------- /devstack/settings: -------------------------------------------------------------------------------- 1 | ######################### 2 | # Devstack Settings # 3 | ######################### 4 | 5 | # Each service you enable has the following meaning: 6 | # q-dr - Add this config flag for Openstack Neutron server node 7 | # q-dr-agent - Add this config flag indicate that dynamic routing agent 8 | # will be running 9 | 10 | # This can be overridden in the localrc file 11 | DR_MODE=${DR_MODE:-allinone} 12 | 13 | # DR_MODE is used to configure how devstack works with neutron-dynamic-routing. 14 | # You can configure it in there ways: 15 | # 16 | # DR_MODE=allinone 17 | # Use this mode if you want to run neutron server and q-dr-agent on same node. 18 | # Useful for a single node deployment or on the control node of a multi-node 19 | # devstack environment. 20 | # 21 | # DR_MODE=dr_plugin 22 | # Use this to enable dr plugin extension on neutron server 23 | # 24 | # DR_MODE=dr_agent 25 | # Use this for the nodes where you want to run q-dr-agent in a multi-node 26 | # devstack environment. 27 | 28 | case $DR_MODE in 29 | allinone) 30 | if is_neutron_legacy_enabled; then 31 | enable_service q-dr q-dr-agent 32 | else 33 | enable_service neutron-dr neutron-dr-agent 34 | fi 35 | ;; 36 | dr_plugin) 37 | if is_neutron_legacy_enabled; then 38 | enable_service q-dr 39 | else 40 | enable_service neutron-dr 41 | fi 42 | ;; 43 | dr_agent) 44 | if is_neutron_legacy_enabled; then 45 | enable_service q-dr-agent 46 | else 47 | enable_service neutron-dr-agent 48 | fi 49 | ;; 50 | esac 51 | 52 | # DR_SUPPORTED_PROTOCOLS specifies the list of protocols supported 53 | # by neutron-dynamic-routing project. ONLY BGP is supported as of now 54 | # and it's enabled by default. The protocols may include: "BGP OSPF ISIS RIP". 55 | # It can be overridden in the localrc file. 56 | DR_SUPPORTED_PROTOCOLS=${DR_SUPPORTED_PROTOCOLS:-"BGP"} 57 | 58 | 59 | ####################### 60 | # Binary Settings # 61 | ####################### 62 | NEUTRON_DYNAMIC_ROUTING_DIR=$DEST/neutron-dynamic-routing 63 | DR_AGENT_BINARY=${DR_AGENT_BINARY:-"$NEUTRON_BIN_DIR/neutron-bgp-dragent"} 64 | 65 | 66 | ################################ 67 | # Protocol Config Settings # 68 | ################################ 69 | 70 | 71 | ########### 72 | # BGP # 73 | ########### 74 | DR_AGENT_BGP_CONF_FILE=${DR_AGENT_BGP_CONF_FILE:-"$NEUTRON_CONF_DIR/bgp_dragent.ini"} 75 | BGP_ROUTER_ID=${BGP_ROUTER_ID:-"127.0.0.1"} 76 | BGP_PLUGIN=${BGP_PLUGIN:-"neutron_dynamic_routing.services.bgp.bgp_plugin.BgpPlugin"} 77 | OSKEN_BGP_SPEAKER_DRIVER="neutron_dynamic_routing.services.bgp.agent.driver.os_ken.driver.OsKenBgpDriver" 78 | 79 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | reno>=3.1.0 # Apache-2.0 2 | sphinx>=2.0.0,!=2.1.0 # BSD 3 | sphinxcontrib-apidoc>=0.2.0 # BSD 4 | sphinxcontrib-svg2pdfconverter>=0.1.0 # BSD 5 | openstackdocstheme>=2.2.1 # Apache-2.0 6 | 7 | -------------------------------------------------------------------------------- /doc/source/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/doc/source/_static/.placeholder -------------------------------------------------------------------------------- /doc/source/admin/agent-scheduler.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | ===== 26 | Agent 27 | ===== 28 | 29 | Neutron-dynamic-routing implements a new agent named "DRAgent". The agent talks 30 | to the neutron-dynamic-routing plugin which resides in the neutron server to get 31 | routing entity configuration. DRAgent interacts with the back-end driver to 32 | realize the required dynamic routing protocol functionality. For details, 33 | please refer to the system design document :doc:`system-design` 34 | 35 | .. note:: 36 | One DRAgent can support multiple drivers but currently ONLY os-ken is 37 | integrated successfully. 38 | 39 | 40 | Scheduler 41 | ========= 42 | 43 | Neutron-dynamic-routing scheduler, schedules a routing entity to a proper DRAgent. 44 | 45 | BGP Scheduler 46 | ------------- 47 | 48 | BGP Speaker and DRAgent has 1:N association which means one BGP speaker can be 49 | scheduled on multiple DRAgents. 50 | 51 | There are different options for the scheduling algorithm to be used, these can 52 | be selected via the ``bgp_drscheduler_driver`` configuration option. 53 | 54 | StaticScheduler 55 | ~~~~~~~~~~~~~~~ 56 | 57 | This is the most simple option, which does no automatic scheduling at all. 58 | Instead it relies on API requests to explicitly associate BGP speaker with 59 | DRAgents and to disassociate them again. 60 | 61 | Sample configuration:: 62 | 63 | bgp_drscheduler_driver = neutron_dynamic_routing.services.bgp.scheduler.bgp_dragent_scheduler.StaticScheduler 64 | 65 | Here is an example to associate/disassociate a BGP Speaker to/from a DRAgent. 66 | 67 | .. TODO(frickler): update the examples to use OSC 68 | 69 | :: 70 | 71 | (neutron) bgp-speaker-list 72 | +--------------------------------------+------+----------+------------+ 73 | | id | name | local_as | ip_version | 74 | +--------------------------------------+------+----------+------------+ 75 | | 0967eb04-59e5-4ca6-a0b0-d584d8d4a132 | bgp2 | 200 | 4 | 76 | | a73432c3-a3fc-4b1e-9be2-6c32a61df579 | bgp1 | 100 | 4 | 77 | +--------------------------------------+------+----------+------------+ 78 | 79 | (neutron) agent-list 80 | +--------------------------------------+---------------------------+---------------------+-------------------+-------+----------------+---------------------------+ 81 | | id | agent_type | host | availability_zone | alive | admin_state_up | binary | 82 | +--------------------------------------+---------------------------+---------------------+-------------------+-------+----------------+---------------------------+ 83 | | 0c21a829-4fd6-4375-8e65-36db4dc434ac | DHCP agent | steve-devstack-test | nova | :-) | True | neutron-dhcp-agent | 84 | | 0f9d6886-910d-4af4-b248-673b22eb9e78 | Metadata agent | steve-devstack-test | | :-) | True | neutron-metadata-agent | 85 | | 5908a304-b9d9-4e8c-a0af-96a066a7c87e | Open vSwitch agent | steve-devstack-test | | :-) | True | neutron-openvswitch-agent | 86 | | ae74e375-6a75-4ebe-b85c-6628d2baf02f | L3 agent | steve-devstack-test | nova | :-) | True | neutron-l3-agent | 87 | | dbd9900e-9d16-444d-afc4-8d0035df5ed5 | BGP dynamic routing agent | steve-devstack-test | | :-) | True | neutron-bgp-dragent | 88 | +--------------------------------------+---------------------------+---------------------+-------------------+-------+----------------+---------------------------+ 89 | 90 | (neutron) bgp-dragent-speaker-add dbd9900e-9d16-444d-afc4-8d0035df5ed5 bgp1 91 | Associated BGP speaker bgp1 to the Dynamic Routing agent. 92 | 93 | (neutron) bgp-speaker-list-on-dragent dbd9900e-9d16-444d-afc4-8d0035df5ed5 94 | +--------------------------------------+------+----------+------------+ 95 | | id | name | local_as | ip_version | 96 | +--------------------------------------+------+----------+------------+ 97 | | a73432c3-a3fc-4b1e-9be2-6c32a61df579 | bgp1 | 100 | 4 | 98 | +--------------------------------------+------+----------+------------+ 99 | 100 | (neutron) bgp-dragent-speaker-remove dbd9900e-9d16-444d-afc4-8d0035df5ed5 bgp1 101 | Disassociated BGP speaker bgp1 from the Dynamic Routing agent. 102 | 103 | (neutron) bgp-speaker-list-on-dragent dbd9900e-9d16-444d-afc4-8d0035df5ed5 104 | 105 | (neutron) 106 | 107 | ReST API's for neutron-dynamic-routing scheduler are defined as part of the 108 | `Neutron API reference`_. 109 | 110 | .. _Neutron API reference: https://docs.openstack.org/api-ref/network/#bgp-dynamic-routing 111 | 112 | ChanceScheduler 113 | ~~~~~~~~~~~~~~~ 114 | 115 | This is the default option. It will automatically schedule newly created BGP 116 | speakers to one of the active DRAgents. When a DRAgent goes down, the BGP 117 | speaker will be disassociated from it and an attempt is made to schedule 118 | it to a different agent. Note that this action will override any manual 119 | associations that have been performed via the API, so you will want to use 120 | this scheduler only in very basic deployments. 121 | 122 | Sample configuration:: 123 | 124 | bgp_drscheduler_driver = neutron_dynamic_routing.services.bgp.scheduler.bgp_dragent_scheduler.ChanceScheduler 125 | 126 | -------------------------------------------------------------------------------- /doc/source/admin/bgp-speaker.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | BGP Speaker 26 | =========== 27 | BGP Speaker acts as a route server using BGP routing protocol. It advertises 28 | routes to the BGP peers which are added to the BGP Speaker. Now there is a 29 | framework that allows different `BGP drivers <../contributor/dragent-drivers.html>`_ 30 | to be plugged into a `dynamic routing agent <./agent-scheduler.html>`_. 31 | 32 | Currently, BGP Speaker only advertises routes for a network to which it is associated. 33 | A BGP Speaker requires association with a "gateway" network to determine eligible routes. 34 | In Neutron, a "gateway" network connects Neutron routers to the upstream routers. An 35 | external network is best for being used as a gateway network. The association builds a 36 | list of all virtual routers with gateways on provider and self-service networks within 37 | the same address scope. Hence, the BGP speaker advertises self-service network prefixes 38 | with the corresponding router as the next-hop IP address. 39 | For details refer to `Route advertisement <./route-advertisement.html>`_. 40 | 41 | Address Scopes 42 | -------------- 43 | `Address scopes `_ 44 | provide flexible control as well as decoupling of address overlap from tenancy, 45 | so this kind control can provide a routable domain, the domain has itself route 46 | and no overlap address, it means an address scope define "a L3 routing domain". 47 | 48 | BGP Speaker will associate the external networks and advertise the tenant's 49 | networks routes. Those networks should reside in the same address scope. 50 | Neutron can route the tenant network directly without NAT. Then Neutron can 51 | host globally routable IPv4 and IPv6 tenant networks. For determining which 52 | tenant networks prefixes should be advertised, Neutron will identify all routers 53 | with gateway ports on the network which had been bounded with BGP Speaker, 54 | check the address scope of the subnets on all connected networks, then begin 55 | advertising nexthops for all tenant networks to routers on the bound network. 56 | 57 | BGP Peer 58 | -------- 59 | BGP peer defined in Neutron represents real BGP infrastructure such as 60 | routers, route reflectors and route servers. When a BGP peer is defined and 61 | associated with a BGP Speaker, Neutron will attempt to open a BGP peering 62 | session with the mentioned remote peer. It is this session, using which Neutron 63 | announces it's routes. 64 | 65 | How to configure a remote peer 66 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | A remote peer can be real or virtual e.g. vRouters or real routers. 68 | The remote peer should be configured to handle peering with Neutron in passive 69 | mode. The peer needs to waits for the Neutron dynamic routing agent to 70 | initiate the peering session. Also, the remote peer can be configured in active 71 | mode, but it still can speak BGP until the complete initialization of BGP Speaker 72 | running on Neutron dynamic routing agent. 73 | 74 | Configuring BGP Speaker: 75 | One needs to ensure below points for setting a BGP connection. 76 | 77 | * Host running Neutron dynamic agent MUST connect to the external router. 78 | * BGP configuration on the router should be proper. 79 | 80 | ``bgp router-id XX.XX.XX.XX`` 81 | This must be an IP address, the unique identifier of BGP routers actually 82 | and can be virtual. If one doesn't configure the router-id, it will be selected 83 | automatically as the highest IP address configured for the local interfaces. 84 | Just a suggestion, please make sure that it is the same as the ``peer_ip`` 85 | which you configure in Neutron for distinguishing easily. 86 | 87 | ``local_as`` 88 | Autonomous System number can be same or different from the AS_id of external 89 | BGP router. AS_id will be same for iBGP and different for eBGP sessions. 90 | 91 | Setting BGP peer: 92 | :: 93 | 94 | neighbor A.B.C.D remote-as AS_ID 95 | A.B.C.D is the host IP which run Neutron dynamic routing agent. 96 | 97 | A Sample Quagga router configuration file forming BGP peering with Neutron: 98 | :: 99 | 100 | ! 101 | password zebra 102 | log file /var/log/quagga/bgpd.log 103 | ! 104 | debug bgp events 105 | debug bgp keepalives 106 | debug bgp updates 107 | debug bgp fsm 108 | debug bgp filters 109 | ! 110 | bgp multiple-instance 111 | ! 112 | router bgp view test-as 113 | bgp router-id 114 | neighbor remote-as 115 | neighbor passive 116 | ! 117 | line vty 118 | ! 119 | 120 | BGP Speaker Architecture 121 | ------------------------ 122 | Dynamic routing project saves BGP Speaker configuration as per the defined 123 | `data model `_. 124 | and pass on the configuration request to the dynamic routing agent for further processing. 125 | The implementation of a BGP Speaker is driver specific. During the driver interface 126 | initialization process, needed configurations are read from the configuration file 127 | and BGP Speaker object instance is created. For details refer to 128 | `BGP drivers <../contributor/dragent-drivers.html>`_. 129 | 130 | BGP Speaker Life Cycle 131 | ~~~~~~~~~~~~~~~~~~~~~~ 132 | Now we support OsKenBgpDriver, BGP Speaker will be processed by Dragent. When 133 | associating a BGP Speaker with an active Dragent, the plugin will send an RPC 134 | message to the agent for calling driver in order to create a BGP Speaker instance. 135 | 136 | In OsKenBgpDriver, the created instance ``BGP Speaker`` will setup by router-id 137 | and ASN, then os-ken will setup new context with speaker configuration and listeners 138 | which monitor whether the related peers are alive. 139 | 140 | Then the following operation could be done. 141 | 142 | * Add peers to BGP Speaker 143 | When BGP Speaker is not associated with an active Dragent, there is no real speaker 144 | instance, so it will be still the db operation until the speaker is associated with 145 | dragent, and all the peers connection before will be setup by ``BGP Speaker`` 146 | creation. If add peers into speaker which is running, Dragent will call driver 147 | to add peer dynamically. For OsKenBgpDriver, it will register a new neighbor 148 | based on your peer configuration and try to establish a session with the peer. 149 | 150 | * Delete peers from BGP Speaker 151 | The same logic with below, but it is reverse. 152 | 153 | If you don't want use the specific BGP Speaker anymore, you can use CLI: 154 | ``neutron bgp-speaker-delete `` 155 | 156 | BGP Plugin will find all the associated Dragent and send RPC ``bgp_speaker_remove_end`` 157 | to make the Dragents to clean the ``BGP Speaker`` instances. This is the same 158 | with CLI: 159 | ``neutron bgp-dragent-speaker-remove `` 160 | BGP Plugin just send rpc ``bgp_speaker_remove_end`` to the specific Dragent. 161 | 162 | Advertisement 163 | ~~~~~~~~~~~~~ 164 | For details refer to `Route Advertisement <./route-advertisement.html>`_. 165 | 166 | How to work 167 | ----------- 168 | For details refer to `Testing <../contributor/testing.html>`_. 169 | -------------------------------------------------------------------------------- /doc/source/admin/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | ==================== 26 | Administration Guide 27 | ==================== 28 | 29 | .. toctree:: 30 | :maxdepth: 2 31 | 32 | system-design 33 | bgp-speaker 34 | route-advertisement 35 | agent-scheduler 36 | -------------------------------------------------------------------------------- /doc/source/admin/route-advertisement.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | Route Advertisement 26 | =================== 27 | BGP 28 | --- 29 | 30 | This page discusses the behavior of BGP dynamic routing about how to advertise 31 | routes and show the routes details in the project. 32 | 33 | BGP dynamic routing could advertise 3 classes of routes: 34 | 35 | * Host routes for floating IP addresses hosted on non-DVR routers, as floatingip 36 | address set on the router namespace, it knows how to route the message to the 37 | correct way, so the next-hop should be the IP address of router gateway port. 38 | * Host routes for floating IP addresses hosted on DVR routers. With DVR-enabled 39 | routers, the floating IP can be reached directly on the compute node hosting 40 | a given instance. As such, host routes for the floating IP address should 41 | advertise the FIP agent gateway on the compute node as the next-hop instead of 42 | the centralized router. This will keep inbound floating IP traffic from 43 | encountering the bottleneck of the centralized router. 44 | * Prefix routes for directly routable tenant networks with address scopes, the 45 | nexthop is the centralized router, the same for DVR and CVR. BGP dynamic 46 | routing could advertise tenant network prefixes to physical network 47 | devices(routers which support BGP protocol), called this 48 | ``Prefixes advertisement``. 49 | 50 | When distributed virtual routing (DVR) is enabled on a router, next-hops for 51 | floating IP's and fixed IP's are not advertised as being at the centralized 52 | router. Host routes with the next-hop set to the appropriate compute node 53 | are advertised. 54 | 55 | Logical Model 56 | ~~~~~~~~~~~~~ 57 | :: 58 | 59 | +--------+ 1 N +---------------------+ 60 | | Router |---------| BgpAdvertisedRoute | 61 | +--------+ +---------------------+ 62 | | N 63 | | 64 | | 1 65 | +---------+ N N +------------+ N N +---------+ 66 | | BgpPeer |-----------| BgpSpeaker |-----------| Network | 67 | +---------+ +------------+ +---------+ 68 | | N 69 | | 70 | | 1 71 | +--------------+ 72 | | AddressScope | 73 | +--------------+ 74 | 75 | .. note:: 76 | A BGP Speaker only supports one address family to speak BGP. A dual-stack IPv4 77 | and IPv6 network needs two BGP Speakers to advertise the routes with BGP, one 78 | for IPv4 and the other for IPv6. So A network can have N number of BGP 79 | Speakers bound to it. 80 | 81 | BgpAdvertisedRoute represents derived data. As the number of 82 | BgpAdvertisedRoutes can be quite large, storing in a database table is not 83 | feasible. BgpAdvertisedRoute information can be derived by joining data 84 | already available in the Neutron database. And now BGP dynamic routing project 85 | process the Bgpadvertiseroutes which should be advertised to external Router is 86 | basing on the exist Neutron DB tables. 87 | Neutron looks on each of the gateway network for any routers with a gateway port 88 | on that network. For each router identified, Neutron locates each floating IP 89 | and tenant network accessible through the router gateway port. Neutron then 90 | advertises each floating IP and tenant network with the IP address of the router 91 | gateway port as the next hop. 92 | 93 | When BGP Plugin is started, it will register callbacks. All callbacks are used for 94 | processing Floating IP, Router Interface and Router Gateway creation or update, this 95 | functions listen the events of these resources for calling Dragent to change the 96 | advertisement routes. 97 | 98 | Now we just focus on the resources which may cause route change, the following 99 | callbacks does this work. 100 | 101 | * floatingip_update_callback 102 | This function listens to the Floating IP's AFTER_UPDATE event, it judges whether 103 | the associated router is changed, and changes the advertisement routes and nexthop 104 | based on that. 105 | * router_interface_callback 106 | This function listens to the tenants' network routes change, it listens to AFTER_CREATE 107 | and AFTER_DELETE events of Router Interface resource. It calls Dragent to advertise 108 | or stop the prefix routes after a interface attach into a router. 109 | * router_gateway_callback 110 | This function listens to the router gateway port creation or deletion. It also focuses 111 | on tenants' network routes change. 112 | 113 | You could get the advertisement routes of specific BGP Speaker like: 114 | ``neutron bgp-speaker-advertiseroute-list `` 115 | It does a complicated db query to generate the list of advertised routes. 116 | For more details refer to `route advertisement db lookup `_ 117 | -------------------------------------------------------------------------------- /doc/source/admin/system-design.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | System Design 26 | ============= 27 | 28 | Introduction 29 | ------------ 30 | Neutron dynamic routing enables advertisement of self-service (private) network 31 | prefixes to physical network devices that support dynamic routing protocols 32 | such as routers, thus removing the conventional dependency on static routes. 33 | 34 | It advertises three classes of routes: 35 | 36 | * Host routes for floating IP addresses hosted on non-DVR routers, the nexthop is 37 | the centralized router. 38 | * Host routes for floating IP addresses hosted on DVR routers, the nexthop is 39 | the appropriate compute node. 40 | * Prefix routes for directly routable tenant networks with address scopes, the 41 | nexthop is the centralized router, the same for DVR and CVR. 42 | 43 | For details refer to `Route Advertisement <./route-advertisement.html>`_. 44 | 45 | Neutron dynamic routing consists of `service plug-in `_ 46 | and agent. The service plug-in implements the Networking service extension and 47 | the agent manages dynamic routing protocol peering sessions. The plug-in communicates 48 | with the agent through RPC. 49 | 50 | Architecture 51 | ------------ 52 | The following figure shows the architecture of this feature:: 53 | 54 | Neutron dynamic Routing System Architecture 55 | +---------------------------------------------------------------+ 56 | | Dynamic Routing plug-in | 57 | | +---------------------------------------------------------+ | 58 | | | Dynamic Routing API/Model | | 59 | | +---------------------------------------------------------+ | 60 | | | Dynamic Routing Agent Scheduler | | 61 | | +---------------------------------------------------------+ | 62 | | | | 63 | +------------------------------|--------------------------------+ 64 | | 65 | | 66 | +-----------+ 67 | | RPC | 68 | +-----------+ 69 | | 70 | | 71 | +----------------------|-------------------------+ 72 | | | 73 | | | 74 | +---------------------------+ +---------------------------+ 75 | | Dynamic Routing Agent1 | | Dynamic Routing Agent2 | 76 | | | | | 77 | | +---------------------+ | | +---------------------+ | 78 | | | Driver Manager | | | | Driver Manager | | 79 | | +---------------------+ | | +---------------------+ | 80 | | | Common Driver API | | | | Common Driver API | | 81 | | +---------------------+ | | +---------------------+ | 82 | | | | | | | 83 | | +---------+-----------+ | | +---------+-----------+ | 84 | | | os-ken | Other | | | | os-ken | Other | | 85 | | | Driver | Drivers | | | | Driver | Drivers | | 86 | | +---------+-----------+ | | +---------+-----------+ | 87 | | | | | 88 | +---------------------------+ +---------------------------+ 89 | 90 | Dynamic Routing Plug-in 91 | ~~~~~~~~~~~~~~~~~~~~~~~ 92 | Using dynamic routing plugin one can enable/disable the support of dynamic routing protocols 93 | in neutron. 94 | 95 | Dynamic Routing API 96 | ~~~~~~~~~~~~~~~~~~~ 97 | Dynamic routing API provides APIs to configure dynamic routing. API's for below mentioned dynamic 98 | protocols are supported. 99 | 100 | BGP 101 | +++ 102 | Three kinds of APIs are available for BGP functionality.For details refer to the 103 | `API document <../reference/index.html>`_. 104 | 105 | * BGP Speaker APIs to advertise Neutron routes outside the Openstack network. 106 | * BGP Peer APIs to form peers with the remote routers. 107 | * BGP DRAgentScheduler APIs to schedule BGP Speaker(s) to one or more hosts running the 108 | dynamic routing agent. 109 | 110 | .. note:: 111 | BGP is the only dynamic routing protocol currently supported. 112 | 113 | Dynamic Routing Model 114 | ~~~~~~~~~~~~~~~~~~~~~ 115 | Dynamic routing model maintains the database and communicates with the dynamic routing agent. 116 | 117 | Dynamic Routing Agent Scheduler 118 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 119 | Dynamic routing agent scheduler, is responsible for scheduling a routing entity. For details refer 120 | to `Agent Scheduler <./agent-scheduler.html>`_. 121 | 122 | Dynamic Routing Agent (DR Agent) 123 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 124 | Dynamic routing can reside on hosts with or without other Networking service agents. 125 | It manages and configures different dynamic routing stack through 126 | `Common Driver API <../contributor/dragent-drivers.html>`_. 127 | 128 | .. note:: 129 | Currently, only integration with `os-ken `_ 130 | is supported. 131 | -------------------------------------------------------------------------------- /doc/source/cli/bgp-peer.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | BGP Peer 3 | ======== 4 | 5 | BGP Peer Create 6 | --------------- 7 | 8 | .. code-block:: console 9 | 10 | usage: neutron bgp-peer-create [-h] 11 | [-f {html,json,json,shell,table,value,yaml,yaml}] 12 | [-c COLUMN] [--max-width ] 13 | [--noindent] [--prefix PREFIX] 14 | [--request-format {json}] 15 | [--tenant-id TENANT_ID] --peer-ip 16 | PEER_IP_ADDRESS --remote-as PEER_REMOTE_AS 17 | [--auth-type PEER_AUTH_TYPE] 18 | [--password AUTH_PASSWORD] 19 | NAME 20 | 21 | Create a BGP Peer. 22 | 23 | **Positional arguments:** 24 | 25 | ``NAME`` 26 | Name of the BGP peer to create 27 | 28 | ``--peer-ip PEER_IP_ADDRESS`` 29 | Peer IP address. 30 | 31 | ``--remote-as PEER_REMOTE_AS`` 32 | Peer AS number. (Integer in [1, 65535] is allowed.) 33 | 34 | **Optional arguments:** 35 | 36 | ``-h, --help`` 37 | show this help message and exit 38 | 39 | ``--auth-type PEER_AUTH_TYPE`` 40 | Authentication algorithm. Supported algorithms: 41 | none(default), md5 42 | 43 | ``--password AUTH_PASSWORD`` 44 | Authentication password. 45 | 46 | BGP Peer List 47 | ------------- 48 | 49 | .. code-block:: console 50 | 51 | usage: neutron bgp-peer-list [-h] 52 | [-f {csv,html,json,json,table,value,yaml,yaml}] 53 | [-c COLUMN] [--max-width ] [--noindent] 54 | [--quote {all,minimal,none,nonnumeric}] 55 | [--request-format {json}] [-D] [-F FIELD] 56 | [-P SIZE] [--sort-key FIELD] 57 | [--sort-dir {asc,desc}] 58 | 59 | List BGP peers. 60 | 61 | **Optional arguments:** 62 | 63 | ``-h, --help`` 64 | show this help message and exit 65 | 66 | ``-D, --show-details`` 67 | Show detailed information. 68 | 69 | ``-F FIELD, --field FIELD`` 70 | Specify the field(s) to be returned by server. You can 71 | repeat this option. 72 | 73 | BGP Peer Show 74 | ------------- 75 | 76 | .. code-block:: console 77 | 78 | usage: neutron bgp-peer-show [-h] 79 | [-f {html,json,json,shell,table,value,yaml,yaml}] 80 | [-c COLUMN] [--max-width ] [--noindent] 81 | [--prefix PREFIX] [--request-format {json}] [-D] 82 | [-F FIELD] 83 | BGP_PEER 84 | 85 | Show information of a given BGP peer. 86 | 87 | **Positional arguments:** 88 | 89 | ``BGP_PEER`` 90 | ID or name of the BGP peer to look up. 91 | 92 | **Optional arguments:** 93 | 94 | ``-h, --help`` 95 | show this help message and exit 96 | 97 | ``-D, --show-details`` 98 | Show detailed information. 99 | 100 | ``-F FIELD, --field FIELD`` 101 | Specify the field(s) to be returned by server. You can 102 | repeat this option. 103 | 104 | BGP Peer Delete 105 | --------------- 106 | 107 | .. code-block:: console 108 | 109 | usage: neutron bgp-peer-delete [-h] [--request-format {json}] BGP_PEER 110 | 111 | Delete a BGP peer. 112 | 113 | **Positional arguments:** 114 | 115 | ``BGP_PEER`` 116 | ID or name of the BGP peer to delete. 117 | 118 | **Optional arguments:** 119 | 120 | ``-h, --help`` 121 | show this help message and exit 122 | 123 | BGP Peer Update 124 | --------------- 125 | 126 | .. code-block:: console 127 | 128 | usage: neutron bgp-peer-update [-h] [--request-format {json}] [--name NAME] 129 | [--password AUTH_PASSWORD] 130 | BGP_PEER 131 | 132 | Update BGP Peer's information. 133 | 134 | **Positional arguments:** 135 | 136 | ``BGP_PEER`` 137 | ID or name of the BGP peer to update. 138 | 139 | **Optional arguments:** 140 | 141 | ``-h, --help`` 142 | show this help message and exit 143 | 144 | ``--name NAME`` 145 | Updated name of the BGP peer. 146 | 147 | ``--password AUTH_PASSWORD`` 148 | Updated authentication password. 149 | 150 | Add Peer to BGP Speaker 151 | ----------------------- 152 | 153 | .. code-block:: console 154 | 155 | usage: neutron bgp-speaker-peer-add [-h] [--request-format {json}] 156 | BGP_SPEAKER BGP_PEER 157 | 158 | Add a peer to the BGP speaker. 159 | 160 | **Positional arguments:** 161 | 162 | ``BGP_SPEAKER`` 163 | ID or name of the BGP speaker. 164 | 165 | ``BGP_PEER`` 166 | ID or name of the BGP peer to add. 167 | 168 | **Optional arguments:** 169 | 170 | ``-h, --help`` 171 | show this help message and exit 172 | 173 | Delete Peer from BGP Speaker 174 | ---------------------------- 175 | 176 | .. code-block:: console 177 | 178 | usage: neutron bgp-speaker-peer-remove [-h] [--request-format {json}] 179 | BGP_SPEAKER BGP_PEER 180 | 181 | Remove a peer from the BGP speaker. 182 | 183 | **Positional arguments:** 184 | 185 | ``BGP_SPEAKER`` 186 | ID or name of the BGP speaker. 187 | 188 | ``BGP_PEER`` 189 | ID or name of the BGP peer to remove. 190 | 191 | **Optional arguments:** 192 | 193 | ``-h, --help`` 194 | show this help message and exit 195 | -------------------------------------------------------------------------------- /doc/source/cli/bgp-speaker.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | BGP Speaker 3 | =========== 4 | 5 | BGP Speaker Create 6 | ------------------ 7 | 8 | .. code-block:: console 9 | 10 | usage: neutron bgp-speaker-create [-h] 11 | [-f {html,json,json,shell,table,value,yaml,yaml}] 12 | [-c COLUMN] [--max-width ] 13 | [--noindent] [--prefix PREFIX] 14 | [--request-format {json}] 15 | [--tenant-id TENANT_ID] --local-as LOCAL_AS 16 | [--ip-version {4,6}] 17 | [--advertise-floating-ip-host-routes {True,False}] 18 | [--advertise-tenant-networks {True,False}] 19 | NAME 20 | 21 | Create a BGP Speaker with a specified NAME. 22 | 23 | **Positional arguments:** 24 | 25 | ``NAME`` 26 | Name of the BGP speaker to create. 27 | 28 | **Optional arguments:** 29 | 30 | ``-h, --help`` 31 | show this help message and exit 32 | 33 | ``--local-as LOCAL_AS`` 34 | Local AS number. (Integer in [1, 65535] is allowed.) 35 | 36 | ``--ip-version {4,6}`` 37 | IP version for the BGP speaker (default is 4) 38 | 39 | ``--advertise-floating-ip-host-routes {True,False}`` 40 | Whether to enable or disable the advertisement of 41 | floating-ip host routes by the BGP speaker. By default 42 | floating ip host routes will be advertised by the BGP 43 | speaker. 44 | 45 | ``--advertise-tenant-networks {True,False}`` 46 | Whether to enable or disable the advertisement of 47 | tenant network routes by the BGP speaker. By default 48 | tenant network routes will be advertised by the BGP 49 | speaker. 50 | 51 | BGP Speaker List 52 | ---------------- 53 | 54 | .. code-block:: console 55 | 56 | usage: neutron bgp-speaker-list [-h] 57 | [-f {csv,html,json,json,table,value,yaml,yaml}] 58 | [-c COLUMN] [--max-width ] 59 | [--noindent] 60 | [--quote {all,minimal,none,nonnumeric}] 61 | [--request-format {json}] [-D] [-F FIELD] 62 | [-P SIZE] [--sort-key FIELD] 63 | [--sort-dir {asc,desc}] 64 | 65 | List BGP speakers. 66 | 67 | **Optional arguments:** 68 | 69 | ``-h, --help`` 70 | show this help message and exit 71 | 72 | ``-D, --show-details`` 73 | Show detailed information. 74 | 75 | ``-F FIELD, --field FIELD`` 76 | Specify the field(s) to be returned by server. You can 77 | repeat this option. 78 | 79 | BGP Speaker Show 80 | ---------------- 81 | 82 | .. code-block:: console 83 | 84 | usage: neutron bgp-speaker-show [-h] 85 | [-f {html,json,json,shell,table,value,yaml,yaml}] 86 | [-c COLUMN] [--max-width ] 87 | [--noindent] [--prefix PREFIX] 88 | [--request-format {json}] [-D] [-F FIELD] 89 | BGP_SPEAKER 90 | 91 | Show information of a given BGP speaker. 92 | 93 | **Positional arguments:** 94 | 95 | ``BGP_SPEAKER`` 96 | ID or name of the BGP speaker to look up. 97 | 98 | **Optional arguments:** 99 | 100 | ``-h, --help`` 101 | show this help message and exit 102 | 103 | ``-D, --show-details`` 104 | Show detailed information. 105 | 106 | ``-F FIELD, --field FIELD`` 107 | Specify the field(s) to be returned by server. You can 108 | repeat this option. 109 | 110 | BGP Speaker Delete 111 | ------------------ 112 | 113 | .. code-block:: console 114 | 115 | usage: neutron bgp-speaker-delete [-h] [--request-format {json}] BGP_SPEAKER 116 | 117 | Delete a BGP speaker. 118 | 119 | **Positional arguments:** 120 | 121 | ``BGP_SPEAKER`` 122 | ID or name of the BGP speaker to delete. 123 | 124 | **Optional arguments:** 125 | 126 | ``-h, --help`` 127 | show this help message and exit 128 | 129 | BGP Speaker Update 130 | ------------------ 131 | 132 | .. code-block:: console 133 | 134 | usage: neutron bgp-speaker-update [-h] [--request-format {json}] [--name NAME] 135 | [--advertise-floating-ip-host-routes {True,False}] 136 | [--advertise-tenant-networks {True,False}] 137 | BGP_SPEAKER 138 | 139 | Update BGP Speaker's information. 140 | 141 | **Positional arguments:** 142 | 143 | ``BGP_SPEAKER`` 144 | ID or name of the BGP speaker to update. 145 | 146 | **Optional arguments:** 147 | 148 | ``-h, --help`` 149 | show this help message and exit 150 | 151 | ``--name NAME`` 152 | Name of the BGP speaker to update. 153 | 154 | ``--advertise-floating-ip-host-routes {True,False}`` 155 | Whether to enable or disable the advertisement of 156 | floating-ip host routes by the BGP speaker. By default 157 | floating ip host routes will be advertised by the BGP 158 | speaker. 159 | 160 | ``--advertise-tenant-networks {True,False}`` 161 | Whether to enable or disable the advertisement of 162 | tenant network routes by the BGP speaker. By default 163 | tenant network routes will be advertised by the BGP 164 | speaker. 165 | 166 | Add Network to BGP Speaker 167 | --------------------------- 168 | 169 | .. code-block:: console 170 | 171 | usage: neutron bgp-speaker-network-add [-h] [--request-format {json}] 172 | BGP_SPEAKER NETWORK 173 | 174 | Add a network to the BGP speaker. 175 | 176 | **Positional arguments:** 177 | 178 | ``BGP_SPEAKER`` 179 | ID or name of the BGP speaker. 180 | 181 | ``NETWORK`` 182 | ID or name of the network to add. 183 | 184 | **Optional arguments:** 185 | 186 | ``-h, --help`` 187 | show this help message and exit 188 | 189 | Delete Network from BGP Speaker 190 | ------------------------------- 191 | 192 | .. code-block:: console 193 | 194 | usage: neutron bgp-speaker-network-remove [-h] [--request-format {json}] 195 | BGP_SPEAKER NETWORK 196 | 197 | Remove a network from the BGP speaker. 198 | 199 | **Positional arguments:** 200 | 201 | ``BGP_SPEAKER`` 202 | ID or name of the BGP speaker. 203 | 204 | ``NETWORK`` 205 | ID or name of the network to remove. 206 | 207 | **Optional arguments:** 208 | 209 | ``-h, --help`` 210 | show this help message and exit 211 | 212 | BGP Advertised Routes List 213 | -------------------------- 214 | 215 | .. code-block:: console 216 | 217 | usage: neutron bgp-speaker-advertiseroute-list [-h] 218 | [-f {csv,html,json,json,table,value,yaml,yaml}] 219 | [-c COLUMN] 220 | [--max-width ] 221 | [--noindent] 222 | [--quote {all,minimal,none,nonnumeric}] 223 | [--request-format {json}] [-D] 224 | [-F FIELD] [-P SIZE] 225 | [--sort-key FIELD] 226 | [--sort-dir {asc,desc}] 227 | BGP_SPEAKER 228 | 229 | List routes advertised by a given BGP speaker. 230 | 231 | **Positional arguments:** 232 | 233 | ``BGP_SPEAKER`` 234 | ID or name of the BGP speaker. 235 | 236 | **Optional arguments:** 237 | 238 | ``-h, --help`` 239 | show this help message and exit 240 | 241 | ``-D, --show-details`` 242 | Show detailed information. 243 | 244 | ``-F FIELD, --field FIELD`` 245 | Specify the field(s) to be returned by server. You can 246 | repeat this option. 247 | -------------------------------------------------------------------------------- /doc/source/cli/dynamic-routing-agent.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | Dynamic Routing Agent 3 | ===================== 4 | 5 | Add BGP Speaker to Dynamic Routing Agent 6 | ---------------------------------------- 7 | 8 | .. code-block:: console 9 | 10 | usage: neutron bgp-dragent-speaker-add [-h] [--request-format {json}] 11 | BGP_DRAGENT_ID BGP_SPEAKER 12 | 13 | Add a BGP speaker to a Dynamic Routing agent. 14 | 15 | **Positional arguments:** 16 | 17 | ``BGP_DRAGENT_ID`` 18 | ID of the Dynamic Routing agent. 19 | 20 | ``BGP_SPEAKER`` 21 | ID or name of the BGP speaker. 22 | 23 | **Optional arguments:** 24 | 25 | ``-h, --help`` 26 | show this help message and exit 27 | 28 | Delete BGP Speaker from Dynamic Routing Agent 29 | --------------------------------------------- 30 | 31 | .. code-block:: console 32 | 33 | usage: neutron bgp-dragent-speaker-remove [-h] [--request-format {json}] 34 | BGP_DRAGENT_ID BGP_SPEAKER 35 | 36 | Removes a BGP speaker from a Dynamic Routing agent. 37 | 38 | **Positional arguments:** 39 | 40 | ``BGP_DRAGENT_ID`` 41 | ID of the Dynamic Routing agent. 42 | 43 | ``BGP_SPEAKER`` 44 | ID or name of the BGP speaker. 45 | 46 | **Optional arguments:** 47 | 48 | ``-h, --help`` 49 | show this help message and exit 50 | 51 | List BGP Speakers hosted by a Dynamic Routing Agent 52 | --------------------------------------------------- 53 | 54 | .. code-block:: console 55 | 56 | usage: neutron bgp-speaker-list-on-dragent [-h] 57 | [-f {csv,html,json,json,table,value,yaml,yaml}] 58 | [-c COLUMN] [--max-width ] 59 | [--noindent] 60 | [--quote {all,minimal,none,nonnumeric}] 61 | [--request-format {json}] [-D] 62 | [-F FIELD] 63 | BGP_DRAGENT_ID 64 | 65 | List BGP speakers hosted by a Dynamic Routing agent. 66 | 67 | **Positional arguments:** 68 | 69 | ``BGP_DRAGENT_ID`` 70 | ID of the Dynamic Routing agent. 71 | 72 | **Optional arguments:** 73 | 74 | ``-h, --help`` 75 | show this help message and exit 76 | 77 | ``-D, --show-details`` 78 | Show detailed information. 79 | 80 | ``-F FIELD, --field FIELD`` 81 | Specify the field(s) to be returned by server. You can 82 | repeat this option. 83 | 84 | List Dynamic Routing Agents Hosting a BGP Speaker 85 | ------------------------------------------------- 86 | 87 | .. code-block:: console 88 | 89 | usage: neutron bgp-dragent-list-hosting-speaker [-h] 90 | [-f {csv,html,json,json,table,value,yaml,yaml}] 91 | [-c COLUMN] 92 | [--max-width ] 93 | [--noindent] 94 | [--quote {all,minimal,none,nonnumeric}] 95 | [--request-format {json}] [-D] 96 | [-F FIELD] 97 | BGP_SPEAKER 98 | 99 | List Dynamic Routing agents hosting a BGP speaker. 100 | 101 | **Positional arguments:** 102 | 103 | ``BGP_SPEAKER`` 104 | ID or name of the BGP speaker. 105 | 106 | **Optional arguments:** 107 | 108 | ``-h, --help`` 109 | show this help message and exit 110 | 111 | ``-D, --show-details`` 112 | Show detailed information. 113 | 114 | ``-F FIELD, --field FIELD`` 115 | Specify the field(s) to be returned by server. You can 116 | repeat this option. 117 | -------------------------------------------------------------------------------- /doc/source/cli/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | Command-Line Interface 26 | ====================== 27 | 28 | Neutron client has provided the command-line interfaces (CLI) to realize dynamic routing 29 | services supported by neutron-dynamic-routing project. 30 | 31 | Current implementation only supports the command line interfaces for BGP functionality. 32 | For query on what specific :command:`neutron bgp` commands are supported, 33 | enter: 34 | 35 | .. code-block:: console 36 | 37 | $ neutron help | grep bgp 38 | 39 | .. toctree:: 40 | :maxdepth: 2 41 | :glob: 42 | 43 | * 44 | -------------------------------------------------------------------------------- /doc/source/conf.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 | # implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | import os 15 | import sys 16 | 17 | sys.path.insert(0, os.path.abspath('../..')) 18 | # -- General configuration ---------------------------------------------------- 19 | 20 | # Add any Sphinx extension module names here, as strings. They can be 21 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 22 | extensions = [ 23 | 'sphinx.ext.autodoc', 24 | #'sphinx.ext.intersphinx', 25 | 'openstackdocstheme', 26 | 'oslo_config.sphinxext', 27 | 'oslo_config.sphinxconfiggen', 28 | 'oslo_policy.sphinxext', 29 | 'oslo_policy.sphinxpolicygen', 30 | 'sphinxcontrib.rsvgconverter', 31 | ] 32 | 33 | # openstackdocstheme options 34 | openstackdocs_repo_name = 'openstack/neutron-dynamic-routing' 35 | openstackdocs_pdf_link = True 36 | openstackdocs_auto_name = False 37 | openstackdocs_bug_project = 'neutron' 38 | openstackdocs_bug_tag = 'doc' 39 | 40 | # autodoc generation is a bit aggressive and a nuisance when doing heavy 41 | # text edit cycles. 42 | # execute "export SPHINX_DEBUG=1" in your terminal to disable 43 | 44 | # The suffix of source filenames. 45 | source_suffix = '.rst' 46 | 47 | # The master toctree document. 48 | master_doc = 'index' 49 | 50 | # General information about the project. 51 | project = 'neutron-dynamic-routing' 52 | copyright = '2013, OpenStack Foundation' 53 | 54 | # If true, '()' will be appended to :func: etc. cross-reference text. 55 | add_function_parentheses = True 56 | 57 | # If true, the current module name will be prepended to all description 58 | # unit titles (such as .. function::). 59 | add_module_names = True 60 | 61 | # The name of the Pygments (syntax highlighting) style to use. 62 | pygments_style = 'native' 63 | 64 | # -- Options for HTML output -------------------------------------------------- 65 | 66 | # The theme to use for HTML and HTML Help pages. Major themes that come with 67 | # Sphinx are currently 'default' and 'sphinxdoc'. 68 | # html_theme_path = ["."] 69 | # html_theme = '_theme' 70 | html_theme = 'openstackdocs' 71 | html_static_path = ['_static'] 72 | 73 | 74 | # Output file base name for HTML help builder. 75 | htmlhelp_basename = '%sdoc' % project 76 | 77 | # -- Options for LaTeX output ------------------------------------------------- 78 | 79 | # Grouping the document tree into LaTeX files. List of tuples 80 | # (source start file, target name, title, author, documentclass 81 | # [howto/manual], torctree_only). 82 | latex_documents = [ 83 | ('index', 84 | 'doc-%s.tex' % project, 85 | '%s Documentation' % project, 86 | 'OpenStack Foundation', 'manual', 87 | # Specify toctree_only=True for a better document structure of 88 | # the generated PDF file. 89 | True), 90 | ] 91 | 92 | # Disable usage of xindy https://bugzilla.redhat.com/show_bug.cgi?id=1643664 93 | latex_use_xindy = False 94 | 95 | latex_domain_indices = False 96 | 97 | latex_elements = { 98 | 'makeindex': '', 99 | 'printindex': '', 100 | 'preamble': r'\setcounter{tocdepth}{3}', 101 | } 102 | 103 | # Example configuration for intersphinx: refer to the Python standard library. 104 | #intersphinx_mapping = {'http://docs.python.org/': None} 105 | 106 | # -- Options for oslo_config.sphinxconfiggen --------------------------------- 107 | 108 | _config_generator_config_files = [ 109 | 'bgp_dragent.ini', 110 | ] 111 | 112 | def _get_config_generator_config_definition(conf): 113 | config_file_path = '../../etc/oslo-config-generator/%s' % conf 114 | # oslo_config.sphinxconfiggen appends '.conf.sample' to the filename, 115 | # strip file extentension (.conf or .ini). 116 | output_file_path = '_static/config_samples/%s' % conf.rsplit('.', 1)[0] 117 | return (config_file_path, output_file_path) 118 | 119 | 120 | config_generator_config_file = [ 121 | _get_config_generator_config_definition(conf) 122 | for conf in _config_generator_config_files 123 | ] 124 | 125 | # -- Options for oslo_policy.sphinxpolicygen --------------------------------- 126 | 127 | policy_generator_config_file = '../../etc/oslo-policy-generator/policy.conf' 128 | sample_policy_basename = '_static/neutron-dynamic-routing' 129 | -------------------------------------------------------------------------------- /doc/source/configuration/bgp_dragent.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | bgp_dragent.ini 3 | =============== 4 | 5 | .. show-options:: 6 | :config-file: etc/oslo-config-generator/bgp_dragent.ini 7 | -------------------------------------------------------------------------------- /doc/source/configuration/index.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | Configuration Guide 3 | =================== 4 | 5 | Configuration 6 | ------------- 7 | 8 | This section provides a list of all possible options for each 9 | configuration file. 10 | 11 | neutron-dynamic-routing uses the following configuration files for its 12 | various services. 13 | 14 | .. toctree:: 15 | :maxdepth: 1 16 | 17 | bgp_dragent 18 | 19 | The following are sample configuration files for neutron-dynamic-routing. 20 | These are generated from code and reflect the current state of code 21 | in the neutron-dynamic-routing repository. 22 | 23 | .. toctree:: 24 | :glob: 25 | :maxdepth: 1 26 | 27 | samples/* 28 | 29 | Policy 30 | ------ 31 | 32 | neutron-dynamic-routing, like most OpenStack projects, uses a policy language 33 | to restrict permissions on REST API actions. 34 | 35 | .. toctree:: 36 | :maxdepth: 1 37 | 38 | Policy Reference 39 | Sample Policy File 40 | -------------------------------------------------------------------------------- /doc/source/configuration/policy-sample.rst: -------------------------------------------------------------------------------- 1 | ========================================== 2 | Sample neutron-dynamic-routing Policy File 3 | ========================================== 4 | 5 | The following is a sample neutron-dynamic-routing policy file for adaptation 6 | and use. 7 | 8 | The sample policy can also be viewed in :download:`file form 9 | `. 10 | 11 | .. important:: 12 | 13 | The sample policy file is auto-generated from neutron-dynamic-routing when 14 | this documentation is built. You must ensure your version of 15 | neutron-dynamic-routing matches the version of this documentation. 16 | 17 | .. literalinclude:: /_static/neutron-dynamic-routing.policy.yaml.sample 18 | -------------------------------------------------------------------------------- /doc/source/configuration/policy.rst: -------------------------------------------------------------------------------- 1 | ================================ 2 | neutron-dynamic-routing policies 3 | ================================ 4 | 5 | The following is an overview of all available policies in 6 | neutron-dynamic-routing. For a sample configuration file, 7 | refer to :doc:`/configuration/policy-sample`. 8 | 9 | .. show-policy:: 10 | :config-file: etc/oslo-policy-generator/policy.conf 11 | -------------------------------------------------------------------------------- /doc/source/configuration/samples/bgp_dragent.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Sample bgp_dragent.ini 3 | ====================== 4 | 5 | This sample configuration can also be viewed in `the raw format 6 | <../../_static/config_samples/bgp_dragent.conf.sample>`_. 7 | 8 | .. literalinclude:: ../../_static/config_samples/bgp_dragent.conf.sample 9 | -------------------------------------------------------------------------------- /doc/source/contributor/contributing.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | ============ 26 | Contributing 27 | ============ 28 | .. include:: ../../../CONTRIBUTING.rst 29 | -------------------------------------------------------------------------------- /doc/source/contributor/dragent-drivers.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | DRAgent Drivers 26 | =============== 27 | 28 | Introduction 29 | ------------ 30 | The Neutron dynamic routing drivers are used to support different dynamic 31 | routing protocol stacks which implement the dynamic routing functionality. 32 | 33 | As shown in the following figure, the drivers are managed by `DRAgent <./agent-scheduler.html>`_ 34 | through a "Driver Manager" which provides consistent APIs to realize the 35 | functionality of a dynamic routing protocol:: 36 | 37 | Neutron Dynamic Routing Drivers 38 | +-------------------------------+ 39 | | DRAgent | 40 | | | 41 | | +-------------------------+ | 42 | | | Driver Manager | | 43 | | +-------------------------+ | 44 | | | Common Driver API | | 45 | | +-------------------------+ | 46 | | | | 47 | | | | 48 | | +------------+------------+ | 49 | | | os-ken | Other | | 50 | | | Driver | Drivers | | 51 | | +------------+------------+ | 52 | | | 53 | +-------------------------------+ 54 | 55 | .. note:: 56 | Currently only the integration with os-ken is supported 57 | BGP is the only protocol supported. 58 | 59 | 60 | Configuration 61 | ------------- 62 | Driver configurations are done in a separate configuration file. 63 | 64 | BGP Driver 65 | ~~~~~~~~~~ 66 | There are two configuration parameters related to BGP which are specified in ``bgp_dragent.ini``. 67 | 68 | * bgp_speaker_driver, to define BGP speaker driver class. Default is os-ken 69 | (neutron_dynamic_routing.services.bgp.agent.driver.os_ken.driver.OsKenBgpDriver). 70 | * bgp_router_id, to define BGP identity (typically an IPv4 address). Default is 71 | a unique loopback interface IP address. 72 | 73 | Common Driver API 74 | ----------------- 75 | Common Driver API is needed to provide a generic and consistent interface 76 | to different drivers. Each driver need to implement the provided 77 | `base driver class `_. 78 | 79 | 80 | BGP 81 | ~~~ 82 | Following interfaces need to be implemented by a driver for realizing BGP 83 | functionality. 84 | 85 | +--------------------------------+-----------------------------------------+ 86 | |API name |Description | 87 | +================================+=========================================+ 88 | |add_bgp_speaker() |Add a BGP Speaker | 89 | +--------------------------------+-----------------------------------------+ 90 | |delete_bgp_speaker() |Delete a BGP speaker | 91 | +--------------------------------+-----------------------------------------+ 92 | |add_bgp_peer() |Add a BGP peer | 93 | +--------------------------------+-----------------------------------------+ 94 | |delete_bgp_peer() |Delete a BGP peer | 95 | +--------------------------------+-----------------------------------------+ 96 | |advertise_route() |Add a new prefix to advertise | 97 | +--------------------------------+-----------------------------------------+ 98 | |withdraw_route() |Withdraw an advertised prefix | 99 | +--------------------------------+-----------------------------------------+ 100 | |get_bgp_speaker_statistics() |Collect BGP Speaker statistics | 101 | +--------------------------------+-----------------------------------------+ 102 | |get_bgp_peer_statistics() |Collect BGP Peer statistics | 103 | +--------------------------------+-----------------------------------------+ 104 | -------------------------------------------------------------------------------- /doc/source/contributor/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | =============== 26 | Developer Guide 27 | =============== 28 | 29 | In the Developer Guide, you will find information on neutron-dynamic-routing 30 | lower level programming APIs. There are sections that cover the core pieces 31 | of neutron-dynamic-routing, including its API, command-lines, database, 32 | system-design, alembic-migration etc. There are also subsections that describe 33 | specific drivers inside neutron-dynamic-routing. Finally, the developer guide 34 | includes information about testing and supported functionalities as well. This 35 | documentation is generated by the Sphinx toolkit and lives in the source 36 | tree. 37 | 38 | .. toctree:: 39 | :maxdepth: 2 40 | 41 | contributing 42 | testing 43 | dragent-drivers 44 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | =================================================== 26 | Welcome to neutron-dynamic-routing's documentation! 27 | =================================================== 28 | 29 | .. NOTE(amotoki): toctree_only=False is specified in latex_documents 30 | in doc/source/conf.py to get a better structure of the PDF doc. 31 | This means the content of this file (index.rst) is NOT rendered 32 | in the generated PDF file. 33 | 34 | .. include:: ../../README.rst 35 | 36 | Contents 37 | ======== 38 | 39 | .. toctree:: 40 | :maxdepth: 2 41 | 42 | install/index 43 | admin/index 44 | configuration/index 45 | reference/index 46 | cli/index 47 | contributor/index 48 | install/usecase-ipv6 49 | 50 | Indices and tables 51 | ================== 52 | 53 | * :ref:`genindex` 54 | * :ref:`search` 55 | -------------------------------------------------------------------------------- /doc/source/install/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | ============ 26 | Installation 27 | ============ 28 | 29 | At the command line:: 30 | 31 | $ pip install neutron-dynamic-routing 32 | 33 | Or, if you have virtualenv wrapper installed:: 34 | 35 | $ mkvirtualenv neutron-dynamic-routing 36 | $ pip install neutron-dynamic-routing 37 | -------------------------------------------------------------------------------- /doc/source/reference/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2016 Huawei Technologies India Pvt Limited. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | 17 | Convention for heading levels in Neutron devref: 18 | ======= Heading 0 (reserved for the title in a document) 19 | ------- Heading 1 20 | ~~~~~~~ Heading 2 21 | +++++++ Heading 3 22 | ''''''' Heading 4 23 | (Avoid deeper levels because they do not render well.) 24 | 25 | API 26 | === 27 | 28 | The reference of the OpenStack neutron-dynamic-routing API is found at 29 | https://docs.openstack.org/api-ref/network/#bgp-dynamic-routing. 30 | -------------------------------------------------------------------------------- /etc/README.txt: -------------------------------------------------------------------------------- 1 | To generate the sample neutron-dynamic-routing configuration files and the 2 | sample policy file, run the following commands respectively from the top level 3 | of the neutron-dynamic-routing directory: 4 | 5 | tox -e genconfig 6 | tox -e genpolicy 7 | 8 | If a 'tox' environment is unavailable, then you can run the following commands 9 | instead to generate the configuration files and the policy file: 10 | 11 | ./tools/generate_config_file_samples.sh 12 | oslopolicy-sample-generator --config-file=etc/oslo-policy-generator/policy.conf 13 | -------------------------------------------------------------------------------- /etc/oslo-config-generator/bgp_dragent.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | output_file = etc/bgp_dragent.ini.sample 3 | wrap_width = 79 4 | 5 | namespace = bgp.agent 6 | namespace = oslo.log 7 | -------------------------------------------------------------------------------- /etc/oslo-policy-generator/policy.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | output_file = etc/policy.yaml.sample 3 | namespace = neutron-dynamic-routing 4 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2011 OpenStack Foundation 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import gettext 17 | 18 | 19 | gettext.install('neutron') 20 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/_i18n.py: -------------------------------------------------------------------------------- 1 | # All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | import oslo_i18n 16 | 17 | DOMAIN = "neutron_dynamic_routing" 18 | 19 | _translators = oslo_i18n.TranslatorFactory(domain=DOMAIN) 20 | 21 | # The primary translation function using the well-known name "_" 22 | _ = _translators.primary 23 | 24 | # The contextual translation function using the name "_C" 25 | _C = _translators.contextual_form 26 | 27 | # The plural translation function using the name "_P" 28 | _P = _translators.plural_form 29 | 30 | # Translators for log levels. 31 | # 32 | # The abbreviated names are meant to reflect the usual use of a short 33 | # name like '_'. The "L" is for "log" and the other letter comes from 34 | # the level. 35 | _LI = _translators.log_info 36 | _LW = _translators.log_warning 37 | _LE = _translators.log_error 38 | _LC = _translators.log_critical 39 | 40 | 41 | def get_available_languages(): 42 | return oslo_i18n.get_available_languages(DOMAIN) 43 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/api/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/api/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/api/rpc/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/api/rpc/agentnotifiers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/api/rpc/agentnotifiers/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/api/rpc/agentnotifiers/bgp_dr_rpc_agent_api.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from neutron_lib import rpc as n_rpc 17 | import oslo_messaging 18 | 19 | from neutron_dynamic_routing.services.bgp.common import constants as bgp_consts 20 | 21 | 22 | class BgpDrAgentNotifyApi: 23 | """API for plugin to notify BGP DrAgent. 24 | 25 | This class implements the client side of an rpc interface. The server side 26 | is neutron_dynamic_routing.services.bgp.agent.bgp_dragent.BgpDrAgent. For 27 | more information about rpc interfaces, please see 28 | https://docs.openstack.org/neutron/latest/contributor/internals/rpc_api.html. 29 | """ 30 | 31 | def __init__(self, topic=bgp_consts.BGP_DRAGENT): 32 | target = oslo_messaging.Target(topic=topic, version='1.0') 33 | self.client = n_rpc.get_client(target) 34 | self.topic = topic 35 | 36 | def agent_updated(self, context, admin_state_up, host): 37 | """Tell BgpDrAgent that agent was updated. 38 | 39 | This effectively tells the bgp_dragent to resync. 40 | """ 41 | self._notification_host_cast( 42 | context, 'agent_updated', 43 | {'admin_state_up': admin_state_up}, host) 44 | 45 | def bgp_routes_advertisement(self, context, bgp_speaker_id, 46 | routes, host): 47 | """Tell BgpDrAgent to begin advertising the given route. 48 | 49 | Invoked on FIP association, adding router port to a tenant network, 50 | and new DVR port-host bindings, and subnet creation(?). 51 | """ 52 | self._notification_host_cast( 53 | context, 'bgp_routes_advertisement_end', 54 | {'advertise_routes': {'speaker_id': bgp_speaker_id, 55 | 'routes': routes}}, host) 56 | 57 | def bgp_routes_withdrawal(self, context, bgp_speaker_id, 58 | routes, host): 59 | """Tell BgpDrAgent to stop advertising the given route. 60 | 61 | Invoked on FIP disassociation, removal of a router port on a 62 | network, and removal of DVR port-host binding, and subnet delete(?). 63 | """ 64 | self._notification_host_cast( 65 | context, 'bgp_routes_withdrawal_end', 66 | {'withdraw_routes': {'speaker_id': bgp_speaker_id, 67 | 'routes': routes}}, host) 68 | 69 | def bgp_peer_disassociated(self, context, bgp_speaker_id, 70 | bgp_peer_ip, host): 71 | """Tell BgpDrAgent about a BGP Peer disassociation. 72 | 73 | This effectively tells the BgpDrAgent to stop a peering session. 74 | """ 75 | self._notification_host_cast( 76 | context, 'bgp_peer_disassociation_end', 77 | {'bgp_peer': {'speaker_id': bgp_speaker_id, 78 | 'peer_ip': bgp_peer_ip}}, host) 79 | 80 | def bgp_peer_associated(self, context, bgp_speaker_id, 81 | bgp_peer_id, host): 82 | """Tell BgpDrAgent about a new BGP Peer association. 83 | 84 | This effectively tells the bgp_dragent to open a peering session. 85 | """ 86 | self._notification_host_cast( 87 | context, 'bgp_peer_association_end', 88 | {'bgp_peer': {'speaker_id': bgp_speaker_id, 89 | 'peer_id': bgp_peer_id}}, host) 90 | 91 | def bgp_speaker_created(self, context, bgp_speaker_id, host): 92 | """Tell BgpDrAgent about the creation of a BGP Speaker. 93 | 94 | Because a BGP Speaker can be created with BgpPeer binding in place, 95 | we need to inform the BgpDrAgent of a new BGP Speaker in case a 96 | peering session needs to opened immediately. 97 | """ 98 | self._notification_host_cast( 99 | context, 'bgp_speaker_create_end', 100 | {'bgp_speaker': {'id': bgp_speaker_id}}, host) 101 | 102 | def bgp_speaker_removed(self, context, bgp_speaker_id, host): 103 | """Tell BgpDrAgent about the removal of a BGP Speaker. 104 | 105 | Because a BGP Speaker can be removed with BGP Peer binding in 106 | place, we need to inform the BgpDrAgent of the removal of a 107 | BGP Speaker in case peering sessions need to be stopped. 108 | """ 109 | self._notification_host_cast( 110 | context, 'bgp_speaker_remove_end', 111 | {'bgp_speaker': {'id': bgp_speaker_id}}, host) 112 | 113 | def _notification_host_cast(self, context, method, payload, host): 114 | """Send payload to BgpDrAgent in the cast mode""" 115 | cctxt = self.client.prepare(topic=self.topic, server=host) 116 | cctxt.cast(context, method, payload=payload) 117 | 118 | def _notification_host_call(self, context, method, payload, host): 119 | """Send payload to BgpDrAgent in the call mode""" 120 | cctxt = self.client.prepare(topic=self.topic, server=host) 121 | cctxt.call(context, method, payload=payload) 122 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/api/rpc/callbacks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/api/rpc/callbacks/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/api/rpc/callbacks/resources.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | BGP_SPEAKER = 'bgp_speaker' 14 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/api/rpc/handlers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/api/rpc/handlers/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/api/rpc/handlers/bgp_speaker_rpc.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from neutron_lib.api.definitions import bgp as bgp_ext 17 | from neutron_lib.plugins import directory 18 | import oslo_messaging 19 | 20 | 21 | class BgpSpeakerRpcCallback: 22 | """BgpDrAgent RPC callback in plugin implementations. 23 | 24 | This class implements the server side of an RPC interface. 25 | The client side of this interface can be found in 26 | neutron_dynamic_routing.services.bgp.agent.bgp_dragent.BgpDrPluginApi. 27 | For more information about changing RPC interfaces, 28 | see https://docs.openstack.org/neutron/latest/ 29 | contributor/internals/rpc_api.html. 30 | """ 31 | 32 | # API version history: 33 | # 1.0 BGPDRPluginApi BASE_RPC_API_VERSION 34 | target = oslo_messaging.Target(version='1.0') 35 | 36 | @property 37 | def plugin(self): 38 | if not hasattr(self, '_plugin'): 39 | self._plugin = directory.get_plugin(bgp_ext.ALIAS) 40 | return self._plugin 41 | 42 | def get_bgp_speaker_info(self, context, bgp_speaker_id): 43 | """Return BGP Speaker details such as peer list and local_as. 44 | 45 | Invoked by the BgpDrAgent to lookup the details of a BGP Speaker. 46 | """ 47 | return self.plugin.get_bgp_speaker_with_advertised_routes( 48 | context, bgp_speaker_id) 49 | 50 | def get_bgp_peer_info(self, context, bgp_peer_id): 51 | """Return BgpPeer details such as IP, remote_as, and credentials. 52 | 53 | Invoked by the BgpDrAgent to lookup the details of a BGP peer. 54 | """ 55 | return self.plugin.get_bgp_peer(context, bgp_peer_id, 56 | ['peer_ip', 'remote_as', 57 | 'auth_type', 'password']) 58 | 59 | def get_bgp_speakers(self, context, host=None, **kwargs): 60 | """Returns the list of all BgpSpeakers. 61 | 62 | Typically invoked by the BgpDrAgent as part of its bootstrap process. 63 | """ 64 | return self.plugin.get_bgp_speakers_for_agent_host(context, host) 65 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/cmd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/cmd/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/cmd/eventlet/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | from neutron.common import eventlet_utils 14 | eventlet_utils.monkey_patch() 15 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/cmd/eventlet/agents/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/cmd/eventlet/agents/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/cmd/eventlet/agents/bgp_dragent.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from neutron_dynamic_routing.services.bgp.agent import entry as bgp_dragent 17 | 18 | 19 | def main(): 20 | bgp_dragent.main() 21 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/db/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/README: -------------------------------------------------------------------------------- 1 | For details refer to: 2 | https://docs.openstack.org/neutron/latest/contributor/alembic_migrations.html#independent-sub-project-tables 3 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/db/migration/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/db/migration/alembic_migrations/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/env.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt Limited. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from logging import config as logging_config 16 | 17 | from alembic import context 18 | from neutron_lib.db import model_base 19 | from oslo_config import cfg 20 | from oslo_db.sqlalchemy import session 21 | import sqlalchemy as sa 22 | from sqlalchemy import event 23 | 24 | from neutron_dynamic_routing.db.migration.models import head # noqa 25 | 26 | 27 | MYSQL_ENGINE = None 28 | DR_VERSION_TABLE = 'alembic_version_dr' 29 | config = context.config 30 | neutron_config = config.neutron_config 31 | logging_config.fileConfig(config.config_file_name) 32 | target_metadata = model_base.BASEV2.metadata 33 | 34 | 35 | def set_mysql_engine(): 36 | try: 37 | mysql_engine = neutron_config.command.mysql_engine 38 | except cfg.NoSuchOptError: 39 | mysql_engine = None 40 | 41 | global MYSQL_ENGINE 42 | MYSQL_ENGINE = (mysql_engine or 43 | model_base.BASEV2.__table_args__['mysql_engine']) 44 | 45 | 46 | def run_migrations_offline(): 47 | set_mysql_engine() 48 | 49 | kwargs = dict() 50 | if neutron_config.database.connection: 51 | kwargs['url'] = neutron_config.database.connection 52 | else: 53 | kwargs['dialect_name'] = neutron_config.database.engine 54 | kwargs['version_table'] = DR_VERSION_TABLE 55 | context.configure(**kwargs) 56 | 57 | with context.begin_transaction(): 58 | context.run_migrations() 59 | 60 | 61 | @event.listens_for(sa.Table, 'after_parent_attach') 62 | def set_storage_engine(target, parent): 63 | if MYSQL_ENGINE: 64 | target.kwargs['mysql_engine'] = MYSQL_ENGINE 65 | 66 | 67 | def run_migrations_online(): 68 | set_mysql_engine() 69 | engine = session.create_engine(neutron_config.database.connection) 70 | 71 | connection = engine.connect() 72 | context.configure( 73 | connection=connection, 74 | target_metadata=target_metadata, 75 | version_table=DR_VERSION_TABLE 76 | ) 77 | try: 78 | with context.begin_transaction(): 79 | context.run_migrations() 80 | finally: 81 | connection.close() 82 | engine.dispose() 83 | 84 | 85 | if context.is_offline_mode(): 86 | run_migrations_offline() 87 | else: 88 | run_migrations_online() 89 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt Limited. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | # 15 | 16 | """${message} 17 | 18 | Revision ID: ${up_revision} 19 | Revises: ${down_revision} 20 | Create Date: ${create_date} 21 | 22 | """ 23 | 24 | # revision identifiers, used by Alembic. 25 | revision = ${repr(up_revision)} 26 | down_revision = ${repr(down_revision)} 27 | % if branch_labels: 28 | branch_labels = ${repr(branch_labels)} 29 | %endif 30 | 31 | from alembic import op 32 | import sqlalchemy as sa 33 | ${imports if imports else ""} 34 | 35 | def upgrade(): 36 | ${upgrades if upgrades else "pass"} 37 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/versions/CONTRACT_HEAD: -------------------------------------------------------------------------------- 1 | a589fdb5724c 2 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/versions/EXPAND_HEAD: -------------------------------------------------------------------------------- 1 | f399fa0f5f25 2 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/versions/newton/contract/4cf8bc3edb66_rename_tenant_to_project.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | # 13 | 14 | """rename tenant to project 15 | 16 | Revision ID: 4cf8bc3edb66 17 | Revises: 61cc795e43e8 18 | Create Date: 2016-07-14 17:32:00.852342 19 | 20 | """ 21 | 22 | from alembic import op 23 | import sqlalchemy as sa 24 | from sqlalchemy.engine import reflection 25 | 26 | from neutron.db import migration 27 | 28 | 29 | # revision identifiers, used by Alembic. 30 | revision = '4cf8bc3edb66' 31 | down_revision = '61cc795e43e8' 32 | 33 | # milestone identifier, used by neutron-db-manage 34 | neutron_milestone = [migration.NEWTON] 35 | 36 | _INSPECTOR = None 37 | 38 | 39 | def get_inspector(): 40 | """Reuse inspector""" 41 | 42 | global _INSPECTOR 43 | 44 | if _INSPECTOR: 45 | return _INSPECTOR 46 | 47 | bind = op.get_bind() 48 | _INSPECTOR = reflection.Inspector.from_engine(bind) 49 | return _INSPECTOR 50 | 51 | 52 | def get_tables(): 53 | """ 54 | Returns hardcoded list of tables which have ``tenant_id`` column. 55 | 56 | The list is hardcoded to match the state of the schema when this 57 | upgrade script is run. 58 | """ 59 | 60 | tables = [ 61 | 'bgp_peers', 62 | 'bgp_speakers', 63 | ] 64 | 65 | return tables 66 | 67 | 68 | def get_columns(table): 69 | """Returns list of columns for given table.""" 70 | inspector = get_inspector() 71 | return inspector.get_columns(table) 72 | 73 | 74 | def get_data(): 75 | """Returns combined list of tuples: [(table, column)]. 76 | 77 | The list is built from tables with a tenant_id column. 78 | """ 79 | 80 | output = [] 81 | tables = get_tables() 82 | for table in tables: 83 | columns = get_columns(table) 84 | 85 | for column in columns: 86 | if column['name'] == 'tenant_id': 87 | output.append((table, column)) 88 | 89 | return output 90 | 91 | 92 | def alter_column(table, column): 93 | old_name = 'tenant_id' 94 | new_name = 'project_id' 95 | 96 | op.alter_column( 97 | table_name=table, 98 | column_name=old_name, 99 | new_column_name=new_name, 100 | existing_type=column['type'], 101 | existing_nullable=column['nullable'] 102 | ) 103 | 104 | 105 | def recreate_index(index, table_name): 106 | old_name = index['name'] 107 | new_name = old_name.replace('tenant', 'project') 108 | 109 | op.drop_index(index_name=op.f(old_name), table_name=table_name) 110 | op.create_index(new_name, table_name, ['project_id']) 111 | 112 | 113 | def upgrade(): 114 | """Code reused from 115 | 116 | Change-Id: I87a8ef342ccea004731ba0192b23a8e79bc382dc 117 | """ 118 | 119 | inspector = get_inspector() 120 | 121 | data = get_data() 122 | for table, column in data: 123 | alter_column(table, column) 124 | 125 | indexes = inspector.get_indexes(table) 126 | for index in indexes: 127 | if 'tenant_id' in index['name']: 128 | recreate_index(index, table) 129 | 130 | 131 | def contract_creation_exceptions(): 132 | """Special migration for the blueprint to support Keystone V3. 133 | We drop all tenant_id columns and create project_id columns instead. 134 | """ 135 | return { 136 | sa.Column: ['.'.join([table, 'project_id']) for table in get_tables()], 137 | sa.Index: get_tables() 138 | } 139 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/versions/newton/contract/61cc795e43e8_initial.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt Limited. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | # 15 | 16 | """initial 17 | 18 | Revision ID: 61cc795e43e8 19 | Revises: start_neutron_dynamic_routing 20 | Create Date: 2016-05-03 08:30:18.421995 21 | 22 | """ 23 | 24 | from neutron.db.migration import cli 25 | 26 | # revision identifiers, used by Alembic. 27 | revision = '61cc795e43e8' 28 | down_revision = 'start_neutron_dynamic_routing' 29 | branch_labels = (cli.CONTRACT_BRANCH,) 30 | 31 | 32 | def upgrade(): 33 | pass 34 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/versions/newton/expand/f399fa0f5f25_initial.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt Limited. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | # 15 | 16 | """initial 17 | 18 | Revision ID: f399fa0f5f25 19 | Revises: None 20 | Create Date: 2016-05-03 08:30:18.421995 21 | 22 | """ 23 | 24 | from neutron.db import migration 25 | from neutron.db.migration import cli 26 | 27 | # revision identifiers, used by Alembic. 28 | revision = 'f399fa0f5f25' 29 | down_revision = 'start_neutron_dynamic_routing' 30 | branch_labels = (cli.EXPAND_BRANCH,) 31 | 32 | # milestone identifier, used by neutron-db-manage 33 | neutron_milestone = [migration.NEWTON] 34 | 35 | 36 | def upgrade(): 37 | pass 38 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/versions/queens/contract/a589fdb5724c_change_size_of_as_number.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | # 13 | 14 | """change size of as number 15 | 16 | Revision ID: a589fdb5724c 17 | Revises: 4cf8bc3edb66 18 | Create Date: 2017-08-31 13:50:28.324422 19 | 20 | """ 21 | 22 | from alembic import op 23 | import sqlalchemy as sa 24 | 25 | from neutron.db import migration 26 | 27 | 28 | # revision identifiers, used by Alembic. 29 | revision = 'a589fdb5724c' 30 | down_revision = '4cf8bc3edb66' 31 | 32 | # milestone identifier, used by neutron-db-manage 33 | neutron_milestone = [migration.QUEENS] 34 | 35 | 36 | def upgrade(): 37 | op.alter_column('bgp_speakers', 'local_as', nullable=False, 38 | type_=sa.BigInteger()) 39 | op.alter_column('bgp_peers', 'remote_as', nullable=False, 40 | type_=sa.BigInteger()) 41 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/alembic_migrations/versions/start_neutron_dynamic_routing.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt Limited. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | # 15 | 16 | """start neutron-dynamic-routing chain 17 | 18 | Revision ID: start_neutron_dynamic_routing 19 | Revises: None 20 | Create Date: 2016-04-26 18:42:08.262632 21 | 22 | """ 23 | 24 | # revision identifiers, used by Alembic. 25 | revision = 'start_neutron_dynamic_routing' 26 | down_revision = None 27 | 28 | 29 | def upgrade(): 30 | pass 31 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/db/migration/models/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/db/migration/models/head.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt Limited. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from neutron_lib.db import model_base 16 | 17 | from neutron_dynamic_routing.db import bgp_db # noqa 18 | from neutron_dynamic_routing.db import bgp_dragentscheduler_db # noqa 19 | 20 | 21 | def get_metadata(): 22 | return model_base.BASEV2.metadata 23 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/extensions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/extensions/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/extensions/bgp.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Hewlett Packard Development Coompany LP 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from neutron_lib.api.definitions import bgp as bgp_api_def 18 | from neutron_lib.api import extensions as api_ext 19 | from neutron_lib import exceptions as n_exc 20 | 21 | from neutron.api.v2 import resource_helper as rh 22 | 23 | from neutron_dynamic_routing._i18n import _ 24 | 25 | 26 | # Dynamic Routing Exceptions 27 | class BgpSpeakerNotFound(n_exc.NotFound): 28 | message = _("BGP speaker %(id)s could not be found.") 29 | 30 | 31 | class BgpPeerNotFound(n_exc.NotFound): 32 | message = _("BGP peer %(id)s could not be found.") 33 | 34 | 35 | class BgpPeerNotAuthenticated(n_exc.NotFound): 36 | message = _("BGP peer %(bgp_peer_id)s not authenticated.") 37 | 38 | 39 | class BgpSpeakerPeerNotAssociated(n_exc.NotFound): 40 | message = _("BGP peer %(bgp_peer_id)s is not associated with " 41 | "BGP speaker %(bgp_speaker_id)s.") 42 | 43 | 44 | class BgpSpeakerNetworkNotAssociated(n_exc.NotFound): 45 | message = _("Network %(network_id)s is not associated with " 46 | "BGP speaker %(bgp_speaker_id)s.") 47 | 48 | 49 | class BgpSpeakerNetworkBindingError(n_exc.Conflict): 50 | message = _("Network %(network_id)s is already bound to BgpSpeaker " 51 | "%(bgp_speaker_id)s.") 52 | 53 | 54 | class NetworkNotBound(n_exc.NotFound): 55 | message = _("Network %(network_id)s is not bound to a BgpSpeaker.") 56 | 57 | 58 | class DuplicateBgpPeerIpException(n_exc.Conflict): 59 | message = _("BGP Speaker %(bgp_speaker_id)s is already configured to " 60 | "peer with a BGP Peer at %(peer_ip)s, it cannot peer with " 61 | "BGP Peer %(bgp_peer_id)s.") 62 | 63 | 64 | class InvalidBgpPeerMd5Authentication(n_exc.BadRequest): 65 | message = _("A password must be supplied when using auth_type md5.") 66 | 67 | 68 | class NetworkNotBoundForIpVersion(NetworkNotBound): 69 | message = _("Network %(network_id)s is not bound to a IPv%(ip_version)s " 70 | "BgpSpeaker.") 71 | 72 | 73 | class Bgp(api_ext.APIExtensionDescriptor): 74 | api_definition = bgp_api_def 75 | 76 | @classmethod 77 | def get_resources(cls): 78 | plural_mappings = rh.build_plural_mappings( 79 | {}, bgp_api_def.RESOURCE_ATTRIBUTE_MAP) 80 | exts = rh.build_resource_info(plural_mappings, 81 | bgp_api_def.RESOURCE_ATTRIBUTE_MAP, 82 | bgp_api_def.ALIAS, 83 | action_map=bgp_api_def.ACTION_MAP) 84 | 85 | return exts 86 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/extensions/bgp_4byte_asn.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | from neutron_lib.api.definitions import bgp_4byte_asn as api_def 14 | from neutron_lib.api import extensions as api_extensions 15 | 16 | 17 | class Bgp_4byte_asn(api_extensions.APIExtensionDescriptor): 18 | """Extension class supporting bgp 4-byte AS numbers. 19 | """ 20 | 21 | api_definition = api_def 22 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/extensions/bgp_dragentscheduler.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import abc 17 | 18 | from neutron.api import extensions 19 | from neutron.api.v2 import resource 20 | from neutron.api import wsgi 21 | from neutron_lib.api.definitions import bgp as bgp_ext 22 | from neutron_lib.api.definitions import bgp_dragentscheduler as api_def 23 | from neutron_lib.api import extensions as api_extensions 24 | from neutron_lib.api import faults 25 | from neutron_lib import exceptions as n_exc 26 | from neutron_lib.exceptions import agent as agent_exc 27 | from neutron_lib.plugins import directory 28 | from oslo_log import log as logging 29 | import webob 30 | 31 | from neutron_dynamic_routing._i18n import _, _LE 32 | 33 | 34 | LOG = logging.getLogger(__name__) 35 | 36 | 37 | class DrAgentInvalid(agent_exc.AgentNotFound): 38 | message = _("BgpDrAgent %(id)s is invalid or has been disabled.") 39 | 40 | 41 | class DrAgentNotHostingBgpSpeaker(n_exc.NotFound): 42 | message = _("BGP speaker %(bgp_speaker_id)s is not hosted " 43 | "by the BgpDrAgent %(agent_id)s.") 44 | 45 | 46 | class DrAgentAssociationError(n_exc.Conflict): 47 | message = _("BgpDrAgent %(agent_id)s is already associated " 48 | "to a BGP speaker.") 49 | 50 | 51 | class BgpSpeakerRescheduleError(n_exc.Conflict): 52 | message = _("Failed rescheduling %(bgp_speaker_id)s: " 53 | "%(failure_reason)s.") 54 | 55 | 56 | class BgpDrSchedulerController(wsgi.Controller): 57 | """Schedule BgpSpeaker for a BgpDrAgent""" 58 | def get_plugin(self): 59 | plugin = directory.get_plugin(bgp_ext.ALIAS) 60 | if not plugin: 61 | LOG.error(_LE('No plugin for BGP routing registered')) 62 | msg = _('The resource could not be found.') 63 | raise webob.exc.HTTPNotFound(msg) 64 | return plugin 65 | 66 | def index(self, request, **kwargs): 67 | plugin = self.get_plugin() 68 | return plugin.list_bgp_speaker_on_dragent( 69 | request.context, kwargs['agent_id']) 70 | 71 | def create(self, request, body, **kwargs): 72 | plugin = self.get_plugin() 73 | return plugin.add_bgp_speaker_to_dragent( 74 | request.context, 75 | kwargs['agent_id'], 76 | body['bgp_speaker_id']) 77 | 78 | def delete(self, request, id, **kwargs): 79 | plugin = self.get_plugin() 80 | return plugin.remove_bgp_speaker_from_dragent( 81 | request.context, kwargs['agent_id'], id) 82 | 83 | 84 | class BgpDrAgentController(wsgi.Controller): 85 | def get_plugin(self): 86 | plugin = directory.get_plugin(bgp_ext.ALIAS) 87 | if not plugin: 88 | LOG.error(_LE('No plugin for BGP routing registered')) 89 | msg = _('The resource could not be found.') 90 | raise webob.exc.HTTPNotFound(msg) 91 | return plugin 92 | 93 | def index(self, request, **kwargs): 94 | plugin = directory.get_plugin(bgp_ext.ALIAS) 95 | return plugin.list_dragent_hosting_bgp_speaker( 96 | request.context, kwargs['bgp_speaker_id']) 97 | 98 | 99 | class Bgp_dragentscheduler(api_extensions.APIExtensionDescriptor): 100 | """Extension class supporting Dynamic Routing scheduler. 101 | """ 102 | 103 | api_definition = api_def 104 | 105 | @classmethod 106 | def get_resources(cls): 107 | """Returns Ext Resources.""" 108 | exts = [] 109 | parent = dict(member_name="agent", 110 | collection_name="agents") 111 | 112 | controller = resource.Resource(BgpDrSchedulerController(), 113 | faults.FAULT_MAP) 114 | exts.append(extensions.ResourceExtension(api_def.BGP_DRINSTANCES, 115 | controller, parent)) 116 | 117 | parent = dict(member_name="bgp_speaker", 118 | collection_name="bgp-speakers") 119 | controller = resource.Resource(BgpDrAgentController(), 120 | faults.FAULT_MAP) 121 | exts.append(extensions.ResourceExtension(api_def.BGP_DRAGENTS, 122 | controller, parent)) 123 | return exts 124 | 125 | 126 | class BgpDrSchedulerPluginBase(metaclass=abc.ABCMeta): 127 | """REST API to operate BGP dynamic routing agent scheduler. 128 | 129 | All the methods must be executed in admin context. 130 | """ 131 | def get_plugin_description(self): 132 | return "Neutron BGP dynamic routing scheduler Plugin" 133 | 134 | def get_plugin_type(self): 135 | return bgp_ext.ALIAS 136 | 137 | @abc.abstractmethod 138 | def add_bgp_speaker_to_dragent(self, context, agent_id, speaker_id): 139 | pass 140 | 141 | @abc.abstractmethod 142 | def remove_bgp_speaker_from_dragent(self, context, agent_id, speaker_id): 143 | pass 144 | 145 | @abc.abstractmethod 146 | def list_dragent_hosting_bgp_speaker(self, context, speaker_id): 147 | pass 148 | 149 | @abc.abstractmethod 150 | def list_bgp_speaker_on_dragent(self, context, agent_id): 151 | pass 152 | 153 | @abc.abstractmethod 154 | def get_bgp_speakers_for_agent_host(self, context, host): 155 | pass 156 | 157 | @abc.abstractmethod 158 | def get_bgp_speaker_by_speaker_id(self, context, speaker_id): 159 | pass 160 | 161 | @abc.abstractmethod 162 | def get_bgp_peer_by_peer_id(self, context, bgp_peer_id): 163 | pass 164 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/policies/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | import itertools 14 | 15 | from neutron_dynamic_routing.policies import bgp_dragent 16 | from neutron_dynamic_routing.policies import bgp_peer 17 | from neutron_dynamic_routing.policies import bgp_speaker 18 | 19 | 20 | def list_rules(): 21 | return itertools.chain( 22 | bgp_speaker.list_rules(), 23 | bgp_peer.list_rules(), 24 | bgp_dragent.list_rules(), 25 | ) 26 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/policies/bgp_dragent.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | from neutron_lib import policy as base 14 | from oslo_policy import policy 15 | 16 | 17 | rules = [ 18 | policy.DocumentedRuleDefault( 19 | 'add_bgp_speaker_to_dragent', 20 | base.RULE_ADMIN_ONLY, 21 | 'Add a BGP speaker to a dynamic routing agent', 22 | [ 23 | { 24 | 'method': 'POST', 25 | 'path': '/agents/{agent_id}/bgp-drinstances', 26 | }, 27 | ] 28 | ), 29 | policy.DocumentedRuleDefault( 30 | 'remove_bgp_speaker_from_dragent', 31 | base.RULE_ADMIN_ONLY, 32 | 'Remove a BGP speaker from a dynamic routing agent', 33 | [ 34 | { 35 | 'method': 'DELETE', 36 | 'path': '/agents/{agent_id}/bgp-drinstances/{bgp_speaker_id}', 37 | }, 38 | ] 39 | ), 40 | policy.DocumentedRuleDefault( 41 | 'list_bgp_speaker_on_dragent', 42 | base.RULE_ADMIN_ONLY, 43 | 'List BGP speakers hosted by a dynamic routing agent', 44 | [ 45 | { 46 | 'method': 'GET', 47 | 'path': '/agents/{agent_id}/bgp-drinstances', 48 | }, 49 | ] 50 | ), 51 | policy.DocumentedRuleDefault( 52 | 'list_dragent_hosting_bgp_speaker', 53 | base.RULE_ADMIN_ONLY, 54 | 'List dynamic routing agents hosting a BGP speaker', 55 | [ 56 | { 57 | 'method': 'GET', 58 | 'path': '/bgp-speakers/{bgp_speaker_id}/bgp-dragents', 59 | }, 60 | ] 61 | ), 62 | ] 63 | 64 | 65 | def list_rules(): 66 | return rules 67 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/policies/bgp_peer.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | from neutron_lib import policy as base 14 | from oslo_policy import policy 15 | 16 | 17 | rules = [ 18 | policy.DocumentedRuleDefault( 19 | 'create_bgp_peer', 20 | base.RULE_ADMIN_ONLY, 21 | 'Create a BGP peer', 22 | [ 23 | { 24 | 'method': 'POST', 25 | 'path': '/bgp-peers', 26 | }, 27 | ] 28 | ), 29 | policy.DocumentedRuleDefault( 30 | 'update_bgp_peer', 31 | base.RULE_ADMIN_ONLY, 32 | 'Update a BGP peer', 33 | [ 34 | { 35 | 'method': 'PUT', 36 | 'path': '/bgp-peers/{id}', 37 | }, 38 | ] 39 | ), 40 | policy.DocumentedRuleDefault( 41 | 'delete_bgp_peer', 42 | base.RULE_ADMIN_ONLY, 43 | 'Delete a BGP peer', 44 | [ 45 | { 46 | 'method': 'DELETE', 47 | 'path': '/bgp-peers/{id}', 48 | }, 49 | ] 50 | ), 51 | policy.DocumentedRuleDefault( 52 | 'get_bgp_peer', 53 | base.RULE_ADMIN_ONLY, 54 | 'Get BGP peers', 55 | [ 56 | { 57 | 'method': 'GET', 58 | 'path': '/bgp-peers', 59 | }, 60 | { 61 | 'method': 'GET', 62 | 'path': '/bgp-peers/{id}', 63 | }, 64 | ] 65 | ), 66 | ] 67 | 68 | 69 | def list_rules(): 70 | return rules 71 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/policies/bgp_speaker.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | from neutron_lib import policy as base 14 | from oslo_policy import policy 15 | 16 | 17 | rules = [ 18 | policy.DocumentedRuleDefault( 19 | 'create_bgp_speaker', 20 | base.RULE_ADMIN_ONLY, 21 | 'Create a BGP speaker', 22 | [ 23 | { 24 | 'method': 'POST', 25 | 'path': '/bgp-speakers', 26 | }, 27 | ] 28 | ), 29 | policy.DocumentedRuleDefault( 30 | 'update_bgp_speaker', 31 | base.RULE_ADMIN_ONLY, 32 | 'Update a BGP speaker', 33 | [ 34 | { 35 | 'method': 'PUT', 36 | 'path': '/bgp-speakers/{id}', 37 | }, 38 | ] 39 | ), 40 | policy.DocumentedRuleDefault( 41 | 'delete_bgp_speaker', 42 | base.RULE_ADMIN_ONLY, 43 | 'Delete a BGP speaker', 44 | [ 45 | { 46 | 'method': 'DELETE', 47 | 'path': '/bgp-speakers/{id}', 48 | }, 49 | ] 50 | ), 51 | policy.DocumentedRuleDefault( 52 | 'get_bgp_speaker', 53 | base.RULE_ADMIN_ONLY, 54 | 'Get BGP speakers', 55 | [ 56 | { 57 | 'method': 'GET', 58 | 'path': '/bgp-speakers', 59 | }, 60 | { 61 | 'method': 'GET', 62 | 'path': '/bgp-speakers/{id}', 63 | }, 64 | ] 65 | ), 66 | 67 | policy.DocumentedRuleDefault( 68 | 'add_bgp_peer', 69 | base.RULE_ADMIN_ONLY, 70 | 'Add a BGP peer to a BGP speaker', 71 | [ 72 | { 73 | 'method': 'PUT', 74 | 'path': '/bgp-speakers/{id}/add_bgp_peer', 75 | }, 76 | ] 77 | ), 78 | policy.DocumentedRuleDefault( 79 | 'remove_bgp_peer', 80 | base.RULE_ADMIN_ONLY, 81 | 'Remove a BGP peer from a BGP speaker', 82 | [ 83 | { 84 | 'method': 'PUT', 85 | 'path': '/bgp-speakers/{id}/remove_bgp_peer', 86 | }, 87 | ] 88 | ), 89 | policy.DocumentedRuleDefault( 90 | 'add_gateway_network', 91 | base.RULE_ADMIN_ONLY, 92 | 'Add a gateway network to a BGP speaker', 93 | [ 94 | { 95 | 'method': 'PUT', 96 | 'path': '/bgp-speakers/{id}/add_gateway_network', 97 | }, 98 | ] 99 | ), 100 | policy.DocumentedRuleDefault( 101 | 'remove_gateway_network', 102 | base.RULE_ADMIN_ONLY, 103 | 'Remove a gateway network from a BGP speaker', 104 | [ 105 | { 106 | 'method': 'PUT', 107 | 'path': '/bgp-speakers/{id}/remove_gateway_network', 108 | }, 109 | ] 110 | ), 111 | policy.DocumentedRuleDefault( 112 | 'get_advertised_routes', 113 | base.RULE_ADMIN_ONLY, 114 | 'Get advertised routes of a BGP speaker', 115 | [ 116 | { 117 | 'method': 'GET', 118 | 'path': '/bgp-speakers/{id}/get_advertised_routes', 119 | }, 120 | ] 121 | ), 122 | ] 123 | 124 | 125 | def list_rules(): 126 | return rules 127 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/services/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/services/bgp/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/agent/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/services/bgp/agent/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/agent/config.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from oslo_config import cfg 17 | 18 | from neutron_dynamic_routing._i18n import _ 19 | 20 | BGP_DRIVER_OPTS = [ 21 | cfg.StrOpt('bgp_speaker_driver', 22 | help=_("BGP speaker driver class to be instantiated.")) 23 | ] 24 | 25 | BGP_PROTO_CONFIG_OPTS = [ 26 | cfg.StrOpt('bgp_router_id', 27 | help=_("32-bit BGP identifier, typically an IPv4 address " 28 | "owned by the system running the BGP DrAgent.")) 29 | ] 30 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/agent/driver/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/services/bgp/agent/driver/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/agent/driver/base.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import abc 17 | 18 | 19 | class BgpDriverBase(metaclass=abc.ABCMeta): 20 | """Base class for BGP Speaking drivers. 21 | 22 | Any class which provides BGP functionality should extend this 23 | defined base class. 24 | """ 25 | 26 | @abc.abstractmethod 27 | def add_bgp_speaker(self, speaker_as): 28 | """Add a BGP speaker. 29 | 30 | :param speaker_as: Specifies BGP Speaker autonomous system number. 31 | Must be an biginteger between MIN_ASNUM and 32 | MAX_4BYTE_ASNUM. 33 | :type speaker_as: biginteger 34 | :raises: BgpSpeakerAlreadyScheduled, BgpSpeakerMaxScheduled, 35 | InvalidParamType, InvalidParamRange 36 | """ 37 | 38 | @abc.abstractmethod 39 | def delete_bgp_speaker(self, speaker_as): 40 | """Deletes BGP speaker. 41 | 42 | :param speaker_as: Specifies BGP Speaker autonomous system number. 43 | Must be an biginteger between MIN_ASNUM and 44 | MAX_4BYTE_ASNUM. 45 | :type speaker_as: biginteger 46 | :raises: BgpSpeakerNotAdded 47 | """ 48 | 49 | @abc.abstractmethod 50 | def add_bgp_peer(self, speaker_as, peer_ip, peer_as, 51 | auth_type='none', password=None): 52 | """Add a new BGP peer. 53 | 54 | :param speaker_as: Specifies BGP Speaker autonomous system number. 55 | Must be an biginteger between MIN_ASNUM and 56 | MAX_4BYTE_ASNUM. 57 | :type speaker_as: biginteger 58 | :param peer_ip: Specifies the IP address of the peer. 59 | :type peer_ip: string 60 | :param peer_as: Specifies Autonomous Number of the peer. 61 | Must be an biginteger between MIN_ASNUM and 62 | MAX_4BYTE_ASNUM. 63 | :type peer_as: biginteger 64 | :param auth_type: Specifies authentication type. 65 | By default, authentication will be disabled. 66 | :type auth_type: value in SUPPORTED_AUTH_TYPES 67 | :param password: Authentication password.By default, authentication 68 | will be disabled. 69 | :type password: string 70 | :raises: BgpSpeakerNotAdded, InvalidParamType, InvalidParamRange, 71 | InvaildAuthType, PasswordNotSpecified 72 | """ 73 | 74 | @abc.abstractmethod 75 | def delete_bgp_peer(self, speaker_as, peer_ip): 76 | """Delete a BGP peer associated with the given peer IP 77 | 78 | :param speaker_as: Specifies BGP Speaker autonomous system number. 79 | Must be an biginteger between MIN_ASNUM and 80 | MAX_4BYTE_ASNUM. 81 | :type speaker_as: biginteger 82 | :param peer_ip: Specifies the IP address of the peer. Must be the 83 | string representation of an IP address. 84 | :type peer_ip: string 85 | :raises: BgpSpeakerNotAdded, BgpPeerNotAdded 86 | """ 87 | 88 | @abc.abstractmethod 89 | def advertise_route(self, speaker_as, cidr, nexthop): 90 | """Add a new prefix to advertise. 91 | 92 | :param speaker_as: Specifies BGP Speaker autonomous system number. 93 | Must be an biginteger between MIN_ASNUM and 94 | MAX_4BYTE_ASNUM. 95 | :type speaker_as: biginteger 96 | :param cidr: CIDR of the network to advertise. Must be the string 97 | representation of an IP network (e.g., 10.1.1.0/24) 98 | :type cidr: string 99 | :param nexthop: Specifies the next hop address for the above 100 | prefix. 101 | :type nexthop: string 102 | :raises: BgpSpeakerNotAdded, InvalidParamType 103 | """ 104 | 105 | @abc.abstractmethod 106 | def withdraw_route(self, speaker_as, cidr, nexthop=None): 107 | """Withdraw an advertised prefix. 108 | 109 | :param speaker_as: Specifies BGP Speaker autonomous system number. 110 | Must be an biginteger between MIN_ASNUM and 111 | MAX_4BYTE_ASNUM. 112 | :type speaker_as: biginteger 113 | :param cidr: CIDR of the network to withdraw. Must be the string 114 | representation of an IP network (e.g., 10.1.1.0/24) 115 | :type cidr: string 116 | :param nexthop: Specifies the next hop address for the above 117 | prefix. 118 | :type nexthop: string 119 | :raises: BgpSpeakerNotAdded, RouteNotAdvertised, InvalidParamType 120 | """ 121 | 122 | @abc.abstractmethod 123 | def get_bgp_speaker_statistics(self, speaker_as): 124 | """Collect BGP Speaker statistics. 125 | 126 | :param speaker_as: Specifies BGP Speaker autonomous system number. 127 | Must be an biginteger between MIN_ASNUM and 128 | MAX_4BYTE_ASNUM. 129 | :type speaker_as: biginteger 130 | :raises: BgpSpeakerNotAdded 131 | :returns: bgp_speaker_stats: string 132 | """ 133 | 134 | @abc.abstractmethod 135 | def get_bgp_peer_statistics(self, speaker_as, peer_ip, peer_as): 136 | """Collect BGP Peer statistics. 137 | 138 | :param speaker_as: Specifies BGP Speaker autonomous system number. 139 | Must be an biginteger between MIN_ASNUM and 140 | MAX_4BYTE_ASNUM. 141 | :type speaker_as: biginteger 142 | :param peer_ip: Specifies the IP address of the peer. 143 | :type peer_ip: string 144 | :param peer_as: Specifies the AS number of the peer. Must be an 145 | biginteger between MIN_ASNUM and MAX_4BYTE_ASNUM. 146 | :type peer_as: biginteger . 147 | :raises: BgpSpeakerNotAdded, BgpPeerNotAdded 148 | :returns: bgp_peer_stats: string 149 | """ 150 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/agent/driver/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from neutron_lib import exceptions as n_exc 17 | 18 | from neutron_dynamic_routing._i18n import _ 19 | 20 | 21 | # BGP Driver Exceptions 22 | class BgpSpeakerNotAdded(n_exc.BadRequest): 23 | message = _("BGP Speaker for local_as=%(local_as)s with " 24 | "router_id=%(rtid)s not added yet.") 25 | 26 | 27 | class BgpSpeakerMaxScheduled(n_exc.BadRequest): 28 | message = _("Already hosting maximum number of BGP Speakers. " 29 | "Allowed scheduled count=%(count)d") 30 | 31 | 32 | class BgpSpeakerAlreadyScheduled(n_exc.Conflict): 33 | message = _("Already hosting BGP Speaker for local_as=%(current_as)d with " 34 | "router_id=%(rtid)s.") 35 | 36 | 37 | class BgpPeerNotAdded(n_exc.BadRequest): 38 | message = _("BGP Peer %(peer_ip)s for remote_as=%(remote_as)s, running " 39 | "for BGP Speaker %(speaker_as)d not added yet.") 40 | 41 | 42 | class RouteNotAdvertised(n_exc.BadRequest): 43 | message = _("Route %(cidr)s not advertised for BGP Speaker " 44 | "%(speaker_as)d.") 45 | 46 | 47 | class InvalidParamType(n_exc.NeutronException): 48 | message = _("Parameter %(param)s must be of %(param_type)s type.") 49 | 50 | 51 | class InvalidParamRange(n_exc.NeutronException): 52 | message = _("%(param)s must be in %(range)s range.") 53 | 54 | 55 | class InvaildAuthType(n_exc.BadRequest): 56 | message = _("Authentication type not supported. Requested " 57 | "type=%(auth_type)s.") 58 | 59 | 60 | class PasswordNotSpecified(n_exc.BadRequest): 61 | message = _("Password not specified for authentication " 62 | "type=%(auth_type)s.") 63 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/agent/driver/os_ken/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/services/bgp/agent/driver/os_ken/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/agent/driver/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import netaddr 17 | 18 | from neutron_lib import constants as lib_consts 19 | 20 | from neutron_dynamic_routing.services.bgp.agent.driver import exceptions as bgp_driver_exc # noqa 21 | 22 | 23 | # Parameter validation functions provided are provided by the base. 24 | def validate_as_num(param, as_num): 25 | if not isinstance(as_num, int): 26 | raise bgp_driver_exc.InvalidParamType(param=param, 27 | param_type='integer') 28 | 29 | if not (lib_consts.MIN_ASNUM <= as_num <= lib_consts.MAX_4BYTE_ASNUM): 30 | # Must be in [AS_NUM_MIN, MAX_4BYTE_ASNUM] range. 31 | allowed_range = ('[' + 32 | str(lib_consts.MIN_ASNUM) + '-' + 33 | str(lib_consts.MAX_4BYTE_ASNUM) + 34 | ']') 35 | raise bgp_driver_exc.InvalidParamRange(param=param, 36 | range=allowed_range) 37 | 38 | 39 | def validate_auth(auth_type, password): 40 | validate_string(password) 41 | if auth_type in lib_consts.SUPPORTED_AUTH_TYPES: 42 | if auth_type != 'none' and password is None: 43 | raise bgp_driver_exc.PasswordNotSpecified(auth_type=auth_type) 44 | if auth_type == 'none' and password is not None: 45 | raise bgp_driver_exc.InvaildAuthType(auth_type=auth_type) 46 | else: 47 | raise bgp_driver_exc.InvaildAuthType(auth_type=auth_type) 48 | 49 | 50 | def validate_ip_addr(ip_addr): 51 | try: 52 | if netaddr.valid_ipv4(ip_addr): 53 | return lib_consts.IP_VERSION_4 54 | elif netaddr.valid_ipv6(ip_addr): 55 | return lib_consts.IP_VERSION_6 56 | raise TypeError 57 | except Exception: 58 | raise bgp_driver_exc.InvalidParamType(param=ip_addr, 59 | param_type='ip-address') 60 | 61 | 62 | def validate_string(param): 63 | if param is not None: 64 | if not isinstance(param, str): 65 | raise bgp_driver_exc.InvalidParamType(param=param, 66 | param_type='string') 67 | 68 | 69 | class BgpMultiSpeakerCache: 70 | """Class for saving multiple BGP speakers information. 71 | 72 | Version history: 73 | 1.0 - Initial version for caching multiple BGP speaker information. 74 | """ 75 | def __init__(self): 76 | self.cache = {} 77 | 78 | def get_hosted_bgp_speakers_count(self): 79 | return len(self.cache) 80 | 81 | def put_bgp_speaker(self, local_as, speaker): 82 | self.cache[local_as] = speaker 83 | 84 | def get_bgp_speaker(self, local_as): 85 | return self.cache.get(local_as) 86 | 87 | def remove_bgp_speaker(self, local_as): 88 | self.cache.pop(local_as, None) 89 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/agent/entry.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import sys 17 | 18 | from oslo_config import cfg 19 | from oslo_service import service 20 | 21 | from neutron.common import config as common_config 22 | from neutron.conf.agent import common as config 23 | from neutron import service as neutron_service 24 | 25 | from neutron_dynamic_routing.services.bgp.agent import config as bgp_dragent_config # noqa 26 | from neutron_dynamic_routing.services.bgp.common import constants as bgp_consts # noqa 27 | 28 | 29 | def register_options(): 30 | config.register_agent_state_opts_helper(cfg.CONF) 31 | config.register_root_helper(cfg.CONF) 32 | cfg.CONF.register_opts(bgp_dragent_config.BGP_DRIVER_OPTS, 'BGP') 33 | cfg.CONF.register_opts(bgp_dragent_config.BGP_PROTO_CONFIG_OPTS, 'BGP') 34 | config.register_external_process_opts(cfg.CONF) 35 | 36 | 37 | def main(): 38 | register_options() 39 | common_config.register_common_config_options() 40 | common_config.init(sys.argv[1:]) 41 | config.setup_logging() 42 | server = neutron_service.Service.create( 43 | binary='neutron-bgp-dragent', 44 | topic=bgp_consts.BGP_DRAGENT, 45 | report_interval=cfg.CONF.AGENT.report_interval, 46 | manager='neutron_dynamic_routing.services.bgp.agent.bgp_dragent.' 47 | 'BgpDrAgentWithStateReport') 48 | service.launch(cfg.CONF, server, restart_method='mutate').wait() 49 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/services/bgp/common/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/common/constants.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | AGENT_TYPE_BGP_ROUTING = 'BGP dynamic routing agent' 17 | 18 | BGP_DRAGENT = 'bgp_dragent' 19 | 20 | BGP_PLUGIN = 'q-bgp-plugin' 21 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/common/opts.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import itertools 17 | 18 | import neutron_dynamic_routing.services.bgp.agent.config 19 | 20 | 21 | def list_bgp_agent_opts(): 22 | return [ 23 | ('bgp', 24 | itertools.chain( 25 | neutron_dynamic_routing.services.bgp.agent. 26 | config.BGP_DRIVER_OPTS, 27 | neutron_dynamic_routing.services.bgp.agent. 28 | config.BGP_PROTO_CONFIG_OPTS) 29 | ) 30 | ] 31 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/services/bgp/scheduler/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/services/bgp/scheduler/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/common/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/common/helpers.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Hewlett Packard Development Co 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from neutron_lib import context 16 | 17 | from neutron.tests.common import helpers 18 | 19 | from neutron_dynamic_routing.services.bgp.common import constants as bgp_const 20 | 21 | 22 | def _get_bgp_dragent_dict(host): 23 | agent = { 24 | 'binary': 'neutron-bgp-dragent', 25 | 'host': host, 26 | 'topic': 'q-bgp_dragent', 27 | 'agent_type': bgp_const.AGENT_TYPE_BGP_ROUTING, 28 | 'configurations': {'bgp_speakers': 1}} 29 | return agent 30 | 31 | 32 | def register_bgp_dragent(host=helpers.HOST, admin_state_up=True, 33 | alive=True): 34 | agent = helpers._register_agent( 35 | _get_bgp_dragent_dict(host)) 36 | 37 | if not admin_state_up: 38 | helpers.set_agent_admin_state(agent['id']) 39 | if not alive: 40 | helpers.kill_agent(agent['id']) 41 | 42 | return helpers.FakePlugin()._get_agent_by_type_and_host( 43 | context.get_admin_context(), agent['agent_type'], agent['host']) 44 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/functional/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/functional/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/functional/services/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/functional/services/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/functional/services/bgp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/functional/services/bgp/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/functional/services/bgp/scheduler/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/functional/services/bgp/scheduler/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/api/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/api/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/api/rpc/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/api/rpc/agentnotifiers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/api/rpc/agentnotifiers/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/api/rpc/agentnotifiers/test_bgp_dr_rpc_agent_api.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from unittest import mock 17 | 18 | from neutron.tests import base 19 | from neutron_lib import context 20 | 21 | from neutron_dynamic_routing.api.rpc.agentnotifiers import bgp_dr_rpc_agent_api 22 | 23 | 24 | class TestBgpDrAgentNotifyApi(base.BaseTestCase): 25 | 26 | def setUp(self): 27 | super().setUp() 28 | self.notifier = ( 29 | bgp_dr_rpc_agent_api.BgpDrAgentNotifyApi()) 30 | 31 | mock_cast_p = mock.patch.object(self.notifier, 32 | '_notification_host_cast') 33 | self.mock_cast = mock_cast_p.start() 34 | mock_call_p = mock.patch.object(self.notifier, 35 | '_notification_host_call') 36 | self.mock_call = mock_call_p.start() 37 | self.context = context.get_admin_context() 38 | self.host = 'host-1' 39 | 40 | def test_agent_updated(self): 41 | admin_state_up = True 42 | host = 'my-hostname' 43 | self.notifier.agent_updated(self.context, admin_state_up, host) 44 | self.assertEqual(1, self.mock_cast.call_count) 45 | self.assertEqual(0, self.mock_call.call_count) 46 | 47 | def test_notify_dragent_bgp_routes_advertisement(self): 48 | bgp_speaker_id = 'bgp-speaker-1' 49 | routes = [{'destination': '1.1.1.1', 'next_hop': '2.2.2.2'}] 50 | self.notifier.bgp_routes_advertisement(self.context, bgp_speaker_id, 51 | routes, self.host) 52 | self.assertEqual(1, self.mock_cast.call_count) 53 | self.assertEqual(0, self.mock_call.call_count) 54 | 55 | def test_notify_dragent_bgp_routes_withdrawal(self): 56 | bgp_speaker_id = 'bgp-speaker-1' 57 | routes = [{'destination': '1.1.1.1'}] 58 | self.notifier.bgp_routes_withdrawal(self.context, bgp_speaker_id, 59 | routes, self.host) 60 | self.assertEqual(1, self.mock_cast.call_count) 61 | self.assertEqual(0, self.mock_call.call_count) 62 | 63 | def test_notify_bgp_peer_disassociated(self): 64 | bgp_speaker_id = 'bgp-speaker-1' 65 | bgp_peer_ip = '1.1.1.1' 66 | self.notifier.bgp_peer_disassociated(self.context, bgp_speaker_id, 67 | bgp_peer_ip, self.host) 68 | self.assertEqual(1, self.mock_cast.call_count) 69 | self.assertEqual(0, self.mock_call.call_count) 70 | 71 | def test_notify_bgp_peer_associated(self): 72 | bgp_speaker_id = 'bgp-speaker-1' 73 | bgp_peer_id = 'bgp-peer-1' 74 | self.notifier.bgp_peer_associated(self.context, bgp_speaker_id, 75 | bgp_peer_id, self.host) 76 | self.assertEqual(1, self.mock_cast.call_count) 77 | self.assertEqual(0, self.mock_call.call_count) 78 | 79 | def test_notify_bgp_speaker_created(self): 80 | bgp_speaker_id = 'bgp-speaker-1' 81 | self.notifier.bgp_speaker_created(self.context, bgp_speaker_id, 82 | self.host) 83 | self.assertEqual(1, self.mock_cast.call_count) 84 | self.assertEqual(0, self.mock_call.call_count) 85 | 86 | def test_notify_bgp_speaker_removed(self): 87 | bgp_speaker_id = 'bgp-speaker-1' 88 | self.notifier.bgp_speaker_removed(self.context, bgp_speaker_id, 89 | self.host) 90 | self.assertEqual(1, self.mock_cast.call_count) 91 | self.assertEqual(0, self.mock_call.call_count) 92 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/api/rpc/handlers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/api/rpc/handlers/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/api/rpc/handlers/test_bgp_speaker_rpc.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from unittest import mock 17 | 18 | from neutron.tests import base 19 | from neutron_lib.api.definitions import bgp as bgp_ext 20 | from neutron_lib.plugins import directory 21 | 22 | from neutron_dynamic_routing.api.rpc.handlers import bgp_speaker_rpc 23 | 24 | 25 | class TestBgpSpeakerRpcCallback(base.BaseTestCase): 26 | 27 | def setUp(self): 28 | super().setUp() 29 | self.plugin = mock.Mock() 30 | directory.add_plugin(bgp_ext.ALIAS, self.plugin) 31 | self.callback = bgp_speaker_rpc.BgpSpeakerRpcCallback() 32 | 33 | def test_get_bgp_speaker_info(self): 34 | self.callback.get_bgp_speaker_info(mock.Mock(), 35 | bgp_speaker_id='id1') 36 | self.assertIsNotNone(len(self.plugin.mock_calls)) 37 | 38 | def test_get_bgp_peer_info(self): 39 | self.callback.get_bgp_peer_info(mock.Mock(), 40 | bgp_peer_id='id1') 41 | self.assertIsNotNone(len(self.plugin.mock_calls)) 42 | 43 | def test_get_bgp_speakers(self): 44 | self.callback.get_bgp_speakers(mock.Mock(), 45 | host='host') 46 | self.assertIsNotNone(len(self.plugin.mock_calls)) 47 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/db/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/services/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/services/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/services/bgp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/services/bgp/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/services/bgp/agent/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/services/bgp/agent/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/services/bgp/driver/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/services/bgp/driver/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/services/bgp/driver/os_ken/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/services/bgp/driver/os_ken/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/services/bgp/driver/test_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Huawei Technologies India Pvt. Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from neutron_lib import constants as lib_consts 17 | 18 | from neutron.tests import base 19 | 20 | from neutron_dynamic_routing.services.bgp.agent.driver import exceptions as bgp_driver_exc # noqa 21 | from neutron_dynamic_routing.services.bgp.agent.driver import utils as bgp_driver_utils # noqa 22 | 23 | FAKE_IP = '2.2.2.5' 24 | FAKE_IPV6 = '2001:db8::' 25 | FAKE_LOCAL_AS = 12345 26 | FAKE_OS_KEN_SPEAKER = {} 27 | EXC_INV_PARAMTYPE = "Parameter %(param)s must be of %(param_type)s type." 28 | EXC_INV_PARAMRANGE = "%(param)s must be in %(range)s range." 29 | EXC_PASSWORD_NOTSPEC = "Password not specified for authentication " + \ 30 | "type=%(auth_type)s." 31 | EXC_INV_AUTHTYPE = "Authentication type not supported. Requested " + \ 32 | "type=%(auth_type)s." 33 | 34 | 35 | class TestValidateMethod(base.BaseTestCase): 36 | 37 | def setUp(self): 38 | super().setUp() 39 | 40 | def test_validate_as_num_with_valid_as_num(self): 41 | self.assertIsNone(bgp_driver_utils.validate_as_num('local_as', 42 | 64512)) 43 | 44 | def test_validate_as_num_with_string_as_num(self): 45 | with self.assertRaisesRegex( 46 | bgp_driver_exc.InvalidParamType, 47 | EXC_INV_PARAMTYPE % {'param': 'local_as', 48 | 'param_type': 'integer'}): 49 | bgp_driver_utils.validate_as_num('local_as', '64512') 50 | 51 | def test_validate_as_num_with_invalid_max_range(self): 52 | allowed_range = ('\\[' + 53 | str(lib_consts.MIN_ASNUM) + '-' + 54 | str(lib_consts.MAX_4BYTE_ASNUM) + 55 | '\\]') 56 | with self.assertRaisesRegex( 57 | bgp_driver_exc.InvalidParamRange, 58 | EXC_INV_PARAMRANGE % {'param': 'local_as', 59 | 'range': allowed_range}): 60 | bgp_driver_utils.validate_as_num('local_as', 61 | lib_consts.MAX_4BYTE_ASNUM + 1) 62 | 63 | def test_validate_as_num_with_invalid_min_range(self): 64 | allowed_range = ('\\[' + 65 | str(lib_consts.MIN_ASNUM) + '-' + 66 | str(lib_consts.MAX_4BYTE_ASNUM) + 67 | '\\]') 68 | with self.assertRaisesRegex( 69 | bgp_driver_exc.InvalidParamRange, 70 | EXC_INV_PARAMRANGE % {'param': 'local_as', 71 | 'range': allowed_range}): 72 | bgp_driver_utils.validate_as_num('local_as', 0) 73 | 74 | def test_validate_auth_with_valid_auth_type(self): 75 | passwords = [None, 'password'] 76 | for (auth_type, passwd) in zip(lib_consts.SUPPORTED_AUTH_TYPES, 77 | passwords): 78 | self.assertIsNone(bgp_driver_utils.validate_auth(auth_type, 79 | passwd)) 80 | 81 | def test_validate_auth_with_integer_password(self): 82 | auth_type = lib_consts.SUPPORTED_AUTH_TYPES[1] 83 | with self.assertRaisesRegex( 84 | bgp_driver_exc.InvalidParamType, 85 | EXC_INV_PARAMTYPE % {'param': '12345', 86 | 'param_type': 'string'}): 87 | bgp_driver_utils.validate_auth(auth_type, 12345) 88 | 89 | def test_validate_auth_with_invalid_auth_type(self): 90 | auth_type = 'abcde' 91 | with self.assertRaisesRegex( 92 | bgp_driver_exc.InvaildAuthType, 93 | EXC_INV_AUTHTYPE % {'auth_type': auth_type}): 94 | bgp_driver_utils.validate_auth(auth_type, 'password') 95 | 96 | def test_validate_auth_with_not_none_auth_type_and_none_password(self): 97 | auth_type = lib_consts.SUPPORTED_AUTH_TYPES[1] 98 | with self.assertRaisesRegex( 99 | bgp_driver_exc.PasswordNotSpecified, 100 | EXC_PASSWORD_NOTSPEC % {'auth_type': auth_type}): 101 | bgp_driver_utils.validate_auth(auth_type, None) 102 | 103 | def test_validate_auth_with_none_auth_type_and_not_none_password(self): 104 | auth_type = None 105 | with self.assertRaisesRegex( 106 | bgp_driver_exc.InvaildAuthType, 107 | EXC_INV_AUTHTYPE % {'auth_type': auth_type}): 108 | bgp_driver_utils.validate_auth(auth_type, 'password') 109 | 110 | def test_validate_ip_addr_with_ipv4_address(self): 111 | self.assertEqual(lib_consts.IP_VERSION_4, 112 | bgp_driver_utils.validate_ip_addr(FAKE_IP)) 113 | 114 | def test_validate_ip_addr_with_ipv6_address(self): 115 | self.assertEqual(lib_consts.IP_VERSION_6, 116 | bgp_driver_utils.validate_ip_addr(FAKE_IPV6)) 117 | 118 | def test_validate_ip_addr_with_integer_ip(self): 119 | with self.assertRaisesRegex( 120 | bgp_driver_exc.InvalidParamType, 121 | EXC_INV_PARAMTYPE % {'param': '12345', 122 | 'param_type': 'ip-address'}): 123 | bgp_driver_utils.validate_ip_addr(12345) 124 | 125 | def test_validate_ip_addr_with_invalid_ipv4_type(self): 126 | with self.assertRaisesRegex( 127 | bgp_driver_exc.InvalidParamType, 128 | EXC_INV_PARAMTYPE % {'param': '1.2.3.a', 129 | 'param_type': 'ip-address'}): 130 | bgp_driver_utils.validate_ip_addr('1.2.3.a') 131 | 132 | def test_validate_ip_addr_with_invalid_ipv6_type(self): 133 | with self.assertRaisesRegex( 134 | bgp_driver_exc.InvalidParamType, 135 | EXC_INV_PARAMTYPE % {'param': '2001:db8::ggg', 136 | 'param_type': 'ip-address'}): 137 | bgp_driver_utils.validate_ip_addr('2001:db8::ggg') 138 | 139 | def test_validate_string_with_string(self): 140 | self.assertIsNone(bgp_driver_utils.validate_string(FAKE_IP)) 141 | 142 | def test_validate_string_with_integer_param(self): 143 | with self.assertRaisesRegex( 144 | bgp_driver_exc.InvalidParamType, 145 | EXC_INV_PARAMTYPE % {'param': '12345', 146 | 'param_type': 'string'}): 147 | bgp_driver_utils.validate_string(12345) 148 | 149 | 150 | class TestBgpMultiSpeakerCache(base.BaseTestCase): 151 | 152 | def setUp(self): 153 | super().setUp() 154 | self.expected_cache = {FAKE_LOCAL_AS: FAKE_OS_KEN_SPEAKER} 155 | self.bs_cache = bgp_driver_utils.BgpMultiSpeakerCache() 156 | 157 | def test_put_bgp_speaker(self): 158 | self.bs_cache.put_bgp_speaker(FAKE_LOCAL_AS, FAKE_OS_KEN_SPEAKER) 159 | self.assertEqual(self.expected_cache, self.bs_cache.cache) 160 | 161 | def test_remove_bgp_speaker(self): 162 | self.bs_cache.put_bgp_speaker(FAKE_LOCAL_AS, FAKE_OS_KEN_SPEAKER) 163 | self.assertEqual(1, len(self.bs_cache.cache)) 164 | self.bs_cache.remove_bgp_speaker(FAKE_LOCAL_AS) 165 | self.assertEqual(0, len(self.bs_cache.cache)) 166 | 167 | def test_get_bgp_speaker(self): 168 | self.bs_cache.put_bgp_speaker(FAKE_LOCAL_AS, FAKE_OS_KEN_SPEAKER) 169 | self.assertEqual( 170 | FAKE_OS_KEN_SPEAKER, 171 | self.bs_cache.get_bgp_speaker(FAKE_LOCAL_AS)) 172 | 173 | def test_get_hosted_bgp_speakers_count(self): 174 | self.bs_cache.put_bgp_speaker(FAKE_LOCAL_AS, FAKE_OS_KEN_SPEAKER) 175 | self.assertEqual(1, self.bs_cache.get_hosted_bgp_speakers_count()) 176 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/services/bgp/scheduler/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/neutron_dynamic_routing/tests/unit/services/bgp/scheduler/__init__.py -------------------------------------------------------------------------------- /neutron_dynamic_routing/tests/unit/services/bgp/test_bgp_plugin.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017 VA Linux Systems Japan K.K. 2 | # Copyright (C) 2017 Fumihiko Kakuma 3 | # All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from unittest import mock 18 | 19 | import netaddr 20 | from neutron.tests import base 21 | from neutron_lib.callbacks import events 22 | from neutron_lib.callbacks import registry 23 | from neutron_lib.callbacks import resources 24 | from neutron_lib import constants as n_const 25 | 26 | from neutron_dynamic_routing.api.rpc.callbacks import resources as dr_resources 27 | from neutron_dynamic_routing.db import bgp_db 28 | from neutron_dynamic_routing.services.bgp import bgp_plugin 29 | 30 | 31 | class TestBgpPlugin(base.BaseTestCase): 32 | 33 | def setUp(self): 34 | super().setUp() 35 | bgp_notify_p = mock.patch('neutron_dynamic_routing.api.rpc.' 36 | 'agentnotifiers.bgp_dr_rpc_agent_api.' 37 | 'BgpDrAgentNotifyApi') 38 | bgp_notify_p.start() 39 | rpc_conn_p = mock.patch('neutron_lib.rpc.Connection') 40 | rpc_conn_p.start() 41 | admin_ctx_p = mock.patch('neutron_lib.context.get_admin_context') 42 | self.admin_ctx_m = admin_ctx_p.start() 43 | self.fake_admin_ctx = mock.Mock() 44 | self.admin_ctx_m.return_value = self.fake_admin_ctx 45 | self.plugin = bgp_plugin.BgpPlugin() 46 | 47 | def _create_test_payload(self, context='test_ctx'): 48 | bgp_speaker = {'id': '11111111-2222-3333-4444-555555555555'} 49 | payload = events.DBEventPayload( 50 | context, 51 | metadata={'plugin': self.plugin}, 52 | states=(bgp_speaker,)) 53 | return payload 54 | 55 | def test__register_callbacks(self): 56 | with mock.patch.object(registry, 'subscribe') as subscribe: 57 | plugin = bgp_plugin.BgpPlugin() 58 | expected_calls = [ 59 | mock.call(plugin.bgp_drscheduler.schedule_bgp_speaker_callback, 60 | dr_resources.BGP_SPEAKER, events.AFTER_CREATE), 61 | mock.call(plugin.floatingip_update_callback, 62 | resources.FLOATING_IP, events.AFTER_CREATE), 63 | mock.call(plugin.floatingip_update_callback, 64 | resources.FLOATING_IP, events.AFTER_UPDATE), 65 | mock.call(plugin.router_interface_callback, 66 | resources.ROUTER_INTERFACE, events.AFTER_CREATE), 67 | mock.call(plugin.router_interface_callback, 68 | resources.ROUTER_INTERFACE, events.BEFORE_CREATE), 69 | mock.call(plugin.router_interface_callback, 70 | resources.ROUTER_INTERFACE, events.AFTER_DELETE), 71 | mock.call(plugin.router_gateway_callback, 72 | resources.ROUTER_GATEWAY, events.AFTER_CREATE), 73 | mock.call(plugin.router_gateway_callback, 74 | resources.ROUTER_GATEWAY, events.AFTER_DELETE), 75 | mock.call(plugin.router_callback, 76 | resources.ROUTER, events.AFTER_UPDATE), 77 | mock.call(plugin.port_callback, 78 | resources.PORT, events.AFTER_UPDATE), 79 | ] 80 | self.assertEqual(subscribe.call_args_list, expected_calls) 81 | 82 | def test_create_bgp_speaker(self): 83 | test_context = 'create_bgp_context' 84 | test_bgp_speaker = {'id': None} 85 | payload = self._create_test_payload(context=test_context) 86 | with mock.patch.object(bgp_db.BgpDbMixin, 87 | 'create_bgp_speaker') as create_bgp_sp: 88 | with mock.patch.object(registry, 'publish') as publish: 89 | create_bgp_sp.return_value = payload.latest_state 90 | self.assertEqual(self.plugin.create_bgp_speaker( 91 | test_context, test_bgp_speaker), 92 | payload.latest_state) 93 | create_bgp_sp.assert_called_once_with(test_context, 94 | test_bgp_speaker) 95 | publish.assert_called_once_with(dr_resources.BGP_SPEAKER, 96 | events.AFTER_CREATE, 97 | self.plugin, 98 | payload=mock.ANY) 99 | publish_payload = publish.call_args_list[0][1]['payload'] 100 | self.assertEqual(payload.latest_state, 101 | publish_payload.latest_state) 102 | self.assertEqual(payload.context, publish_payload.context) 103 | 104 | def test_floatingip_update_callback(self): 105 | new_fip = {'floating_ip_address': netaddr.IPAddress('10.10.10.10'), 106 | 'router_id': '', 'floating_network_id': 'a-b-c-d-e'} 107 | old_fip = new_fip.copy() 108 | old_fip.update(router_id='old-router-id') 109 | 110 | test_context = 'test_context' 111 | 112 | get_bpg_speakers_name = '_bgp_speakers_for_gw_network_by_family' 113 | with mock.patch.object(self.plugin, get_bpg_speakers_name) as get_bgp: 114 | with mock.patch.object(self.plugin, 115 | 'stop_route_advertisements') as stop_ad: 116 | with mock.patch.object(self.plugin, '_bgp_rpc') as bgp_rpc: 117 | bgp_speaker = mock.Mock() 118 | bgp_speaker.id = '11111111-2222-3333-4444-555555555555' 119 | get_bgp.return_value = [bgp_speaker] 120 | 121 | self.plugin.floatingip_update_callback( 122 | test_context, events.AFTER_UPDATE, None, 123 | payload=events.DBEventPayload( 124 | test_context, states=(old_fip, new_fip))) 125 | 126 | get_bgp.assert_called_once_with(self.fake_admin_ctx, 127 | 'a-b-c-d-e', 128 | n_const.IP_VERSION_4) 129 | 130 | old_host_route = [{'destination': '10.10.10.10/32', 131 | 'next_hop': None}] 132 | stop_ad.assert_called_once_with(self.fake_admin_ctx, 133 | bgp_rpc, 134 | bgp_speaker.id, 135 | old_host_route) 136 | -------------------------------------------------------------------------------- /neutron_dynamic_routing/version.py: -------------------------------------------------------------------------------- 1 | # Copyright 2011 OpenStack Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | import pbr.version 16 | 17 | version_info = pbr.version.VersionInfo('neutron_dynamic_routing') 18 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["pbr>=5.7.0", "setuptools>=64.0.0", "wheel"] 3 | build-backend = "pbr.build" 4 | 5 | -------------------------------------------------------------------------------- /releasenotes/notes/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/releasenotes/notes/.placeholder -------------------------------------------------------------------------------- /releasenotes/notes/add-static-scheduler-a3b0f54b964ae306.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | A new BGP scheduler has been added, called ``StaticScheduler``. It will 5 | not perform any automatic scheduling of speakers to agents, instead 6 | relying on API calls to perform explicit scheduling, fulfilling the 7 | needs of larger deployments. 8 | See also bug `1920065 `_. 9 | The plan is to make the ``StaticScheduler`` the default option for the next 10 | release and possibly deprecate the current default, ``ChanceScheduler``. 11 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-py27-support-795303ca12cccd34.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 2.7 support has been dropped. Last release of 5 | neutron-dynamic-routing to support python 2.7 is OpenStack Train. The 6 | minimum version of Python now supported by neutron-dynamic-routing is 7 | Python 3.6. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-py39-a9a5f0b7addc2f12.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 3.9 support has been dropped. The last release of neutron-dynamic-routing 5 | to support py39 is Openstack 2025.1 (Epoxy). 6 | For details about supported runtimes in Openstack 2025.2 please check: 7 | https://governance.openstack.org/tc/reference/runtimes/2025.2.html 8 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-python-3-6-and-3-7-efc3424202bf3f90.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 3.6 & 3.7 support has been dropped. The minimum version of Python now 5 | supported is Python 3.8. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/dvr-aware-announcements-24bfcb8fee87161d.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | DVR-aware BGP announcements are now supported for IPv4. Host routes 5 | for instances are announced as /32 host routes, using the appropriate 6 | floating IP gateway port on the host as the next-hop. This allows 7 | network traffic to bypass the centralized router on the network 8 | node and ingress/egress directly on the compute node. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/fix-address-scope-calculation-c8ac84662a6547bd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | Fixes the iteration to obtain the address_scope linked to a subnet. 5 | A network can be linked to more than one subnet (ipv4 and ipv6), 6 | but if one of them does not have an address_scope, a null object 7 | element access failure occured. 8 | See bug `1998104 `_. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/mp-bgp-support-d408e8569e94d07f.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | The os-ken driver now supports announcement of IPv6 prefixes 5 | over IPv4 sessions and vice-versa. Peers can opt in/out with 6 | MP-BGP capabilities configured on the peer end of BGP sessions 7 | established with the os-ken driver. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/rehome-dynamic-routing-apidef-d656e3273baac4e8.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - The API definitions of ``neutron-dynamic-routing``, ``bgp``, 4 | ``bgp_4byte_asn`` and ``bgp_dragent_scheduler``, are now available 5 | in ``neutron_lib.api.definitions``. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/rpc-workers-4941f3b9136418df.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | The BGP service plugin RPC queue has been added to RPC workers, like 5 | it is done in other Neutron service plugins (l3-plugin, metering, etc.). 6 | This fixes RPC requests and AMQP heartbeats not getting processed in 7 | time, causing AMQP connection dropping, and other unpredictable unwanted 8 | behavior. 9 | See bug `1974057 `_. 10 | -------------------------------------------------------------------------------- /releasenotes/notes/sqlalchemy-20-abaa3d2895131ab4.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | In preparation for the upcoming SQLAlchemy 2.0 release, several fixes 5 | have been made regarding the use of context decorators. 6 | See bugs `1980671 `_ 7 | and `1984238 `_. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/static-scheduler-2288b8173f9357a6.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | Multiple issues in the implementation of the StaticScheduler have been 5 | fixed that may have caused peers to be erroneously descheduled. 6 | See bug `1980235 `_. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/support-4byte-asn-d89d7100c0890ebf.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - The neutron-dynamic-routing supports 4-byte AS Numbers now. -------------------------------------------------------------------------------- /releasenotes/source/2023.1.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2023.1 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/2023.1 7 | -------------------------------------------------------------------------------- /releasenotes/source/2023.2.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2023.2 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2023.2 7 | -------------------------------------------------------------------------------- /releasenotes/source/2024.1.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2024.1 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2024.1 7 | -------------------------------------------------------------------------------- /releasenotes/source/2024.2.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2024.2 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2024.2 7 | -------------------------------------------------------------------------------- /releasenotes/source/2025.1.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2025.1 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2025.1 7 | -------------------------------------------------------------------------------- /releasenotes/source/README.rst: -------------------------------------------------------------------------------- 1 | =========================================== 2 | Neutron Dynamic Routing Release Notes Howto 3 | =========================================== 4 | 5 | Release notes are a new feature for documenting new features in 6 | OpenStack projects. Background on the process, tooling, and 7 | methodology is documented in a `mailing list post by Doug Hellman `_. 8 | 9 | For information on how to create release notes, please consult the 10 | `Release Notes documentation `_. 11 | -------------------------------------------------------------------------------- /releasenotes/source/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/releasenotes/source/_static/.placeholder -------------------------------------------------------------------------------- /releasenotes/source/_templates/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/neutron-dynamic-routing/446514412b4e516faa15c5c1481e0e4f13cba93d/releasenotes/source/_templates/.placeholder -------------------------------------------------------------------------------- /releasenotes/source/index.rst: -------------------------------------------------------------------------------- 1 | ====================================== 2 | Neutron Dynamic Routing Release Notes 3 | ====================================== 4 | 5 | .. toctree:: 6 | :maxdepth: 1 7 | 8 | README.rst 9 | unreleased 10 | 2025.1 11 | 2024.2 12 | 2024.1 13 | 2023.2 14 | 2023.1 15 | zed 16 | yoga 17 | xena 18 | wallaby 19 | victoria 20 | ussuri 21 | train 22 | stein 23 | rocky 24 | queens 25 | -------------------------------------------------------------------------------- /releasenotes/source/queens.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Queens Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/queens 7 | -------------------------------------------------------------------------------- /releasenotes/source/rocky.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Rocky Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/rocky 7 | -------------------------------------------------------------------------------- /releasenotes/source/stein.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Stein Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/stein 7 | -------------------------------------------------------------------------------- /releasenotes/source/train.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Train Series Release Notes 3 | ========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/train 7 | -------------------------------------------------------------------------------- /releasenotes/source/unreleased.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | Current Series Release Notes 3 | ============================= 4 | 5 | .. release-notes:: 6 | -------------------------------------------------------------------------------- /releasenotes/source/ussuri.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Ussuri Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/ussuri 7 | -------------------------------------------------------------------------------- /releasenotes/source/victoria.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | Victoria Series Release Notes 3 | ============================= 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/victoria 7 | -------------------------------------------------------------------------------- /releasenotes/source/wallaby.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | Wallaby Series Release Notes 3 | ============================ 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/wallaby 7 | -------------------------------------------------------------------------------- /releasenotes/source/xena.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Xena Series Release Notes 3 | ========================= 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/xena 7 | -------------------------------------------------------------------------------- /releasenotes/source/yoga.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Yoga Series Release Notes 3 | ========================= 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/yoga 7 | -------------------------------------------------------------------------------- /releasenotes/source/zed.rst: -------------------------------------------------------------------------------- 1 | ======================== 2 | Zed Series Release Notes 3 | ======================== 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/zed 7 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Requirements lower bounds listed here are our best effort to keep them up to 2 | # date but we do not test them so no guarantee of having them all correct. If 3 | # you find any incorrect lower bounds, let us know or propose a fix. 4 | pbr!=2.1.0,>=2.0.0 # Apache-2.0 5 | 6 | eventlet>=0.27.0 # MIT 7 | httplib2>=0.9.1 # MIT 8 | netaddr>=0.7.18 # BSD 9 | SQLAlchemy>=1.3.3 # MIT 10 | alembic>=0.9.6 # MIT 11 | neutron-lib>=2.12.0 # Apache-2.0 12 | os-ken>=0.3.0 # Apache-2.0 13 | oslo.config>=5.2.0 # Apache-2.0 14 | oslo.db>=4.44.0 # Apache-2.0 15 | oslo.log>=3.36.0 # Apache-2.0 16 | oslo.messaging>=5.29.0 # Apache-2.0 17 | oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0 18 | oslo.service!=1.28.1,>=1.24.0 # Apache-2.0 19 | oslo.utils>=4.5.0 # Apache-2.0 20 | neutron>=25.0.0.0b1 # Apache-2.0 21 | 22 | # The comment below indicates this project repo is current with neutron-lib 23 | # and should receive neutron-lib consumption patches as they are released 24 | # in neutron-lib. It also implies the project will stay current with TC 25 | # and infra initiatives ensuring consumption patches can land. 26 | # neutron-lib-current 27 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = neutron-dynamic-routing 3 | summary = Neutron Dynamic Routing 4 | description_file = 5 | README.rst 6 | author = OpenStack 7 | author_email = openstack-discuss@lists.openstack.org 8 | home_page = https://docs.openstack.org/neutron-dynamic-routing/latest/ 9 | python_requires = >=3.10 10 | classifier = 11 | Environment :: OpenStack 12 | Intended Audience :: Information Technology 13 | Intended Audience :: System Administrators 14 | License :: OSI Approved :: Apache Software License 15 | Operating System :: POSIX :: Linux 16 | Programming Language :: Python 17 | Programming Language :: Python :: Implementation :: CPython 18 | Programming Language :: Python :: 3 :: Only 19 | Programming Language :: Python :: 3 20 | Programming Language :: Python :: 3.10 21 | Programming Language :: Python :: 3.11 22 | Programming Language :: Python :: 3.12 23 | 24 | [files] 25 | packages = 26 | neutron_dynamic_routing 27 | 28 | [entry_points] 29 | console_scripts = 30 | neutron-bgp-dragent = neutron_dynamic_routing.cmd.eventlet.agents.bgp_dragent:main 31 | neutron.db.alembic_migrations = 32 | neutron-dynamic-routing = neutron_dynamic_routing.db.migration:alembic_migrations 33 | oslo.config.opts = 34 | bgp.agent = neutron_dynamic_routing.services.bgp.common.opts:list_bgp_agent_opts 35 | oslo.policy.policies = 36 | neutron-dynamic-routing = neutron_dynamic_routing.policies:list_rules 37 | neutron.policies = 38 | neutron-dynamic-routing = neutron_dynamic_routing.policies:list_rules 39 | neutron.service_plugins = 40 | bgp = neutron_dynamic_routing.services.bgp.bgp_plugin:BgpPlugin 41 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import setuptools 17 | 18 | setuptools.setup( 19 | setup_requires=['pbr>=2.0.0'], 20 | pbr=True) 21 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | hacking>=6.1.0,<6.2.0 # Apache-2.0 2 | coverage!=4.4,>=4.0 # Apache-2.0 3 | fixtures>=3.0.0 # Apache-2.0/BSD 4 | flake8-import-order>=0.18.0,<0.19.0 # LGPLv3 5 | python-subunit>=1.0.0 # Apache-2.0/BSD 6 | oslo.concurrency>=3.26.0 # Apache-2.0 7 | stestr>=1.0.0 # Apache-2.0 8 | testresources>=2.0.0 # Apache-2.0/BSD 9 | testtools>=2.2.0 # MIT 10 | testscenarios>=0.4 # Apache-2.0/BSD 11 | WebOb>=1.8.2 # MIT 12 | WebTest>=2.0.27 # MIT 13 | oslotest>=3.2.0 # Apache-2.0 14 | tempest>=17.1.0 # Apache-2.0 15 | -------------------------------------------------------------------------------- /tools/check_unit_test_structure.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script identifies the unit test modules that do not correspond 4 | # directly with a module in the code tree. See TESTING.rst for the 5 | # intended structure. 6 | 7 | neutron_path=$(cd "$(dirname "$0")/.." && pwd) 8 | base_test_path=neutron_dynamic_routing/tests/unit 9 | test_path=$neutron_path/$base_test_path 10 | 11 | test_files=$(find ${test_path} -iname 'test_*.py') 12 | 13 | ignore_regexes=( 14 | "^plugins.*$" 15 | ) 16 | 17 | error_count=0 18 | ignore_count=0 19 | total_count=0 20 | for test_file in ${test_files[@]}; do 21 | relative_path=${test_file#$test_path/} 22 | expected_path=$(dirname $neutron_path/neutron_dynamic_routing/$relative_path) 23 | test_filename=$(basename "$test_file") 24 | expected_filename=${test_filename#test_} 25 | # Module filename (e.g. foo/bar.py -> foo/test_bar.py) 26 | filename=$expected_path/$expected_filename 27 | # Package dir (e.g. foo/ -> test_foo.py) 28 | package_dir=${filename%.py} 29 | if [ ! -f "$filename" ] && [ ! -d "$package_dir" ]; then 30 | for ignore_regex in ${ignore_regexes[@]}; do 31 | if [[ "$relative_path" =~ $ignore_regex ]]; then 32 | ((ignore_count++)) 33 | continue 2 34 | fi 35 | done 36 | echo "Unexpected test file: $base_test_path/$relative_path" 37 | ((error_count++)) 38 | fi 39 | ((total_count++)) 40 | done 41 | 42 | if [ "$ignore_count" -ne 0 ]; then 43 | echo "$ignore_count unmatched test modules were ignored" 44 | fi 45 | 46 | if [ "$error_count" -eq 0 ]; then 47 | echo 'Success! All test modules match targets in the code tree.' 48 | exit 0 49 | else 50 | echo "Failure! $error_count of $total_count test modules do not match targets in the code tree." 51 | exit 1 52 | fi 53 | -------------------------------------------------------------------------------- /tools/clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | rm -rf ./*.deb ./*.tar.gz ./*.dsc ./*.changes 3 | rm -rf */*.deb 4 | rm -rf ./plugins/**/build/ ./plugins/**/dist 5 | rm -rf ./plugins/**/lib/neutron_*_plugin.egg-info ./plugins/neutron-* 6 | -------------------------------------------------------------------------------- /tools/generate_config_file_samples.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | set -e 16 | 17 | GEN_CMD=oslo-config-generator 18 | 19 | if ! type "$GEN_CMD" > /dev/null; then 20 | echo "ERROR: $GEN_CMD not installed on the system." 21 | exit 1 22 | fi 23 | 24 | for file in `ls etc/oslo-config-generator/*`; do 25 | $GEN_CMD --config-file=$file 26 | done 27 | 28 | set -x 29 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py3,pep8,pylint 3 | minversion = 3.18.0 4 | 5 | [testenv] 6 | setenv = VIRTUAL_ENV={envdir} 7 | OS_LOG_CAPTURE={env:OS_LOG_CAPTURE:true} 8 | OS_STDOUT_CAPTURE={env:OS_STDOUT_CAPTURE:true} 9 | OS_STDERR_CAPTURE={env:OS_STDERR_CAPTURE:true} 10 | PYTHONWARNINGS=default::DeprecationWarning 11 | usedevelop = True 12 | deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} 13 | -r{toxinidir}/requirements.txt 14 | -r{toxinidir}/test-requirements.txt 15 | allowlist_externals = 16 | find 17 | bash 18 | commands = 19 | find . -type f -name "*.py[c|o]" -delete 20 | find . -type l -name "*.py[c|o]" -delete 21 | find . -depth -path "*/__pycache__*" -delete 22 | stestr run {posargs} 23 | # there is also secret magic in stestr which lets you run in a fail only 24 | # mode. To do this define the TRACE_FAILONLY environmental variable. 25 | 26 | [testenv:functional] 27 | setenv = OS_TEST_PATH=./neutron_dynamic_routing/tests/functional 28 | commands = 29 | stestr run {posargs} 30 | stestr slowest 31 | 32 | [testenv:releasenotes] 33 | deps = {[testenv:docs]deps} 34 | commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html 35 | 36 | [testenv:pep8] 37 | commands = 38 | flake8 39 | neutron-db-manage --subproject neutron-dynamic-routing --database-connection sqlite:// check_migration 40 | {[testenv:genconfig]commands} 41 | {[testenv:genpolicy]commands} 42 | 43 | [testenv:cover] 44 | setenv = 45 | {[testenv]setenv} 46 | PYTHON=coverage run --source neutron_dynamic_routing --parallel-mode 47 | commands = 48 | stestr run --no-subunit-trace {posargs} 49 | coverage combine 50 | coverage html -d cover 51 | coverage xml -o cover/coverage.xml 52 | 53 | [testenv:venv] 54 | commands = {posargs} 55 | 56 | [testenv:docs] 57 | deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} 58 | -r{toxinidir}/doc/requirements.txt 59 | commands = 60 | sphinx-build -W -b html doc/source doc/build/html 61 | 62 | [testenv:pdf-docs] 63 | deps = {[testenv:docs]deps} 64 | allowlist_externals = 65 | make 66 | commands = 67 | sphinx-build -W -b latex doc/source doc/build/pdf 68 | make -C doc/build/pdf 69 | 70 | [flake8] 71 | # E125 continuation line does not distinguish itself from next logical line 72 | # E126 continuation line over-indented for hanging indent 73 | # E128 continuation line under-indented for visual indent 74 | # E129 visually indented line with same indent as next logical line 75 | # E265 block comment should start with ‘# ‘ 76 | # H405 multi line docstring summary not separated with an empty line 77 | # I202 Additional newline in a group of imports 78 | # TODO(marun) H404 multi line docstring should start with a summary 79 | # N530 direct neutron imports not allowed 80 | # TODO(ihrachys) -- reenable N537 when new neutron-lib release is available 81 | # N537 Log messages should not be translated 82 | # H106 Don’t put vim configuration in source files 83 | # H203 Use assertIs(Not)None to check for None 84 | # W504 line break after binary operator 85 | # (W503 and W504 are incompatible and we need to choose one of them. 86 | # Existing codes follows W503, so we disable W504.) 87 | ignore = E125,E126,E128,E129,E265,H404,H405,I202,N530,N537,W504 88 | enable-extensions=H106,H203 89 | show-source = true 90 | exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools,.ropeproject,rally-scenarios 91 | import-order-style = pep8 92 | 93 | [testenv:pylint] 94 | deps = 95 | {[testenv]deps} 96 | pylint 97 | commands = 98 | pylint --rcfile=.pylintrc --output-format=colorized {posargs:neutron_dynamic_routing} 99 | 100 | [hacking] 101 | import_exceptions = neutron_dynamic_routing._i18n 102 | local-check-factory = neutron_lib.hacking.checks.factory 103 | 104 | [testenv:genconfig] 105 | commands = bash {toxinidir}/tools/generate_config_file_samples.sh 106 | 107 | [testenv:genpolicy] 108 | commands = oslopolicy-sample-generator --config-file=etc/oslo-policy-generator/policy.conf 109 | 110 | [testenv:dev] 111 | # run locally (not in the gate) using editable mode 112 | # https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs 113 | commands = 114 | pip install -q -e "git+https://opendev.org/openstack/neutron#egg=neutron" 115 | 116 | [testenv:py-dev] 117 | commands = 118 | {[testenv:dev]commands} 119 | {[testenv]commands} 120 | 121 | [testenv:pep8-dev] 122 | deps = 123 | {[testenv]deps} 124 | commands = 125 | {[testenv:dev]commands} 126 | {[testenv:pep8]commands} 127 | --------------------------------------------------------------------------------