Imported Upstream version 4.8.10

This commit is contained in:
Mario Fetka
2021-10-03 11:06:28 +02:00
parent 10dfc9587b
commit 03a8170b15
2361 changed files with 1883897 additions and 338759 deletions

View File

@@ -20,3 +20,7 @@
"""
Package containing LDAP updates unit tests.
"""
import ipatests.util
ipatests.util.check_ipaclient_unittests()

View File

@@ -0,0 +1,50 @@
# Copyright (C) 2018 FreeIPA Contributors see COPYING for license
from __future__ import absolute_import
import pytest
from ipapython.ipachangeconf import IPAChangeConf
@pytest.fixture(scope='function')
def config_filename(tmpdir):
filename = tmpdir.mkdir('data').join('config_file.conf')
filename.write('SOME_CONF /some/user/defined/path\n')
return filename
def test_addifnotset_action(config_filename):
"""Test if addifnotset action adds a comment about the modified conf.
IPA doesn't want to break existing configuration, if a value already exists
it adds a comment to the modified setting and a note about that on the line
above.
New settings will be added without any note.
"""
ipa_conf = IPAChangeConf('IPA Installer Test')
ipa_conf.setOptionAssignment(' ')
opts = [
{
'action': 'addifnotset',
'name': 'SOME_CONF',
'type': 'option',
'value': '/path/defined/by/ipa',
},
{
'action': 'addifnotset',
'name': 'NEW_CONF',
'type': 'option',
'value': '/path/to/somewhere',
},
]
ipa_conf.changeConf(str(config_filename), opts)
assert config_filename.readlines() == [
'# SOME_CONF modified by IPA\n',
'#SOME_CONF /path/defined/by/ipa\n',
'SOME_CONF /some/user/defined/path\n',
'NEW_CONF /path/to/somewhere\n',
]

View File

@@ -0,0 +1,37 @@
# Copyright (C) 2018 FreeIPA Contributors see COPYING for license
from __future__ import absolute_import
import tempfile
import pytest
from ipaclient.install.client import check_ldap_conf
from ipapython.admintool import ScriptError
@pytest.mark.parametrize("lines,expected", [
(["PORT 389"], "PORT"),
(["HOST example.org"], "HOST"),
(["HOST example.org", "# PORT 389"], "HOST"),
(["\tHOST example.org", "# PORT 389"], "HOST"),
(["HOST example.org", "PORT 389"], "HOST, PORT"),
(["# HOST example.org", "# PORT 389"], None),
(["URI PORT"], None),
([], None),
])
def test_check_ldap(lines, expected):
with tempfile.NamedTemporaryFile('w+') as f:
for line in lines:
f.write(line)
f.write('\n')
f.write('\n')
f.flush()
if expected is None:
assert check_ldap_conf(f.name) is True
else:
with pytest.raises(ScriptError) as e:
check_ldap_conf(f.name)
msg = e.value.msg
assert msg.endswith(expected)

View File

@@ -20,17 +20,18 @@
Test the `ipaserver/install/ldapupdate.py` module.
"""
import unittest
from __future__ import absolute_import
import os
import nose
import pytest
from ipalib import api
from ipalib import errors
from ipaserver.install.ldapupdate import LDAPUpdate, BadSyntax
from ipaserver.install import installutils
from ipapython import ipautil, ipaldap
from ipaplatform.paths import paths
from ipapython import ipaldap
from ipaplatform.constants import constants as platformconstants
from ipapython.dn import DN
"""
@@ -45,294 +46,216 @@ have occurred as expected.
The DM password needs to be set in ~/.ipa/.dmpw
"""
class test_update(unittest.TestCase):
@pytest.mark.tier0
@pytest.mark.needs_ipaapi
class TestUpdate:
"""
Test the LDAP updater.
"""
def setUp(self):
@pytest.fixture(autouse=True)
def update_setup(self, request):
fqdn = installutils.get_fqdn()
pwfile = api.env.dot_ipa + os.sep + ".dmpw"
if ipautil.file_exists(pwfile):
fp = open(pwfile, "r")
self.dm_password = fp.read().rstrip()
fp.close()
if os.path.isfile(pwfile):
with open(pwfile, "r") as fp:
self.dm_password = fp.read().rstrip()
else:
raise nose.SkipTest("No directory manager password")
self.updater = LDAPUpdate(dm_password=self.dm_password, sub_dict={}, live_run=True)
self.ld = ipaldap.IPAdmin(fqdn)
self.ld.do_simple_bind(bindpw=self.dm_password)
if ipautil.file_exists("0_reset.update"):
self.testdir="./"
elif ipautil.file_exists("ipatests/test_install/0_reset.update"):
self.testdir= "./ipatests/test_install/"
else:
raise nose.SkipTest("Unable to find test update files")
pytest.skip("No directory manager password")
self.updater = LDAPUpdate(dm_password=self.dm_password, sub_dict={})
self.ld = ipaldap.LDAPClient.from_hostname_secure(fqdn)
self.ld.simple_bind(bind_dn=ipaldap.DIRMAN_DN,
bind_password=self.dm_password)
self.testdir = os.path.abspath(os.path.dirname(__file__))
if not os.path.isfile(os.path.join(self.testdir,
"0_reset.update")):
pytest.skip("Unable to find test update files")
self.container_dn = DN(self.updater._template_str('cn=test, cn=accounts, $SUFFIX'))
self.user_dn = DN(self.updater._template_str('uid=tuser, cn=test, cn=accounts, $SUFFIX'))
def tearDown(self):
if self.ld:
self.ld.unbind()
def fin():
if self.ld:
self.ld.unbind()
request.addfinalizer(fin)
def test_0_reset(self):
"""
Reset the updater test data to a known initial state (test_0_reset)
"""
try:
modified = self.updater.update([self.testdir + "0_reset.update"])
modified = self.updater.update([os.path.join(self.testdir,
"0_reset.update")])
except errors.NotFound:
# Just means the entry doesn't exist yet
modified = True
self.assertTrue(modified)
assert modified
with self.assertRaises(errors.NotFound):
entries = self.ld.get_entries(
with pytest.raises(errors.NotFound):
self.ld.get_entries(
self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
with self.assertRaises(errors.NotFound):
entries = self.ld.get_entries(
with pytest.raises(errors.NotFound):
self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
def test_1_add(self):
"""
Test the updater with an add directive (test_1_add)
"""
modified = self.updater.update([self.testdir + "1_add.update"])
modified = self.updater.update([os.path.join(self.testdir,
"1_add.update")])
self.assertTrue(modified)
assert modified
entries = self.ld.get_entries(
self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
assert len(entries) == 1
entry = entries[0]
objectclasses = entry.get('objectclass')
for item in ('top', 'nsContainer'):
self.assertTrue(item in objectclasses)
assert item in objectclasses
self.assertEqual(entry.single_value['cn'], 'test')
assert entry.single_value['cn'] == 'test'
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
assert len(entries) == 1
entry = entries[0]
objectclasses = entry.get('objectclass')
for item in ('top', 'person', 'posixaccount', 'krbprincipalaux', 'inetuser'):
self.assertTrue(item in objectclasses)
assert item in objectclasses
self.assertEqual(entry.single_value['loginshell'], paths.BASH)
self.assertEqual(entry.single_value['sn'], 'User')
self.assertEqual(entry.single_value['uid'], 'tuser')
self.assertEqual(entry.single_value['cn'], 'Test User')
actual = entry.single_value['loginshell']
assert actual == platformconstants.DEFAULT_ADMIN_SHELL
assert entry.single_value['sn'] == 'User'
assert entry.single_value['uid'] == 'tuser'
assert entry.single_value['cn'] == 'Test User'
def test_2_update(self):
"""
Test the updater when adding an attribute to an existing entry (test_2_update)
"""
modified = self.updater.update([self.testdir + "2_update.update"])
self.assertTrue(modified)
modified = self.updater.update([os.path.join(self.testdir,
"2_update.update")])
assert modified
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
assert len(entries) == 1
entry = entries[0]
self.assertEqual(entry.single_value['gecos'], 'Test User')
assert entry.single_value['gecos'] == 'Test User'
def test_3_update(self):
"""
Test the updater forcing an attribute to a given value (test_3_update)
"""
modified = self.updater.update([self.testdir + "3_update.update"])
self.assertTrue(modified)
modified = self.updater.update([os.path.join(self.testdir,
"3_update.update")])
assert modified
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
assert len(entries) == 1
entry = entries[0]
self.assertEqual(entry.single_value['gecos'], 'Test User New')
assert entry.single_value['gecos'] == 'Test User New'
def test_4_update(self):
"""
Test the updater adding a new value to a single-valued attribute (test_4_update)
"""
modified = self.updater.update([self.testdir + "4_update.update"])
self.assertTrue(modified)
modified = self.updater.update([os.path.join(self.testdir,
"4_update.update")])
assert modified
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
assert len(entries) == 1
entry = entries[0]
self.assertEqual(entry.single_value['gecos'], 'Test User New2')
assert entry.single_value['gecos'] == 'Test User New2'
def test_5_update(self):
"""
Test the updater adding a new value to a multi-valued attribute (test_5_update)
"""
modified = self.updater.update([self.testdir + "5_update.update"])
self.assertTrue(modified)
modified = self.updater.update([os.path.join(self.testdir,
"5_update.update")])
assert modified
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
assert len(entries) == 1
entry = entries[0]
self.assertEqual(sorted(entry.get('cn')), sorted(['Test User', 'Test User New']))
actual = sorted(entry.get('cn'))
expected = sorted(['Test User', 'Test User New'])
assert actual == expected
def test_6_update(self):
"""
Test the updater removing a value from a multi-valued attribute (test_6_update)
"""
modified = self.updater.update([self.testdir + "6_update.update"])
self.assertTrue(modified)
modified = self.updater.update([os.path.join(self.testdir,
"6_update.update")])
assert modified
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
assert len(entries) == 1
entry = entries[0]
self.assertEqual(sorted(entry.get('cn')), sorted(['Test User']))
assert sorted(entry.get('cn')) == sorted(['Test User'])
def test_6_update_1(self):
"""
Test the updater removing a non-existent value from a multi-valued attribute (test_6_update_1)
"""
modified = self.updater.update([self.testdir + "6_update.update"])
self.assertFalse(modified)
modified = self.updater.update([os.path.join(self.testdir,
"6_update.update")])
assert not modified
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
assert len(entries) == 1
entry = entries[0]
self.assertEqual(sorted(entry.get('cn')), sorted(['Test User']))
assert sorted(entry.get('cn')) == sorted(['Test User'])
def test_7_cleanup(self):
"""
Reset the test data to a known initial state (test_7_cleanup)
"""
try:
modified = self.updater.update([self.testdir + "0_reset.update"])
modified = self.updater.update([os.path.join(self.testdir,
"0_reset.update")])
except errors.NotFound:
# Just means the entry doesn't exist yet
modified = True
self.assertTrue(modified)
assert modified
with self.assertRaises(errors.NotFound):
entries = self.ld.get_entries(
with pytest.raises(errors.NotFound):
self.ld.get_entries(
self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
with self.assertRaises(errors.NotFound):
entries = self.ld.get_entries(
with pytest.raises(errors.NotFound):
self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
def test_8_badsyntax(self):
"""
Test the updater with an unknown keyword (test_8_badsyntax)
"""
with self.assertRaises(BadSyntax):
modified = self.updater.update([self.testdir + "8_badsyntax.update"])
with pytest.raises(BadSyntax):
self.updater.update(
[os.path.join(self.testdir, "8_badsyntax.update")])
def test_9_badsyntax(self):
"""
Test the updater with an incomplete line (test_9_badsyntax)
"""
with self.assertRaises(BadSyntax):
modified = self.updater.update([self.testdir + "9_badsyntax.update"])
def test_from_dict(self):
"""
Test updating from a dict.
This replicates what was done in test 1.
"""
# First make sure we're clean
with self.assertRaises(errors.NotFound):
entries = self.ld.get_entries(
self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
with self.assertRaises(errors.NotFound):
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
update = {
self.container_dn:
{'dn': self.container_dn,
'updates': ['add:objectClass: top',
'add:objectClass: nsContainer',
'add:cn: test'
],
},
self.user_dn:
{'dn': self.user_dn,
'updates': ['add:objectclass: top',
'add:objectclass: person',
'add:objectclass: posixaccount',
'add:objectclass: krbprincipalaux',
'add:objectclass: inetuser',
'add:homedirectory: /home/tuser',
'add:loginshell: /bin/bash',
'add:sn: User',
'add:uid: tuser',
'add:uidnumber: 999',
'add:gidnumber: 999',
'add:cn: Test User',
],
},
}
modified = self.updater.update_from_dict(update)
self.assertTrue(modified)
entries = self.ld.get_entries(
self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
entry = entries[0]
objectclasses = entry.get('objectclass')
for item in ('top', 'nsContainer'):
self.assertTrue(item in objectclasses)
self.assertEqual(entry.single_value['cn'], 'test')
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
self.assertEqual(len(entries), 1)
entry = entries[0]
objectclasses = entry.get('objectclass')
for item in ('top', 'person', 'posixaccount', 'krbprincipalaux', 'inetuser'):
self.assertTrue(item in objectclasses)
self.assertEqual(entry.single_value['loginshell'], paths.BASH)
self.assertEqual(entry.single_value['sn'], 'User')
self.assertEqual(entry.single_value['uid'], 'tuser')
self.assertEqual(entry.single_value['cn'], 'Test User')
# Now delete
update = {
self.container_dn:
{'dn': self.container_dn,
'deleteentry': None,
},
self.user_dn:
{'dn': self.user_dn,
'deleteentry': 'deleteentry: reset: nada',
},
}
modified = self.updater.update_from_dict(update)
self.assertTrue(modified)
with self.assertRaises(errors.NotFound):
entries = self.ld.get_entries(
self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
with self.assertRaises(errors.NotFound):
entries = self.ld.get_entries(
self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*'])
with pytest.raises(BadSyntax):
self.updater.update(
[os.path.join(self.testdir, "9_badsyntax.update")])