Deletes tenant parameter from keystone_user

The tenant parameter was made deprecated in Kilo and to be removed in Liberty:
see bug/1472437 and corresponding patch.

This patch removes the tenant parameter from the keystone_user provider and the
manifests using it.

From now on, a user is assigned to a project (tenant) through the
keystone_user_role provider.

For instance,

When using the default domain:
  keystone_user_role {'user1@project':
    ensure => present,
    roles  => ['admin'],
  }

When using non default domains:
  keystone_user_role {'user1::domain1@project1::domain2':
    ensure => present,
    roles  => ['admin'],
  }

Change-Id: I79f1bca4c67a4c92234431b2ae867933172a1ebe
This commit is contained in:
Gilles Dubreuil 2015-09-29 17:19:49 +10:00
parent 99e055c2e8
commit 8461e9acfb
10 changed files with 5 additions and 288 deletions

View File

@ -36,13 +36,6 @@ Puppet::Type.type(:keystone_user).provide(
@property_hash = self.class.request('user', 'create', properties)
@property_hash[:name] = resource[:name]
@property_hash[:domain] = user_domain
if resource[:tenant]
# DEPRECATED - To be removed in next release (Liberty)
# https://bugs.launchpad.net/puppet-keystone/+bug/1472437
set_project(resource[:tenant])
@property_hash[:tenant] = resource[:tenant]
end
@property_hash[:ensure] = :present
end
@ -144,76 +137,6 @@ Puppet::Type.type(:keystone_user).provide(
@property_flush[:replace_password] = value
end
def find_project_for_user(projname, project_id = nil)
# DEPRECATED - To be removed in next release (Liberty)
# https://bugs.launchpad.net/puppet-keystone/+bug/1472437
user_name, user_domain = self.class.name_and_domain(resource[:name], resource[:domain])
project_name, project_domain = self.class.name_and_domain(projname, nil, user_domain)
self.class.request('project', 'list', ['--user', id, '--long']).each do |project|
if (project_id == project[:id]) ||
((projname == project_name) && (project_domain == self.class.domain_name_from_id(project[:domain_id])))
return projname
end
end
return nil
end
def set_project(name)
# DEPRECATED - To be removed in next release (Liberty)
# https://bugs.launchpad.net/puppet-keystone/+bug/1472437
project_name, domain_name = self.class.name_and_domain(name)
project = self.class.fetch_project(project_name, domain_name)
project_id = project ? project[:id] : nil
unless project_id
raise(Puppet::Error, "No project found for name #{name} and domain #{domain}")
end
if project_id == :absent
raise(Puppet::Error, "Project #{newproject} missing when creating user #{resource[:name]}")
end
# Currently the only way to assign a user to a tenant not using user-create
# is to use role-add - this means we also need a role - there is usual
# a default role called _member_ which can be used for this purpose. What
# usually happens in a puppet module is that immediately after calling
# keystone_user, the module will then assign a role to that user. It is
# ok for a user to have the _member_ role and another role.
default_role = "_member_"
begin
self.class.request('role', 'show', default_role)
rescue
self.class.request('role', 'create', default_role)
end
# finally, assign the user to the project with the role
self.class.request('role', 'add', [default_role, '--project', project_id, '--user', id])
name
end
# DEPRECATED - To be removed in next release (Liberty)
# https://bugs.launchpad.net/puppet-keystone/+bug/1472437
def tenant=(value)
@property_hash[:tenant] = set_project(resource[:tenant])
end
# DEPRECATED - To be removed in next release (Liberty)
# https://bugs.launchpad.net/puppet-keystone/+bug/1472437
def tenant
return resource[:tenant] if sym_to_bool(resource[:ignore_default_tenant])
# use the one returned from instances
tenant_name = @property_hash[:project]
if tenant_name.nil? or tenant_name.empty?
# if none (i.e. ldap backend) use the given one
tenant_name = resource[:tenant]
else
return tenant_name
end
if tenant_name.nil? or tenant_name.empty?
return nil # nothing found, nothing given
end
project_name, domain_name = self.class.name_and_domain(tenant_name)
project = self.class.fetch_project(project_name, domain_name)
project_id = project ? project[:id] : nil
find_project_for_user(tenant_name, project_id)
end
def domain
@property_hash[:domain]
end

View File

@ -14,19 +14,6 @@ Puppet::Type.newtype(:keystone_user) do
newvalues(/\S+/)
end
newparam(:ignore_default_tenant) do
# DEPRECATED - To be removed in next release (Liberty)
# https://bugs.launchpad.net/puppet-keystone/+bug/1472437
validate do |v|
Puppet.warning('([keystone_user]: The ignore_default_tenant parameter is deprecated and will be removed in the future.')
end
newvalues(/(t|T)rue/, /(f|F)alse/, true, false)
defaultto(false)
munge do |value|
value.to_s.downcase.to_sym
end
end
newproperty(:enabled) do
newvalues(/(t|T)rue/, /(f|F)alse/, true, false)
defaultto(true)
@ -54,15 +41,6 @@ Puppet::Type.newtype(:keystone_user) do
end
end
newproperty(:tenant) do
# DEPRECATED - To be removed in next release (Liberty)
# https://bugs.launchpad.net/puppet-keystone/+bug/1472437
validate do |v|
Puppet.warning('([keystone_user]: The tenant parameter is deprecated and will be removed in the future. Please use keystone_user_role to assign a user to a project.')
end
newvalues(/\S+/)
end
newproperty(:email) do
newvalues(/^(\S+@\S+)|$/)
end
@ -89,12 +67,6 @@ Puppet::Type.newtype(:keystone_user) do
end
end
autorequire(:keystone_tenant) do
# DEPRECATED - To be removed in next release (Liberty)
# https://bugs.launchpad.net/puppet-keystone/+bug/1472437
self[:tenant]
end
autorequire(:keystone_domain) do
# use the domain parameter if given, or the one from name if any
self[:domain] or Util.split_domain(self[:name])[1]

View File

@ -152,8 +152,6 @@ define keystone::resource::service_identity(
'enabled' => true,
'password' => $password,
'email' => $email,
'tenant' => $tenant,
'ignore_default_tenant' => $ignore_default_tenant,
'domain' => $user_domain_real,
})
if ! $password {

View File

@ -33,10 +33,6 @@
# Admin user. Optional.
# Defaults to admin.
#
# [*ignore_default_tenant*]
# Ignore setting the default tenant value when the user is created. Optional.
# Defaults to false.
#
# [*admin_tenant_desc*]
# Optional. Description for admin tenant,
# Defaults to 'admin tenant'
@ -82,7 +78,6 @@ class keystone::roles::admin(
$admin_tenant = 'openstack',
$admin_roles = ['admin'],
$service_tenant = 'services',
$ignore_default_tenant = false,
$admin_tenant_desc = 'admin tenant',
$service_tenant_desc = 'Tenant for the openstack services',
$configure_user = true,
@ -116,13 +111,11 @@ class keystone::roles::admin(
if $configure_user {
keystone_user { $admin:
ensure => present,
enabled => true,
tenant => $admin_tenant,
email => $email,
password => $password,
domain => $admin_user_domain,
ignore_default_tenant => $ignore_default_tenant,
ensure => present,
enabled => true,
email => $email,
password => $password,
domain => $admin_user_domain,
}
}

View File

@ -112,7 +112,6 @@ describe 'basic keystone server with resources' do
keystone_user { 'adminv3::admin_domain':
ensure => present,
enabled => true,
tenant => 'openstackv3::admin_domain',
email => 'test@example.tld',
password => 'a_big_secret',
}

View File

@ -112,7 +112,6 @@ describe 'keystone server running with Apache/WSGI as Identity Provider' do
keystone_user { 'adminv3::admin_domain':
ensure => present,
enabled => true,
tenant => 'openstackv3::admin_domain',
email => 'test@example.tld',
password => 'a_big_secret',
}

View File

@ -111,7 +111,6 @@ describe 'keystone server running with Apache/WSGI with resources' do
keystone_user { 'adminv3::admin_domain':
ensure => present,
enabled => true,
tenant => 'openstackv3::admin_domain',
email => 'test@example.tld',
password => 'a_big_secret',
}

View File

@ -24,10 +24,8 @@ describe 'keystone::roles::admin' do
it { is_expected.to contain_keystone_user('admin').with(
:ensure => 'present',
:enabled => true,
:tenant => 'openstack',
:email => 'foo@bar',
:password => 'ChangeMe',
:ignore_default_tenant => 'false'
)}
it { is_expected.to contain_keystone_role('admin').with_ensure('present') }
it { is_expected.to contain_keystone_user_role('admin@openstack').with(
@ -47,7 +45,6 @@ describe 'keystone::roles::admin' do
:admin_tenant => 'admin',
:admin_roles => ['admin', 'heat_stack_owner'],
:service_tenant => 'foobar',
:ignore_default_tenant => 'true',
:admin_tenant_desc => 'admin something else',
:service_tenant_desc => 'foobar description',
}
@ -66,10 +63,8 @@ describe 'keystone::roles::admin' do
it { is_expected.to contain_keystone_user('admin').with(
:ensure => 'present',
:enabled => true,
:tenant => 'admin',
:email => 'foo@baz',
:password => 'foo',
:ignore_default_tenant => 'true'
)}
it { is_expected.to contain_keystone_user_role('admin@admin').with(
:roles => ['admin', 'heat_stack_owner'],
@ -117,7 +112,6 @@ describe 'keystone::roles::admin' do
end
it { is_expected.to contain_keystone_user('admin').with(
:domain => 'admin_user_domain',
:tenant => 'admin_tenant'
)}
it { is_expected.to contain_keystone_tenant('admin_tenant').with(:domain => 'admin_project_domain') }
it { is_expected.to contain_keystone_domain('admin_user_domain') }
@ -137,7 +131,6 @@ describe 'keystone::roles::admin' do
end
it { is_expected.to contain_keystone_user('admin').with(
:domain => 'admin_user_domain',
:tenant => 'admin_tenant::admin_project_domain'
)}
it { is_expected.to contain_keystone_tenant('admin_tenant::admin_project_domain').with(:domain => 'admin_project_domain') }
it { is_expected.to contain_keystone_domain('admin_user_domain') }

View File

@ -40,7 +40,6 @@ describe 'keystone::resource::service_identity' do
:ensure => 'present',
:password => 'secrete',
:email => 'neutron@localhost',
:tenant => 'services',
)}
it { is_expected.to contain_keystone_user_role("#{title}@services").with(
@ -89,7 +88,6 @@ describe 'keystone::resource::service_identity' do
:ensure => 'present',
:password => 'secrete',
:email => 'neutron@localhost',
:tenant => 'services',
:domain => 'userdomain',
)}
it { is_expected.to contain_keystone_user_role("#{title}@services").with(
@ -108,7 +106,6 @@ describe 'keystone::resource::service_identity' do
:ensure => 'present',
:password => 'secrete',
:email => 'neutron@localhost',
:tenant => 'services',
:domain => 'userdomain',
)}
it { is_expected.to contain_keystone_domain('userdomain').with(
@ -129,7 +126,6 @@ describe 'keystone::resource::service_identity' do
:ensure => 'present',
:password => 'secrete',
:email => 'neutron@localhost',
:tenant => 'services',
:domain => 'defaultdomain',
)}
it { is_expected.to contain_keystone_domain('defaultdomain').with(

View File

@ -31,7 +31,6 @@ describe provider_class do
:ensure => :present,
:enabled => 'True',
:password => 'secret',
:tenant => 'project2::domain2',
:email => 'user1@example.com',
:domain => 'domain1',
}
@ -50,11 +49,6 @@ describe provider_class do
describe 'when managing a user' do
describe '#create' do
it 'creates a user' do
provider.class.expects(:openstack)
.with('role', 'show', '--format', 'shell', '_member_')
.returns('name="_member_"')
provider.class.expects(:openstack)
.with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id'])
provider.class.expects(:openstack)
.with('user', 'create', '--format', 'shell', ['user1', '--enable', '--password', 'secret', '--email', 'user1@example.com', '--domain', 'domain1'])
.returns('email="user1@example.com"
@ -62,11 +56,6 @@ enabled="True"
id="user1_id"
name="user1"
username="user1"
')
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2'])
.returns('name="project2"
id="project2_id"
')
provider.create
expect(provider.exists?).to be_truthy
@ -139,114 +128,6 @@ name="domain3"
expect(instances[2].name).to eq('user3::domain3')
end
end
describe '#tenant' do
it 'gets the tenant with default backend' do
provider.class.expects(:openstack)
.with('project', 'list', '--quiet', '--format', 'csv', ['--user', 'user1_id', '--long'])
.returns('"ID","Name","Domain ID","Description","Enabled"
"project2_id","project2","domain2_id","",True
')
provider.instance_variable_get('@property_hash')[:id] = 'user1_id'
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2'])
.returns('name="project2"
id="project2_id"
')
tenant = provider.tenant
expect(tenant).to eq('project2::domain2')
end
it 'gets the tenant with LDAP backend' do
provider.instance_variable_get('@property_hash')[:id] = 'user1_id'
provider.class.expects(:openstack)
.with('project', 'list', '--quiet', '--format', 'csv', ['--user', 'user1_id', '--long'])
.returns('"ID","Name","Domain ID","Description","Enabled"
"project1_id","project1","domain1_id","",True
"project2_id","project2","domain2_id","",True
"project3_id","project3","domain3_id","",True
')
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2'])
.returns('name="project2"
id="project2_id"
')
tenant = provider.tenant
expect(tenant).to eq('project2::domain2')
end
end
describe '#tenant=' do
context 'when using default backend' do
it 'sets the tenant' do
provider.instance_variable_get('@property_hash')[:id] = 'user1_id'
provider.instance_variable_get('@property_hash')[:domain] = 'domain1'
provider.class.expects(:openstack)
.with('role', 'show', '--format', 'shell', '_member_')
.returns('name="_member_"')
provider.class.expects(:openstack)
.with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id'])
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2'])
.returns('name="project2"
id="project2_id"
')
provider.tenant=('project2::domain2')
end
end
context 'when using LDAP read-write backend' do
it 'sets the tenant when _member_ role exists' do
provider.instance_variable_get('@property_hash')[:id] = 'user1_id'
provider.instance_variable_get('@property_hash')[:domain] = 'domain1'
provider.class.expects(:openstack)
.with('role', 'show', '--format', 'shell', '_member_')
.returns('name="_member_"')
provider.class.expects(:openstack)
.with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id'])
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2'])
.returns('name="project2"
id="project2_id"
')
provider.tenant=('project2::domain2')
end
it 'sets the tenant when _member_ role does not exist' do
provider.instance_variable_get('@property_hash')[:id] = 'user1_id'
provider.instance_variable_get('@property_hash')[:domain] = 'domain1'
provider.class.expects(:openstack)
.with('role', 'show', '--format', 'shell', '_member_')
.raises(Puppet::ExecutionFailure, 'no such role _member_')
provider.class.expects(:openstack)
.with('role', 'create', '--format', 'shell', '_member_')
.returns('name="_member_"')
provider.class.expects(:openstack)
.with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id'])
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2'])
.returns('name="project2"
id="project2_id"
')
provider.tenant=('project2::domain2')
end
end
context 'when using LDAP read-only backend' do
it 'sets the tenant when _member_ role exists' do
provider.instance_variable_get('@property_hash')[:id] = 'user1_id'
provider.instance_variable_get('@property_hash')[:domain] = 'domain1'
provider.class.expects(:openstack)
.with('role', 'show', '--format', 'shell', '_member_')
.returns('name="_member_"')
provider.class.expects(:openstack)
.with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id'])
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2'])
.returns('name="project2"
id="project2_id"
')
provider.tenant=('project2::domain2')
end
end
end
end
describe "#password" do
@ -256,7 +137,6 @@ id="project2_id"
:ensure => 'present',
:enabled => 'True',
:password => 'foo',
:tenant => 'foo',
:email => 'foo@example.com',
:domain => 'domain1',
}
@ -366,7 +246,6 @@ ac43ec53d5a74a0b9f51523ae41a29f0
:enabled => 'True',
:password => 'secret',
:replace_password => 'False',
:tenant => 'project2',
:email => 'user1@example.com',
:domain => 'domain1',
}
@ -393,7 +272,6 @@ ac43ec53d5a74a0b9f51523ae41a29f0
:ensure => 'present',
:enabled => 'True',
:password => 'secret',
:tenant => 'project1::domain2',
:email => 'user1@example.com',
}
end
@ -448,18 +326,12 @@ id="project1_id"
:ensure => 'present',
:enabled => 'True',
:password => 'secret',
:tenant => 'project1::domain2',
:email => 'user1@example.com',
:domain => 'domain1',
}
end
it 'uses given domain in commands' do
provider.class.expects(:openstack)
.with('role', 'show', '--format', 'shell', '_member_')
.returns('name="_member_"')
provider.class.expects(:openstack)
.with('role', 'add', ['_member_', '--project', 'project1_id', '--user', 'user1_id'])
provider.class.expects(:openstack)
.with('user', 'create', '--format', 'shell', ['user1', '--enable', '--password', 'secret', '--email', 'user1@example.com', '--domain', 'domain1'])
.returns('email="user1@example.com"
@ -467,11 +339,6 @@ enabled="True"
id="user1_id"
name="user1"
username="user1"
')
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain2'])
.returns('name="projec1"
id="project1_id"
')
provider.create
expect(provider.exists?).to be_truthy
@ -486,17 +353,11 @@ id="project1_id"
:ensure => 'present',
:enabled => 'True',
:password => 'secret',
:tenant => 'project1::domain2',
:email => 'user1@example.com',
}
end
it 'uses given domain in commands' do
provider.class.expects(:openstack)
.with('role', 'show', '--format', 'shell', '_member_')
.returns('name="_member_"')
provider.class.expects(:openstack)
.with('role', 'add', ['_member_', '--project', 'project1_id', '--user', 'user1_id'])
provider.class.expects(:openstack)
.with('user', 'create', '--format', 'shell', ['user1', '--enable', '--password', 'secret', '--email', 'user1@example.com', '--domain', 'domain1'])
.returns('email="user1@example.com"
@ -504,11 +365,6 @@ enabled="True"
id="user1_id"
name="user1"
username="user1"
')
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain2'])
.returns('name="project1"
id="project1_id"
')
provider.create
expect(provider.exists?).to be_truthy
@ -524,18 +380,12 @@ id="project1_id"
:ensure => 'present',
:enabled => 'True',
:password => 'secret',
:tenant => 'project1::domain2',
:email => 'user1@example.com',
:domain => 'domain1',
}
end
it 'uses the resource domain in commands' do
provider.class.expects(:openstack)
.with('role', 'show', '--format', 'shell', '_member_')
.returns('name="_member_"')
provider.class.expects(:openstack)
.with('role', 'add', ['_member_', '--project', 'project1_id', '--user', 'user1_id'])
provider.class.expects(:openstack)
.with('user', 'create', '--format', 'shell', ['user1', '--enable', '--password', 'secret', '--email', 'user1@example.com', '--domain', 'domain1'])
.returns('email="user1@example.com"
@ -543,11 +393,6 @@ enabled="True"
id="user1_id"
name="user1"
username="user1"
')
provider.class.expects(:openstack)
.with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain2'])
.returns('name="project1"
id="project1_id"
')
provider.create
expect(provider.exists?).to be_truthy