From 8f1ca7078619b8ab67de2580522f7174bed40774 Mon Sep 17 00:00:00 2001
From: Tim Rozet <trozet@redhat.com>
Date: Tue, 24 Nov 2015 14:39:12 -0500
Subject: [PATCH] Adds configuration support for OpenDaylight SDN Controller

In order to use OpenDaylight with Neutron, ML2 must be configured to
point to the OpenDaylight controller instance.  It also requires the
networking-odl python library to drive communication with ODL.
Additionally each Open vSwitch instance must be configured to set the ODL
Controller as it's manager.

Change-Id: If067e1057bec2d48f700838d86077a550bd27bd2
Signed-off-by: Tim Rozet <trozet@redhat.com>
---
 manifests/plugins/ml2/opendaylight.pp              | 51 +++++++++++++++++
 manifests/plugins/ovs/opendaylight.pp              | 63 +++++++++++++++++++++
 .../neutron_plugins_ml2_opendaylight_spec.rb       | 65 ++++++++++++++++++++++
 .../neutron_plugins_ovs_opendaylight_spec.rb       | 60 ++++++++++++++++++++
 4 files changed, 239 insertions(+)
 create mode 100644 manifests/plugins/ml2/opendaylight.pp
 create mode 100644 manifests/plugins/ovs/opendaylight.pp
 create mode 100644 spec/classes/neutron_plugins_ml2_opendaylight_spec.rb
 create mode 100644 spec/classes/neutron_plugins_ovs_opendaylight_spec.rb

diff --git a/manifests/plugins/ml2/opendaylight.pp b/manifests/plugins/ml2/opendaylight.pp
new file mode 100644
index 0000000..7dc7937
--- /dev/null
+++ b/manifests/plugins/ml2/opendaylight.pp
@@ -0,0 +1,51 @@
+#
+# Install the OpenDaylight and generate config file
+# from parameters in the other classes.
+#
+# === Parameters
+#
+# [*odl_controller_ip*]
+# (required) The OpenDaylight controller IP
+#
+# [*package_ensure*]
+# (optional) The intended state of the python-networking-odl
+# package, i.e. any of the possible values of the 'ensure'
+# property for a package resource type.
+# Defaults to 'present'
+#
+# [*odl_username*]
+# (optional) The opendaylight controller username
+# Defaults to 'admin'
+#
+# [*odl_password*]
+# (optional) The opendaylight controller password
+# Defaults to 'admin'
+#
+# [*odl_port*]
+# (optional) The opendaylight controller port
+# Defaults to '8080'
+#
+class neutron::plugins::ml2::opendaylight (
+  $odl_controller_ip,
+  $package_ensure    = 'present',
+  $odl_username      = 'admin',
+  $odl_password      = 'admin',
+  $odl_port          = '8080',
+) {
+  include ::neutron::params
+  require ::neutron::plugins::ml2
+
+  ensure_resource('package', 'python-networking-odl',
+    {
+      ensure => $package_ensure,
+      tag    => 'openstack',
+    }
+  )
+
+  neutron_plugin_ml2 {
+    'ml2_odl/username': value => $odl_username;
+    'ml2_odl/password': value => $odl_password;
+    'ml2_odl/url':      value => "http://${odl_controller_ip}:${odl_port}/controller/nb/v2/neutron";
+  }
+
+}
diff --git a/manifests/plugins/ovs/opendaylight.pp b/manifests/plugins/ovs/opendaylight.pp
new file mode 100644
index 0000000..3ebdb0e
--- /dev/null
+++ b/manifests/plugins/ovs/opendaylight.pp
@@ -0,0 +1,63 @@
+#
+# Configure OVS to use OpenDaylight
+#
+# === Parameters
+#
+# [*odl_controller_ip*]
+# (required) The OpenDaylight controller IP
+#
+# [*tunnel_ip*]
+# (required) The IP of the host to use for tunneling
+# tenant VXLAN/GRE over
+#
+# [*odl_port*]
+# (optional) The opendaylight controller port
+# Defaults to '8080'
+#
+# [*provider_mappings*]
+# (optional) bridge mappings required if using VLAN
+# tenant type.  Example: provider_mappings=br-ex:eth0
+# Defaults to false
+#
+# [*odl_username*]
+# (optional) The opendaylight controller username
+# Defaults to 'admin'
+#
+# [*odl_password*]
+# (optional) The opendaylight controller password
+# Defaults to 'admin'
+#
+class neutron::plugins::ovs::opendaylight (
+  $odl_controller_ip,
+  $tunnel_ip,
+  $odl_port          = '8080',
+  $provider_mappings = false,
+  $odl_username      = 'admin',
+  $odl_password      = 'admin',
+) {
+
+  exec { 'Wait for NetVirt OVSDB to come up':
+    command   => "/bin/curl -o /dev/null --fail --silent --head -u ${odl_username}:${odl_password} \
+                    http://${odl_controller_ip}:${odl_port}/restconf/operational/network-topology:network-topology/topology/netvirt:1",
+    tries     => 20,
+    try_sleep => 60,
+  } ->
+  # OVS manager
+  exec { 'Set OVS Manager to OpenDaylight':
+    command => "/usr/bin/ovs-vsctl set-manager tcp:${odl_controller_ip}:6640",
+    unless  => "/usr/bin/ovs-vsctl show | /usr/bin/grep 'Manager \"tcp:${odl_controller_ip}:6640\"'",
+  } ->
+  # local ip
+  exec { 'Set local_ip Other Option':
+    command => "/usr/bin/ovs-vsctl set Open_vSwitch $(ovs-vsctl get Open_vSwitch . _uuid) other_config:local_ip=${tunnel_ip}",
+    unless  => "/usr/bin/ovs-vsctl list Open_vSwitch | /usr/bin/grep 'local_ip=\"${tunnel_ip}\"'",
+  }
+
+  # set mappings for VLAN
+  if $provider_mappings {
+    exec { 'Set provider_mappings Other Option':
+      command => "/usr/bin/ovs-vsctl set Open_vSwitch $(ovs-vsctl get Open_vSwitch . _uuid) other_config:provider_mappings=${provider_mappings}",
+      unless  => "/usr/bin/ovs-vsctl list Open_vSwitch | /usr/bin/grep 'provider_mappings' | /usr/bin/grep ${provider_mappings}",
+    }
+  }
+}
diff --git a/spec/classes/neutron_plugins_ml2_opendaylight_spec.rb b/spec/classes/neutron_plugins_ml2_opendaylight_spec.rb
new file mode 100644
index 0000000..5772b3b
--- /dev/null
+++ b/spec/classes/neutron_plugins_ml2_opendaylight_spec.rb
@@ -0,0 +1,65 @@
+require 'spec_helper'
+
+describe 'neutron::plugins::ml2::opendaylight' do
+
+  let :pre_condition do
+    "class { 'neutron::server': auth_password => 'password'}
+     class { 'neutron':
+      rabbit_password => 'passw0rd',
+      core_plugin     => 'neutron.plugins.ml2.plugin.Ml2Plugin' }"
+  end
+
+  let :default_params do
+    {
+      :package_ensure => 'present',
+      :odl_username   => 'admin',
+      :odl_password   => 'admin',
+      :odl_port       => '8080',
+    }
+  end
+
+  let :params do
+    {
+      :odl_controller_ip => '127.0.0.1',
+    }
+  end
+
+  let :test_facts do
+    {
+      :operatingsystem        => 'default',
+      :operatingsystemrelease => 'default',
+    }
+  end
+
+
+  shared_examples_for 'neutron plugin opendaylight ml2' do
+    before do
+      params.merge!(default_params)
+    end
+
+    it { is_expected.to contain_class('neutron::params') }
+
+    it 'should have' do
+      is_expected.to contain_package('python-networking-odl').with(
+        :ensure => params[:package_ensure],
+        :tag    => 'openstack'
+        )
+    end
+  end
+
+  context 'on RedHat platforms' do
+    let :facts do
+      test_facts.merge({:osfamily => 'RedHat'})
+    end
+
+    it_configures 'neutron plugin opendaylight ml2'
+  end
+
+  context 'on Debian platforms' do
+    let :facts do
+      test_facts.merge({:osfamily => 'Debian'})
+    end
+
+    it_configures 'neutron plugin opendaylight ml2'
+  end
+end
diff --git a/spec/classes/neutron_plugins_ovs_opendaylight_spec.rb b/spec/classes/neutron_plugins_ovs_opendaylight_spec.rb
new file mode 100644
index 0000000..d6b93df
--- /dev/null
+++ b/spec/classes/neutron_plugins_ovs_opendaylight_spec.rb
@@ -0,0 +1,60 @@
+require 'spec_helper'
+
+describe 'neutron::plugins::ovs::opendaylight' do
+
+  let :pre_condition do
+    "class { 'neutron::server': auth_password => 'password'}
+     class { 'neutron':
+      rabbit_password => 'passw0rd',
+      core_plugin     => 'neutron.plugins.ml2.plugin.Ml2Plugin' }"
+  end
+
+  let :default_params do
+    {
+      :provider_mappings => false,
+      :odl_username      => 'admin',
+      :odl_password      => 'admin',
+      :odl_port          => '8080',
+    }
+  end
+
+  let :params do
+    {
+      :odl_controller_ip => '127.0.0.1',
+      :tunnel_ip         => '127.0.0.1',
+    }
+  end
+
+  let :test_facts do
+    {
+      :operatingsystem        => 'default',
+      :operatingsystemrelease => 'default',
+    }
+  end
+
+
+  shared_examples_for 'neutron plugin opendaylight ovs' do
+    before do
+      params.merge!(default_params)
+    end
+
+    it { is_expected.to contain_class('neutron::params') }
+
+  end
+
+  context 'on RedHat platforms' do
+    let :facts do
+      test_facts.merge({:osfamily => 'RedHat'})
+    end
+
+    it_configures 'neutron plugin opendaylight ovs'
+  end
+
+  context 'on Debian platforms' do
+    let :facts do
+      test_facts.merge({:osfamily => 'Debian'})
+    end
+
+    it_configures 'neutron plugin opendaylight ovs'
+  end
+end
-- 
2.5.0