Fixes user and project search by name in openstack_user resource

As project and user names are only unique for each domain and some
Keystone settings may filter user listing, any user or project search by
name needs to include the associated domain.

This change fixes any search done by name of a project or user in the
openstack_user resource. It is
assumed that if no domain is specified and there are multiple elements
with the same name, the first search result is
chosen.

Closes-Bug: #1871144

Change-Id: I0ed3ffabab5f8b0959c3b2c50a3619f378e59c9e
Signed-off-by: Henrique Santos <hfigueiredosantos@tecnico.ulisboa.pt>
(cherry picked from commit 3085252eab)
This commit is contained in:
Henrique Santos 2020-04-14 16:02:48 +01:00 committed by Lance Albertson
parent 325ad8a4cc
commit 6fd801ac2a
3 changed files with 42 additions and 16 deletions

52
libraries/openstack_user.rb Normal file → Executable file
View File

@ -1,4 +1,3 @@
#
# Copyright 2016 cloudbau GmbH
#
@ -30,9 +29,14 @@ module OpenstackclientCookbook
default_action :create
action :create do
user = new_resource.connection.users.find { |u| u.name == new_resource.user_name }
project = new_resource.connection.projects.find { |p| p.name == new_resource.project_name }
domain = new_resource.connection.domains.find { |u| u.name == new_resource.domain_name }
domain = new_resource.connection.domains.find { |d| d.name == new_resource.domain_name }
project = new_resource.connection.projects.find do |p|
(p.name == new_resource.project_name) && (domain ? p.domain_id == domain.id : {})
end
user = new_resource.connection.users.find_by_name(
new_resource.user_name,
domain ? { domain_id: domain.id } : {}
).first
if user
log "User with name: \"#{new_resource.user_name}\" already exists"
elsif domain
@ -54,7 +58,11 @@ module OpenstackclientCookbook
end
action :delete do
user = new_resource.connection.users.find { |u| u.name == new_resource.user_name }
domain = new_resource.connection.domains.find { |d| d.name == new_resource.domain_name }
user = new_resource.connection.users.find_by_name(
new_resource.user_name,
domain ? { domain_id: domain.id } : {}
).first
if user
user.destroy
else
@ -64,15 +72,27 @@ module OpenstackclientCookbook
# Grant a role in a project
action :grant_role do
user = new_resource.connection.users.find { |u| u.name == new_resource.user_name }
project = new_resource.connection.projects.find { |p| p.name == new_resource.project_name }
domain = new_resource.connection.domains.find { |d| d.name == new_resource.domain_name }
project = new_resource.connection.projects.find do |p|
(p.name == new_resource.project_name) && (domain ? p.domain_id == domain.id : {})
end
role = new_resource.connection.roles.find { |r| r.name == new_resource.role_name }
user = new_resource.connection.users.find_by_name(
new_resource.user_name,
domain ? { domain_id: domain.id } : {}
).first
project.grant_role_to_user role.id, user.id if role && project && user
end
action :revoke_role do
user = new_resource.connection.users.find { |u| u.name == new_resource.user_name }
project = new_resource.connection.projects.find { |p| p.name == new_resource.project_name }
domain = new_resource.connection.domains.find { |d| d.name == new_resource.domain_name }
user = new_resource.connection.users.find_by_name(
new_resource.user_name,
domain ? { domain_id: domain.id } : {}
).first
project = new_resource.connection.projects.find do |p|
(p.name == new_resource.project_name) && (domain ? p.domain_id == domain.id : {})
end
role = new_resource.connection.roles.find { |r| r.name == new_resource.role_name }
project.revoke_role_from_user role.id, user.id if role && project && user
end
@ -82,15 +102,21 @@ module OpenstackclientCookbook
# only used to identify a user who is in that domain. This action grants
# the user a role in the domain.
action :grant_domain do
user = new_resource.connection.users.find { |u| u.name == new_resource.user_name }
domain = new_resource.connection.domains.find { |p| p.name == new_resource.domain_name }
domain = new_resource.connection.domains.find { |d| d.name == new_resource.domain_name }
user = new_resource.connection.users.find_by_name(
new_resource.user_name,
domain ? { domain_id: domain.id } : {}
).first
role = new_resource.connection.roles.find { |r| r.name == new_resource.role_name }
user.grant_role role.id if role && domain && user
end
action :revoke_domain do
user = new_resource.connection.users.find { |u| u.name == new_resource.user_name }
domain = new_resource.connection.domains.find { |p| p.name == new_resource.domain_name }
domain = new_resource.connection.domains.find { |d| d.name == new_resource.domain_name }
user = new_resource.connection.users.find_by_name(
new_resource.user_name,
domain ? { domain_id: domain.id } : {}
).first
role = new_resource.connection.roles.find { |r| r.name == new_resource.role_name }
user.revoke_role role.id if role && domain && user
end

View File

@ -6,7 +6,7 @@ description 'Installs the fog-openstack gem and offers LWRPs to use it'
issues_url 'https://launchpad.net/openstack-chef'
source_url 'https://opendev.org/openstack/cookbook-openstack-client'
chef_version '>= 14.0'
version '18.0.0'
version '18.1.0'
%w(ubuntu redhat centos).each do |os|
supports os

4
spec/user_spec.rb Normal file → Executable file
View File

@ -29,7 +29,7 @@ describe 'openstackclient_test::user' do
double :user,
create: true,
destroy: true,
find: nil
find_by_name: []
end
let(:found_user) do
@ -44,7 +44,7 @@ describe 'openstackclient_test::user' do
double :user,
create: true,
destroy: true,
find: found_user
find_by_name: [found_user]
end
let(:found_role) do