Some openstack installations use characters that are not in \w, the old regex, now moved to string2hash was more permissible, and there's probably no reason the regex in pythondict2hash can't be just as permissible. Change-Id: I35b964d96e6a558f1a10daa2391a398db60ea800
140 lines
4.2 KiB
Ruby
140 lines
4.2 KiB
Ruby
require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/nova')
|
|
|
|
Puppet::Type.type(:nova_aggregate).provide(
|
|
:openstack,
|
|
:parent => Puppet::Provider::Nova
|
|
) do
|
|
desc <<-EOT
|
|
Provider to manage nova aggregations
|
|
EOT
|
|
|
|
@credentials = Puppet::Provider::Openstack::CredentialsV3.new
|
|
|
|
mk_resource_methods
|
|
|
|
def self.instances
|
|
request('aggregate', 'list').collect do |el|
|
|
attrs = request('aggregate', 'show', el[:name])
|
|
properties = parsestring(attrs[:properties]) rescue nil
|
|
new(
|
|
:ensure => :present,
|
|
:name => attrs[:name],
|
|
:id => attrs[:id],
|
|
:availability_zone => attrs[:availability_zone],
|
|
:metadata => properties,
|
|
:hosts => string2list(attrs[:hosts]).sort,
|
|
:filter_hosts => attrs[:filter_hosts]
|
|
)
|
|
end
|
|
end
|
|
|
|
def self.string2list(input)
|
|
return input[1..-2].split(",").map { |x| x.match(/'(.*?)'/)[1] }
|
|
end
|
|
|
|
def self.prefetch(resources)
|
|
instances_ = instances
|
|
resources.keys.each do |name|
|
|
if provider = instances_.find{ |instance| instance.name == name }
|
|
resources[name].provider = provider
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.get_known_hosts
|
|
# get list of hosts known to be active from openstack
|
|
return request('compute service', 'list', ['--service', 'nova-compute']).map{|el| el[:host]}
|
|
end
|
|
|
|
def exists?
|
|
@property_hash[:ensure] == :present
|
|
end
|
|
|
|
def destroy
|
|
@property_hash[:hosts].each do |h|
|
|
properties = [@property_hash[:name], h]
|
|
self.class.request('aggregate', 'remove host', properties)
|
|
end
|
|
self.class.request('aggregate', 'delete', @property_hash[:name])
|
|
end
|
|
|
|
def create
|
|
properties = [@resource[:name]]
|
|
if not @resource[:availability_zone].nil? and not @resource[:availability_zone].empty?
|
|
properties << "--zone" << @resource[:availability_zone]
|
|
end
|
|
if not @resource[:metadata].nil? and not @resource[:metadata].empty?
|
|
@resource[:metadata].each do |key, value|
|
|
properties << "--property" << "#{key}=#{value}"
|
|
end
|
|
end
|
|
@property_hash = self.class.request('aggregate', 'create', properties)
|
|
if not @resource[:hosts].nil? and not @resource[:hosts].empty?
|
|
# filter host list by known hosts if filter_hosts is set
|
|
if @resource[:filter_hosts] == :true
|
|
@resource[:hosts] = @resource[:hosts] & self.class.get_known_hosts()
|
|
end
|
|
@resource[:hosts].each do |host|
|
|
properties = [@property_hash[:name], host]
|
|
self.class.request('aggregate', 'add host', properties)
|
|
end
|
|
end
|
|
end
|
|
|
|
def availability_zone=(value)
|
|
self.class.request('aggregate', 'set', [ @resource[:name], '--zone', @resource[:availability_zone] ])
|
|
end
|
|
|
|
def metadata=(value)
|
|
# clear obsolete keys
|
|
if @property_hash[:metadata].keys.length > 0
|
|
properties = [@resource[:name] ]
|
|
(@property_hash[:metadata].keys - @resource[:metadata].keys).each do |key|
|
|
properties << "--property" << "#{key}"
|
|
end
|
|
self.class.request('aggregate', 'unset', properties)
|
|
end
|
|
properties = [@resource[:name] ]
|
|
@resource[:metadata].each do |key, value|
|
|
properties << "--property" << "#{key}=#{value}"
|
|
end
|
|
self.class.request('aggregate', 'set', properties)
|
|
end
|
|
|
|
def hosts=(value)
|
|
# filter host list by known hosts if filter_hosts is set
|
|
if @resource[:filter_hosts] == :true
|
|
value &= self.class.get_known_hosts()
|
|
end
|
|
if not @property_hash[:hosts].nil?
|
|
# remove hosts that are not present in update
|
|
(@property_hash[:hosts] - value).each do |host|
|
|
self.class.request('aggregate', 'remove host', [@property_hash[:id], host])
|
|
end
|
|
# add hosts that are not already present
|
|
(value - @property_hash[:hosts]).each do |host|
|
|
self.class.request('aggregate', 'add host', [@property_hash[:id], host])
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.string2hash(input)
|
|
return Hash[input.scan(/(\S+)='([^']*)'/)]
|
|
end
|
|
|
|
def self.pythondict2hash(input)
|
|
return JSON.parse(input.gsub(/u'([^']*)'/, '"\1"').gsub(/'/, '"'))
|
|
end
|
|
|
|
def self.parsestring(input)
|
|
if input[0] == '{'
|
|
# 4.0.0+ output, python dict
|
|
return self.pythondict2hash(input)
|
|
else
|
|
# Pre-4.0.0 output, key=value
|
|
return self.string2hash(input)
|
|
end
|
|
end
|
|
|
|
end
|