Schema change so the nisnetgroup triples work properly.

If we use cn for hostname there is no easy way to distinguish between
a host and a hostgroup. So adding a fqdn attribute to be used to store
the hostname instead.
This commit is contained in:
Rob Crittenden 2009-05-13 17:16:05 -04:00
parent 7ef34b8cda
commit e5bec4ae39
6 changed files with 49 additions and 47 deletions

View File

@ -3,7 +3,8 @@ attributeTypes: (2.16.840.1.113730.3.8.3.1 NAME 'ipaUniqueID' DESC 'Unique ident
attributeTypes: (2.16.840.1.113730.3.8.3.2 NAME 'ipaClientVersion' DESC 'Text string describing client version of the IPA software installed' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v2' )
attributeTypes: (2.16.840.1.113730.3.8.3.3 NAME 'enrolledBy' DESC 'DN of administrator who performed manual enrollment of the host' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'IPA v2' )
attributeTypes: (2.16.840.1.113730.3.8.3.4 NAME 'enrollmentPwd' DESC 'Password used to bulk enroll machines' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.1 NAME 'ipaHost' AUXILIARY MAY ( userPassword $ ipaClientVersion $ enrolledBy) X-ORIGIN 'IPA v2' )
attributeTypes: (2.16.840.1.113730.3.8.3.43 NAME 'fqdn' DESC 'FQDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.1 NAME 'ipaHost' AUXILIARY MUST ( fqdn ) MAY ( userPassword $ ipaClientVersion $ enrolledBy) X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.2 NAME 'ipaService' DESC 'IPA service objectclass' AUXILIARY X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.3 NAME 'nestedGroup' DESC 'Group that supports nesting' SUP groupOfNames STRUCTURAL MAY memberOf X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.4 NAME 'ipaUserGroup' DESC 'IPA user group object class' SUP nestedGroup STRUCTURAL X-ORIGIN 'IPA v2' )

View File

@ -40,21 +40,21 @@ def get_host(hostname):
if hostname.endswith('.'):
hostname = hostname[:-1]
try:
dn = ldap.find_entry_dn("cn", hostname, "ipaHost")
dn = ldap.find_entry_dn("fqdn", hostname, "ipaHost")
except errors.NotFound:
dn = ldap.find_entry_dn("serverhostname", hostname, "ipaHost")
return dn
def validate_host(ugettext, cn):
def validate_host(ugettext, fqdn):
"""
Require at least one dot in the hostname (to support localhost.localdomain)
"""
dots = len(cn.split('.'))
dots = len(fqdn.split('.'))
if dots < 2:
return 'Fully-qualified hostname required'
return None
default_attributes = ['cn','description','localityname','nshostlocation','nshardwareplatform','nsosversion']
default_attributes = ['fqdn','description','localityname','nshostlocation','nshardwareplatform','nsosversion']
def determine_os():
(sysname, nodename, release, version, machine) = os.uname()
@ -74,7 +74,7 @@ class host(Object):
Host object.
"""
takes_params = (
Str('cn', validate_host,
Str('fqdn', validate_host,
cli_name='hostname',
primary_key=True,
normalizer=lambda value: value.lower(),
@ -127,11 +127,13 @@ class host_add(crud.Add):
:param hostname: The name of the host being added.
:param kw: Keyword arguments for the other LDAP attributes.
"""
assert 'fqdn' not in kw
assert 'cn' not in kw
assert 'dn' not in kw
assert 'krbprincipalname' not in kw
ldap = self.api.Backend.ldap
kw['fqdn'] = hostname
kw['cn'] = hostname
kw['serverhostname'] = hostname.split('.',1)[0]
kw['dn'] = ldap.make_host_dn(hostname)
@ -221,7 +223,7 @@ class host_mod(crud.Mod):
:param hostname: The name of the host to retrieve.
:param kw: Keyword arguments for the other LDAP attributes.
"""
assert 'cn' not in kw
assert 'fqdn' not in kw
assert 'dn' not in kw
ldap = self.api.Backend.ldap
dn = get_host(hostname)
@ -258,13 +260,12 @@ class host_find(crud.Find):
# FIXME: add this attribute to cn=ipaconfig
#search_fields_conf_str = config.get('ipahostsearchfields')
#search_fields = search_fields_conf_str.split(",")
search_fields = ['cn','serverhostname','description','localityname','nshostlocation','nshardwareplatform','nsosversion']
search_fields = ['fqdn','serverhostname','description','localityname','nshostlocation','nshardwareplatform','nsosversion']
search_kw = {}
for s in search_fields:
search_kw[s] = term
# Can't use ldap.get_object_type() since cn is also used for group dns
search_kw['objectclass'] = "ipaHost"
if kw.get('all', False):
search_kw['attributes'] = ['*']

View File

@ -109,7 +109,7 @@ class ldap(CrudBackend):
"""
Construct host dn from hostname
"""
return 'cn=%s,%s,%s' % (
return 'fqdn=%s,%s,%s' % (
self.dn.escape_dn_chars(hostname),
self.api.env.container_host,
self.api.env.basedn,

View File

@ -31,10 +31,10 @@ class test_Host(XMLRPC_test):
"""
Test the `f_host` plugin.
"""
cn = u'ipatesthost.%s' % api.env.domain
fqdn = u'ipatesthost.%s' % api.env.domain
description = u'Test host'
localityname = u'Undisclosed location'
kw={'cn': cn, 'description': description, 'localityname': localityname}
kw={'fqdn': fqdn, 'description': description, 'localityname': localityname}
def test_add(self):
"""
@ -43,52 +43,52 @@ class test_Host(XMLRPC_test):
res = api.Command['host_add'](**self.kw)
assert type(res) is dict
assert res['description'] == self.description
assert res['cn'] == self.cn
assert res['fqdn'] == self.fqdn
assert res['l'] == self.localityname
def test_doshow_all(self):
"""
Test the `xmlrpc.host_show` method with all attributes.
"""
kw={'cn':self.cn, 'all': True}
kw={'fqdn':self.fqdn, 'all': True}
res = api.Command['host_show'](**kw)
assert res
assert res.get('description','') == self.description
assert res.get('cn','') == self.cn
assert res.get('fqdn','') == self.fqdn
assert res.get('l','') == self.localityname
def test_doshow_minimal(self):
"""
Test the `xmlrpc.host_show` method with default attributes.
"""
kw={'cn':self.cn}
kw={'fqdn':self.fqdn}
res = api.Command['host_show'](**kw)
assert res
assert res.get('description','') == self.description
assert res.get('cn','') == self.cn
assert res.get('fqdn','') == self.fqdn
assert res.get('localityname','') == self.localityname
def test_find_all(self):
"""
Test the `xmlrpc.host_find` method with all attributes.
"""
kw={'cn':self.cn, 'all': True}
kw={'fqdn':self.fqdn, 'all': True}
res = api.Command['host_find'](**kw)
assert res
assert len(res) == 2
assert res[1].get('description','') == self.description
assert res[1].get('cn','') == self.cn
assert res[1].get('fqdn','') == self.fqdn
assert res[1].get('l','') == self.localityname
def test_find_minimal(self):
"""
Test the `xmlrpc.host_find` method with default attributes.
"""
res = api.Command['host_find'](self.cn)
res = api.Command['host_find'](self.fqdn)
assert res
assert len(res) == 2
assert res[1].get('description','') == self.description
assert res[1].get('cn','') == self.cn
assert res[1].get('fqdn','') == self.fqdn
assert res[1].get('localityname','') == self.localityname
def test_mod(self):
@ -96,27 +96,27 @@ class test_Host(XMLRPC_test):
Test the `xmlrpc.host_mod` method.
"""
newdesc = u'Updated host'
modkw={'cn': self.cn, 'description': newdesc}
modkw={'fqdn': self.fqdn, 'description': newdesc}
res = api.Command['host_mod'](**modkw)
assert res
assert res.get('description','') == newdesc
# Ok, double-check that it was changed
res = api.Command['host_show'](self.cn)
res = api.Command['host_show'](self.fqdn)
assert res
assert res.get('description','') == newdesc
assert res.get('cn','') == self.cn
assert res.get('fqdn','') == self.fqdn
def test_remove(self):
"""
Test the `xmlrpc.host_del` method.
"""
res = api.Command['host_del'](self.cn)
res = api.Command['host_del'](self.fqdn)
assert res == True
# Verify that it is gone
try:
res = api.Command['host_show'](self.cn)
res = api.Command['host_show'](self.fqdn)
except errors.NotFound:
pass
else:

View File

@ -35,7 +35,7 @@ class test_Host(XMLRPC_test):
description=u'Test host group'
kw={'cn': cn, 'description': description}
host_cn = u'ipatesthost.%s' % api.env.domain
host_fqdn = u'ipatesthost.%s' % api.env.domain
host_description = u'Test host'
host_localityname = u'Undisclosed location'
@ -52,18 +52,18 @@ class test_Host(XMLRPC_test):
"""
Add a host to test add/remove member.
"""
kw={'cn': self.host_cn, 'description': self.host_description, 'localityname': self.host_localityname}
kw={'fqdn': self.host_fqdn, 'description': self.host_description, 'localityname': self.host_localityname}
res = api.Command['host_add'](**kw)
assert res
assert res.get('description','') == self.host_description
assert res.get('cn','') == self.host_cn
assert res.get('fqdn','') == self.host_fqdn
def test_addmember(self):
"""
Test the `xmlrpc.hostgroup_add_member` method.
"""
kw={}
kw['hosts'] = self.host_cn
kw['hosts'] = self.host_fqdn
res = api.Command['hostgroup_add_member'](self.cn, **kw)
assert res == tuple()
@ -75,7 +75,7 @@ class test_Host(XMLRPC_test):
assert res
assert res.get('description','') == self.description
assert res.get('cn','') == self.cn
assert res.get('member','').startswith('cn=%s' % self.host_cn)
assert res.get('member','').startswith('fqdn=%s' % self.host_fqdn)
def test_find(self):
"""
@ -86,7 +86,7 @@ class test_Host(XMLRPC_test):
assert len(res) == 2, res
assert res[1].get('description','') == self.description
assert res[1].get('cn','') == self.cn
assert res[1].get('member','').startswith('cn=%s' % self.host_cn)
assert res[1].get('member','').startswith('fqdn=%s' % self.host_fqdn)
def test_mod(self):
"""
@ -109,7 +109,7 @@ class test_Host(XMLRPC_test):
Test the `xmlrpc.hostgroup_remove_member` method.
"""
kw={}
kw['hosts'] = self.host_cn
kw['hosts'] = self.host_fqdn
res = api.Command['hostgroup_remove_member'](self.cn, **kw)
assert res == tuple()
@ -132,12 +132,12 @@ class test_Host(XMLRPC_test):
"""
Test the `xmlrpc.host_del` method.
"""
res = api.Command['host_del'](self.host_cn)
res = api.Command['host_del'](self.host_fqdn)
assert res == True
# Verify that it is gone
try:
res = api.Command['host_show'](self.host_cn)
res = api.Command['host_show'](self.host_fqdn)
except errors.NotFound:
pass
else:

View File

@ -45,10 +45,10 @@ class test_Netgroup(XMLRPC_test):
ng_description=u'Netgroup'
ng_kw={'cn': ng_cn, 'description': ng_description, 'nisdomainname': u'example.com'}
host_cn = u'ipatesthost.%s' % api.env.domain
host_fqdn = u'ipatesthost.%s' % api.env.domain
host_description=u'Test host'
host_localityname=u'Undisclosed location'
host_kw={'cn': host_cn, 'description': host_description, 'localityname': host_localityname}
host_kw={'fqdn': host_fqdn, 'description': host_description, 'localityname': host_localityname}
hg_cn=u'ng1'
hg_description=u'Netgroup'
@ -82,7 +82,7 @@ class test_Netgroup(XMLRPC_test):
res = api.Command['host_add'](**self.host_kw)
assert res
assert res.get('description','') == self.host_description
assert res.get('cn','') == self.host_cn
assert res.get('fqdn','') == self.host_fqdn
# Add a hostgroup
res = api.Command['hostgroup_add'](**self.hg_kw)
@ -107,7 +107,7 @@ class test_Netgroup(XMLRPC_test):
Test the `xmlrpc.netgroup_add_member` method.
"""
kw={}
kw['hosts'] = self.host_cn
kw['hosts'] = self.host_fqdn
res = api.Command['netgroup_add_member'](self.ng_cn, **kw)
assert res == tuple()
@ -131,9 +131,9 @@ class test_Netgroup(XMLRPC_test):
Test the `xmlrpc.netgroup_add_member` method again to test dupes.
"""
kw={}
kw['hosts'] = self.host_cn
kw['hosts'] = self.host_fqdn
res = api.Command['netgroup_add_member'](self.ng_cn, **kw)
assert is_member_of(res, 'cn=%s' % self.host_cn)
assert is_member_of(res, 'fqdn=%s' % self.host_fqdn)
kw={}
kw['hostgroups'] = self.hg_cn
@ -170,7 +170,7 @@ class test_Netgroup(XMLRPC_test):
assert res
assert res.get('description','') == self.ng_description
assert res.get('cn','') == self.ng_cn
assert is_member_of(res.get('memberhost',[]), 'cn=%s' % self.host_cn)
assert is_member_of(res.get('memberhost',[]), 'fqdn=%s' % self.host_fqdn)
assert is_member_of(res.get('memberhost',[]), 'cn=%s' % self.hg_cn)
assert is_member_of(res.get('memberuser',[]), 'uid=%s' % self.user_uid)
assert is_member_of(res.get('memberuser',[]), 'cn=%s' % self.group_cn)
@ -206,7 +206,7 @@ class test_Netgroup(XMLRPC_test):
Test the `xmlrpc.hostgroup_remove_member` method.
"""
kw={}
kw['hosts'] = self.host_cn
kw['hosts'] = self.host_fqdn
res = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert res == tuple()
@ -230,9 +230,9 @@ class test_Netgroup(XMLRPC_test):
Test the `xmlrpc.netgroup_remove_member` method again to test not found.
"""
kw={}
kw['hosts'] = self.host_cn
kw['hosts'] = self.host_fqdn
res = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert is_member_of(res, 'cn=%s' % self.host_cn)
assert is_member_of(res, 'fqdn=%s' % self.host_fqdn)
kw={}
kw['hostgroups'] = self.hg_cn
@ -269,12 +269,12 @@ class test_Netgroup(XMLRPC_test):
Remove the test data we added
"""
# Remove the host
res = api.Command['host_del'](self.host_cn)
res = api.Command['host_del'](self.host_fqdn)
assert res == True
# Verify that it is gone
try:
res = api.Command['host_show'](self.host_cn)
res = api.Command['host_show'](self.host_fqdn)
except errors.NotFound:
pass
else: