Merge pull request #801 from xenolog/bug/1248744

Backport retry connections to Quantum API
This commit is contained in:
Vladimir Kuklin 2013-11-07 08:43:45 -08:00
commit 532940bd5b
6 changed files with 85 additions and 191 deletions

View File

@ -60,7 +60,7 @@ Puppet::Type.type(:l3_if_downup).provide(:ruby) do
rv = false
loop do
begin
ping(['-c1',ipaddr])
ping(['-n', '-c1', ipaddr])
rv = true
break
rescue Puppet::ExecutionFailure => e
@ -173,7 +173,7 @@ Puppet::Type.type(:l3_if_downup).provide(:ruby) do
# rg = line.match('^\s*([0-9A-Za-z\.\-\_]+):')
# if rg
# if_list.push(rg[1].to_sym)
# end
# end
# end
# end
# return if_list

View File

@ -4,6 +4,14 @@ require 'puppet/util/inifile'
require 'tempfile'
class Puppet::Provider::Quantum < Puppet::Provider
def self.prefetch(resources)
instances.each do |i|
res = resources[i.name.to_s]
if ! res.nil?
res.provider = i
end
end
end
def self.quantum_credentials
@quantum_credentials ||= get_quantum_credentials
@ -57,108 +65,80 @@ class Puppet::Provider::Quantum < Puppet::Provider
# end
def self.auth_quantum(*args)
#todo: Rewrite, using ruby-openstack
begin
q = quantum_credentials
rescue Exception => e
raise(e)
end
# args_str = args.join '` '
# notice("ARGS: #{args_str}\n")
q = quantum_credentials
rv = nil
retries = 60
timeout = 120 # default timeout 2min.
end_time = Time.now.to_i + timeout
loop do
begin
rv = quantum('--os-tenant-name', q['admin_tenant_name'], '--os-username', q['admin_user'], '--os-password', q['admin_password'], '--os-auth-url', auth_endpoint, args)
break
rescue Exception => e
if e.message =~ /(\(HTTP\s+400\))|(\[Errno 111\]\s+Connection\s+refused)|(503\s+Service\s+Unavailable)|(Max\s+retries\s+exceeded)/
notice("Can't connect to quantum backend. Waiting for retry...")
retries -= 1
sleep 2
if retries <= 1
notice("Can't connect to quantum backend. No more retries, auth failed")
raise(e)
#break
end
else
rescue Puppet::ExecutionFailure => e
if ! e.message =~ /(\(HTTP\s+400\))|
(400-\{\'message\'\:\s+\'\'\})|
(\[Errno 111\]\s+Connection\s+refused)|
(503\s+Service\s+Unavailable)|
(\:\s+Maximum\s+attempts\s+reached)|
(Unauthorized\:\s+bad\s+credentials)|
(Max\s+retries\s+exceeded)/
raise(e)
#break
end
current_time = Time.now.to_i
if current_time > end_time
#raise(e)
break
else
wa = end_time - current_time
Puppet::debug("Non-fatal error: \"#{e.message}\"")
notice("Quantum API not avalaible. Wait up to #{wa} sec.")
end
sleep(2) # do not remove!!! It's a positive brake!
end
end
return rv
end
def auth_quantum(*args)
self.class.auth_quantum(args)
end
#todo: rewrite through API
def check_quantum_api_availability(timeout)
if timeout.to_i < 1
timeout = 45 # default timeout 45sec.
end
end_time = Time.now.to_i + timeout
rv = false
loop do
begin
auth_quantum('net-list')
rv = true
break
rescue Puppet::ExecutionFailure => e
current_time = Time.now.to_i
if current_time > end_time
break
else
wa = end_time - current_time
notice("Quantum API not avalaible. Wait up to #{wa} sec.")
end
sleep(0.5) # do not remove!!! It's a positive brake!
end
end
return rv
end
#private
# def self.list_quantum_objects
# ids = []
# (auth_quantum('index').split("\n")[2..-1] || []).collect do |line|
# ids << line.split[0]
# end
# return ids
# end
# def self.get_quantum_attr(id, attr)
# (auth_quantum('show', id).split("\n") || []).collect do |line|
# if line =~ /^#{attr}:/
# return line.split(': ')[1..-1]
# end
# end
# end
def self.list_keystone_tenants
q = quantum_credentials
tenants_id = {}
keystone(
'--os-tenant-name', q['admin_tenant_name'],
'--os-username', q['admin_user'],
'--os-password', q['admin_password'],
'--os-auth-url', auth_endpoint,
'tenant-list').split("\n")[3..-2].collect do |tenant|
t_id = tenant.split[1]
t_name = tenant.split[3]
tenants_id[t_name] = t_id
timeout = 120 # default timeout 2min.
end_time = Time.now.to_i + timeout
loop do
begin
keystone(
'--os-tenant-name', q['admin_tenant_name'],
'--os-username', q['admin_user'],
'--os-password', q['admin_password'],
'--os-auth-url', auth_endpoint,
'tenant-list'
).split("\n")[3..-2].collect do |tenant|
t_id = tenant.split[1]
t_name = tenant.split[3]
tenants_id[t_name] = t_id
end
break
rescue Puppet::ExecutionFailure => e
current_time = Time.now.to_i
if current_time > end_time
raise(e)
#break
else
wa = end_time - current_time
notice("Keystone API not avalaible. Wait up to #{wa} sec.")
end
sleep(2) # do not remove!!! It's a positive brake!
end
end
tenants_id
return tenants_id
end
# def list_keystone_tenants
# self.class.list_keystone_tenants
# end
end
# vim: set ts=2 sw=2 et :
# vim: set ts=2 sw=2 et :

View File

@ -10,7 +10,6 @@ Puppet::Type.type(:quantum_floatingip_pool).provide(
commands :quantum => 'quantum'
commands :keystone => 'keystone'
commands :sleep => 'sleep'
# I need to setup caching and what-not to make this lookup performance not suck
def self.instances
@ -45,15 +44,6 @@ Puppet::Type.type(:quantum_floatingip_pool).provide(
rv
end
def self.prefetch(resources)
instances.each do |i|
res = resources[i.name.to_s]
if ! res.nil?
res.provider = i
end
end
end
def pool_size
@property_hash[:pool_size]
end
@ -80,21 +70,7 @@ Puppet::Type.type(:quantum_floatingip_pool).provide(
def _create_N(n)
for i in 0...n.to_i do
retries = 30
loop do
begin
auth_quantum('floatingip-create', '--tenant-id', tenant_id[@resource[:name]], @resource[:ext_net])
break
rescue Exception => e
notice("Can't connect to quantum backend. Waiting for retry...")
retries -= 1
if retries <= 1
notice("Can't connect to quantum backend. No more retries.")
raise(e)
end
sleep 2
end
end
auth_quantum('floatingip-create', '--tenant-id', tenant_id[@resource[:name]], @resource[:ext_net])
end
end
@ -117,21 +93,7 @@ Puppet::Type.type(:quantum_floatingip_pool).provide(
Puppet::debug("*** Can't find in cache floating IP with ID:'#{fip_id}'")
end
if details[:tenant_id] == t_id
retries = 30
loop do
begin
auth_quantum('floatingip-delete', fip_id)
break
rescue Exception => e
notice("Can't connect to quantum backend. Waiting for retry...")
retries -= 1
if retries <= 1
notice("Can't connect to quantum backend. No more retries.")
raise(e)
end
sleep 2
end
end
auth_quantum('floatingip-delete', fip_id)
nn -= 1
break if nn <= 0
end
@ -165,48 +127,23 @@ Puppet::Type.type(:quantum_floatingip_pool).provide(
self.class.floatingip_list(args)
end
def self.floatingip_list(*args)
rv = ''
retries = 30
loop do
begin
rv = auth_quantum('floatingip-list', args)
break
rescue Exception => e
notice("Can't connect to quantum backend. Waiting for retry...")
retries -= 1
if retries <= 1
notice("Can't connect to quantum backend. No more retries.")
raise(e)
end
sleep 2
end
rv = auth_quantum('floatingip-list', args)
if rv.nil?
raise(Puppet::ExecutionFailure, "Can't fetch floatingip-list. Quantum or Keystone API not availaible.")
end
return rv
end
def floatingip_show(*args)
self.class.floatingip_show(args)
end
def self.floatingip_show(*args)
rv = ''
retries = 30
loop do
begin
rv = auth_quantum('floatingip-show', args)
break
rescue Exception => e
notice("Can't connect to quantum backend. Waiting for retry...")
retries -= 1
if retries <= 1
notice("Can't connect to quantum backend. No more retries.")
raise(e)
end
sleep 2
end
rv = auth_quantum('floatingip-show', args)
if rv.nil?
raise(Puppet::ExecutionFailure, "Can't execute floatingip_show. Quantum or Keystone API not availaible.")
end
return rv
end
end
# vim: set ts=2 sw=2 et :
# vim: set ts=2 sw=2 et :

View File

@ -10,12 +10,16 @@ Puppet::Type.type(:quantum_net).provide(
optional_commands :quantum => 'quantum'
optional_commands :keystone => 'keystone'
optional_commands :sleep => 'sleep'
# I need to setup caching and what-not to make this lookup performance not suck
def self.instances
network_list = auth_quantum("net-list")
return [] if network_list.chomp.empty?
if network_list.nil?
raise(Puppet::ExecutionFailure, "Can't prefetch net-list. Quantum or Keystone API not availaible.")
elsif network_list.chomp.empty?
return []
end
network_list.split("\n")[3..-2].collect do |net|
new(
@ -25,15 +29,6 @@ Puppet::Type.type(:quantum_net).provide(
end
end
def self.prefetch(resources)
instances.each do |i|
res = resources[i.name.to_s]
if ! res.nil?
res.provider = i
end
end
end
def exists?
@property_hash[:ensure] == :present
end
@ -65,8 +60,6 @@ Puppet::Type.type(:quantum_net).provide(
optional_opts.push("--shared")
end
check_quantum_api_availability(120)
auth_quantum('net-create',
'--tenant_id', tenant_id[@resource[:tenant]],
@resource[:name],

View File

@ -10,12 +10,15 @@ Puppet::Type.type(:quantum_router).provide(
optional_commands :quantum => 'quantum'
optional_commands :keystone => 'keystone'
optional_commands :sleep => 'sleep'
# I need to setup caching and what-not to make this lookup performance not suck
def self.instances
router_list = auth_quantum("router-list")
return [] if router_list.chomp.empty?
if router_list.nil?
raise(Puppet::ExecutionFailure, "Can't prefetch router-list. Quantum or Keystone API not availaible.")
elsif router_list.chomp.empty?
return []
end
router_list.split("\n")[3..-2].collect do |net|
new(
@ -25,15 +28,6 @@ Puppet::Type.type(:quantum_router).provide(
end
end
def self.prefetch(resources)
instances.each do |i|
res = resources[i.name.to_s]
if ! res.nil?
res.provider = i
end
end
end
def exists?
@property_hash[:ensure] == :present
end
@ -54,8 +48,6 @@ Puppet::Type.type(:quantum_router).provide(
admin_state.push('--admin-state-down')
end
check_quantum_api_availability(120)
router_info = auth_quantum('router-create',
'--tenant_id', tenant_id[@resource[:tenant]],
admin_state,

View File

@ -10,12 +10,15 @@ Puppet::Type.type(:quantum_subnet).provide(
optional_commands :quantum => 'quantum'
optional_commands :keystone => 'keystone'
optional_commands :sleep => 'sleep'
# I need to setup caching and what-not to make this lookup performance not suck
def self.instances
network_list = auth_quantum("subnet-list")
return [] if network_list.chomp.empty?
if network_list.nil?
raise(Puppet::ExecutionFailure, "Can't prefetch subnet-list. Quantum or Keystone API not availaible.")
elsif network_list.chomp.empty?
return []
end
network_list.split("\n")[3..-2].collect do |net|
new(
@ -25,15 +28,6 @@ Puppet::Type.type(:quantum_subnet).provide(
end
end
def self.prefetch(resources)
instances.each do |i|
res = resources[i.name.to_s]
if ! res.nil?
res.provider = i
end
end
end
def exists?
@property_hash[:ensure] == :present
end
@ -75,8 +69,6 @@ Puppet::Type.type(:quantum_subnet).provide(
end
end
check_quantum_api_availability(120)
auth_quantum('subnet-create',
'--tenant-id', tenant_id[@resource[:tenant]],
'--name', @resource[:name],