Files
puppet-nova/lib/puppet/provider/nova_flavor/openstack.rb
Takashi Kajinami 0ed626e146 Use system scope credentials in providers
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
2022-02-21 14:54:47 +00:00

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