From 7dce6e2b07ea1c309f78d84a9dec82e5727d5797 Mon Sep 17 00:00:00 2001 From: Juan Vidal Allende Date: Tue, 8 Aug 2017 09:25:54 +0200 Subject: [PATCH] Add option to deploy OpenDaylight SDN Controller - This commit adds a new ML2 backend that uses OpenDaylight SDN Controller and networking-odl to handle neutron networking. - Installation of OpenDaylight uses the official ansible-opendaylight Ansible role. - It requires OpenvSwitch as traffic forwarder. - New test scenario for OpenDaylight Change-Id: I67083992660a1aca4b6edd5ecf4f28113c0e547f --- defaults/main.yml | 3 + doc/source/app-opendaylight.rst | 96 +++++++++++++++++++ doc/source/index.rst | 1 + meta/main.yml | 6 ++ ...opendaylight-support-453dc9324eafaae7.yaml | 7 ++ tasks/providers/opendaylight_config.yml | 61 ++++++++++++ tests/ansible-role-requirements.yml | 4 + tests/neutron-overrides-opendaylight.yml | 40 ++++++++ tests/opendaylight_inventory | 61 ++++++++++++ tox.ini | 10 ++ vars/main.yml | 20 +++- vars/redhat-7.yml | 2 + vars/suse-42.yml | 2 + vars/ubuntu-16.04.yml | 2 + 14 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 doc/source/app-opendaylight.rst create mode 100644 releasenotes/notes/neutron-opendaylight-support-453dc9324eafaae7.yaml create mode 100644 tasks/providers/opendaylight_config.yml create mode 100644 tests/neutron-overrides-opendaylight.yml create mode 100644 tests/opendaylight_inventory diff --git a/defaults/main.yml b/defaults/main.yml index dde11c74..5cfd45b2 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -50,6 +50,8 @@ networking_calico_git_repo: https://git.openstack.org/openstack/networking-calic networking_calico_git_install_branch: master dragonflow_git_repo: https://git.openstack.org/openstack/dragonflow dragonflow_git_install_branch: master +networking_odl_git_repo: https://git.openstack.org/openstack/networking-odl +networking_odl_git_install_branch: master # Developer mode neutron_developer_mode: false @@ -123,6 +125,7 @@ neutron_metering_agent_init_overrides: {} neutron_ml2_conf_ini_overrides: {} neutron_neutron_conf_overrides: {} neutron_nuage_conf_ini_overrides: {} +neutron_opendaylight_conf_ini_overrides: {} neutron_openvswitch_agent_ini_overrides: {} neutron_openvswitch_agent_init_overrides: {} # Provide a list of access controls to update the default policy.json with. diff --git a/doc/source/app-opendaylight.rst b/doc/source/app-opendaylight.rst new file mode 100644 index 00000000..f8a9e741 --- /dev/null +++ b/doc/source/app-opendaylight.rst @@ -0,0 +1,96 @@ +======================================== +Scenario - OpenDaylight and Open vSwitch +======================================== + +Overview +~~~~~~~~ + +Deployers can choose to enhance neutron capabilities by means of the +OpenDaylight SDN Controller, which works together with Open vSwitch to provide +advanced networking capabilities. This document explains how to use them +in your environment. + +Recommended reading +~~~~~~~~~~~~~~~~~~~ + +Since this is an extension of the basic Open vSwitch scenario, it is worth +reading that scenario to get some background. It is also recommended to be +familiar with OpenDaylight and networking-odl projects and their configuration. + + * `Scenario: Open vSwitch `_ + * `OpenDaylight SDN Controller `_ + * `Networking-odl `_ + +Prerequisites +~~~~~~~~~~~~~ + +The `OpenDaylight Ansible role `_ +needs to be available in Ansible's role path. + +OpenStack-Ansible user variables +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the following user variables in your +``/etc/openstack_deploy/user_variables.yml``: + +.. code-block:: yaml + + ### Ensure the openvswitch kernel module is loaded + openstack_host_specific_kernel_modules: + - name: "openvswitch" + pattern: "CONFIG_OPENVSWITCH" + group: "network_hosts" + + ### Use OpenDaylight SDN Controller + neutron_plugin_type: "ml2.opendaylight" + odl_ip: "{{ hostvars[groups['opendaylight'][0]]['ansible_default_ipv4']['address'] }}" + neutron_opendaylight_conf_ini_overrides: + ml2_odl: + url: "http://{{ odl_ip }}:8080/controller/nb/v2/neutron" + username: + password: + +Most of the content of this file is self-explanatory. The first block is used +to deploy Open vSwitch in all network hosts. + +The second block is instructing Ansible to deploy OpenDaylight SDN Controller. +This is done by specifying ``neutron_plugin_type`` to ``ml2.opendaylight``. +The IP address of the OpenDaylight controller needs to be inferred from the +deployment configuration as well. That can be used with a line such as the one +in the example. + +After that, some configuration is needed to integrate OpenDaylight and Neutron, +using the ``ml2_odl`` section. + + * **url**: OpenDaylight's northbound url. This is automatically retrieved from + the deployment configuration, so just need to copy the example line. + * **username**: OpenDaylight northbound API username + * **password**: OpenDaylight northbound API password for + +Apart from these options, the deployer might want to change the installation +method for OpenDaylight Ansible role. This role uses pre-packaged binaries, +which can be either ``deb`` or ``rpm`` files, and by default it will download +these binaries from OpenDaylight repositories, trying to guess the correct +package depending on the underlying operating system. + +Also, the set of features that will be enabled in the OpenDaylight SDN +controller defaults to ``odl-netvirt-openstack``, which is the minimum for an +OpenStack integration. The deployer can modify this value by providing a list +of feature names in the ``opendaylight_extra_features`` variable. + +For more information, see OpenDaylight Ansible role documentation. + +Security information +~~~~~~~~~~~~~~~~~~~~ + +Communications between the OpenDaylight SDN Controller and Open vSwitch are not +secured by default. For further information on securing this interface, see +these manuals: + +TLS Support on OpenDaylight OpenFlow plugin: + + https://wiki.opendaylight.org/view/OpenDaylight_OpenFlow_Plugin:_TLS_Support + +Secure Communication Between OpenFlow Switches and Controllers + + https://www.thinkmind.org/download.php?articleid=afin_2015_2_30_40047 diff --git a/doc/source/index.rst b/doc/source/index.rst index 3ad5dbce..47b85ba0 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -9,6 +9,7 @@ Neutron role for OpenStack-Ansible app-openvswitch.rst app-nuage.rst app-calico.rst + app-opendaylight.rst :tags: openstack, neutron, cloud, ansible :category: \*nix diff --git a/meta/main.yml b/meta/main.yml index 418b4a9d..3e562415 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -53,3 +53,9 @@ dependencies: neutron_services['neutron-server']['group'] ]) | length > 0 }}" + - role: opendaylight + install_method: "{{ opendaylight_install_method }}" + extra_features: "{{ opendaylight_extra_features }}" + when: + - neutron_plugin_type == "ml2.opendaylight" + - inventory_hostname in groups["opendaylight"] diff --git a/releasenotes/notes/neutron-opendaylight-support-453dc9324eafaae7.yaml b/releasenotes/notes/neutron-opendaylight-support-453dc9324eafaae7.yaml new file mode 100644 index 00000000..597a20e9 --- /dev/null +++ b/releasenotes/notes/neutron-opendaylight-support-453dc9324eafaae7.yaml @@ -0,0 +1,7 @@ +--- +features: + - The ``OpenDaylight SDN Controller`` can be deployed as + a neutron ML2 backend. + You can set the ``neutron_plugin_type`` to + ``ml2.opendaylight`` to utilize this code path. + The usage of ``OpenDaylight`` is currently experimental. diff --git a/tasks/providers/opendaylight_config.yml b/tasks/providers/opendaylight_config.yml new file mode 100644 index 00000000..73a515a7 --- /dev/null +++ b/tasks/providers/opendaylight_config.yml @@ -0,0 +1,61 @@ +--- +# Copyright 2017, Ericsson AB +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Install OpenDaylight pip packages + pip: + name: "{{ neutron_optional_opendaylight_pip_packages }}" + state: "{{ neutron_pip_package_state }}" + virtualenv: "{{ neutron_bin | dirname }}" + virtualenv_site_packages: "no" + extra_args: >- + {{ neutron_developer_mode | ternary(pip_install_developer_constraints | default('--constraint /opt/developer-pip-constraints.txt'), '') }} + {{ (pip_install_upper_constraints is defined) | ternary('--constraint ' + pip_install_upper_constraints | default(''),'') }} + {{ pip_install_options | default('') }} + register: install_packages + until: install_packages|success + retries: 5 + delay: 2 + tags: + - opendaylight-install + - opendaylight-pip-packages + +- name: Ensure Open vSwitch service is started and enabled + service: + name: "{{ neutron_ovs_service_name }}" + state: started + enabled: yes + +- name: Retrieve current OvS manager + command: ovs-vsctl get-manager + register: ovs_manager + changed_when: False + +- name: Set ODL as OvS manager + command: ovs-vsctl set-manager tcp:{{ odl_ip }}:6640 + when: ovs_manager.stdout == "" + +- name: Configure hosts for networking-odl, force kernel datapath + command: "{{ neutron_bin }}/neutron-odl-ovs-hostconfig --noovs_dpdk" + when: ovs_manager.stdout == "" + +- name: Retrieve current OvS local ip + command: ovs-vsctl get Open_vSwitch . other_config:local_ip + ignore_errors: yes + register: ovs_local_ip + changed_when: False + +- name: Set local ip for OpenvSwitch + command: "ovs-vsctl set Open_vSwitch . other_config:local_ip={{ neutron_local_ip }}" + when: ovs_local_ip.rc != 0 diff --git a/tests/ansible-role-requirements.yml b/tests/ansible-role-requirements.yml index 3c5d6116..267d0416 100644 --- a/tests/ansible-role-requirements.yml +++ b/tests/ansible-role-requirements.yml @@ -58,3 +58,7 @@ src: https://git.openstack.org/openstack/openstack-ansible-os_neutron scm: git version: stable/ocata +- name: opendaylight + scm: git + src: https://git.opendaylight.org/gerrit/p/integration/packaging/ansible-opendaylight.git + version: master diff --git a/tests/neutron-overrides-opendaylight.yml b/tests/neutron-overrides-opendaylight.yml new file mode 100644 index 00000000..88091268 --- /dev/null +++ b/tests/neutron-overrides-opendaylight.yml @@ -0,0 +1,40 @@ +--- +# Copyright 2017, Ericsson AB +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +### Ensure the openvswitch kernel module is loaded +openstack_host_specific_kernel_modules: + - name: "openvswitch" + pattern: "CONFIG_OPENVSWITCH" + group: "network_hosts" + +### Use OpenDaylight SDN Controller +neutron_plugin_type: "ml2.opendaylight" +odl_ip: "{{ hostvars[groups['opendaylight'][0]]['ansible_default_ipv4']['address'] }}" +neutron_opendaylight_conf_ini_overrides: + ml2_odl: + url: "http://{{ odl_ip }}:8080/controller/nb/v2/neutron" + username: admin + password: admin + +tempest_run: yes + +tempest_plugins: + - name: neutron + repo: https://git.openstack.org/openstack/neutron + branch: master + +tempest_test_whitelist: + - neutron.tests.tempest.api.test_networks* diff --git a/tests/opendaylight_inventory b/tests/opendaylight_inventory new file mode 100644 index 00000000..f12d9d93 --- /dev/null +++ b/tests/opendaylight_inventory @@ -0,0 +1,61 @@ +[all] +localhost +infra1 +server1 +server2 +agents1 +agents2 + +[physical_host] +localhost + +[all_containers] +infra1 +server1 +server2 +agents1 +agents2 + +[rabbitmq_all] +infra1 + +[galera_all] +infra1 + +[memcached_all] +infra1 + +[service_all:children] +rabbitmq_all +galera_all +memcached_all + +[keystone_all] +infra1 + +[neutron_server] +server1 +server2 + +[opendaylight] +server1 + +[neutron_agent] +[neutron_dhcp_agent] +[neutron_metering_agent] +[neutron_l3_agent] +[neutron_lbaas_agent] +[neutron_metadata_agent] + +[neutron_all:children] +neutron_agent +neutron_dhcp_agent +neutron_metering_agent +neutron_l3_agent +neutron_lbaas_agent +neutron_metadata_agent +neutron_server +opendaylight + +[utility_all] +infra1 diff --git a/tox.ini b/tox.ini index 8b34ec1f..410f1f7e 100644 --- a/tox.ini +++ b/tox.ini @@ -148,6 +148,16 @@ commands = bash -c "{toxinidir}/tests/tests-repo-clone.sh" bash -c "{toxinidir}/tests/common/test-ansible-functional.sh" +[testenv:opendaylight] +deps = + {[testenv:ansible]deps} +setenv = + {[testenv]setenv} + ANSIBLE_INVENTORY={toxinidir}/tests/opendaylight_inventory + ANSIBLE_OVERRIDES={toxinidir}/tests/neutron-overrides-opendaylight.yml +commands = + bash -c "{toxinidir}/tests/tests-repo-clone.sh" + bash -c "{toxinidir}/tests/common/test-ansible-functional.sh" [testenv:linters] deps = diff --git a/vars/main.yml b/vars/main.yml index 6ab22278..6778a85c 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -26,7 +26,8 @@ neutron_package_list: |- {% set packages = neutron_distro_packages %} {% if (neutron_services['neutron-openvswitch-agent']['group'] in group_names and neutron_services['neutron-openvswitch-agent'].service_en | bool) or (neutron_services['dragonflow-controller-agent']['group'] in group_names and neutron_services['dragonflow-controller-agent'].service_en | bool) - or (neutron_services['dragonflow-l3-agent']['group'] in group_names and neutron_services['dragonflow-l3-agent'].service_en | bool) %} + or (neutron_services['dragonflow-l3-agent']['group'] in group_names and neutron_services['dragonflow-l3-agent'].service_en | bool) + or (neutron_plugin_type == 'ml2.opendaylight') %} {% set _ = packages.extend(neutron_ovs_distro_packages) %} {% endif %} {% if neutron_services['neutron-linuxbridge-agent']['group'] in group_names and neutron_services['neutron-linuxbridge-agent'].service_en | bool %} @@ -87,6 +88,9 @@ neutron_optional_dragonflow_pip_packages: - dragonflow - python-etcd +neutron_optional_opendaylight_pip_packages: + - networking-odl + neutron_proprietary_nuage_pip_packages: - nuage-openstack-neutron - nuage-openstack-neutronclient @@ -100,6 +104,7 @@ neutron_developer_constraints: - "git+{{ neutron_dynamic_routing_git_repo }}@{{ neutron_dynamic_routing_git_install_branch }}#egg=neutron-dynamic-routing" - "git+{{ networking_calico_git_repo }}@{{ networking_calico_git_install_branch }}#egg=networking-calico" - "git+{{ dragonflow_git_repo }}@{{ dragonflow_git_install_branch }}#egg=dragonflow" + - "git+{{ networking_odl_git_repo }}@{{ networking_odl_git_install_branch }}#egg=networking-odl" neutron_bin: "/openstack/venvs/neutron-{{ neutron_venv_tag }}/bin" @@ -195,6 +200,14 @@ neutron_plugins: mechanisms: "sriovnicswitch" plugin_ini: plugins/ml2/sriov_nic_agent.ini plugin_conf_ini_overrides: "{{ neutron_sriov_nic_agent_ini_overrides }}" + ml2.opendaylight: + drivers_type: "local,flat,vlan,gre,vxlan" + mechanisms: "opendaylight_v2" + plugin_conf_ini_overrides: "{{ neutron_opendaylight_conf_ini_overrides }}" + plugin_core: neutron.plugins.ml2.plugin.Ml2Plugin + plugin_ini: plugins/ml2/ml2_conf.ini + driver_interface: "openvswitch" + l3_agent_mode: "legacy" ### ### ML2 Plugin Configuration @@ -219,6 +232,11 @@ _neutron_non_tunnel_types: # Tunnel network types used by the OVS agent neutron_tunnel_types: "{{ neutron_ml2_drivers_type.split(',') | difference(_neutron_non_tunnel_types) | join(',') }}" +# OpenDaylight +opendaylight_extra_features: ['odl-netvirt-openstack'] +opendaylight_install_method: "{{ (ansible_os_family=='Debian') | ternary('deb_repo', 'rpm_repo') }}" + + ### ### L3 Agent Plugin Configuration ### diff --git a/vars/redhat-7.yml b/vars/redhat-7.yml index 79f15853..242d7d9b 100644 --- a/vars/redhat-7.yml +++ b/vars/redhat-7.yml @@ -18,6 +18,8 @@ neutron_checksum_script: /etc/sysconfig/network-scripts/ifup-post-metadata-check neutron_ovs_distro_packages: - openvswitch +neutron_ovs_service_name: openvswitch + neutron_distro_packages: - conntrack-tools - dnsmasq diff --git a/vars/suse-42.yml b/vars/suse-42.yml index 5e3a20e1..71a0b5a6 100644 --- a/vars/suse-42.yml +++ b/vars/suse-42.yml @@ -19,6 +19,8 @@ neutron_checksum_script: /etc/sysconfig/network/scripts/ifup-post-metadata-check neutron_ovs_distro_packages: - openvswitch +neutron_ovs_service_name: openvswitch + neutron_distro_packages: - conntrack-tools - dnsmasq diff --git a/vars/ubuntu-16.04.yml b/vars/ubuntu-16.04.yml index 3e90be97..360ff2a5 100644 --- a/vars/ubuntu-16.04.yml +++ b/vars/ubuntu-16.04.yml @@ -19,6 +19,8 @@ neutron_ovs_distro_packages: - openvswitch-common - openvswitch-switch +neutron_ovs_service_name: openvswitch-switch + neutron_driver_vpnaas: neutron_vpnaas.services.vpn.device_drivers.strongswan_ipsec.StrongSwanDriver neutron_vpnaas_service_provider: VPN:strongswan:neutron_vpnaas.services.vpn.service_drivers.ipsec.IPsecVPNDriver:default