fuel-plugin-ironic/deployment_scripts/puppet/modules/ironic/lib/puppet/provider/ironic_images_setter/ini_setting.rb

151 lines
4.1 KiB
Ruby

require 'rubygems'
require 'net/http'
require 'net/https'
require 'json'
require 'puppet/util/inifile'
class KeystoneError < Puppet::Error
end
class KeystoneConnectionError < KeystoneError
end
class KeystoneAPIError < KeystoneError
end
RETRY_COUNT = 10
RETRY_SLEEP = 3
def handle_request(req, url)
begin
use_ssl = url.scheme == "https" ? true : false
http = Net::HTTP.start(url.hostname, url.port, {:use_ssl => use_ssl})
res = http.request(req)
if res.code != '200'
raise KeystoneAPIError, "Received error response from Keystone server at #{url}: #{res.message}"
end
rescue Errno::ECONNREFUSED => detail
raise KeystoneConnectionError, "Failed to connect to Keystone server at #{url}: #{detail}"
rescue SocketError => detail
raise KeystoneConnectionError, "Failed to connect to Keystone server at #{url}: #{detail}"
end
res
end
def keystone_v2_authenticate(auth_url,
username,
password,
tenantId=nil,
tenantName=nil)
post_args = {
'auth' => {
'passwordCredentials' => {
'username' => username,
'password' => password
},
}}
if tenantId
post_args['auth']['tenantId'] = tenantId
end
if tenantName
post_args['auth']['tenantName'] = tenantName
end
url = URI.parse("#{auth_url}/tokens")
req = Net::HTTP::Post.new url.path
req['content-type'] = 'application/json'
req.body = post_args.to_json
res = handle_request(req, url)
data = JSON.parse res.body
return data['access']['token']['id']
end
def glance_images(glance_url, token)
url = URI.parse("#{glance_url}/images")
req = Net::HTTP::Get.new url.path
req['content-type'] = 'application/json'
req['x-auth-token'] = token
res = handle_request(req, url)
data = JSON.parse res.body
data['images']
end
Puppet::Type.type(:ironic_images_setter).provide(:ruby) do
@ironic_images = nil
def authenticate
keystone_v2_authenticate(
@resource[:auth_url],
@resource[:auth_username],
@resource[:auth_password],
nil,
@resource[:auth_tenant_name])
end
def find_image_by_name(images, name)
found_images = images.select{|image| image['name'] == name}
if found_images.length == 1
return found_images[0]['id']
elsif found_images.length == 0
raise KeystoneAPIError, "Image with name '#{name}' not found."
elsif found_images.length > 1
raise KeystoneAPIError, "Found multiple matches for name: '#{name}'"
end
end
def exists?
ini_file = Puppet::Util::IniConfig::File.new
ini_file.read("/etc/ironic/ironic.conf")
ironic_images.each do |setting, id|
if ! ( ini_file['fuel'] && ini_file['fuel'][setting] && ini_file['fuel'][setting] == id)
return nil
end
end
end
def create
config
end
def ironic_images
@ironic_images ||= get_ironic_images
end
def get_ironic_images
token = authenticate
RETRY_COUNT.times do |n|
begin
all_images = glance_images(@resource[:glance_url], token)
rescue => e
debug "Request failed: '#{e.message}' Retry: '#{n}'"
if n == RETRY_COUNT - 1
raise KeystoneAPIError, 'Unable to get images.'
end
sleep RETRY_SLEEP
next
end
ironic_images = Hash.new
ironic_images['deploy_kernel'] = find_image_by_name(all_images, 'ironic-deploy-linux')
ironic_images['deploy_ramdisk'] = find_image_by_name(all_images, 'ironic-deploy-initramfs')
ironic_images['deploy_squashfs'] = find_image_by_name(all_images, 'ironic-deploy-squashfs')
return ironic_images
end
end
def config
ironic_images.each do |setting, id|
Puppet::Type.type(:ironic_config).new(
{:name => "fuel/#{setting}", :value => id}
).provider.create
end
end
end