Search code examples
puppet

Create exported resource inside Puppet custom type


I try to create custom type in Puppet in order to generate some content based on some host state (eg generate token file in /etc directory).

Also I want to create File[/etc/token] inside this custom type and export it into PuppetDB in order to collect it on all other hosts within cluster

I've tried such code but it does not work as expected:

  def generate
    return [] unless self[:export]

    cluster = self[:cluster]
    user    = self[:name]
    should  = self.should(:ensure) || :present

    path    = "/etc/#{cluster}.#{user}.token"
    return [] if catalog.resource(:file, path)

    token = Puppet::Resource.new(:file, path)
    token[:ensure] = should
    token[:content] = provider.create_token
    token.virtual = true
    token.exported = true

    [Puppet::Type.type(:file).new(token)]
  end

Without token.virtual = true and token.exported = true this function can generate required file locally as expected but I can not export it

The only workaround is to use custom fact with required content eg $fact['user_token'] and export this content using default way:

  if $facts['user_token'] {
    @@file { '/etc/clustername.username.token':
      ensure  => file,
      content => $facts['user_token'],
    }
  }

Does anybody know how to generate exported resource inside custom type code?

Thank you


Solution

  • Does anybody know how to generate exported resource inside custom type code?

    You cannot use data extracted from the target node by a resource instance to export a resource. The timing and context of resource evaluation are both wrong:

    • Resources are exported during catalog building. By the time the catalog is being applied to the target node, it is too late.
    • Resources are exported by the catalog-building host. This is generally a machine different from the target node, and it does not have access to any data obtained from target node, except node facts. Other nodes typically do not have direct access to the exported-resource data, much less write access.

    On the other hand, if you don't need data (other than node facts) extracted from the target node, then you don't need to do the job in a plugin type. The usual approach in this case would be to create a defined-type wrapper for the plugin type, and put the resource export there.