diff --git a/lib/puppet/provider/neutron_plugin_midonet/ini_setting.rb b/lib/puppet/provider/neutron_plugin_midonet/ini_setting.rb new file mode 100644 index 000000000..ad3e48313 --- /dev/null +++ b/lib/puppet/provider/neutron_plugin_midonet/ini_setting.rb @@ -0,0 +1,22 @@ +Puppet::Type.type(:neutron_plugin_midonet).provide( + :ini_setting, + :parent => Puppet::Type.type(:ini_setting).provider(:ruby) +) do + + def section + resource[:name].split('/', 2).first + end + + def setting + resource[:name].split('/', 2).last + end + + def separator + '=' + end + + def file_path + '/etc/neutron/plugins/midonet/midonet.ini' + end + +end diff --git a/lib/puppet/type/neutron_plugin_midonet.rb b/lib/puppet/type/neutron_plugin_midonet.rb new file mode 100644 index 000000000..7d8e69c22 --- /dev/null +++ b/lib/puppet/type/neutron_plugin_midonet.rb @@ -0,0 +1,49 @@ +Puppet::Type.newtype(:neutron_plugin_midonet) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from midonet.ini' + newvalues(/\S+\/\S+/) + end + + autorequire(:file) do + ['/etc/neutron/plugins/midonet'] + 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 + + def is_to_s( currentvalue ) + if resource.secret? + return '[old secret redacted]' + else + return currentvalue + end + end + + def should_to_s( newvalue ) + if resource.secret? + return '[new secret redacted]' + else + return newvalue + end + end + end + + newparam(:secret, :boolean => true) do + desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' + + newvalues(:true, :false) + + defaultto false + end + +end diff --git a/manifests/agents/dhcp.pp b/manifests/agents/dhcp.pp index fb540fe15..f8093ba8e 100644 --- a/manifests/agents/dhcp.pp +++ b/manifests/agents/dhcp.pp @@ -88,6 +88,9 @@ class neutron::agents::dhcp ( Package[$::neutron::params::dnsmasq_packages] -> Package<| title == 'neutron-dhcp-agent' |> ensure_packages($::neutron::params::dnsmasq_packages) } + /^midonet.*/: { + ensure_packages($::neutron::params::midonet_server_package) + } default: { fail("Unsupported dhcp_driver ${dhcp_driver}") } diff --git a/manifests/config.pp b/manifests/config.pp index 41865a54f..164ff0b45 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -54,6 +54,9 @@ # [**plugin_cisco_config**] # (optional) Manage configuration of cisco_plugins.ini # +# [**plugin_midonet_config**] +# (optional) Manage configuration of plugins/midonet/midonet.ini +# # [**plugin_ml2_config**] # (optional) Manage configuration of ml2_conf.ini # @@ -76,6 +79,7 @@ class neutron::config ( $plugin_cisco_db_conn_config = {}, $plugin_cisco_l2network_config = {}, $plugin_cisco_config = {}, + $plugin_midonet_config = {}, $plugin_ml2_config = {}, $plugin_ovs_config = {}, ) { @@ -92,6 +96,7 @@ class neutron::config ( validate_hash($plugin_cisco_db_conn_config) validate_hash($plugin_cisco_l2network_config) validate_hash($plugin_cisco_config) + validate_hash($plugin_midonet_config) validate_hash($plugin_ml2_config) validate_hash($plugin_ovs_config) @@ -106,6 +111,7 @@ class neutron::config ( create_resources('neutron_plugin_cisco_db_conn', $plugin_cisco_db_conn_config) create_resources('neutron_plugin_cisco_l2network', $plugin_cisco_l2network_config) create_resources('neutron_plugin_cisco', $plugin_cisco_config) + create_resources('neutron_plugin_midonet', $plugin_midonet_config) create_resources('neutron_plugin_ml2', $plugin_ml2_config) create_resources('neutron_plugin_ovs', $plugin_ovs_config) } diff --git a/manifests/params.pp b/manifests/params.pp index 4b5346506..5cc309422 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -31,6 +31,9 @@ class neutron::params { $cisco_config_file = '/etc/neutron/plugins/cisco/cisco_plugins.ini' $cisco_ml2_config_file = '/etc/neutron/plugins/ml2/ml2_conf_cisco.ini' + $midonet_server_package = 'python-neutron-plugin-midonet' + $midonet_config_file = '/etc/neutron/plugins/midonet/midonet.ini' + $nvp_server_package = 'openstack-neutron-nicira' $dhcp_agent_package = false @@ -100,6 +103,9 @@ class neutron::params { $cisco_config_file = '/etc/neutron/plugins/cisco/cisco_plugins.ini' $cisco_ml2_config_file = '/etc/neutron/plugins/ml2/ml2_conf_cisco.ini' + $midonet_server_package = 'python-neutron-plugin-midonet' + $midonet_config_file = '/etc/neutron/plugins/midonet/midonet.ini' + $nvp_server_package = 'neutron-plugin-nicira' $dhcp_agent_package = 'neutron-dhcp-agent' diff --git a/manifests/plugins/midonet.pp b/manifests/plugins/midonet.pp new file mode 100644 index 000000000..54b7c8f71 --- /dev/null +++ b/manifests/plugins/midonet.pp @@ -0,0 +1,144 @@ +# == Class: midonet::neutron_plugin +# +# Install and configure Midonet Neutron Plugin. Please note that this manifest +# does not install the 'python-neutron-midonet-plugin' package, it only +# configures Neutron to do so needed for this deployment. Check out the +# MidoNet module to do so. +# +# === Parameters +# +# [*midonet_api_ip*] +# IP address of the MidoNet api service +# [*midonet_api_port*] +# IP address of the MidoNet port service. MidoNet runs in a Tomcat, so 8080 +# is used by default. +# [*keystone_username*] +# Username from which midonet api will authenticate against Keystone (neutron +# service is desirable and defaulted) +# [*keystone_password*] +# Password from which midonet api will authenticate against Keystone +# [*keystone_tenant*] +# Tenant from which midonet api will authenticate against Keystone (services +# tenant is desirable and defaulted) +# [*sync_db*] +# Whether 'midonet-db-manage' should run to create and/or syncrhonize the database +# with MidoNet specific tables. Defaults to false +# +# === Examples +# +# An example call would be: +# +# class {'neutron:plugins::midonet': +# midonet_api_ip => '23.123.5.32', +# midonet_api_port => '8080', +# keystone_username => 'neutron', +# keystone_password => '32kjaxT0k3na', +# keystone_tenant => 'services', +# sync_db => true +# } +# +# You can alternatively use the Hiera's yaml style: +# neutron::plugin::midonet::midonet_api_ip: '23.213.5.32' +# neutron::plugin::midonet::port: '8080' +# neutron::plugin::midonet::keystone_username: 'neutron' +# neutron::plugin::midonet::keystone_password: '32.kjaxT0k3na' +# neutron::plugin::midonet::keystone_tenant: 'services' +# neutron::plugin::midonet::sync_db: true +# +# === Authors +# +# Midonet (http://MidoNet.org) +# +# === Copyright +# +# Copyright (c) 2015 Midokura SARL, All Rights Reserved. +# +# 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. +# +class neutron::plugins::midonet ( + $midonet_api_ip = '127.0.0.1', + $midonet_api_port = '8080', + $keystone_username = 'neutron', + $keystone_password = undef, + $keystone_tenant = 'services', + $sync_db = false +) { + + include ::neutron::params + + Neutron_plugin_midonet<||> ~> Service['neutron-server'] + + ensure_resource('file', '/etc/neutron/plugins/midonet', { + ensure => directory, + owner => 'root', + group => 'neutron', + mode => '0640'} + ) + + # Ensure the neutron package is installed before config is set + # under both RHEL and Ubuntu + if ($::neutron::params::server_package) { + Package['neutron-server'] -> Neutron_plugin_midonet<||> + } else { + Package['neutron'] -> Neutron_plugin_midonet<||> + } + + # Although this manifest does not install midonet plugin package because it + # is not available in common distro repos, this statement forces you to + # have an orchestrator/wrapper manifest that does that job. + Package[$::neutron::params::midonet_server_package] -> Neutron_plugin_midonet<||> + + neutron_plugin_midonet { + 'MIDONET/midonet_uri': value => "http://${midonet_api_ip}:${midonet_api_port}/midonet-api"; + 'MIDONET/username': value => $keystone_username; + 'MIDONET/password': value => $keystone_password, secret =>true; + 'MIDONET/project_id': value => $keystone_tenant; + } + + 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::midonet_config_file}", + require => [ Package['neutron-server'], Package[$::neutron::params::midonet_server_package] ], + notify => Service['neutron-server'], + } + } + + # In RH, this link is used to start Neutron process but in Debian, it's used only + # to manage database synchronization. + if defined(File['/etc/neutron/plugin.ini']) { + File <| path == '/etc/neutron/plugin.ini' |> { target => $::neutron::params::midonet_config_file } + } + else { + file {'/etc/neutron/plugin.ini': + ensure => link, + target => $::neutron::params::midonet_config_file, + require => Package[$::neutron::params::midonet_server_package] + } + } + + if $sync_db { + + Package<| title == $::neutron::params::midonet_server_package |> ~> Exec['midonet-db-sync'] + + exec { 'midonet-db-sync': + command => 'midonet-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini upgrade head', + path => '/usr/bin', + before => Service['neutron-server'], + subscribe => Neutron_config['database/connection'], + refreshonly => true + } + } +} + diff --git a/spec/classes/neutron_plugins_midonet_spec.rb b/spec/classes/neutron_plugins_midonet_spec.rb new file mode 100644 index 000000000..4dd58320f --- /dev/null +++ b/spec/classes/neutron_plugins_midonet_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' + +describe 'neutron::plugins::midonet' do + + let :pre_condition do + "class { 'neutron::server': auth_password => 'password' } + class { 'neutron': rabbit_password => 'passw0rd' } + package { 'python-neutron-plugin-midonet': }" + end + + let :default_params do + { + :midonet_api_ip => '127.0.0.1', + :midonet_api_port => '8080', + :keystone_username => 'neutron', + :keystone_password => 'test_midonet', + :keystone_tenant => 'services' + } + end + + shared_examples_for 'neutron midonet plugin' do + + let :params do + {} + end + + before do + params.merge!(default_params) + end + + it 'should create plugin symbolic link' do + is_expected.to contain_file('/etc/neutron/plugin.ini').with( + :ensure => 'link', + :target => '/etc/neutron/plugins/midonet/midonet.ini', + :require => 'Package[python-neutron-plugin-midonet]') + end + + it 'should perform default configuration of' do + midonet_uri = "http://" + params[:midonet_api_ip] + ":" + params[:midonet_api_port] + "/midonet-api"; + is_expected.to contain_neutron_plugin_midonet('MIDONET/midonet_uri').with_value(midonet_uri) + is_expected.to contain_neutron_plugin_midonet('MIDONET/username').with_value(params[:keystone_username]) + is_expected.to contain_neutron_plugin_midonet('MIDONET/password').with_value(params[:keystone_password]) + is_expected.to contain_neutron_plugin_midonet('MIDONET/project_id').with_value(params[:keystone_tenant]) + end + + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian'} + end + it 'configures /etc/default/neutron-server' do + is_expected.to contain_file_line('/etc/default/neutron-server:NEUTRON_PLUGIN_CONFIG').with( + :path => '/etc/default/neutron-server', + :match => '^NEUTRON_PLUGIN_CONFIG=(.*)$', + :line => 'NEUTRON_PLUGIN_CONFIG=/etc/neutron/plugins/midonet/midonet.ini', + :require => ['Package[neutron-server]', 'Package[python-neutron-plugin-midonet]'], + :notify => 'Service[neutron-server]' + ) + end + it_configures 'neutron midonet plugin' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat'} + end + it_configures 'neutron midonet plugin' + end + +end