diff --git a/lib/puppet/resource_api.rb b/lib/puppet/resource_api.rb index 1d24145b..b31f4ed5 100644 --- a/lib/puppet/resource_api.rb +++ b/lib/puppet/resource_api.rb @@ -73,7 +73,13 @@ def type_definition if type_definition.feature?('canonicalize') attributes = my_provider.canonicalize(context, [attributes])[0] end - # $stderr.puts "C: #{attributes.inspect}" + + # puppet defines a name attribute, but this only works for types that support name + if definition[:attributes][:name].nil? && attributes[:title].nil? + attributes[:title] = attributes[:name] + attributes.delete(:name) + end + super(attributes) end @@ -368,6 +374,10 @@ def call_provider(value); end @context ||= PuppetContext.new(definition) end + define_singleton_method(:title_patterns) do + [[%r{\A(.*)\Z}m, [[namevar_name]]]] + end + def context self.class.context end diff --git a/spec/acceptance/namevar_spec.rb b/spec/acceptance/namevar_spec.rb new file mode 100644 index 00000000..f05f60ba --- /dev/null +++ b/spec/acceptance/namevar_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' +require 'open3' + +RSpec.describe 'type with multiple namevars' do + let(:common_args) { '--verbose --trace --modulepath spec/fixtures' } + + describe 'using `puppet resource`' do + it 'is returns the values correctly' do + stdout_str, status = Open3.capture2e("puppet resource #{common_args} multiple_namevar") + expect(stdout_str.strip).to match %r{^multiple_namevar} + expect(status).to eq 0 + end + it 'is returns the required resource correctly' do + stdout_str, status = Open3.capture2e("puppet resource #{common_args} multiple_namevar yum") + expect(stdout_str.strip).to match %r{^multiple_namevar \{ \'yum\'} + expect(stdout_str.strip).to match %r{ensure => \'present\'} + expect(status).to eq 0 + end + it 'does not match the first namevar' do + stdout_str, status = Open3.capture2e("puppet resource #{common_args} multiple_namevar php") + expect(stdout_str.strip).to match %r{^multiple_namevar \{ \'php\'} + expect(stdout_str.strip).to match %r{ensure => \'absent\'} + expect(status).to eq 0 + end + end +end diff --git a/spec/fixtures/test_module/lib/puppet/provider/multiple_namevar/multiple_namevar.rb b/spec/fixtures/test_module/lib/puppet/provider/multiple_namevar/multiple_namevar.rb new file mode 100644 index 00000000..9cc77527 --- /dev/null +++ b/spec/fixtures/test_module/lib/puppet/provider/multiple_namevar/multiple_namevar.rb @@ -0,0 +1,29 @@ +require 'puppet/resource_api' +require 'puppet/resource_api/simple_provider' + +# Implementation for the title_provider type using the Resource API. +class Puppet::Provider::MultipleNamevar::MultipleNamevar < Puppet::ResourceApi::SimpleProvider + + def get(_context) + [ + { package: 'php', manager: 'yum', ensure: 'present', }, + { package: 'php', manager: 'gem', ensure: 'present', }, + { package: 'mysql', manager: 'yum', ensure: 'present', }, + { package: 'mysql', manager: 'gem', ensure: 'present', }, + { package: 'foo', manager: 'bar', ensure: 'present', }, + { package: 'bar', manager: 'foo', ensure: 'present', }, + ] + end + + def create(context, name, should) + context.notice("Creating '#{name}' with #{should.inspect}") + end + + def update(context, name, should) + context.notice("Updating '#{name}' with #{should.inspect}") + end + + def delete(context, name) + context.notice("Deleting '#{name}'") + end +end diff --git a/spec/fixtures/test_module/lib/puppet/type/multiple_namevar.rb b/spec/fixtures/test_module/lib/puppet/type/multiple_namevar.rb new file mode 100644 index 00000000..224b64ac --- /dev/null +++ b/spec/fixtures/test_module/lib/puppet/type/multiple_namevar.rb @@ -0,0 +1,25 @@ +require 'puppet/resource_api' + +Puppet::ResourceApi.register_type( + name: 'multiple_namevar', + docs: <<-EOS, + This type provides Puppet with the capabilities to manage ... + EOS + attributes: { + ensure: { + type: 'Enum[present, absent]', + desc: 'Whether this resource should be present or absent on the target system.', + default: 'present', + }, + package: { + type: 'String', + desc: 'The name of the file you want to manage.', + behaviour: :namevar, + }, + manager: { + type: 'String', + desc: 'The directory containing the resource you want to manage.', + behaviour: :namevar, + }, + }, +)