
This change enforces usage of system scope credentials to manage flavors, aggregates, and services, following the new policy rules for SRBAC support in nova. The logic to look up credential for the nova service user from [keystone_authtoken] is left to keep backward compatibility but is deprecated and will be removed. Depends-on: https://review.opendev.org/806474 Depends-on: https://review.opendev.org/828025 Depends-on: https://review.opendev.org/828874 Change-Id: I71779f0f1459d64914589a94a440336386266306
188 lines
5.9 KiB
Ruby
188 lines
5.9 KiB
Ruby
require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/nova')
|
|
|
|
Puppet::Type.type(:nova_flavor).provide(
|
|
:openstack,
|
|
:parent => Puppet::Provider::Nova
|
|
) do
|
|
desc <<-EOT
|
|
Manage Nova flavor
|
|
EOT
|
|
|
|
@credentials = Puppet::Provider::Openstack::CredentialsV3.new
|
|
|
|
def initialize(value={})
|
|
super(value)
|
|
@property_flush = {}
|
|
@project_flush = {}
|
|
end
|
|
|
|
def create
|
|
opts = [@resource[:name]]
|
|
opts << (@resource[:is_public] == :true ? '--public' : '--private')
|
|
(opts << '--id' << @resource[:id]) if @resource[:id]
|
|
(opts << '--ram' << @resource[:ram]) if @resource[:ram]
|
|
(opts << '--disk' << @resource[:disk]) if @resource[:disk]
|
|
(opts << '--ephemeral' << @resource[:ephemeral]) if @resource[:ephemeral]
|
|
(opts << '--vcpus' << @resource[:vcpus]) if @resource[:vcpus]
|
|
(opts << '--swap' << @resource[:swap]) if @resource[:swap]
|
|
(opts << '--rxtx-factor' << @resource[:rxtx_factor]) if @resource[:rxtx_factor]
|
|
@property_hash = self.class.system_request('flavor', 'create', opts)
|
|
if @resource[:properties] and !(@resources[:properties].empty?)
|
|
prop_opts = [@resource[:name]]
|
|
prop_opts << props_to_s(@resource[:properties])
|
|
self.class.system_request('flavor', 'set', prop_opts)
|
|
end
|
|
|
|
if @resource[:project] and @resource[:project] != ''
|
|
proj_opts = [@resource[:name]]
|
|
proj_opts << '--project' << @resource[:project]
|
|
self.class.system_request('flavor', 'set', proj_opts)
|
|
|
|
project = self.class.system_request('project', 'show', @resource[:project])
|
|
@property_hash[:project_name] = project[:name]
|
|
@property_hash[:project] = project[:id]
|
|
|
|
elsif @resource[:project_name] and @resource[:project_name] != ''
|
|
proj_opts = [@resource[:name]]
|
|
proj_opts << '--project' << @resource[:project_name]
|
|
self.class.system_request('flavor', 'set', proj_opts)
|
|
|
|
project = self.class.system_request('project', 'show', @resource[:project_name])
|
|
@property_hash[:project_name] = project[:name]
|
|
@property_hash[:project] = project[:id]
|
|
end
|
|
|
|
@property_hash[:ensure] = :present
|
|
end
|
|
|
|
def exists?
|
|
@property_hash[:ensure] == :present
|
|
end
|
|
|
|
def destroy
|
|
self.class.system_request('flavor', 'delete', @property_hash[:id])
|
|
@property_hash.clear
|
|
end
|
|
|
|
mk_resource_methods
|
|
|
|
[
|
|
:is_public,
|
|
:id,
|
|
:ram,
|
|
:disk,
|
|
:vcpus,
|
|
:swap,
|
|
:rtxt_factor,
|
|
].each do |attr|
|
|
define_method(attr.to_s + "=") do |value|
|
|
fail("{#attr.to_s} is read only")
|
|
end
|
|
end
|
|
|
|
def properties=(value)
|
|
@property_flush[:properties] = value
|
|
end
|
|
|
|
def project=(value)
|
|
@project_flush[:project] = value
|
|
end
|
|
|
|
def project_name=(value)
|
|
@project_flush[:project_name] = value
|
|
end
|
|
|
|
def self.instances
|
|
system_request('flavor', 'list', ['--long', '--all']).collect do |attrs|
|
|
project = system_request('flavor', 'show', [attrs[:id], '-c', 'access_project_ids'])
|
|
|
|
access_project_ids = project[:access_project_ids]
|
|
# Client can return None and this should be considered as ''
|
|
if access_project_ids.downcase.chomp == 'none'
|
|
project_value = ''
|
|
# If the ids are formatted as Array, surrounding [] should be removed
|
|
elsif access_project_ids.start_with?('[') and access_project_ids.end_with?(']')
|
|
# TODO(tkajinam): We'd need to consider multiple projects can be returned
|
|
project_value = access_project_ids[1..-2]
|
|
else
|
|
project_value = access_project_ids
|
|
end
|
|
project_value = project_value.gsub('\'', '')
|
|
|
|
if project_value != ''
|
|
project = system_request('project', 'show', project_value)
|
|
project_id = project[:id]
|
|
project_name = project[:name]
|
|
else
|
|
project_id = ''
|
|
project_name = ''
|
|
end
|
|
|
|
properties = Hash[attrs[:properties].scan(/(\S+)='([^']*)'/)] rescue nil
|
|
new(
|
|
:ensure => :present,
|
|
:name => attrs[:name],
|
|
:id => attrs[:id],
|
|
:ram => attrs[:ram],
|
|
:disk => attrs[:disk],
|
|
:ephemeral => attrs[:ephemeral],
|
|
:vcpus => attrs[:vcpus],
|
|
:is_public => attrs[:is_public].downcase.chomp == 'true'? true : false,
|
|
:swap => attrs[:swap],
|
|
:rxtx_factor => attrs[:rxtx_factor],
|
|
:properties => properties,
|
|
:project => project_id,
|
|
:project_name => project_name,
|
|
)
|
|
end
|
|
end
|
|
|
|
def self.prefetch(resources)
|
|
flavors = instances
|
|
resources.keys.each do |name|
|
|
if provider = flavors.find{ |flavor| flavor.name == name }
|
|
resources[name].provider = provider
|
|
end
|
|
end
|
|
end
|
|
|
|
def flush
|
|
unless @property_flush.empty?
|
|
opts = [@resource[:name]]
|
|
opts << props_to_s(@property_flush[:properties])
|
|
|
|
self.class.system_request('flavor', 'set', opts)
|
|
@property_flush.clear
|
|
end
|
|
|
|
unless @project_flush.empty?
|
|
if @project_flush[:project]
|
|
if @property_hash[:project] and @property_hash[:project] != ''
|
|
opts = [@resource[:name], '--project', @property_hash[:project]]
|
|
self.class.system_request('flavor', 'unset', opts)
|
|
end
|
|
if @project_flush[:project] != ''
|
|
opts = [@resource[:name], '--project', @project_flush[:project]]
|
|
self.class.system_request('flavor', 'set', opts)
|
|
end
|
|
elsif @project_flush[:project_name]
|
|
if @property_hash[:project_name] and @property_hash[:project_name] != ''
|
|
opts = [@resource[:name], '--project', @property_hash[:project_name]]
|
|
self.class.system_request('flavor', 'unset', opts)
|
|
end
|
|
if @project_flush[:project_name] != ''
|
|
opts = [@resource[:name], '--project', @project_flush[:project_name]]
|
|
self.class.system_request('flavor', 'set', opts)
|
|
end
|
|
end
|
|
@project_flush.clear
|
|
end
|
|
end
|
|
private
|
|
|
|
def props_to_s(props)
|
|
props.flat_map{ |k, v| ['--property', "#{k}=#{v}"] }
|
|
end
|
|
end
|
|
|