]> git.donarmstrong.com Git - dsa-puppet.git/blob - 3rdparty/modules/openstacklib/lib/puppet/provider/openstack.rb
try with modules from master
[dsa-puppet.git] / 3rdparty / modules / openstacklib / lib / puppet / provider / openstack.rb
1 require 'csv'
2 require 'puppet'
3
4 class Puppet::Error::OpenstackAuthInputError < Puppet::Error
5 end
6
7 class Puppet::Error::OpenstackUnauthorizedError < Puppet::Error
8 end
9
10 class Puppet::Provider::Openstack < Puppet::Provider
11
12   initvars # so commands will work
13   commands :openstack => 'openstack'
14
15   # Returns an array of hashes, where the keys are the downcased CSV headers
16   # with underscores instead of spaces
17   def self.request(service, action, properties, credentials=nil)
18     env = credentials ? credentials.to_env : {}
19     Puppet::Util.withenv(env) do
20       rv = nil
21       timeout = 10
22       end_time = Time.now.to_i + timeout
23       loop do
24         begin
25           if(action == 'list')
26             response = openstack(service, action, '--quiet', '--format', 'csv', properties)
27             response = parse_csv(response)
28             keys = response.delete_at(0) # ID,Name,Description,Enabled
29             rv = response.collect do |line|
30               hash = {}
31               keys.each_index do |index|
32                 key = keys[index].downcase.gsub(/ /, '_').to_sym
33                 hash[key] = line[index]
34               end
35               hash
36             end
37           elsif(action == 'show' || action == 'create')
38             rv = {}
39             # shell output is name="value"\nid="value2"\ndescription="value3" etc.
40             openstack(service, action, '--format', 'shell', properties).split("\n").each do |line|
41               # key is everything before the first "="
42               key, val = line.split("=", 2)
43               next unless val # Ignore warnings
44               # value is everything after the first "=", with leading and trailing double quotes stripped
45               val = val.gsub(/\A"|"\Z/, '')
46               rv[key.downcase.to_sym] = val
47             end
48           else
49             rv = openstack(service, action, properties)
50           end
51           break
52         rescue Puppet::ExecutionFailure => e
53           if e.message =~ /HTTP 401/
54             raise(Puppet::Error::OpenstackUnauthorizedError, 'Could not authenticate.')
55           elsif e.message =~ /Unable to establish connection/
56             current_time = Time.now.to_i
57             if current_time > end_time
58               break
59             else
60               wait = end_time - current_time
61               Puppet::debug("Non-fatal error: \"#{e.message}\"; retrying for #{wait} more seconds.")
62               if wait > timeout - 2 # Only notice the first time
63                 notice("#{service} service is unavailable. Will retry for up to #{wait} seconds.")
64               end
65             end
66             sleep(2)
67           else
68             raise e
69           end
70         end
71       end
72       return rv
73     end
74   end
75
76   private
77
78   def self.parse_csv(text)
79     # Ignore warnings - assume legitimate output starts with a double quoted
80     # string.  Errors will be caught and raised prior to this
81     text = text.split("\n").drop_while { |line| line !~ /^\".*\"/ }.join("\n")
82     return CSV.parse(text + "\n")
83   end
84 end