X-Git-Url: https://git.adam-barratt.org.uk/?a=blobdiff_plain;f=3rdparty%2Fmodules%2Fkeystone%2Flib%2Fpuppet%2Fprovider%2Fkeystone_user_role%2Fopenstack.rb;h=e670a67506492dda00c4489eff8d68ceb7fa39af;hb=2dc39f2a756f82040d82cba324b21f44fad8ef3f;hp=da2b87044bf420727ec157ba3b2114c162e3da1e;hpb=d4b6110c989169c702f039a4c7dc1b309685bba3;p=mirror%2Fdsa-puppet.git diff --git a/3rdparty/modules/keystone/lib/puppet/provider/keystone_user_role/openstack.rb b/3rdparty/modules/keystone/lib/puppet/provider/keystone_user_role/openstack.rb index da2b87044..e670a6750 100644 --- a/3rdparty/modules/keystone/lib/puppet/provider/keystone_user_role/openstack.rb +++ b/3rdparty/modules/keystone/lib/puppet/provider/keystone_user_role/openstack.rb @@ -1,4 +1,5 @@ require 'puppet/provider/keystone' +require 'puppet/provider/keystone/util' Puppet::Type.type(:keystone_user_role).provide( :openstack, @@ -7,7 +8,7 @@ Puppet::Type.type(:keystone_user_role).provide( desc "Provider to manage keystone role assignments to users." - @credentials = Puppet::Provider::Openstack::CredentialsV2_0.new + @credentials = Puppet::Provider::Openstack::CredentialsV3.new def initialize(value={}) super(value) @@ -15,9 +16,6 @@ Puppet::Type.type(:keystone_user_role).provide( end def create - properties = [] - properties << '--project' << get_project - properties << '--user' << get_user if resource[:roles] resource[:roles].each do |role| self.class.request('role', 'add', [role] + properties) @@ -26,9 +24,6 @@ Puppet::Type.type(:keystone_user_role).provide( end def destroy - properties = [] - properties << '--project' << get_project - properties << '--user' << get_user if @property_hash[:roles] @property_hash[:roles].each do |role| self.class.request('role', 'remove', [role] + properties) @@ -38,10 +33,8 @@ Puppet::Type.type(:keystone_user_role).provide( end def exists? - if @user_role_hash - return ! @property_hash[:name].empty? - else - roles = self.class.request('user role', 'list', [get_user, '--project', get_project]) + if self.class.user_role_hash.nil? || self.class.user_role_hash.empty? + roles = self.class.request('role', 'list', properties) # Since requesting every combination of users, roles, and # projects is so expensive, construct the property hash here # instead of in self.instances so it can be used in the role @@ -55,8 +48,8 @@ Puppet::Type.type(:keystone_user_role).provide( role[:name] end end - return @property_hash[:ensure] == :present end + return @property_hash[:ensure] == :present end def roles @@ -68,13 +61,11 @@ Puppet::Type.type(:keystone_user_role).provide( # determine the roles to be added and removed remove = current_roles - Array(value) add = Array(value) - current_roles - user = get_user - project = get_project add.each do |role_name| - self.class.request('role', 'add', [role_name, '--project', project, '--user', user]) + self.class.request('role', 'add', [role_name] + properties) end remove.each do |role_name| - self.class.request('role', 'remove', [role_name, '--project', project, '--user', user]) + self.class.request('role', 'remove', [role_name] + properties) end end @@ -91,6 +82,19 @@ Puppet::Type.type(:keystone_user_role).provide( private + def properties + properties = [] + if get_project_id + properties << '--project' << get_project_id + elsif get_domain + properties << '--domain' << get_domain + else + error("No project or domain specified for role") + end + properties << '--user' << get_user_id + properties + end + def get_user resource[:name].rpartition('@').first end @@ -99,12 +103,67 @@ Puppet::Type.type(:keystone_user_role).provide( resource[:name].rpartition('@').last end + # if the role is for a domain, it will be specified as + # user@::domain - the "project" part will be empty + def get_domain + # use defined because @domain may be nil + return @domain if defined?(@domain) + projname, domname = Util.split_domain(get_project) + if projname.nil? + @domain = domname # no project specified, so must be a domain + else + @domain = nil # not a domain specific role + end + @domain + end + + def get_user_id + @user_id ||= Puppet::Resource.indirection.find("Keystone_user/#{get_user}")[:id] + end + + def get_project_id + # use defined because @project_id may be nil + return @project_id if defined?(@project_id) + projname, domname = Util.split_domain(get_project) + if projname.nil? + @project_id = nil + else + @project_id ||= Puppet::Resource.indirection.find("Keystone_tenant/#{get_project}")[:id] + end + @project_id + end + def self.get_projects - request('project', 'list').collect { |project| project[:name] } + request('project', 'list', '--long').collect do |project| + { + :id => project[:id], + :name => project[:name], + :domain_id => project[:domain_id], + :domain => domain_name_from_id(project[:domain_id]) + } + end end - def self.get_users(project) - request('user', 'list', ['--project', project]).collect { |user| user[:name] } + def self.get_users(project_id=nil, domain_id=nil) + properties = ['--long'] + if project_id + properties << '--project' << project_id + elsif domain_id + properties << '--domain' << domain_id + end + request('user', 'list', properties).collect do |user| + { + :id => user[:id], + :name => user[:name], + # note - column is "Domain" but it is really the domain id + :domain_id => user[:domain], + :domain => domain_name_from_id(user[:domain]) + } + end + end + + def self.user_role_hash + @user_role_hash end def self.set_user_role_hash(user_role_hash) @@ -112,16 +171,32 @@ Puppet::Type.type(:keystone_user_role).provide( end def self.build_user_role_hash - hash = @user_role_hash || {} + # The new hash will have the property that if the + # given key does not exist, create it with an empty + # array as the value for the hash key + hash = @user_role_hash || Hash.new{|h,k| h[k] = []} return hash unless hash.empty? - projects = get_projects - projects.each do |project| - users = get_users(project) - users.each do |user| - user_roles = request('user role', 'list', [user, '--project', project]) - hash["#{user}@#{project}"] = [] - user_roles.each do |role| - hash["#{user}@#{project}"] << role[:name] + # Need a mapping of project id to names. + project_hash = {} + Puppet::Type.type(:keystone_tenant).provider(:openstack).instances.each do |project| + project_hash[project.id] = project.name + end + # Need a mapping of user id to names. + user_hash = {} + Puppet::Type.type(:keystone_user).provider(:openstack).instances.each do |user| + user_hash[user.id] = user.name + end + # need a mapping of role id to name + role_hash = {} + request('role', 'list').each {|role| role_hash[role[:id]] = role[:name]} + # now, get all role assignments + request('role assignment', 'list').each do |assignment| + if assignment[:user] + if assignment[:project] + hash["#{user_hash[assignment[:user]]}@#{project_hash[assignment[:project]]}"] << role_hash[assignment[:role]] + else + domainname = domain_id_to_name(assignment[:domain]) + hash["#{user_hash[assignment[:user]]}@::#{domainname}"] << role_hash[assignment[:role]] end end end