From 68ddc7a81145999594a4b52d2e59e5874aac0d10 Mon Sep 17 00:00:00 2001 From: Pradeep Kilambi Date: Thu, 19 Jun 2014 17:22:23 -0400 Subject: [PATCH] Support for Cisco ML2 Mech Driver Partially Implements: blueprint support-ml2-nexus-driver Change-Id: I5e0486c9db22abfcbab205e6f57bbafe8f0b5dd4 --- manifests/params.pp | 10 +-- manifests/plugins/ml2/cisco/nexus.pp | 63 +++++++++++++++++ manifests/plugins/ml2/cisco/nexus_creds.pp | 30 ++++++++ .../classes/neutron_plugins_cisco_ml2_spec.rb | 68 +++++++++++++++++++ templates/ml2_conf_cisco.ini.erb | 59 ++++++++++++++++ 5 files changed, 226 insertions(+), 4 deletions(-) create mode 100644 manifests/plugins/ml2/cisco/nexus.pp create mode 100644 manifests/plugins/ml2/cisco/nexus_creds.pp create mode 100644 spec/classes/neutron_plugins_cisco_ml2_spec.rb create mode 100644 templates/ml2_conf_cisco.ini.erb diff --git a/manifests/params.pp b/manifests/params.pp index 88f579e77..914fa4bcd 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -19,8 +19,9 @@ $linuxbridge_server_package = 'openstack-neutron-linuxbridge' $linuxbridge_config_file = '/etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini' - $cisco_server_package = 'openstack-neutron-cisco' - $cisco_config_file = '/etc/neutron/plugins/cisco/cisco_plugins.ini' + $cisco_server_package = 'openstack-neutron-cisco' + $cisco_config_file = '/etc/neutron/plugins/cisco/cisco_plugins.ini' + $cisco_ml2_config_file = '/etc/neutron/plugins/ml2/ml2_conf_cisco.ini' $nvp_server_package = 'openstack-neutron-nicira' @@ -69,8 +70,9 @@ $linuxbridge_server_package = 'neutron-plugin-linuxbridge' $linuxbridge_config_file = '/etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini' - $cisco_server_package = 'neutron-plugin-cisco' - $cisco_config_file = '/etc/neutron/plugins/cisco/cisco_plugins.ini' + $cisco_server_package = 'neutron-plugin-cisco' + $cisco_config_file = '/etc/neutron/plugins/cisco/cisco_plugins.ini' + $cisco_ml2_config_file = '/etc/neutron/plugins/ml2/ml2_conf_cisco.ini' $nvp_server_package = 'neutron-plugin-nicira' diff --git a/manifests/plugins/ml2/cisco/nexus.pp b/manifests/plugins/ml2/cisco/nexus.pp new file mode 100644 index 000000000..079226134 --- /dev/null +++ b/manifests/plugins/ml2/cisco/nexus.pp @@ -0,0 +1,63 @@ +# +# Configure the Mech Driver for cisco neutron plugin +# More info available here: +# https://wiki.openstack.org/wiki/Neutron/ML2/MechCiscoNexus +# +# === Parameters +# +# [*neutron_config*] +# Neutron switch configuration for ml2_cisco_conf.ini +# Example nexus config format: +# { 'switch_hostname' => {'username' => 'admin', +# 'ssh_port' => 22, +# 'password' => "password", +# 'ip_address' => "172.18.117.28", +# 'servers' => { +# 'control01' => "portchannel:20", +# 'control02' => "portchannel:10" +# }}} +# + +class neutron::plugins::ml2::cisco::nexus ( + $nexus_config = undef, +) +{ + if !$nexus_config { + fail('No nexus config specified') + } + + # For Ubuntu: This package is not available upstream + # Please use the source from: + # https://launchpad.net/~cisco-openstack/+archive/python-ncclient + # and install it manually + package { 'python-ncclient': + ensure => installed, + } ~> Service['neutron-server'] + + Neutron_plugin_ml2<||> -> + file { $::neutron::params::cisco_ml2_config_file: + owner => 'root', + group => 'root', + content => template('neutron/ml2_conf_cisco.ini.erb'), + } ~> Service['neutron-server'] + + file {'/var/lib/neutron/.ssh': + ensure => directory, + owner => 'neutron', + require => Package['neutron-server'] + } + + create_resources(neutron::plugins::ml2::cisco::nexus_creds, $nexus_config) + + if $::osfamily == 'Debian' { + file_line { '/etc/default/neutron-server:NEUTRON_PLUGIN_CONFIG': + path => '/etc/default/neutron-server', + match => '^NEUTRON_PLUGIN_CONFIG=(.*)$', + line => "NEUTRON_PLUGIN_CONFIG=${::neutron::params::cisco_ml2_config_file}", + require => [ Package['neutron-server'], + Package['neutron-plugin-ml2']], + notify => Service['neutron-server'], + } + } +} + diff --git a/manifests/plugins/ml2/cisco/nexus_creds.pp b/manifests/plugins/ml2/cisco/nexus_creds.pp new file mode 100644 index 000000000..451cfbe54 --- /dev/null +++ b/manifests/plugins/ml2/cisco/nexus_creds.pp @@ -0,0 +1,30 @@ +# +# Configure the Mech Driver for cisco neutron plugin +# More info available here: +# https://wiki.openstack.org/wiki/Neutron/ML2/MechCiscoNexus +# +# +# neutron::plugins::ml2::cisco::nexus_creds used by +# neutron::plugins::ml2::cisco::nexus +# + +define neutron::plugins::ml2::cisco::nexus_creds( + $username, + $password, + $servers, + $ip_address, + $ssh_port +) { + + neutron_plugin_cisco_credentials { + "${username}/username": value => $username; + "${password}/password": value => $password; + } + + exec {'nexus_creds': + unless => "/bin/cat /var/lib/neutron/.ssh/known_hosts | /bin/grep ${username}", + command => "/usr/bin/ssh-keyscan -t rsa ${username} >> /var/lib/neutron/.ssh/known_hosts", + user => 'neutron', + require => Package['neutron-server'] + } +} diff --git a/spec/classes/neutron_plugins_cisco_ml2_spec.rb b/spec/classes/neutron_plugins_cisco_ml2_spec.rb new file mode 100644 index 000000000..a9a318525 --- /dev/null +++ b/spec/classes/neutron_plugins_cisco_ml2_spec.rb @@ -0,0 +1,68 @@ +# +# Unit tests for neutron::plugins::ml2 class +# + +require 'spec_helper' + +describe 'neutron::plugins::ml2::cisco::nexus' 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 + { + :nexus_config => nil + } + end + + let :params do + {} + end + + let :facts do + { :osfamily => 'Debian' } + end + + context 'fail when missing nexus_config' do + it 'should fails to configure cisco nexus driver' do + expect { subject }.to raise_error(Puppet::Error, /No nexus config specified/) + end + end + + context 'when using cisco' do + let (:nexus_config) do + { 'cvf2leaff2' => {'username' => 'prad', + "ssh_port" => 22, + "password" => "password", + "ip_address" => "172.18.117.28", + "servers" => { + "control02" => "portchannel:20", + "control01" => "portchannel:10" + } + } + } + end + + before :each do + params.merge!(:nexus_config => nexus_config ) + end + + it 'installs ncclient package' do + should contain_package('python-ncclient').with( + :ensure => 'installed' + ) + end + + it 'configures /etc/default/neutron-server' do + should contain_file_line('/etc/default/neutron-server:NEUTRON_PLUGIN_CONFIG').with( + :line => 'NEUTRON_PLUGIN_CONFIG=/etc/neutron/plugins/ml2/ml2_conf_cisco.ini', + :require => ['Package[neutron-server]', 'Package[neutron-plugin-ml2]'] + ) + end + end + +end diff --git a/templates/ml2_conf_cisco.ini.erb b/templates/ml2_conf_cisco.ini.erb new file mode 100644 index 000000000..cb880d9d7 --- /dev/null +++ b/templates/ml2_conf_cisco.ini.erb @@ -0,0 +1,59 @@ +[ml2_cisco] + +# (StrOpt) A short prefix to prepend to the VLAN number when creating a +# VLAN interface. For example, if an interface is being created for +# VLAN 2001 it will be named 'q-2001' using the default prefix. +# +# vlan_name_prefix = q- +# Example: vlan_name_prefix = vnet- + +# (BoolOpt) A flag to enable round robin scheduling of routers for SVI. +# svi_round_robin = False + +# +# (StrOpt) The name of the physical_network managed via the Cisco Nexus Switch. +# This string value must be present in the ml2_conf.ini network_vlan_ranges +# variable. +# +# managed_physical_network = +# Example: managed_physical_network = physnet1 + +# Cisco Nexus Switch configurations. +# Each switch to be managed by Openstack Neutron must be configured here. +# +# Cisco Nexus Switch Format. +# [ml2_mech_cisco_nexus:] +# = (1) +# ssh_port= (2) +# username= (3) +# password= (4) +# +# (1) For each host connected to a port on the switch, specify the hostname +# and the Nexus physical port (interface) it is connected to. +# Valid intf_type's are 'ethernet' and 'port-channel'. +# The default setting for is 'ethernet' and need not be +# added to this setting. +# (2) The TCP port for connecting via SSH to manage the switch. This is +# port number 22 unless the switch has been configured otherwise. +# (3) The username for logging into the switch to manage it. +# (4) The password for logging into the switch to manage it. +# +# Example: +# [ml2_mech_cisco_nexus:1.1.1.1] +# compute1=1/1 +# compute2=ethernet:1/2 +# compute3=port-channel:1 +# ssh_port=22 +# username=admin +# password=mySecretPassword + +<% nexus_config.each do |switch_hostname, switch_data| %> +[ML2_MECH_CISCO_NEXUS:<%= switch_data['ip_address'] %>] +<%- switch_data['servers'].each do|host_name, port| -%> +<%=host_name-%>=<%= port %> +<%- end -%> +ssh_port=<%= switch_data['ssh_port'] %> +username=<%= switch_data['username'] %> +password=<%= switch_data['password'] %> +<% end %> +