diff --git a/lib/puppet/provider/swift_ceilometer_config/openstackconfig.rb b/lib/puppet/provider/swift_ceilometer_config/openstackconfig.rb new file mode 100644 index 00000000..4a4935f0 --- /dev/null +++ b/lib/puppet/provider/swift_ceilometer_config/openstackconfig.rb @@ -0,0 +1,10 @@ +Puppet::Type.type(:swift_ceilometer_config).provide( + :openstackconfig, + :parent => Puppet::Type.type(:openstack_config).provider(:ruby) +) do + + def self.file_path + '/etc/swift/ceilometer.conf' + end + +end diff --git a/lib/puppet/type/swift_ceilometer_config.rb b/lib/puppet/type/swift_ceilometer_config.rb new file mode 100644 index 00000000..d0e60dcd --- /dev/null +++ b/lib/puppet/type/swift_ceilometer_config.rb @@ -0,0 +1,64 @@ +Puppet::Type.newtype(:swift_ceilometer_config) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from ceilometer.conf' + newvalues(/\S+\/\S+/) + end + + newproperty(:value, :array_matching => :all) do + desc 'The value of the setting to be defined.' + def insync?(is) + return true if @should.empty? + return false unless is.is_a? Array + return false unless is.length == @should.length + # we don't care about the order of items in array, hence + # it is necessary to override insync + return ( + is & @should == is or + is & @should.map(&:to_s) == is + ) + end + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + newvalues(/^[\S ]*$/) + + 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 + + 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(:anchor) do + ['swift::install::end'] + end + +end diff --git a/manifests/deps.pp b/manifests/deps.pp index 7ab5c222..b9c5aee6 100644 --- a/manifests/deps.pp +++ b/manifests/deps.pp @@ -24,6 +24,9 @@ class swift::deps { Anchor['swift::config::begin'] -> Swift_proxy_config<||> -> Anchor['swift::config::end'] Swift_proxy_config<||> ~> Service<| tag == 'swift-proxy-service' |> + Anchor['swift::config::begin'] -> Swift_ceilometer_config<||> -> Anchor['swift::config::end'] + Swift_ceilometer_config<||> ~> Service<| tag == 'swift-proxy-service' |> + Anchor['swift::config::begin'] -> Swift_storage_policy<||> -> Anchor['swift::config::end'] # storage policy is now used by proxy and object Swift_storage_policy<||> ~> Service<| tag == 'swift-proxy-service' |> diff --git a/manifests/proxy/ceilometer.pp b/manifests/proxy/ceilometer.pp index d2a66422..2e29eeae 100644 --- a/manifests/proxy/ceilometer.pp +++ b/manifests/proxy/ceilometer.pp @@ -195,6 +195,7 @@ class swift::proxy::ceilometer( ) inherits swift { include swift::deps + include swift::params Package['python-ceilometermiddleware'] ~> Service<| title == 'swift-proxy-server' |> @@ -206,6 +207,17 @@ class swift::proxy::ceilometer( $project_domain_name_real = $facts['os_service_default'] } + file { '/etc/swift/ceilometer.conf': + ensure => present, + owner => $::swift::params::user, + group => $::swift::params::group, + mode => '0640', + require => Anchor['swift::config::begin'], + before => Anchor['swift::config::end'], + } + + File['/etc/swift/ceilometer.conf'] -> Swift_ceilometer_config<||> + swift_proxy_config { 'filter:ceilometer/topic': value => $topic; 'filter:ceilometer/driver': value => $driver; @@ -223,10 +235,11 @@ class swift::proxy::ceilometer( 'filter:ceilometer/user_domain_name': value => $user_domain_name; 'filter:ceilometer/password': value => $password, secret => true; 'filter:ceilometer/region_name': value => $region_name; + 'filter:ceilometer/extra_config_files': value => '/etc/swift/ceilometer.conf'; } if $default_transport_url =~ /^rabbit.*/ { - oslo::messaging::rabbit { 'swift_proxy_config': + oslo::messaging::rabbit { 'swift_ceilometer_config': rabbit_ha_queues => $rabbit_ha_queues, heartbeat_timeout_threshold => $rabbit_heartbeat_timeout_threshold, heartbeat_rate => $rabbit_heartbeat_rate, @@ -242,16 +255,19 @@ class swift::proxy::ceilometer( kombu_failover_strategy => $kombu_failover_strategy, kombu_compression => $kombu_compression, } - oslo::messaging::amqp { 'swift_proxy_config': } + oslo::messaging::amqp { 'swift_ceilometer_config': } } elsif $default_transport_url =~ /^amqp.*/ { - oslo::messaging::rabbit { 'swift_proxy_config': } - oslo::messaging::amqp { 'swift_proxy_config': + oslo::messaging::rabbit { 'swift_ceilometer_config': } + oslo::messaging::amqp { 'swift_ceilometer_config': ssl_ca_file => $notification_ssl_ca_file, ssl_cert_file => $notification_ssl_cert_file, ssl_key_file => $notification_ssl_key_file, ssl_key_password => $amqp_ssl_key_password, } + } else { + oslo::messaging::rabbit { 'swift_ceilometer_config': } + oslo::messaging::amqp { 'swift_ceilometer_config': } } package { 'python-ceilometermiddleware': diff --git a/spec/classes/swift_proxy_ceilometer_spec.rb b/spec/classes/swift_proxy_ceilometer_spec.rb index 4dbb2f44..61b41726 100644 --- a/spec/classes/swift_proxy_ceilometer_spec.rb +++ b/spec/classes/swift_proxy_ceilometer_spec.rb @@ -30,12 +30,20 @@ describe 'swift::proxy::ceilometer' do it { is_expected.to contain_swift_proxy_config('filter:ceilometer/topic').with_value('') } it { is_expected.to contain_swift_proxy_config('filter:ceilometer/control_exchange').with_value('') } it { is_expected.to contain_swift_proxy_config('filter:ceilometer/nonblocking_notify').with_value('') } + it { is_expected.to contain_swift_proxy_config('filter:ceilometer/extra_config_files').with_value('/etc/swift/ceilometer.conf') } it { is_expected.to contain_package('python-ceilometermiddleware').with( :ensure => 'present', :name => platform_params[:ceilometermiddleware_package_name], :tag => ['openstack', 'swift-support-package'], )} + + it { is_expected.to contain_file('/etc/swift/ceilometer.conf').with( + :ensure => 'present', + :owner => 'swift', + :group => 'swift', + :mode => '0640', + )} end describe "when overriding default parameters with rabbit driver" do @@ -83,7 +91,7 @@ describe 'swift::proxy::ceilometer' do it { is_expected.to contain_swift_proxy_config('filter:ceilometer/url').with_value('rabbit://user:pass@host:1234/virt').with_secret(true) } end - it { is_expected.to contain_oslo__messaging__rabbit('swift_proxy_config').with( + it { is_expected.to contain_oslo__messaging__rabbit('swift_ceilometer_config').with( :rabbit_ha_queues => '', :heartbeat_timeout_threshold => '', :heartbeat_rate => '', @@ -99,7 +107,7 @@ describe 'swift::proxy::ceilometer' do :kombu_failover_strategy => '', :kombu_compression => '', )} - it { is_expected.to contain_oslo__messaging__amqp('swift_proxy_config') } + it { is_expected.to contain_oslo__messaging__amqp('swift_ceilometer_config') } context 'with overridden rabbit ssl params' do before do @@ -113,7 +121,7 @@ describe 'swift::proxy::ceilometer' do }) end - it { is_expected.to contain_oslo__messaging__rabbit('swift_proxy_config').with( + it { is_expected.to contain_oslo__messaging__rabbit('swift_ceilometer_config').with( :rabbit_use_ssl => true, :kombu_ssl_ca_certs => '/etc/ca.cert', :kombu_ssl_certfile => '/etc/certfile', diff --git a/spec/unit/provider/swift_ceilometer_config/openstackconfig_spec.rb b/spec/unit/provider/swift_ceilometer_config/openstackconfig_spec.rb new file mode 100644 index 00000000..79f74105 --- /dev/null +++ b/spec/unit/provider/swift_ceilometer_config/openstackconfig_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +provider_class = Puppet::Type.type(:swift_ceilometer_config).provider(:openstackconfig) + +describe provider_class do + + it 'should default to the default setting when no other one is specified' do + resource = Puppet::Type::Swift_ceilometer_config.new( + { + :name => 'DEFAULT/foo', + :value => 'bar' + } + ) + provider = provider_class.new(resource) + expect(provider.section).to eq('DEFAULT') + expect(provider.setting).to eq('foo') + end + + it 'should allow setting to be set explicitly' do + resource = Puppet::Type::Swift_ceilometer_config.new( + { + :name => 'dude/foo', + :value => 'bar' + } + ) + provider = provider_class.new(resource) + expect(provider.section).to eq('dude') + expect(provider.setting).to eq('foo') + end + + it 'should ensure absent when is specified as a value' do + resource = Puppet::Type::Swift_ceilometer_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::Swift_ceilometer_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 diff --git a/spec/unit/type/swift_ceilometer_config_spec.rb b/spec/unit/type/swift_ceilometer_config_spec.rb new file mode 100644 index 00000000..058c56d0 --- /dev/null +++ b/spec/unit/type/swift_ceilometer_config_spec.rb @@ -0,0 +1,64 @@ +require 'puppet' +require 'puppet/type/swift_ceilometer_config' + +describe 'Puppet::Type.type(:swift_ceilometer_config)' do + before :each do + @swift_ceilometer_config = Puppet::Type.type(:swift_ceilometer_config).new(:name => 'DEFAULT/foo', :value => 'bar') + end + + it 'should require a name' do + expect { + Puppet::Type.type(:swift_ceilometer_config).new({}) + }.to raise_error(Puppet::Error, 'Title or name must be provided') + end + + it 'should not expect a name with whitespace' do + expect { + Puppet::Type.type(:swift_ceilometer_config).new(:name => 'f oo') + }.to raise_error(Puppet::Error, /Parameter name failed/) + end + + it 'should fail when there is no section' do + expect { + Puppet::Type.type(:swift_ceilometer_config).new(:name => 'foo') + }.to raise_error(Puppet::Error, /Parameter name failed/) + end + + it 'should not require a value when ensure is absent' do + Puppet::Type.type(:swift_ceilometer_config).new(:name => 'DEFAULT/foo', :ensure => :absent) + end + + it 'should accept a valid value' do + @swift_ceilometer_config[:value] = 'bar' + expect(@swift_ceilometer_config[:value]).to eq(['bar']) + end + + it 'should accept a value with whitespace' do + @swift_ceilometer_config[:value] = 'b ar' + expect(@swift_ceilometer_config[:value]).to eq(['b ar']) + end + + it 'should accept valid ensure values' do + @swift_ceilometer_config[:ensure] = :present + expect(@swift_ceilometer_config[:ensure]).to eq(:present) + @swift_ceilometer_config[:ensure] = :absent + expect(@swift_ceilometer_config[:ensure]).to eq(:absent) + end + + it 'should not accept invalid ensure values' do + expect { + @swift_ceilometer_config[:ensure] = :latest + }.to raise_error(Puppet::Error, /Invalid value/) + end + + it 'should autorequire the package that install the file' do + catalog = Puppet::Resource::Catalog.new + anchor = Puppet::Type.type(:anchor).new(:name => 'swift::install::end') + catalog.add_resource anchor, @swift_ceilometer_config + dependency = @swift_ceilometer_config.autorequire + expect(dependency.size).to eq(1) + expect(dependency[0].target).to eq(@swift_ceilometer_config) + expect(dependency[0].source).to eq(anchor) + end + +end