]> git.donarmstrong.com Git - dsa-puppet.git/blobdiff - 3rdparty/modules/openstacklib/lib/puppet/provider/openstack.rb
try with modules from master
[dsa-puppet.git] / 3rdparty / modules / openstacklib / lib / puppet / provider / openstack.rb
diff --git a/3rdparty/modules/openstacklib/lib/puppet/provider/openstack.rb b/3rdparty/modules/openstacklib/lib/puppet/provider/openstack.rb
new file mode 100644 (file)
index 0000000..155e5b9
--- /dev/null
@@ -0,0 +1,84 @@
+require 'csv'
+require 'puppet'
+
+class Puppet::Error::OpenstackAuthInputError < Puppet::Error
+end
+
+class Puppet::Error::OpenstackUnauthorizedError < Puppet::Error
+end
+
+class Puppet::Provider::Openstack < Puppet::Provider
+
+  initvars # so commands will work
+  commands :openstack => 'openstack'
+
+  # Returns an array of hashes, where the keys are the downcased CSV headers
+  # with underscores instead of spaces
+  def self.request(service, action, properties, credentials=nil)
+    env = credentials ? credentials.to_env : {}
+    Puppet::Util.withenv(env) do
+      rv = nil
+      timeout = 10
+      end_time = Time.now.to_i + timeout
+      loop do
+        begin
+          if(action == 'list')
+            response = openstack(service, action, '--quiet', '--format', 'csv', properties)
+            response = parse_csv(response)
+            keys = response.delete_at(0) # ID,Name,Description,Enabled
+            rv = response.collect do |line|
+              hash = {}
+              keys.each_index do |index|
+                key = keys[index].downcase.gsub(/ /, '_').to_sym
+                hash[key] = line[index]
+              end
+              hash
+            end
+          elsif(action == 'show' || action == 'create')
+            rv = {}
+            # shell output is name="value"\nid="value2"\ndescription="value3" etc.
+            openstack(service, action, '--format', 'shell', properties).split("\n").each do |line|
+              # key is everything before the first "="
+              key, val = line.split("=", 2)
+              next unless val # Ignore warnings
+              # value is everything after the first "=", with leading and trailing double quotes stripped
+              val = val.gsub(/\A"|"\Z/, '')
+              rv[key.downcase.to_sym] = val
+            end
+          else
+            rv = openstack(service, action, properties)
+          end
+          break
+        rescue Puppet::ExecutionFailure => e
+          if e.message =~ /HTTP 401/
+            raise(Puppet::Error::OpenstackUnauthorizedError, 'Could not authenticate.')
+          elsif e.message =~ /Unable to establish connection/
+            current_time = Time.now.to_i
+            if current_time > end_time
+              break
+            else
+              wait = end_time - current_time
+              Puppet::debug("Non-fatal error: \"#{e.message}\"; retrying for #{wait} more seconds.")
+              if wait > timeout - 2 # Only notice the first time
+                notice("#{service} service is unavailable. Will retry for up to #{wait} seconds.")
+              end
+            end
+            sleep(2)
+          else
+            raise e
+          end
+        end
+      end
+      return rv
+    end
+  end
+
+  private
+
+  def self.parse_csv(text)
+    # Ignore warnings - assume legitimate output starts with a double quoted
+    # string.  Errors will be caught and raised prior to this
+    text = text.split("\n").drop_while { |line| line !~ /^\".*\"/ }.join("\n")
+    return CSV.parse(text + "\n")
+  end
+end