Hi Rich, I've got the hang of it.
It boils down to this: for a property of a puppet resource to be taken into account as a key of the resource it has to be a parameter, not a property: For the code to work you change newproperty(:domain) do to newparam(:domain) do As a side note, the test you setup won't cut it as self.title_patterns is *not* called when using the :pre_condition rspec trick. I provide sample tests in the next section. TLDR follows. To be able to have a resource whose key is spread on multiple parameters you have to: 1. add isnamevar to each *parameter* defined with 'newparam' in the type (not 'newproperty'); 2. create the self.title_patterns In this case this is enough (identity is done by default if no proc is given): def self.title_patterns [ [ /^(.+)::(.+)$/, [ [:name], [:domain] ] ], [ /^(.+)$/, [ [:name] ] ] ] end To test this thing you can do it in the associated type test like (spec/unit/type/keystone_tenant.rb): r = [] r << Puppet::Type.type(:keystone_tenant).new(:title => 'one', :name => 'foo', :domain => 'one'); r << Puppet::Type.type(:keystone_tenant).new(:title => 'two', :name => 'foo', :domain => 'two'); r << Puppet::Type.type(:keystone_tenant).new(:title => 'foo::tree); catalog = Puppet::Resource::Catalog.new; expect{r.each {|r| catalog.add_resource(r) }}.not_to raise_error This is just inspiration. If you remove title_pattern or isnamevar definition the code above will blow. Other tests can be: expect(r[2].uniqueness_key).to contain_exactly(['foo', 'three']) This test the regex parsing. Ok, I didn't look into the consequences of changing domain from property to parameter. But it looks like it does imply other changes in the code. Rich Megginson <rmegg...@redhat.com> writes: > On 09/16/2015 02:58 PM, Cody Herriges wrote: > > I wrote my first composite namevar type a few years and ago and all the > magic is basically a single block of code inside the type... > > https://github.com/puppetlabs/puppetlabs-java_ks/blob/master/lib/puppet/type/java_ks.rb#L145-L169 > > It basically boils down to these three things: > > * Pick your namevars > (https://github.com/puppetlabs/puppetlabs-java_ks/blob/master/lib/puppet/type/java_ks.rb#L49-L64) > * Pick a delimiter > - Personally I'd use @ here since we are talking about domains > > Unfortunately, not only is "domains" an overloaded term, but "@" is > already in use as a delimiter for keystone_user_role, and "@" is a > legal character in usernames. > > > * Build your self.title_patterns method, accounting for delimited names > and arbitrary names. > > While it looks like the README never got updated, the java_ks example > supports both meaningful titles and arbitrary ones. > > java_ks { 'activemq_puppetca_keystore': > ensure => latest, > name => 'puppetca', > certificate => '/etc/puppet/ssl/certs/ca.pem', > target => '/etc/activemq/broker.ks', > password => 'puppet', > trustcacerts => true, > } > > java_ks { 'broker.example.com:/etc/activemq/broker.ks': > ensure => latest, > certificate => > '/etc/puppet/ssl/certs/broker.example.com.pe-internal-broker.pem', > private_key => > '/etc/puppet/ssl/private_keys/broker.example.com.pe-internal-broker.pem', > password => 'puppet', > } > > You'll notice the first being an arbitrary title and the second > utilizing a ":" as a delimiter and omitting the name and target parameters. > > Another code example can be found in the package type. > > https://github.com/puppetlabs/puppet/blob/master/lib/puppet/type/package.rb#L268-L291. > > Ok. I've hacked a lib/puppet/type/keystone_tenant.rb to use name and > domain with "isnamevar" and added a title_patterns like this: > > def self.title_patterns > identity = lambda {|x| x} > [ > [ > /^(.+)::(.+)$/, > [ > [ :name, identity ], > [ :domain, identity ] > ] > ], > [ > /^(.+)$/, > [ > [ :name, identity ] > ] > ] > ] > end > > Then I hacked one of the simple rspec-puppet files to do this: > > let :pre_condition do > [ > 'keystone_tenant { "tenant1": name => "tenant", domain => "domain1" }', > 'keystone_tenant { "tenant2": name => "tenant", domain => "domain2" }' > ] > end > > because what I'm trying to do is not rely on the title of the > resource, but to make the combination of 'name' + 'domain' the actual > "name" of the resource. This doesn't work. This is the error I get > running spec: > > Failure/Error: it { is_expected.to > contain_package('python-keystone').with_ensure > ("present") } > Puppet::Error: > Puppet::Parser::AST::Resource failed with error ArgumentError: Cannot > alias Keystone_tenant[tenant2] to ["tenant"]; resource > ["Keystone_tenant", "tenant"] already declared at line 3 on node > unused.redhat.com > # ./vendor/gems/puppet-3.8.2/lib/puppet/resource/catalog.rb:137:in > `alias' > # ./vendor/gems/puppet-3.8.2/lib/puppet/resource/catalog.rb:111:in > `create_resource_aliases' > # ./vendor/gems/puppet-3.8.2/lib/puppet/resource/catalog.rb:90:in > `add_one_resource' > > Is there any way to accomplish the above? If not, please tell me now > and put me out of my misery, and we can go back to the original plan > of forcing everyone to use "::" in the resource titles and names. > > > > __________________________________________________________________________ > OpenStack Development Mailing List (not for usage questions) > Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev > > > __________________________________________________________________________ > OpenStack Development Mailing List (not for usage questions) > Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev -- Sofer Athlan-Guyot __________________________________________________________________________ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev