On Tue, May 17, 2011 at 5:40 AM, Luke Kanies <[email protected]> wrote:
> Thanks for the patches.
>
> How do you expect to use this type?  Can you provide some example use cases?

I also wanted the community to give feedback on the name in
particular. I'm not convinced 'web' is the best name for this type,
but I can see a bunch of utility here.

I like the idea of being able to treat REST API calls as Puppet resources...

>
> I've got a comment below, too.
>
> On May 16, 2011, at 8:22 PM, Mo Morsi wrote:
>
>> Adds a new resource type to puppet for web requests
>> and implements a provider of that type using the
>> ruby curl interface provided by the 'curb' rubygem
>>
>> Signed-off-by: Mo Morsi <[email protected]>
>> ---
>> Local-branch: feature/master/7474
>> lib/puppet/provider/web_request/curl.rb |  128 
>> +++++++++++++++++++++++++++++++
>> lib/puppet/type/web_request.rb          |   50 ++++++++++++
>> 2 files changed, 178 insertions(+), 0 deletions(-)
>> create mode 100644 lib/puppet/provider/web_request/curl.rb
>> create mode 100644 lib/puppet/type/web_request.rb
>>
>> diff --git a/lib/puppet/provider/web_request/curl.rb 
>> b/lib/puppet/provider/web_request/curl.rb
>> new file mode 100644
>> index 0000000..479bfd5
>> --- /dev/null
>> +++ b/lib/puppet/provider/web_request/curl.rb
>> @@ -0,0 +1,128 @@
>> +require 'curb'
>> +require 'uuid'
>> +require 'fileutils'
>> +
>> +# Helper to invoke the web request w/ curl
>> +def web_request(method, uri, request_params, params = {})
>
> These methods should really all be in the provider, rather than at the global 
> level.
>
>> +  raise Puppet::Error, "Must specify valid http method and uri" if 
>> method.nil? || uri.nil? || method == "" || uri == ""
>> +
>> +  curl = Curl::Easy.new
>> +
>> +  if params.has_key?(:cookie)
>> +    curl.enable_cookies = true
>> +    curl.cookiefile = params[:cookie]
>> +    curl.cookiejar  = params[:cookie]
>> +  end
>> +
>> +  curl.follow_location = (params.has_key?(:follow) && params[:follow])
>> +
>> +  case(method)
>> +  when 'get'
>> +    url = uri
>> +    url += ";" + request_params.collect { |k,v| "#{k}=#{v}" }.join("&") 
>> unless request_params.nil?
>> +    curl.url = url
>> +    curl.http_get
>> +    return curl
>> +
>> +  when 'post'
>> +    cparams = []
>> +    request_params.each_pair { |k,v| cparams << 
>> Curl::PostField.content(k,v) } unless request_params.nil?
>> +    curl.url = uri
>> +    curl.http_post(cparams)
>> +    return curl
>> +
>> +  #when 'put'
>> +  #when 'delete'
>> +  end
>> +end
>> +
>> +# Helper to verify the response
>> +def verify_result(result, verify = {})
>> +  returns = (verify.has_key?(:returns) && !verify[:returns].nil?) ? 
>> verify[:returns] : "200"
>> +  returns = [returns] unless returns.is_a? Array
>> +  unless returns.include?(result.response_code.to_s)
>> +    raise Puppet::Error, "Invalid HTTP Return Code: #{result.response_code},
>> +                          was expecting one of #{returns.join(", ")}"
>> +  end
>> +
>> +  if verify.has_key?(:body) && !verify[:body].nil? && !(result.body_str =~ 
>> Regexp.new(verify[:body]))
>> +    raise Puppet::Error, "Expecting #{verify[:body]} in the result"
>> +  end
>> +end
>> +
>> +# Helper to process/parse web parameters
>> +def process_params(request_method, params, uri)
>> +  begin
>> +    # Set request method and generate a unique session key
>> +    session = "/tmp/#{UUID.new.generate}"
>> +
>> +    # Invoke a login request if necessary
>> +    if params[:login]
>> +      login_params = params[:login].reject { |k,v| ['http_method', 
>> 'uri'].include?(k) }
>> +      web_request(params[:login]['http_method'], params[:login]['uri'],
>> +                  login_params, :cookie => session, :follow => 
>> params[:follow]).close
>> +    end
>> +
>> +    # Check to see if we should actually run the request
>> +    skip_request = !params[:unless].nil?
>> +    if params[:unless]
>> +      result = web_request(params[:unless]['http_method'], 
>> params[:unless]['uri'],
>> +                           params[:unless]['parameters'],
>> +                           :cookie => session, :follow => params[:follow])
>> +      begin
>> +        verify_result(result,
>> +                      :returns => params[:unless]['returns'],
>> +                      :body    => params[:unless]['verify'])
>> +      rescue Puppet::Error => e
>> +        skip_request = false
>> +      end
>> +      result.close
>> +    end
>> +    return if skip_request
>> +
>> +    # Actually run the request and verify the result
>> +    uri = params[:name] if uri.nil?
>> +    result = web_request(request_method, uri, params[:parameters],
>> +                         :cookie => session, :follow => params[:follow])
>> +    verify_result(result,
>> +                  :returns => params[:returns],
>> +                  :body    => params[:verify])
>> +    result.close
>> +
>> +    # Invoke a logout request if necessary
>> +    if params[:logout]
>> +      logout_params = params[:login].reject { |k,v| ['http_method', 
>> 'uri'].include?(k) }
>> +      web_request(params[:logout]['http_method'], params[:logout]['uri'],
>> +                  logout_params, :cookie => session, :follow => 
>> params[:follow]).close
>> +    end
>> +
>> +  rescue Exception => e
>> +    raise Puppet::Error, "An exception was raised when invoking web 
>> request: #{e}"
>> +
>> +  ensure
>> +    FileUtils.rm_f(session) if params[:logout]
>> +  end
>> +end
>> +
>> +# Puppet provider definition
>> +Puppet::Type.type(:web_request).provide :curl do
>> +  desc "Use curl to access web resources"
>> +
>> +  def get
>> +    @uri
>> +  end
>> +
>> +  def post
>> +    @uri
>> +  end
>> +
>> +  def get=(uri)
>> +    @uri = uri
>> +    process_params('get', @resource, uri)
>> +  end
>> +
>> +  def post=(uri)
>> +    @uri = uri
>> +    process_params('post', @resource, uri)
>> +  end
>> +end
>> diff --git a/lib/puppet/type/web_request.rb b/lib/puppet/type/web_request.rb
>> new file mode 100644
>> index 0000000..d95e286
>> --- /dev/null
>> +++ b/lib/puppet/type/web_request.rb
>> @@ -0,0 +1,50 @@
>> +Puppet::Type.newtype(:web_request) do
>> +    @doc = "Issue a request via the world wide web"
>> +
>> +    newparam :name
>> +
>> +    newproperty(:get) do
>> +      desc "Issue get request to the specified uri"
>> +      # TODO valid value to be a uri
>> +    end
>> +
>> +    newproperty(:post) do
>> +      desc "Issue get request to the specified uri"
>> +      # TODO valid value to be a uri
>> +    end
>> +
>> +    # TODO implement
>> +    #newproperty(:delete)
>> +    #newproperty(:put)
>> +
>> +    newparam(:parameters) do
>> +      desc "Hash of parameters to include in the web request"
>> +    end
>> +
>> +    newparam(:returns) do
>> +      desc "Expected http return codes of the request"
>> +      defaultto "200"
>> +      # TODO validate value(s) is among possible valid http return codes
>> +    end
>> +
>> +    newparam(:follow) do
>> +      desc "Boolean indicating if redirects should be followed"
>> +      newvalues(:true, :false)
>> +    end
>> +
>> +    newparam(:verify) do
>> +      desc "String to verify as being part of the result"
>> +    end
>> +
>> +    newparam(:login) do
>> +      desc "Login parameters to be used if a login is required before 
>> making the request"
>> +    end
>> +
>> +    newparam(:logout) do
>> +      desc "Logout parameters to be used if a logout is requred after 
>> making the request"
>> +    end
>> +
>> +    newparam(:unless) do
>> +      desc "Do not run request if the request specified here succeeds"
>> +    end
>> +end
>> --
>> 1.7.2.3
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "Puppet Developers" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to 
>> [email protected].
>> For more options, visit this group at 
>> http://groups.google.com/group/puppet-dev?hl=en.
>>
>
>
> --
> The trouble with the rat race is that even if you win, you're still a
> rat.  -- Lily Tomlin
> ---------------------------------------------------------------------
> Luke Kanies  -|-   http://puppetlabs.com   -|-   http://about.me/lak
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Puppet Developers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group at 
> http://groups.google.com/group/puppet-dev?hl=en.
>
>



-- 
Nigel Kersten
Product, Puppet Labs
@nigelkersten

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to