+++ /dev/null
-# Run test ie with: rspec spec/unit/provider/nova_spec.rb
-
-require 'puppet/util/inifile'
-
-class Puppet::Provider::Nova < Puppet::Provider
-
- def self.conf_filename
- '/etc/nova/nova.conf'
- end
-
- def self.withenv(hash, &block)
- saved = ENV.to_hash
- hash.each do |name, val|
- ENV[name.to_s] = val
- end
-
- yield
- ensure
- ENV.clear
- saved.each do |name, val|
- ENV[name] = val
- end
- end
-
- def self.nova_conf
- return @nova_conf if @nova_conf
- @nova_conf = Puppet::Util::IniConfig::File.new
- @nova_conf.read(conf_filename)
- @nova_conf
- end
-
- def self.nova_credentials
- @nova_credentials ||= get_nova_credentials
- end
-
- def nova_credentials
- self.class.nova_credentials
- end
-
- def self.get_nova_credentials
- #needed keys for authentication
- auth_keys = ['auth_host', 'auth_port', 'auth_protocol',
- 'admin_tenant_name', 'admin_user', 'admin_password']
- conf = nova_conf
- if conf and conf['keystone_authtoken'] and
- auth_keys.all?{|k| !conf['keystone_authtoken'][k].nil?}
- return Hash[ auth_keys.map \
- { |k| [k, conf['keystone_authtoken'][k].strip] } ]
- else
- raise(Puppet::Error, "File: #{conf_filename} does not contain all " +
- "required sections. Nova types will not work if nova is not " +
- "correctly configured.")
- end
- end
-
- def self.get_auth_endpoint
- q = nova_credentials
- "#{q['auth_protocol']}://#{q['auth_host']}:#{q['auth_port']}/v2.0/"
- end
-
- def self.auth_endpoint
- @auth_endpoint ||= get_auth_endpoint
- end
-
- def self.auth_nova(*args)
- q = nova_credentials
- authenv = {
- :OS_AUTH_URL => self.auth_endpoint,
- :OS_USERNAME => q['admin_user'],
- :OS_TENANT_NAME => q['admin_tenant_name'],
- :OS_PASSWORD => q['admin_password']
- }
- begin
- withenv authenv do
- nova(args)
- end
- rescue Exception => e
- if (e.message =~ /\[Errno 111\] Connection refused/) or
- (e.message =~ /\(HTTP 400\)/)
- sleep 10
- withenv authenv do
- nova(args)
- end
- else
- raise(e)
- end
- end
- end
-
- def auth_nova(*args)
- self.class.auth_nova(args)
- end
-
- def self.reset
- @nova_conf = nil
- @nova_credentials = nil
- end
-
- def self.str2hash(s)
- #parse string
- if s.include? "="
- k, v = s.split("=", 2)
- return {k.gsub(/'/, "") => v.gsub(/'/, "")}
- else
- return s.gsub(/'/, "")
- end
- end
-
- def self.str2list(s)
- #parse string
- if s.include? ","
- if s.include? "="
- new = {}
- else
- new = []
- end
- s.split(",").each do |el|
- ret = str2hash(el.strip())
- if s.include? "="
- new.update(ret)
- else
- new.push(ret)
- end
- end
- return new
- else
- return str2hash(s.strip())
- end
- end
-
- def self.cliout2list(output)
- #don't proceed with empty output
- if output.empty?
- return []
- end
- lines = []
- output.each_line do |line|
- #ignore lines starting with '+'
- if not line.match("^\\+")
- #split line at '|' and remove useless information
- line = line.gsub(/^\| /, "").gsub(/ \|$/, "").gsub(/[\n]+/, "")
- line = line.split("|").map do |el|
- el.strip().gsub(/^-$/, "")
- end
- #check every element for list
- line = line.map do |el|
- el = str2list(el)
- end
- lines.push(line)
- end
- end
- #create a list of hashes and return the list
- hash_list = []
- header = lines[0]
- lines[1..-1].each do |line|
- hash_list.push(Hash[header.zip(line)])
- end
- return hash_list
- end
-
- def self.nova_aggregate_resources_ids
- #produce a list of hashes with Id=>Name pairs
- lines = []
- #run command
- cmd_output = auth_nova("aggregate-list")
- #parse output
- hash_list = cliout2list(cmd_output)
- #only interessted in Id and Name
- hash_list.map{ |e| e.delete("Availability Zone")}
- hash_list.map{ |e| e['Id'] = e['Id'].to_i}
- return hash_list
- end
-
- def self.nova_aggregate_resources_get_name_by_id(name)
- #find the id by the given name
- nova_aggregate_resources_ids.each do |entry|
- if entry["Name"] == name
- return entry["Id"]
- end
- end
- #name not found
- return nil
- end
-
- def self.nova_aggregate_resources_attr(id)
- #run command to get details for given Id
- cmd_output = auth_nova("aggregate-details", id)
- list = cliout2list(cmd_output)[0]
- if ! list["Hosts"].is_a?(Array)
- if list["Hosts"] == ""
- list["Hosts"] = []
- else
- list["Hosts"] = [ list["Hosts"] ]
- end
- end
- return list
- end
-
-end