Custom Provider and Metaprogramming(?) class level methods versus instance level methods

34 views
Skip to first unread message

Leonard Smith

unread,
Feb 11, 2014, 10:04:14 PM2/11/14
to puppe...@googlegroups.com
To all,

My ruby is failing me as I try to create a custom provider. I have a custom provider I am writing that uses the net-ldap gem that will, based on the custom type create, destroy and modify LDAP entries. What I am struggling with is the difference between the class level methods: self.instance and self.prefetch and instance level methods: create, destroy, etc.

As things currently stand I have in my custom provider code

  def self.ldap_connection  ## Class level method
    Puppet.debug("Creating new LDAP connection")
    unless @ldap_connection
      @ldap_conection = Net::LDAP.new(
        :host => '127.0.01',
        .......
     @ldap_connection
   end

   def self.prefetch           ## Class level method
      ldap_connection.search(:base => Services_Base, :filter => searchFilter ) do |entry|
       .... <code to parse output>
       results << new ( .... )
       results
   end

  def create   ## Instance level method
    self.class.ldap_connection.add(:dn => mydn, :attributes => myattr)
  end


The above all works fine, I can create and destory LDAP entries and modify attributes based on my custom type without a problem. But if you look at the self.ldap_connection I hard-coded the host. What I want to do, is create a parameter in the type, called ldapserver, which I then can use in self.ldap_connect. 

I tried 

@ldap_conection = Net::LDAP.new(
        :host => @resource[:ldapserver],

But when I debug @resource[:ldapserver] it is nil so I'm obviously not access it correctly. I also tried @@resource[:ldapserver] thinking resource is a class level variable, but still no luck. 

I've also tried to make def ldap_connection, so it is an instance level method,but the I run into issues in self.instances where I need to open a LDAP connection to prefetch, and the method is instance level, so not available at the class level, self.instances.

Thanks
Len

bert hajee

unread,
Feb 12, 2014, 9:29:07 AM2/12/14
to puppe...@googlegroups.com
Len,

You can call a class method from an instance just like any other method with a parameter. So if you might want to consider calling it with the ldap server as a parameter.

def self.ldap_connection(ldap_host)
    Puppet.debug("Creating new LDAP connection")
    unless @ldap_connection
      @ldap_conection = Net::LDAP.new(
        :host => ldap_host,
        .......
     @ldap_connection
   end

and call it from an instance method:

 def create   ## Instance level method
    self.class.ldap_connection(my_ldapserver).add(:dn => mydn, :attributes => myattr)
  end

Hope this helps.

Bert
Op woensdag 12 februari 2014 04:04:14 UTC+1 schreef Leonard Smith:

Leonard Smith

unread,
Feb 12, 2014, 1:18:02 PM2/12/14
to puppe...@googlegroups.com
Bert,

Thank you for the response. I ended up having a class level method that creates the connection, where I pass the server name, password, etc. And then another class level method to access the ldap connection, which the instance level methods call. So in pre-fetch I create the connection, and I can directly access the ldap connection in self.instances. But create and destroy makes a call to the 'accessor' method. 

Thanks
Len

bert hajee

unread,
Feb 12, 2014, 1:22:42 PM2/12/14
to puppe...@googlegroups.com
My pleasure. If you like, you can checkout easy type. Easy type is an add-on library that aims to take the intricacies for writing custom types away. It might help you.

Regards,

Bert

Op woensdag 12 februari 2014 19:18:02 UTC+1 schreef Leonard Smith:
Reply all
Reply to author
Forward
0 new messages