]> git.donarmstrong.com Git - dsa-puppet.git/blobdiff - 3rdparty/modules/keystone/lib/puppet/provider/keystone_user_role/openstack.rb
Update to Kilo
[dsa-puppet.git] / 3rdparty / modules / keystone / lib / puppet / provider / keystone_user_role / openstack.rb
index da2b87044bf420727ec157ba3b2114c162e3da1e..e670a67506492dda00c4489eff8d68ceb7fa39af 100644 (file)
@@ -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