]> git.donarmstrong.com Git - dsa-puppet.git/blob - 3rdparty/modules/keystone/lib/puppet/provider/keystone_user_role/openstack.rb
5b9a1b58728b16c422769dfd0d34b030424bbf49
[dsa-puppet.git] / 3rdparty / modules / keystone / lib / puppet / provider / keystone_user_role / openstack.rb
1 require 'puppet/provider/keystone'
2
3 Puppet::Type.type(:keystone_user_role).provide(
4   :openstack,
5   :parent => Puppet::Provider::Keystone
6 ) do
7
8   desc "Provider to manage keystone role assignments to users."
9
10   def create
11     properties = []
12     properties << '--project' << get_project
13     properties << '--user' << get_user
14     if resource[:roles]
15       resource[:roles].each do |role|
16         request('role', 'add', role, resource[:auth], properties)
17       end
18     end
19   end
20
21   def exists?
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
28     else
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
33       # and destroy methods
34       @property_hash[:name] = resource[:name]
35       if roles.empty?
36         @property_hash[:ensure] = :absent
37       else
38         @property_hash[:ensure] = :present
39         @property_hash[:roles]  = roles.collect do |role|
40           role[:name]
41         end
42       end
43       return @property_hash[:ensure] == :present
44     end
45   end
46
47   def destroy
48     properties = []
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)
54       end
55     end
56     @property_hash[:ensure] = :absent
57   end
58
59
60   def roles
61     @property_hash[:roles]
62   end
63
64   def roles=(value)
65     current_roles = roles
66     # determine the roles to be added and removed
67     remove = current_roles - Array(value)
68     add    = Array(value) - current_roles
69     user = get_user
70     project = get_project
71     add.each do |role_name|
72       request('role', 'add', role_name, resource[:auth], ['--project', project, '--user', user])
73     end
74     remove.each do |role_name|
75       request('role', 'remove', role_name, resource[:auth], ['--project', project, '--user', user])
76     end
77   end
78
79
80   def self.instances
81     instances = build_user_role_hash
82     instances.collect do |title, roles|
83       new(
84         :name   => title,
85         :ensure => :present,
86         :roles  => roles
87       )
88     end
89   end
90
91   def instance(name)
92     self.class.user_role_hash.select { |role_name, roles| role_name == name } || {}
93   end
94
95   private
96
97   def get_user
98     resource[:name].rpartition('@').first
99   end
100
101   def get_project
102     resource[:name].rpartition('@').last
103   end
104
105   # We split get_projects into class and instance methods
106   # so that the appropriate request method gets called
107   def get_projects
108     request('project', 'list', nil, resource[:auth]).collect do |project|
109       project[:name]
110     end
111   end
112
113   def self.get_projects
114     request('project', 'list', nil, nil).collect do |project|
115       project[:name]
116     end
117   end
118
119   def get_users(project)
120     request('user', 'list', nil, resource[:auth], ['--project', project]).collect do |user|
121       user[:name]
122     end
123   end
124
125   def self.get_users(project)
126     request('user', 'list', nil, nil, ['--project', project]).collect do |user|
127       user[:name]
128     end
129   end
130
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
135   end
136
137   def self.user_role_hash
138     @user_role_hash
139   end
140
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)
147       users.each do |user|
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]
152         end
153       end
154     end
155     set_user_role_hash(hash)
156     hash
157   end
158
159 end