From e4a0b96628e09170ac775b98ce42503b5857a576 Mon Sep 17 00:00:00 2001 From: Hamdy Khader Date: Wed, 3 Jul 2019 17:31:39 +0300 Subject: [PATCH] Add support for neutron-mlnx-agent Configure mlnx neutron agent and start the required services. Change-Id: I32fbaac96ad0476b5cf1f9f3b93e1cc8119fc59e --- .../provider/eswitchd_config/ini_setting.rb | 15 +++ .../neutron_mlnx_agent_config/ini_setting.rb | 15 +++ lib/puppet/type/eswitchd_config.rb | 25 ++++ lib/puppet/type/neutron_mlnx_agent_config.rb | 25 ++++ manifests/agents/ml2/mlnx.pp | 84 +++++++++++++ manifests/params.pp | 4 + spec/classes/neutron_agents_ml2_mlnx_spec.rb | 116 ++++++++++++++++++ .../ini_setting_spec.rb | 63 ++++++++++ 8 files changed, 347 insertions(+) create mode 100644 lib/puppet/provider/eswitchd_config/ini_setting.rb create mode 100644 lib/puppet/provider/neutron_mlnx_agent_config/ini_setting.rb create mode 100644 lib/puppet/type/eswitchd_config.rb create mode 100644 lib/puppet/type/neutron_mlnx_agent_config.rb create mode 100644 manifests/agents/ml2/mlnx.pp create mode 100644 spec/classes/neutron_agents_ml2_mlnx_spec.rb create mode 100644 spec/unit/provider/neutron_mlnx_agent_config/ini_setting_spec.rb diff --git a/lib/puppet/provider/eswitchd_config/ini_setting.rb b/lib/puppet/provider/eswitchd_config/ini_setting.rb new file mode 100644 index 000000000..72b886cab --- /dev/null +++ b/lib/puppet/provider/eswitchd_config/ini_setting.rb @@ -0,0 +1,15 @@ +Puppet::Type.type(:eswitchd_config).provide( + :ini_setting, + :parent => Puppet::Type.type(:openstack_config).provider(:ini_setting) +) do + + def self.file_path + '/etc/neutron/plugins/ml2/eswitchd.conf' + end + + # added for backwards compatibility with older versions of inifile + def file_path + self.class.file_path + end + +end diff --git a/lib/puppet/provider/neutron_mlnx_agent_config/ini_setting.rb b/lib/puppet/provider/neutron_mlnx_agent_config/ini_setting.rb new file mode 100644 index 000000000..f6eb40923 --- /dev/null +++ b/lib/puppet/provider/neutron_mlnx_agent_config/ini_setting.rb @@ -0,0 +1,15 @@ +Puppet::Type.type(:neutron_mlnx_agent_config).provide( + :ini_setting, + :parent => Puppet::Type.type(:openstack_config).provider(:ini_setting) +) do + + def self.file_path + '/etc/neutron/plugins/mlnx/mlnx_conf.ini' + end + + # added for backwards compatibility with older versions of inifile + def file_path + self.class.file_path + end + +end diff --git a/lib/puppet/type/eswitchd_config.rb b/lib/puppet/type/eswitchd_config.rb new file mode 100644 index 000000000..07d7e0e5d --- /dev/null +++ b/lib/puppet/type/eswitchd_config.rb @@ -0,0 +1,25 @@ +Puppet::Type.newtype(:eswitchd_config) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from /etc/neutron/plugins/ml2/eswitchd.conf' + newvalues(/\S+\/\S+/) + end + + newparam(:ensure_absent_val) do + desc 'A value that is specified as the value property will behave as if ensure => absent was specified' + defaultto('') + end + + autorequire(:package) do ['neutron'] end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + end +end diff --git a/lib/puppet/type/neutron_mlnx_agent_config.rb b/lib/puppet/type/neutron_mlnx_agent_config.rb new file mode 100644 index 000000000..3bbb476ee --- /dev/null +++ b/lib/puppet/type/neutron_mlnx_agent_config.rb @@ -0,0 +1,25 @@ +Puppet::Type.newtype(:neutron_mlnx_agent_config) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from /etc/neutron/plugins/mlnx/mlnx_conf.ini' + newvalues(/\S+\/\S+/) + end + + newparam(:ensure_absent_val) do + desc 'A value that is specified as the value property will behave as if ensure => absent was specified' + defaultto('') + end + + autorequire(:package) do ['neutron'] end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + end +end diff --git a/manifests/agents/ml2/mlnx.pp b/manifests/agents/ml2/mlnx.pp new file mode 100644 index 000000000..ed2d43a07 --- /dev/null +++ b/manifests/agents/ml2/mlnx.pp @@ -0,0 +1,84 @@ +# +# == Class: neutron::agents::ml2::mlnx +# +# Setups MLNX neutron agent when using ML2 plugin +# +# === Parameters +# +# [*package_ensure*] +# (optional) The state of the package +# Defaults to 'present' +# +# [*enabled*] +# (required) Whether or not to enable the MLNX Agent +# Defaults to true +# +# [*manage_service*] +# (optional) Whether to start/stop the service +# Defaults to true +# +# [*physical_device_mappings*] +# (optional) Array of : +# All physical networks listed in network_vlan_ranges +# on the server should have mappings to appropriate +# interfaces on each agent. +# Value should be of type array, Defaults to $::os_service_default +# +# [*polling_interval*] +# (optional) The number of seconds the agent will wait between +# polling for local device changes. +# Defaults to '2" +# + +class neutron::agents::ml2::mlnx ( + $package_ensure = 'present', + $enabled = true, + $manage_service = true, + $physical_device_mappings = $::os_service_default, + $polling_interval = 2, +) { + + include ::neutron::deps + include ::neutron::params + + $mlnx_agent_package = $::neutron::params::mlnx_agent_package + $mlnx_agent_service = $::neutron::params::mlnx_agent_service + $eswitchd_service = $::neutron::params::eswitchd_service + + neutron_mlnx_agent_config { + 'eswitch/physical_device_mappings': value => pick(join(any2array($physical_device_mappings), ','), $::os_service_default); + 'agent/polling_interval': value => $polling_interval; + } + + eswitchd_config { + 'DAEMON/fabrics': value => pick(join(any2array($physical_device_mappings), ','), $::os_service_default); + } + + package { $mlnx_agent_package: + ensure => $package_ensure, + tag => ['openstack', 'neutron-package'], + } + + if $manage_service { + if $enabled { + $service_ensure = 'running' + } else { + $service_ensure = 'stopped' + } + } + + service { $mlnx_agent_service: + ensure => $service_ensure, + name => $mlnx_agent_service, + enable => $enabled, + tag => 'neutron-service', + } + + service { $eswitchd_service: + ensure => $service_ensure, + name => $eswitchd_service, + enable => $enabled, + tag => 'neutron-service', + } + +} diff --git a/manifests/params.pp b/manifests/params.pp index b6707d57c..997bdea2b 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -39,6 +39,8 @@ class neutron::params { $nsx_config_file = '/etc/neutron/plugins/vmware/nsx.ini' $sfc_package = "python${pyvers}-networking-sfc" $group = 'neutron' + $mlnx_agent_package = 'python-networking-mlnx' + $eswitchd_service = 'eswitchd' if($::osfamily == 'Redhat') { $nobody_user_group = 'nobody' @@ -88,6 +90,7 @@ class neutron::params { $networking_baremetal_agent_package = 'python2-ironic-neutron-agent' $networking_baremetal_agent_service = 'ironic-neutron-agent' $networking_ansible_package = "python${pyvers}-networking-ansible" + $mlnx_agent_service = 'neutron-mlnx-agent' } elsif($::osfamily == 'Debian') { $nobody_user_group = 'nogroup' $package_name = 'neutron-common' @@ -134,6 +137,7 @@ class neutron::params { $l2gw_package = "python${pyvers}-networking-l2gw" $neutron_wsgi_script_path = '/usr/lib/cgi-bin/neutron' $neutron_wsgi_script_source = '/usr/bin/neutron-api' + $mlnx_agent_service = 'neutron-plugin-mlnx-agent' } else { fail("Unsupported osfamily ${::osfamily}") } diff --git a/spec/classes/neutron_agents_ml2_mlnx_spec.rb b/spec/classes/neutron_agents_ml2_mlnx_spec.rb new file mode 100644 index 000000000..a334c8229 --- /dev/null +++ b/spec/classes/neutron_agents_ml2_mlnx_spec.rb @@ -0,0 +1,116 @@ +require 'spec_helper' + +describe 'neutron::agents::ml2::mlnx' do + let :pre_condition do + "class { 'neutron': }" + end + + let :default_params do + { + :package_ensure => 'present', + :enabled => true, + :manage_service => true + } + end + + let :params do + {} + end + + shared_examples 'neutron mlnx agent with ml2 plugin' do + let :p do + default_params.merge(params) + end + + it { should contain_class('neutron::params') } + + + it 'configures /etc/neutron/plugins/mlnx/mlnx_config.ini' do + should contain_neutron_mlnx_agent_config('eswitch/physical_device_mappings').with_value('') + end + + + it 'installs neutron mlnx agent package' do + should contain_package(platform_params[:mlnx_agent_package]).with( + :name => platform_params[:mlnx_agent_package], + :ensure => p[:package_ensure], + :tag => ['openstack', 'neutron-package'], + ) + should contain_package(platform_params[:mlnx_agent_package]).that_requires('Anchor[neutron::install::begin]') + should contain_package(platform_params[:mlnx_agent_package]).that_notifies('Anchor[neutron::install::end]') + end + + it 'configures neutron mlnx agent service' do + should contain_service(platform_params[:mlnx_agent_service]).with( + :name => platform_params[:mlnx_agent_service], + :enable => true, + :ensure => 'running', + :tag => 'neutron-service', + ) + should contain_service(platform_params[:mlnx_agent_service]).that_subscribes_to('Anchor[neutron::service::begin]') + should contain_service(platform_params[:mlnx_agent_service]).that_notifies('Anchor[neutron::service::end]') + should contain_service('eswitchd').that_subscribes_to('Anchor[neutron::service::begin]') + should contain_service('eswitchd').that_notifies('Anchor[neutron::service::end]') + end + + context 'with manage_service as false' do + before :each do + params.merge!(:manage_service => false) + end + it 'should not start/stop service' do + should contain_service(platform_params[:mlnx_agent_service]).without_ensure + should contain_service('eswitchd').without_ensure + end + end + + context 'when supplying device mapping' do + before :each do + params.merge!(:physical_device_mappings => ['physnet1:eth1']) + end + + it 'configures physical device mappings' do + should contain_neutron_mlnx_agent_config('eswitch/physical_device_mappings').with_value(['physnet1:eth1']) + should contain_eswitchd_config('DAEMON/fabrics').with_value(['physnet1:eth1']) + end + end + + context 'when supplying empty device mapping' do + before :each do + params.merge!(:physical_device_mappings => "") + end + + it 'configures physical device mappings with exclusion' do + should contain_neutron_mlnx_agent_config('eswitch/physical_device_mappings').with_value('') + should contain_eswitchd_config('DAEMON/fabrics').with_value('') + end + end + + end + + on_supported_os({ + :supported_os => OSDefaults.get_supported_os + }).each do |os,facts| + context "on #{os}" do + let (:facts) do + facts.merge!(OSDefaults.get_facts()) + end + + let (:platform_params) do + case facts[:osfamily] + when 'Debian' + { + :mlnx_agent_package => 'python-networking-mlnx', + :mlnx_agent_service => 'neutron-plugin-mlnx-agent' + } + when 'RedHat' + { + :mlnx_agent_package => 'python-networking-mlnx', + :mlnx_agent_service => 'neutron-mlnx-agent' + } + end + end + + it_behaves_like 'neutron mlnx agent with ml2 plugin' + end + end +end diff --git a/spec/unit/provider/neutron_mlnx_agent_config/ini_setting_spec.rb b/spec/unit/provider/neutron_mlnx_agent_config/ini_setting_spec.rb new file mode 100644 index 000000000..a17d50e00 --- /dev/null +++ b/spec/unit/provider/neutron_mlnx_agent_config/ini_setting_spec.rb @@ -0,0 +1,63 @@ +$LOAD_PATH.push( + File.join( + File.dirname(__FILE__), + '..', + '..', + '..', + 'fixtures', + 'modules', + 'inifile', + 'lib') +) + +require 'spec_helper' + +provider_class = Puppet::Type.type(:neutron_mlnx_agent_config).provider(:ini_setting) + +describe provider_class do + + it 'should default to the default setting when no other one is specified' do + resource = Puppet::Type::Neutron_mlnx_agent_config.new( + { + :name => 'DEFAULT/foo', + :value => 'bar' + } + ) + provider = provider_class.new(resource) + expect(provider.section).to eq('DEFAULT') + expect(provider.setting).to eq('foo') + expect(provider.file_path).to eq('/etc/neutron/plugins/mlnx/mlnx_conf.ini') + end + + it 'should allow setting to be set explicitly' do + resource = Puppet::Type::Neutron_mlnx_agent_config.new( + { + :name => 'dude/foo', + :value => 'bar' + } + ) + provider = provider_class.new(resource) + expect(provider.section).to eq('dude') + expect(provider.setting).to eq('foo') + expect(provider.file_path).to eq('/etc/neutron/plugins/mlnx/mlnx_conf.ini') + end + + it 'should ensure absent when is specified as a value' do + resource = Puppet::Type::Neutron_mlnx_agent_config.new( + {:name => 'dude/foo', :value => ''} + ) + provider = provider_class.new(resource) + provider.exists? + expect(resource[:ensure]).to eq :absent + end + + it 'should ensure absent when value matches ensure_absent_val' do + resource = Puppet::Type::Neutron_mlnx_agent_config.new( + {:name => 'dude/foo', :value => 'foo', :ensure_absent_val => 'foo' } + ) + provider = provider_class.new(resource) + provider.exists? + expect(resource[:ensure]).to eq :absent + end + +end