3 require 'puppet/provider/keystone_user/openstack'
5 provider_class = Puppet::Type.type(:keystone_user).provider(:openstack)
7 describe provider_class do
9 shared_examples 'authenticated with environment variables' do
10 ENV['OS_USERNAME'] = 'test'
11 ENV['OS_PASSWORD'] = 'abc123'
12 ENV['OS_PROJECT_NAME'] = 'test'
13 ENV['OS_AUTH_URL'] = 'http://127.0.0.1:5000'
23 :email => 'foo@example.com',
28 Puppet::Type::Keystone_user.new(user_attrs)
32 provider_class.new(resource)
35 describe 'when managing a user' do
36 it_behaves_like 'authenticated with environment variables' do
38 it 'creates a user' do
39 provider.class.stubs(:openstack)
40 .with('user', 'list', '--quiet', '--format', 'csv', '--long')
41 .returns('"ID","Name","Project","Email","Enabled"
42 "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True
44 provider.class.stubs(:openstack)
45 .with('user', 'create', '--format', 'shell', ['foo', '--enable', '--password', 'foo', '--project', 'foo', '--email', 'foo@example.com'])
46 .returns('email="foo@example.com"
48 id="12b23f07d4a3448d8189521ab09610b0"
50 project_id="5e2001b2248540f191ff22627dc0c2d7"
54 expect(provider.exists?).to be_truthy
58 describe '#destroy' do
59 it 'destroys a user' do
60 provider.class.stubs(:openstack)
61 .with('user', 'list', '--quiet', '--format', 'csv', '--long')
62 .returns('"ID","Name","Project","Email","Enabled"')
63 provider.class.stubs(:openstack)
64 .with('user', 'delete', [])
66 expect(provider.exists?).to be_falsey
72 context 'when user does not exist' do
74 provider.class.stubs(:openstack)
75 .with('user', 'list', '--quiet', '--format', 'csv', '--long')
76 .returns('"ID","Name","Project","Email","Enabled"')
77 response = provider.exists?
80 it { is_expected.to be_falsey }
84 describe '#instances' do
85 it 'finds every user' do
86 provider.class.stubs(:openstack)
87 .with('user', 'list', '--quiet', '--format', 'csv', '--long')
88 .returns('"ID","Name","Project","Email","Enabled"
89 "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True
91 instances = Puppet::Type::Keystone_user::ProviderOpenstack.instances
92 expect(instances.count).to eq(1)
97 it 'gets the tenant with default backend' do
98 provider.class.stubs(:openstack)
99 .with('user', 'list', '--quiet', '--format', 'csv', '--long')
100 .returns('"ID","Name","Project","Email","Enabled"
101 "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True
103 provider.class.stubs(:openstack)
104 .with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'foo'])
105 .returns('"ID","Name","Project","User"
106 "9fe2ff9ee4384b1894a90878d3e92bab","_member_","foo","foo"
108 tenant = provider.tenant
109 expect(tenant).to eq('foo')
112 it 'gets the tenant with LDAP backend' do
113 provider.class.stubs(:openstack)
114 .with('user', 'list', '--quiet', '--format', 'csv', '--long')
115 .returns('"ID","Name","Project","Email","Enabled"
116 "1cb05cfed7c24279be884ba4f6520262","foo","","foo@example.com",True
118 provider.class.expects(:openstack)
119 .with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'foo'])
120 .returns('"ID","Name","Project","User"
121 "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo"
123 tenant = provider.tenant
124 expect(tenant).to eq('foo')
128 describe '#tenant=' do
129 context 'when using default backend' do
130 it 'sets the tenant' do
131 provider.class.expects(:openstack)
132 .with('user', 'set', ['foo', '--project', 'bar'])
133 provider.class.expects(:openstack)
134 .with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'bar'])
135 .returns('"ID","Name","Project","User"
136 "9fe2ff9ee4384b1894a90878d3e92bab","_member_","bar","foo"
138 provider.tenant=('bar')
142 context 'when using LDAP read-write backend' do
143 it 'sets the tenant when _member_ role exists' do
144 provider.class.expects(:openstack)
145 .with('user', 'set', ['foo', '--project', 'bar'])
146 provider.class.expects(:openstack)
147 .with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'bar'])
149 provider.class.expects(:openstack)
150 .with('role', 'show', '--format', 'shell', ['_member_'])
151 .returns('id="9fe2ff9ee4384b1894a90878d3e92bab"
154 provider.class.expects(:openstack)
155 .with('role', 'add', ['_member_', '--project', 'bar', '--user', 'foo'])
156 provider.tenant=('bar')
158 it 'sets the tenant when _member_ role does not exist' do
159 provider.class.expects(:openstack)
160 .with('user', 'set', ['foo', '--project', 'bar'])
161 provider.class.expects(:openstack)
162 .with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'bar'])
164 provider.class.expects(:openstack)
165 .with('role', 'show', '--format', 'shell', ['_member_'])
166 .raises(Puppet::ExecutionFailure, 'no such role _member_')
167 provider.class.expects(:openstack)
168 .with('role', 'create', '--format', 'shell', ['_member_'])
169 .returns('name="_member_"')
170 provider.class.expects(:openstack)
171 .with('role', 'add', ['_member_', '--project', 'bar', '--user', 'foo'])
172 .returns('id="8wr2ff9ee4384b1894a90878d3e92bab"
175 provider.tenant=('bar')
179 # This doesn't make sense, need to clarify what's happening with LDAP mock
181 context 'when using LDAP read-only backend' do
182 it 'sets the tenant when _member_ role exists' do
183 provider.class.expects(:openstack)
184 .with('user', 'set', [['foo', '--project', 'bar']])
185 .raises(Puppet::ExecutionFailure, 'You are not authorized to perform the requested action: LDAP user update')
186 provider.class.expects(:openstack)
187 .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar']])
189 provider.class.expects(:openstack)
190 .with('role', 'show', '--format', 'shell', [['_member_']])
191 .returns('id="9fe2ff9ee4384b1894a90878d3e92bab"
194 provider.class.expects(:openstack)
195 .with('role', 'add', [['_member_', '--project', 'bar', '--user', 'foo']])
196 provider.tenant=('bar')
199 it 'sets the tenant and gets an unexpected exception message' do
200 provider.class.expects(:openstack)
201 .with('user', 'set', [['foo', '--project', 'bar']])
202 .raises(Puppet::ExecutionFailure, 'unknown error message')
203 expect{ provider.tenant=('bar') }.to raise_error(Puppet::ExecutionFailure, /unknown error message/)
211 describe "#password" do
215 :ensure => 'present',
219 :email => 'foo@example.com',
224 Puppet::Type::Keystone_user.new(user_attrs)
228 provider_class.new(resource)
231 shared_examples 'with auth-url environment variable' do
232 ENV['OS_AUTH_URL'] = 'http://localhost:5000'
235 it_behaves_like 'with auth-url environment variable' do
236 it 'checks the password' do
237 Puppet::Provider::Openstack.stubs(:openstack)
238 .with('token', 'issue', ['--format', 'value'])
239 .returns('2015-05-14T04:06:05Z
240 e664a386befa4a30878dcef20e79f167
241 8dce2ae9ecd34c199d2877bf319a3d06
242 ac43ec53d5a74a0b9f51523ae41a29f0
244 password = provider.password
245 expect(password).to eq('foo')
248 it 'fails the password check' do
249 Puppet::Provider::Openstack.stubs(:openstack)
250 .with('token', 'issue', ['--format', 'value'])
251 .raises(Puppet::ExecutionFailure, 'HTTP 401 invalid authentication')
252 password = provider.password
253 expect(password).to eq(nil)
257 describe 'when updating a user with unmanaged password' do
262 :ensure => 'present',
265 :replace_password => 'False',
267 :email => 'foo@example.com',
271 it 'should not try to check password' do
272 expect(provider.password).to eq('foo')