Skip to content

Commit b02a908

Browse files
authored
Merge pull request #445 from gcoxmoz/chain-431
Add olcChainConfig overlay
2 parents 628a5d1 + d91d5ac commit b02a908

File tree

2 files changed

+178
-46
lines changed
  • lib/puppet/provider/openldap_overlay
  • spec/unit/puppet/provider/openldap_overlay

2 files changed

+178
-46
lines changed

lib/puppet/provider/openldap_overlay/olc.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def create
6969
'auditlog' => 'olcAuditLogConfig',
7070
'autoca' => 'olcAutoCAConfig',
7171
'autogroup' => 'olcAutomaticGroups',
72+
'chain' => 'olcChainConfig',
7273
'collect' => 'olcCollectConfig',
7374
'constraint' => 'olcConstraintConfig',
7475
'dds' => 'olcDDSConfig',
@@ -115,7 +116,10 @@ def create
115116
end
116117

117118
def getDn(suffix)
118-
if suffix == 'cn=config'
119+
case suffix
120+
when 'cn=frontend'
121+
'olcDatabase={-1}frontend,cn=config'
122+
when 'cn=config'
119123
if resource[:overlay].to_s == 'rwm'
120124
slapcat('(olcDatabase=relay)').split("\n").map do |line|
121125
return line.split[1] if line =~ %r{^dn: }
@@ -134,6 +138,7 @@ def self.getSuffix(database)
134138
found = false
135139
slapcat("(olcDatabase=#{database})").split("\n").map do |line|
136140
found = true if line =~ %r{^dn: olcDatabase=#{database.gsub('{', '\{').gsub('}', '\}')},}
141+
return 'cn=frontend' if database == '{-1}frontend'
137142
return 'cn=config' if database == '{0}config'
138143
return 'cn=config' if database =~ %r{\{\d+\}relay$}
139144
return line.split[1] if line =~ %r{^olcSuffix: } && found

spec/unit/puppet/provider/openldap_overlay/olc_spec.rb

Lines changed: 172 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,68 +4,195 @@
44

55
# rubocop:disable RSpec/MultipleMemoizedHelpers
66
describe Puppet::Type.type(:openldap_overlay).provider(:olc) do
7-
let(:params) do
8-
{
9-
title: 'memberof on dc=example,dc=com',
10-
name: 'memberof on dc=example,dc=com',
11-
overlay: 'memberof',
12-
suffix: 'dc=example,dc=com',
13-
provider: described_class.name,
14-
}
15-
end
16-
17-
let(:resource) do
18-
Puppet::Type.type(:openldap_overlay).new(params)
19-
end
7+
describe 'instances' do
8+
describe 'ppolicy' do
9+
before do
10+
slapcat_overlay_output = <<~OUTPUT
11+
dn: olcOverlay={1}ppolicy,olcDatabase={2}mdb,cn=config
12+
objectClass: olcConfig
13+
objectClass: olcOverlayConfig
14+
objectClass: olcPPolicyConfig
15+
olcOverlay: {1}ppolicy
16+
olcPPolicyDefault: cn=default_password_policy,ou=policies,dc=example,dc=com
17+
olcPPolicyHashCleartext: FALSE
18+
olcPPolicyUseLockout: FALSE
19+
olcPPolicyForwardUpdates: FALSE
20+
structuralObjectClass: olcPPolicyConfig
21+
entryUUID: db7e0900-7457-103f-9aab-a3df2413523b
22+
creatorsName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
23+
createTimestamp: 20250131194650Z
24+
entryCSN: 20250131194650.121815Z#000000#000#000000
25+
modifiersName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
26+
modifyTimestamp: 20250131194650Z
27+
OUTPUT
28+
slapcat_db_output = <<~OUTPUT
29+
dn: olcDatabase={2}mdb,cn=config
30+
objectClass: olcDatabaseConfig
31+
objectClass: olcMdbConfig
32+
olcDatabase: {2}mdb
33+
olcSuffix: dc=example,dc=com
34+
OUTPUT
35+
allow(described_class).to receive(:slapcat).with(
36+
'(olcOverlay=*)'
37+
).and_return(slapcat_overlay_output)
38+
allow(described_class).to receive(:slapcat).with(
39+
'(olcDatabase={2}mdb)'
40+
).and_return(slapcat_db_output)
41+
end
2042

21-
let(:provider) do
22-
resource.provider
23-
end
43+
it 'reads a ppolicy object' do
44+
expect(described_class.instances.size).to eq(1)
45+
expect(described_class.instances[0].name).to eq('ppolicy on dc=example,dc=com')
46+
expect(described_class.instances[0].overlay).to eq('ppolicy')
47+
expect(described_class.instances[0].suffix).to eq('dc=example,dc=com')
48+
expect(described_class.instances[0].index).to eq(1)
49+
expect(described_class.instances[0].options).to eq(
50+
{
51+
'olcPPolicyDefault' => 'cn=default_password_policy,ou=policies,dc=example,dc=com',
52+
'olcPPolicyHashCleartext' => 'FALSE',
53+
'olcPPolicyUseLockout' => 'FALSE',
54+
'olcPPolicyForwardUpdates' => 'FALSE',
55+
}
56+
)
57+
end
58+
end
2459

25-
let(:tmpfile) { instance_spy(Tempfile) }
26-
let(:tmpfile_path) { double }
27-
let(:tmpfile_content) { double }
28-
29-
before do
30-
allow(provider).to receive(:slapcat).and_return('foo')
31-
allow(Tempfile).to receive(:new).and_return(tmpfile)
32-
allow(tmpfile).to receive(:path).and_return(tmpfile_path)
33-
allow(IO).to receive(:read).with(tmpfile_path).and_return(tmpfile_content)
34-
allow(Puppet).to receive(:debug).with(tmpfile_content)
35-
allow(provider).to receive(:getDn).and_return('dc=example,dc=com')
36-
allow(provider).to receive(:ldapmodify)
37-
end
60+
describe 'chain' do
61+
before do
62+
slapcat_overlay_output = <<~OUTPUT
63+
dn: olcOverlay={0}chain,olcDatabase={-1}frontend,cn=config
64+
objectClass: olcConfig
65+
objectClass: olcOverlayConfig
66+
objectClass: olcChainConfig
67+
olcOverlay: {0}chain
68+
olcChainCacheURI: FALSE
69+
olcChainMaxReferralDepth: 1
70+
olcChainReturnError: TRUE
71+
OUTPUT
72+
slapcat_db_output = <<~OUTPUT
73+
dn: olcDatabase={-1}frontend,cn=config
74+
objectClass: olcDatabaseConfig
75+
objectClass: olcFrontendConfig
76+
olcDatabase: {-1}frontend
77+
OUTPUT
78+
allow(described_class).to receive(:slapcat).with(
79+
'(olcOverlay=*)'
80+
).and_return(slapcat_overlay_output)
81+
allow(described_class).to receive(:slapcat).with(
82+
'(olcDatabase={-1}frontend)'
83+
).and_return(slapcat_db_output)
84+
end
3885

39-
describe 'when creating' do
40-
it 'creates an overlay' do
41-
provider.create
42-
expect(tmpfile).to have_received(:<<).with("dn: olcOverlay=memberof,dc=example,dc=com\n")
43-
expect(tmpfile).to have_received(:<<).with("objectClass: olcMemberOf\n")
44-
expect(tmpfile).to have_received(:<<).with("olcOverlay: memberof\n")
45-
expect(provider).to have_received(:ldapmodify)
86+
it 'reads a chain object' do
87+
expect(described_class.instances.size).to eq(1)
88+
expect(described_class.instances[0].name).to eq('chain on cn=frontend')
89+
expect(described_class.instances[0].overlay).to eq('chain')
90+
expect(described_class.instances[0].suffix).to eq('cn=frontend')
91+
expect(described_class.instances[0].index).to eq(0)
92+
expect(described_class.instances[0].options).to eq(
93+
{
94+
'olcChainCacheURI' => 'FALSE',
95+
'olcChainMaxReferralDepth' => '1',
96+
'olcChainReturnError' => 'TRUE',
97+
}
98+
)
99+
end
46100
end
47101
end
48102

49-
describe 'with smbk5pwd' do
103+
describe 'creating overlay' do
50104
let(:params) do
51105
{
52-
title: 'smbk5pwd on dc=example,dc=com',
53-
options: {
54-
'olcSmbK5PwdEnable' => %w[samba shadow],
55-
},
106+
title: 'memberof on dc=example,dc=com',
107+
overlay: 'memberof',
108+
suffix: 'dc=example,dc=com',
109+
provider: described_class.name,
56110
}
57111
end
58112

113+
let(:resource) do
114+
Puppet::Type.type(:openldap_overlay).new(params)
115+
end
116+
117+
let(:provider) do
118+
resource.provider
119+
end
120+
121+
let(:tmpfile) { instance_spy(Tempfile) }
122+
let(:tmpfile_path) { double }
123+
let(:tmpfile_content) { double }
124+
125+
before do
126+
allow(provider).to receive(:slapcat).and_return('foo')
127+
allow(Tempfile).to receive(:new).and_return(tmpfile)
128+
allow(tmpfile).to receive(:path).and_return(tmpfile_path)
129+
allow(IO).to receive(:read).with(tmpfile_path).and_return(tmpfile_content)
130+
allow(Puppet).to receive(:debug).with(tmpfile_content)
131+
allow(provider).to receive(:ldapmodify)
132+
end
133+
59134
describe 'when creating' do
135+
before do
136+
allow(provider).to receive(:getDn).and_return('dc=example,dc=com')
137+
end
138+
60139
it 'creates an overlay' do
61140
provider.create
62-
expect(tmpfile).to have_received(:<<).with("dn: olcOverlay=smbk5pwd,dc=example,dc=com\n")
63-
expect(tmpfile).to have_received(:<<).with("objectClass: olcSmbK5PwdConfig\n")
64-
expect(tmpfile).to have_received(:<<).with("olcOverlay: smbk5pwd\n")
65-
expect(tmpfile).to have_received(:<<).with("olcSmbK5PwdEnable: samba\nolcSmbK5PwdEnable: shadow\n")
141+
expect(tmpfile).to have_received(:<<).with("dn: olcOverlay=memberof,dc=example,dc=com\n")
142+
expect(tmpfile).to have_received(:<<).with("objectClass: olcMemberOf\n")
143+
expect(tmpfile).to have_received(:<<).with("olcOverlay: memberof\n")
66144
expect(provider).to have_received(:ldapmodify)
67145
end
68146
end
147+
148+
describe 'with smbk5pwd' do
149+
before do
150+
allow(provider).to receive(:getDn).and_return('dc=example,dc=com')
151+
end
152+
153+
let(:params) do
154+
{
155+
title: 'smbk5pwd on dc=example,dc=com',
156+
options: {
157+
'olcSmbK5PwdEnable' => %w[samba shadow],
158+
},
159+
}
160+
end
161+
162+
describe 'when creating' do
163+
it 'creates an overlay' do
164+
provider.create
165+
expect(tmpfile).to have_received(:<<).with("dn: olcOverlay=smbk5pwd,dc=example,dc=com\n")
166+
expect(tmpfile).to have_received(:<<).with("objectClass: olcSmbK5PwdConfig\n")
167+
expect(tmpfile).to have_received(:<<).with("olcOverlay: smbk5pwd\n")
168+
expect(tmpfile).to have_received(:<<).with("olcSmbK5PwdEnable: samba\nolcSmbK5PwdEnable: shadow\n")
169+
expect(provider).to have_received(:ldapmodify)
170+
end
171+
end
172+
end
173+
174+
describe 'with chain' do
175+
let(:params) do
176+
{
177+
title: 'chain on cn=frontend',
178+
suffix: 'cn=frontend',
179+
options: {
180+
'olcChainMaxReferralDepth' => '1',
181+
},
182+
}
183+
end
184+
185+
describe 'when creating' do
186+
it 'creates an overlay' do
187+
provider.create
188+
expect(tmpfile).to have_received(:<<).with("dn: olcOverlay=chain,olcDatabase={-1}frontend,cn=config\n")
189+
expect(tmpfile).to have_received(:<<).with("objectClass: olcChainConfig\n")
190+
expect(tmpfile).to have_received(:<<).with("olcOverlay: chain\n")
191+
expect(tmpfile).to have_received(:<<).with("olcChainMaxReferralDepth: 1\n")
192+
expect(provider).to have_received(:ldapmodify)
193+
end
194+
end
195+
end
69196
end
70197
end
71198
# rubocop:enable RSpec/MultipleMemoizedHelpers

0 commit comments

Comments
 (0)