1 require 'puppet/provider/keystone'
3 Puppet::Type.type(:keystone_user_role).provide(
5 :parent => Puppet::Provider::Keystone
8 desc "Provider to manage keystone role assignments to users."
12 properties << '--project' << get_project
13 properties << '--user' << get_user
15 resource[:roles].each do |role|
16 request('role', 'add', role, resource[:auth], properties)
22 # If we just ran self.instances, no need to make the request again
23 # instance() will find it cached in @user_role_hash
24 if self.class.user_role_hash
25 return ! instance(resource[:name]).empty?
26 # If we don't have the hash ready, we don't need to rebuild the
27 # whole thing just to check on one particular user/role
29 roles = request('user role', 'list', nil, resource[:auth], ['--project', get_project, get_user])
30 # Since requesting every combination of users, roles, and
31 # projects is so expensive, construct the property hash here
32 # instead of in self.instances so it can be used in the role
34 @property_hash[:name] = resource[:name]
36 @property_hash[:ensure] = :absent
38 @property_hash[:ensure] = :present
39 @property_hash[:roles] = roles.collect do |role|
43 return @property_hash[:ensure] == :present
49 properties << '--project' << get_project
50 properties << '--user' << get_user
51 if @property_hash[:roles]
52 @property_hash[:roles].each do |role|
53 request('role', 'remove', role, resource[:auth], properties)
56 @property_hash[:ensure] = :absent
61 @property_hash[:roles]
66 # determine the roles to be added and removed
67 remove = current_roles - Array(value)
68 add = Array(value) - current_roles
71 add.each do |role_name|
72 request('role', 'add', role_name, resource[:auth], ['--project', project, '--user', user])
74 remove.each do |role_name|
75 request('role', 'remove', role_name, resource[:auth], ['--project', project, '--user', user])
81 instances = build_user_role_hash
82 instances.collect do |title, roles|
92 self.class.user_role_hash.select { |role_name, roles| role_name == name } || {}
98 resource[:name].rpartition('@').first
102 resource[:name].rpartition('@').last
105 # We split get_projects into class and instance methods
106 # so that the appropriate request method gets called
108 request('project', 'list', nil, resource[:auth]).collect do |project|
113 def self.get_projects
114 request('project', 'list', nil, nil).collect do |project|
119 def get_users(project)
120 request('user', 'list', nil, resource[:auth], ['--project', project]).collect do |user|
125 def self.get_users(project)
126 request('user', 'list', nil, nil, ['--project', project]).collect do |user|
131 # Class methods for caching user_role_hash so both class and instance
132 # methods can access the value
133 def self.set_user_role_hash(user_role_hash)
134 @user_role_hash = user_role_hash
137 def self.user_role_hash
141 def self.build_user_role_hash
142 hash = user_role_hash || {}
143 return hash unless hash.empty?
144 projects = get_projects
145 projects.each do |project|
146 users = get_users(project)
148 user_roles = request('user role', 'list', nil, nil, ['--project', project, user])
149 hash["#{user}@#{project}"] = []
150 user_roles.each do |role|
151 hash["#{user}@#{project}"] << role[:name]
155 set_user_role_hash(hash)