diff --git a/Gemfile b/Gemfile index 6d857d34..0b31d2f8 100644 --- a/Gemfile +++ b/Gemfile @@ -24,6 +24,8 @@ group :tests do # the test gems required for module testing gem 'puppetlabs_spec_helper', '~> 2.7' gem 'rspec-puppet' + + gem 'CFPropertyList' end group :development do diff --git a/lib/puppet/resource_api/simple_provider.rb b/lib/puppet/resource_api/simple_provider.rb index 8c96fc7b..a1e94ee4 100644 --- a/lib/puppet/resource_api/simple_provider.rb +++ b/lib/puppet/resource_api/simple_provider.rb @@ -22,17 +22,28 @@ def set(context, changes) is = { name: name, ensure: 'absent' } if is.nil? should = { name: name, ensure: 'absent' } if should.nil? + name_hash = if context.type.namevars.length > 1 + # pass a name_hash containing the values of all namevars + name_hash = { title: name } + context.type.namevars.each do |namevar| + name_hash[namevar] = change[:should][namevar] + end + name_hash + else + name + end + if is[:ensure].to_s == 'absent' && should[:ensure].to_s == 'present' context.creating(name) do - create(context, name, should) + create(context, name_hash, should) end elsif is[:ensure].to_s == 'present' && should[:ensure].to_s == 'present' context.updating(name) do - update(context, name, should) + update(context, name_hash, should) end elsif is[:ensure].to_s == 'present' && should[:ensure].to_s == 'absent' context.deleting(name) do - delete(context, name) + delete(context, name_hash) end end end diff --git a/spec/fixtures/test_module/lib/puppet/provider/composite_namevar/composite_namevar.rb b/spec/fixtures/test_module/lib/puppet/provider/composite_namevar/composite_namevar.rb index 94ec8ea4..61a6a9b6 100644 --- a/spec/fixtures/test_module/lib/puppet/provider/composite_namevar/composite_namevar.rb +++ b/spec/fixtures/test_module/lib/puppet/provider/composite_namevar/composite_namevar.rb @@ -1,7 +1,8 @@ require 'puppet/resource_api' +require 'puppet/resource_api/simple_provider' # Implementation for the title_provider type using the Resource API. -class Puppet::Provider::CompositeNamevar::CompositeNamevar +class Puppet::Provider::CompositeNamevar::CompositeNamevar < Puppet::ResourceApi::SimpleProvider def initialize @current_values ||= [ { title: 'php-yum', package: 'php', manager: 'yum', ensure: 'present', value: 'a' }, @@ -13,25 +14,25 @@ def initialize ] end - def set(context, changes) - changes.each do |name, change| - next unless change[:is] != change[:should] + def get(_context) + @current_values + end - match = @current_values.find do |item| - context.type.namevars.all? do |namevar| - item[namevar] == change[:should][namevar] - end - end - if match - match[:ensure] = change[:should][:ensure] - else - context.created([name], message: 'Adding new record') - @current_values << change[:should].dup - end - end + def create(context, name, should) + context.notice("Creating '#{name[:title]}' with #{should.inspect}") + context.notice("namevar :package value `#{name[:package]}`") + context.notice("namevar :manager value `#{name[:manager]}`") end - def get(_context) - @current_values + def update(context, name, should) + context.notice("Updating '#{name[:title]}' with #{should.inspect}") + context.notice("namevar :package value `#{name[:package]}`") + context.notice("namevar :manager value `#{name[:manager]}`") + end + + def delete(context, name) + context.notice("Deleting '#{name[:title]}'") + context.notice("namevar :package value `#{name[:package]}`") + context.notice("namevar :manager value `#{name[:manager]}`") end end diff --git a/spec/puppet/resource_api/simple_provider_spec.rb b/spec/puppet/resource_api/simple_provider_spec.rb index 63056f4c..e0ea67f0 100644 --- a/spec/puppet/resource_api/simple_provider_spec.rb +++ b/spec/puppet/resource_api/simple_provider_spec.rb @@ -66,6 +66,7 @@ def delete(context, _name); end allow(context).to receive(:type).and_return(type_def) allow(type_def).to receive(:feature?).with('simple_get_filter') allow(type_def).to receive(:check_schema) + allow(type_def).to receive(:namevars).and_return([:name]) end it 'calls create once' do @@ -109,6 +110,7 @@ def delete(context, _name); end allow(context).to receive(:updating).with('title').and_yield allow(context).to receive(:type).and_return(type_def) allow(type_def).to receive(:feature?).with('simple_get_filter') + allow(type_def).to receive(:namevars).and_return([:name]) end it 'does not call create' do @@ -140,6 +142,7 @@ def delete(context, _name); end allow(context).to receive(:deleting).with('title').and_yield allow(context).to receive(:type).and_return(type_def) allow(type_def).to receive(:feature?).with('simple_get_filter') + allow(type_def).to receive(:namevars).and_return([:name]) end it 'does not call create' do @@ -179,6 +182,7 @@ def delete(context, _name); end allow(context).to receive(:updating).with('to update').and_yield allow(context).to receive(:deleting).with('to delete').and_yield allow(type_def).to receive(:feature?).with('simple_get_filter').exactly(3).times + allow(type_def).to receive(:namevars).and_return([:name]) end it 'calls the crud methods' do @@ -209,4 +213,35 @@ def delete(context, _name); end it { expect { provider.set(context, changes) }.to raise_error %r{SimpleProvider cannot be used with a Type that is not ensurable} } end + + context 'with a type with multiple namevars' do + let(:should_values) { { name: 'title', parent: 'foo', wibble: 'wub', ensure: 'present' } } + let(:title) { 'foo#wub' } + let(:changes) do + { title => + { + should: should_values, + } } + end + let(:name_hash) do + { + title: title, + parent: 'foo', + wibble: 'wub', + } + end + + before(:each) do + allow(context).to receive(:creating).with(title).and_yield + allow(context).to receive(:type).and_return(type_def) + allow(type_def).to receive(:feature?).with('simple_get_filter') + allow(type_def).to receive(:check_schema) + allow(type_def).to receive(:namevars).and_return([:parent, :wibble]) + end + + it 'calls create once' do + expect(provider).to receive(:create).with(context, name_hash, should_values).once + provider.set(context, changes) + end + end end