Hi Mo,
On Tue, 2011-05-10 at 12:51 -0400, Mo Morsi wrote:
On 05/05/2011 07:35 AM, Mark McLoughlin wrote:
>> diff --git
a/recipes/aeolus_recipe/lib/puppet/provider/web/curl.rb
b/recipes/aeolus_recipe/lib/puppet/provider/web/curl.rb
>> new file mode 100644
>> index 0000000..b5f4468
>> --- /dev/null
>> +++ b/recipes/aeolus_recipe/lib/puppet/provider/web/curl.rb
> ....
>> +# Puppet provider definition
>> +Puppet::Type.type(:web).provide :curl do
>> + desc "Use curl to access web resources"
>> +
>> + def http_method
>> + @request_method
>> + end
>> +
>> + def http_method=(request_method)
>> + begin
>> + # Set request method and generate a unique session key
>> + @request_method = request_method
>> + session = "/tmp/#{UUID.new.generate}"
>> +
>> + # Invoke a login request if necessary
> ...
>
> I'm a bit surprised to see all this happening in http_method=
>
> Care to explain why, just for my own education? :)
Sure. When it comes to puppet resource types and providers you can only
perform operations in properties, for example in the 'service' provider
type, setting the 'ensure' property to 'running' will invoke
'service
<name> start', while setting the 'enable' property to 'true'
will invoke
'chkconfig <name> on'.
Honestly wasn't sure what the best name for the property to actual
perform the operation in in this case, if you have a better suggestion
than 'http_method', I'm all ears.
Okay, after reading a bit more I'm starting to grok it :)
I'm still struggling to convince myself that we can be sure all the
resource parameters are set before the http_method property is assigned
to - i.e. that @resource[:uri] is guaranteed to be set before
http_method= is called.
Also, maybe in this case a property assignment isn't the best interface
between the resource type and the provider - we can define any interface
we like and do e.g.
newproperty(:http_method) do
...
newvalue(:get) do
provider.get
end
newvalue(:post) do
provider.post
end
end
Dunno, just an idea
>> +define
aeolus::conductor::provider($type="",$url=""){
>> + web{ "provider-$name":
>> + uri => "https://localhost/conductor/admin/providers",
>> + http_method => 'post',
>> + parameters => { 'provider[name]' => $name,
'provider[url]' => $url,
>> + 'provider[provider_type_codename]' => $type },
>> + returns => '200',
>> + verify => '.*Provider added.*',
>> + follow => true,
>> + unless => { 'http_method' => 'get',
>> + 'uri' =>
'https://localhost/conductor/admin/providers',
>> + 'verify' => ".*$name.*" },
>
> Would something like this be better:
>
> unless => { http_method => 'get',
> uri =>
'https://localhost/conductor/admin/providers',
> parameters => { 'q' => $name },
> verify =>
".*/admin/providers/.*>$name</a>.*" }
>
> i.e. run a search query and use a more specific regexp?
Well it actually does run a search query as is right now. And the nice
thing is that we can set the regex to whatever we want to look for in
the aeolus-configuration recipe without modifying the backend web
provider itself.
At some point though I would like to expand this to not only be able to
supply a regex but an xpath location at which that regex should appear.
I just mean that, in order to check whether a provider exists, we could
limit the providers returned by the GET using the q=$provider_name query
parameter and tighten up the regexp to match the HTML provided
It sounds like we're going to have an XML and JSON REST API for this
stuff, though, which would make this much less error prone
> Also, now that I type that ... it looks like "unless"
doesn't re-use the
> web type, right? i.e. parameters are automatically provided? It'd be
> cool if it re-used the same type somehow
It does reuse the web type. You can specify the parameters as you
suggested as is right now.
Hmm, I don't see that:
+ if @resource[:unless]
+ result = web_request(@resource[:unless]['http_method'],
i.e. if you add a new parameter to the web type, it isn't automatically
available to use in unless clauses
(Again, what you have is fine - I'm just trying to understand puppet
better)
...
>> +define aeolus::conductor::hwp($memory='',
$cpu='', $storage='', $architecture=''){
>> + web{ "hwp-$name":
>> + uri =>
"https://localhost/conductor/admin/hardware_profiles",
>> + http_method => 'post',
>> + parameters => {'hardware_profile[name]' => $name,
>> + 'hardware_profile[memory_attributes][value]'
=> $memory,
>> + 'hardware_profile[cpu_attributes][value]'
=> $cpu,
>> + 'hardware_profile[storage_attributes][value]'
=> $storage,
>> + 'hardware_profile[architecture_attributes][value]'
=> $architecture,
>> + 'hardware_profile[memory_attributes][name]'
=> 'memory',
>> + 'hardware_profile[memory_attributes][unit]'
=> 'MB',
>> + 'hardware_profile[cpu_attributes][name]'
=> 'cpu',
>> + 'hardware_profile[cpu_attributes][unit]'
=> 'count',
>> + 'hardware_profile[storage_attributes][name]'
=> 'storage',
>> + 'hardware_profile[storage_attributes][unit]'
=> 'GB',
>> + 'hardware_profile[architecture_attributes][name]'
=> 'architecture',
>> + 'hardware_profile[architecture_attributes][unit]'
=> 'label',
>> + 'commit' => 'Save'},
>> + returns => '200',
>> + #verify => '.*Hardware profile added.*',
>> + follow => true,
>> + unless => { 'http_method' => 'get',
>> + 'uri' =>
'https://localhost/conductor/admin/hardware_profiles',
>> + 'verify' => ".*$name.*" },
>
> Is there something weird going on with GET on the hardware_profiles
> resource?
>
> Without 'Accept: text/html', I'm seeing:
>
> The error occurred while evaluating nil.[]):
> app/controllers/admin/hardware_profiles_controller.rb:206:in
`build_hardware_profile'
> app/controllers/admin/hardware_profiles_controller.rb:14:in `index'
> app/controllers/admin/hardware_profiles_controller.rb:11:in `index'
> compass (0.10.4)
lib/compass/app_integration/rails/actionpack2/action_controller.rb:7:in `process'
>
> i.e. it's following the "format.js" path and breaking. Is that a
> conductor bug?
>
Not fully sure what the issue your describing here. Do we need to
specify this additional header in the request for this to work? How does
format.js play into this?
It seemed to be fully working when I tried it out, not sure what the
difference between our environments is. If there is an error in the
conductor logs due to this request, I'm tempted to say its an issue on
that side (since the request looks like it should be valid). We'll need
to debug this further tho.
Yep, I think there's an issue on the conductor side
Compare the result of:
$> /usr/bin/curl -H 'Accept: text/html' -b /tmp/aeolus-admin.cookie
http://localhost:3000/conductor/hardware_profiles
to:
$> /usr/bin/curl -b /tmp/aeolus-admin.cookie
http://localhost:3000/conductor/hardware_profiles
The backtrace above is the error I see with the latter
Cheers,
Mark.