Type/Provider Error: /Type[name]: Could not evaluate: No ability to determine if xxx exists

242 views
Skip to first unread message

lupin...@gmail.com

unread,
Mar 13, 2015, 3:54:56 AM3/13/15
to puppet...@googlegroups.com
Hi,

I'm on my first attempt of writing a custom type/provider and hope to learn on the process. I'm got a stumbling block and lost on what's going with this as I have defined the exist? method which apparently the usual suspect for this error.

puppet resource tsam_host 'wakwak' ip='192.168.20.1' ensure=present 
Error: /Tsam_host[wakwak]: Could not evaluate: No ability to determine if tsam_host exists
Error: Could not run: No ability to determine if tsam_host exists


modules/tsam/lib/puppet/provider/tsam_host/ruby.rb

Puppet::Type.type(:tsam_host).provide(:ruby) do
        header    
= ':content_type => :json, :accept => :json'
        baseurl    
= 'https://xxx....@172.16.210.10'
        host_uri  
= '/isam/host_records'
        deploy_uri
= '/pending_changes/deploy'

       
def exist?
            ip        
= resource[:ip]
           
begin
              response
= RestClient.get  "#{baseurl}#{host_uri}/#{ip}/hostnames",header
             
exit if response.code == 200
           
rescue Puppet::ExecutionFailure => e
             
exit!
           
end
       
end

       
def create
            host      
= resource[:name]
            ip        
= resource[:ip]
            postdata  
= '{ "addr" => ip, "hostnames" => [{ host }]}'
           
RestClient.post "#{baseurl}#{host_uri}", postdata.to_json, header
           
RestClient.get  "#{baseurl}#{deploy_uri}",header
       
end

       
def destroy
       
end
end


/modules/tsam/lib/puppet/type$ cat tsam_host.rb
Puppet::Type.newtype(:tsam_host) do
        desc
'Create hostname/ip mapping( hostfile ) entry on Access Manager Appliance Web Service API'

        ensurable

        newproperty
(:ip) do
                desc
'The IPV4 address of the host to be added'
       
end

        newparam
(:name, :namevar => true) do
                desc
'The host name.'
       
end
end


Appreciate for any pointers.
Lupin

jcbollinger

unread,
Mar 13, 2015, 9:02:47 AM3/13/15
to puppet...@googlegroups.com


On Friday, March 13, 2015 at 2:54:56 AM UTC-5, lupin...@gmail.com wrote:
Hi,

I'm on my first attempt of writing a custom type/provider and hope to learn on the process. I'm got a stumbling block and lost on what's going with this as I have defined the exist? method which apparently the usual suspect for this error.


Yes, you have defined an exist? method.  No, that is not the usual suspect, nor does it have any particular significance at all.  The method you want is exists? (note the second 's').


John

lupin...@gmail.com

unread,
Mar 14, 2015, 5:53:04 AM3/14/15
to puppet...@googlegroups.com

Thank you John, the missing (s) causes that issue..gaah. Now I have a seems working piece at least it can create the resource but I got an odd error message.


@102:~/.puppet/modules/tsam/lib/puppet/provider/tsam_host$ puppet resource tsam_host clu02 ip='192.168.200.32' ensure=present --debug
Debug: Loaded state in 0.00 seconds
Notice: /Tsam_host[clu02]/ensure: created
Debug: Finishing transaction 23116360
Debug: Storing state
Debug: Stored state in 0.01 seconds
Error: Could not run: undefined method `ip' for Tsam_host[clu02](provider=ruby):Puppet::Type::Tsam_host::ProviderRuby


I can't spot which 'ip' method it's referring to.

require 'rest_client'
require 'json'


Puppet::Type.type(:tsam_host).provide(:ruby) do


       
def exists?
            baseurl    
= 'https://xxxx:xx...@172.16.210.10'
            host_uri  
= '/isam/host_records'
           
RestClient.get("#{baseurl}#{host_uri}/" + resource[:ip] + "/hostnames",:content_type => :json, :accept => :json) {|response, request, result|
             
if response.code == 200
                     
true
             
else
                     
false
             
end

           
}
       
end

       
def create
            baseurl    
= 'https://xxx:xx...@172.16.210.10'

            host_uri  
= '/isam/host_records'
            deploy_uri
= '/pending_changes/deploy'

           
RestClient.post "#{baseurl}#{host_uri}", { 'addr' => resource[:ip], 'hostnames' => [{'name' => resource[:name] }]}.to_json,:content_type => :json, :accept => :json
           
RestClient.get  "#{baseurl}#{deploy_uri}",:content_type => :json, :accept => :json

       
end

       
def destroy
       
end
end



Thanks in advance
Lupin







Krzysztof Suszyński

unread,
Mar 14, 2015, 6:22:21 AM3/14/15
to puppet...@googlegroups.com
You have declared a property ip. This means that it will be ensurable as well and you should declare setter and getter for it:

def ip=(newip)
 
# Mayby like this
  host      
= resource[:name]
  postdata  
= {
   
'addr'      => newip,
   
'hostnames' => [ host ]
 
}

 
RestClient.put("#{baseurl}#{host_uri}", postdata.to_json, header)
 
RestClient.get("#{baseurl}#{deploy_uri}", header)
end

def ip
 
# Mayby like this
  result
= RestClient.get("#{baseurl}#{deploy_uri}", header)
  result
.ip
end

Getters will be executed if type exists. Setters will be executed if resource[:ip] value differ from one returned from your getter.

I recommend you read the book "Puppet Types and Providers" by Dan Bode. Buy or search web for ebook.

lupin...@gmail.com

unread,
Mar 17, 2015, 1:14:48 AM3/17/15
to puppet...@googlegroups.com
Thank you. I ended up making it a param for now. :)  
Reply all
Reply to author
Forward
0 new messages