summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2012-01-20 15:10:44 -0500
committerMartin Kosek <mkosek@redhat.com>2012-01-26 14:11:33 +0100
commit52e3488b75e1ed2de7a021148169901a522dbbcb (patch)
treecaa45cbdf88aa0ef96e16b1651bea49ddfad52ec
parented061ce91011ce6ebf99c46f6424f0ee14d42def (diff)
downloadfreeipa-52e3488b75e1ed2de7a021148169901a522dbbcb.tar.gz
freeipa-52e3488b75e1ed2de7a021148169901a522dbbcb.tar.xz
freeipa-52e3488b75e1ed2de7a021148169901a522dbbcb.zip
Add support for storing MAC address in host entries.
macaddress is a multi-valued attribute and we allow multiple entries. This is from the objectclass ieee802device. This is added manually when doing a mod or add and not as a default to support existing host entries that do not have this objectclass. If this were added to the defaults then existing hosts missing this objectclass would not be found by host-find. It is possible to get ethers data out of nss by configuring nsswitch.conf to use ldap for ethers and running getent ethers <hostname> I tested nslcd and it only returned one macaddress value. https://fedorahosted.org/freeipa/ticket/1132
-rw-r--r--API.txt9
-rw-r--r--VERSION2
-rw-r--r--ipalib/plugins/host.py22
-rw-r--r--tests/test_xmlrpc/objectclasses.py1
-rw-r--r--tests/test_xmlrpc/test_host_plugin.py65
5 files changed, 94 insertions, 5 deletions
diff --git a/API.txt b/API.txt
index 2937c24f4..ebf23181a 100644
--- a/API.txt
+++ b/API.txt
@@ -1653,7 +1653,7 @@ output: Output('notmatched', (<type 'list'>, <type 'tuple'>, <type 'NoneType'>),
output: Output('error', (<type 'list'>, <type 'tuple'>, <type 'NoneType'>), None)
output: Output('value', <type 'bool'>, None)
command: host_add
-args: 1,14,3
+args: 1,15,3
arg: Str('fqdn', attribute=True, cli_name='hostname', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9][a-zA-Z0-9-\\.]{0,254}$', pattern_errmsg='may only include letters, numbers, and -', primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
option: Str('l', attribute=True, cli_name='locality', multivalue=False, required=False)
@@ -1663,6 +1663,7 @@ option: Str('nsosversion', attribute=True, cli_name='os', multivalue=False, requ
option: Str('userpassword', attribute=True, cli_name='password', multivalue=False, required=False)
option: Flag('random', attribute=False, autofill=True, cli_name='random', default=False, multivalue=False, required=False)
option: Bytes('usercertificate', attribute=True, cli_name='certificate', multivalue=False, required=False)
+option: Str('macaddress', attribute=True, cli_name='macaddress', csv=True, multivalue=True, pattern='^([a-fA-F0-9]{2}[:|\\-]?){5}[a-fA-F0-9]{2}$', pattern_errmsg='Must be of the form HH:HH:HH:HH:HH:HH, where each H is a hexadecimal character.', required=False)
option: Flag('force', autofill=True, default=False)
option: Flag('no_reverse', autofill=True, default=False)
option: Str('ip_address?')
@@ -1696,7 +1697,7 @@ output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('result', <type 'bool'>, None)
output: Output('value', <type 'unicode'>, None)
command: host_find
-args: 1,28,4
+args: 1,29,4
arg: Str('criteria?', noextrawhitespace=False)
option: Str('fqdn', attribute=True, autofill=False, cli_name='hostname', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9][a-zA-Z0-9-\\.]{0,254}$', pattern_errmsg='may only include letters, numbers, and -', primary_key=True, query=True, required=False)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
@@ -1706,6 +1707,7 @@ option: Str('nshardwareplatform', attribute=True, autofill=False, cli_name='plat
option: Str('nsosversion', attribute=True, autofill=False, cli_name='os', multivalue=False, query=True, required=False)
option: Str('userpassword', attribute=True, autofill=False, cli_name='password', multivalue=False, query=True, required=False)
option: Bytes('usercertificate', attribute=True, autofill=False, cli_name='certificate', multivalue=False, query=True, required=False)
+option: Str('macaddress', attribute=True, autofill=False, cli_name='macaddress', csv=True, multivalue=True, pattern='^([a-fA-F0-9]{2}[:|\\-]?){5}[a-fA-F0-9]{2}$', pattern_errmsg='Must be of the form HH:HH:HH:HH:HH:HH, where each H is a hexadecimal character.', query=True, required=False)
option: Int('timelimit?', autofill=False, minvalue=0)
option: Int('sizelimit?', autofill=False, minvalue=0)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -1731,7 +1733,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: host_mod
-args: 1,16,3
+args: 1,17,3
arg: Str('fqdn', attribute=True, cli_name='hostname', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9][a-zA-Z0-9-\\.]{0,254}$', pattern_errmsg='may only include letters, numbers, and -', primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
option: Str('l', attribute=True, autofill=False, cli_name='locality', multivalue=False, required=False)
@@ -1741,6 +1743,7 @@ option: Str('nsosversion', attribute=True, autofill=False, cli_name='os', multiv
option: Str('userpassword', attribute=True, autofill=False, cli_name='password', multivalue=False, required=False)
option: Flag('random', attribute=False, autofill=True, cli_name='random', default=False, multivalue=False, required=False)
option: Bytes('usercertificate', attribute=True, autofill=False, cli_name='certificate', multivalue=False, required=False)
+option: Str('macaddress', attribute=True, autofill=False, cli_name='macaddress', csv=True, multivalue=True, pattern='^([a-fA-F0-9]{2}[:|\\-]?){5}[a-fA-F0-9]{2}$', pattern_errmsg='Must be of the form HH:HH:HH:HH:HH:HH, where each H is a hexadecimal character.', required=False)
option: Str('setattr*', cli_name='setattr', exclude='webui')
option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('delattr*', cli_name='delattr', exclude='webui')
diff --git a/VERSION b/VERSION
index ff245b559..2afbba27d 100644
--- a/VERSION
+++ b/VERSION
@@ -79,4 +79,4 @@ IPA_DATA_VERSION=20100614120000
# #
########################################################
IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=21
+IPA_API_VERSION_MINOR=22
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index fb5f4ea24..a37297e48 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -224,7 +224,7 @@ class host(LDAPObject):
default_attributes = [
'fqdn', 'description', 'l', 'nshostlocation', 'krbprincipalname',
'nshardwareplatform', 'nsosversion', 'usercertificate', 'memberof',
- 'managedby', 'memberindirect', 'memberofindirect',
+ 'managedby', 'memberindirect', 'memberofindirect', 'macaddress',
]
uuid_attribute = 'ipauniqueid'
attribute_members = {
@@ -306,6 +306,14 @@ class host(LDAPObject):
label=_('Principal name'),
flags=['no_create', 'no_update', 'no_search'],
),
+ Str('macaddress*',
+ normalizer=lambda value: value.upper(),
+ pattern='^([a-fA-F0-9]{2}[:|\-]?){5}[a-fA-F0-9]{2}$',
+ pattern_errmsg='Must be of the form HH:HH:HH:HH:HH:HH, where each H is a hexadecimal character.',
+ csv=True,
+ label=_('MAC address'),
+ doc=_('Hardware MAC address(es) on this host'),
+ ),
)
def get_dn(self, *keys, **options):
@@ -442,6 +450,7 @@ class host_add(LDAPCreate):
x509.verify_cert_subject(ldap, keys[-1], cert)
entry_attrs['usercertificate'] = cert
entry_attrs['managedby'] = dn
+ entry_attrs['objectclass'].append('ieee802device')
return dn
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
@@ -681,6 +690,17 @@ class host_mod(LDAPUpdate):
if options.get('random'):
entry_attrs['userpassword'] = ipa_generate_password()
setattr(context, 'randompassword', entry_attrs['userpassword'])
+ if 'macaddress' in entry_attrs:
+ if 'objectclass' in entry_attrs:
+ obj_classes = entry_attrs['objectclass']
+ else:
+ (_dn, _entry_attrs) = ldap.get_entry(
+ dn, ['objectclass']
+ )
+ obj_classes = _entry_attrs['objectclass']
+ if 'ieee802device' not in obj_classes:
+ obj_classes.append('ieee802device')
+ entry_attrs['objectclass'] = obj_classes
return dn
diff --git a/tests/test_xmlrpc/objectclasses.py b/tests/test_xmlrpc/objectclasses.py
index 3569579ef..cdcc6420c 100644
--- a/tests/test_xmlrpc/objectclasses.py
+++ b/tests/test_xmlrpc/objectclasses.py
@@ -44,6 +44,7 @@ group = [
]
host = [
+ u'ieee802device',
u'ipaobject',
u'nshost',
u'ipahost',
diff --git a/tests/test_xmlrpc/test_host_plugin.py b/tests/test_xmlrpc/test_host_plugin.py
index 5e7137060..9459aec39 100644
--- a/tests/test_xmlrpc/test_host_plugin.py
+++ b/tests/test_xmlrpc/test_host_plugin.py
@@ -431,6 +431,71 @@ class test_host(Declarative):
dict(
+ desc='Add MAC address to %r' % fqdn1,
+ command=('host_mod', [fqdn1], dict(macaddress=u'00:50:56:30:F6:5F')),
+ expected=dict(
+ value=fqdn1,
+ summary=u'Modified host "%s"' % fqdn1,
+ result=dict(
+ description=[u'Updated host 1'],
+ fqdn=[fqdn1],
+ l=[u'Undisclosed location 1'],
+ krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)],
+ managedby_host=[u'%s' % fqdn1],
+ usercertificate=[base64.b64decode(servercert)],
+ valid_not_before=fuzzy_date,
+ valid_not_after=fuzzy_date,
+ subject=lambda x: DN(x) == \
+ DN(('CN',api.env.host),('O',api.env.realm)),
+ serial_number=fuzzy_digits,
+ md5_fingerprint=fuzzy_hash,
+ sha1_fingerprint=fuzzy_hash,
+ macaddress=[u'00:50:56:30:F6:5F'],
+ issuer=fuzzy_issuer,
+ has_keytab=False,
+ has_password=False,
+ ),
+ ),
+ ),
+
+
+ dict(
+ desc='Add another MAC address to %r' % fqdn1,
+ command=('host_mod', [fqdn1], dict(macaddress=[u'00:50:56:30:F6:5F', u'00:50:56:2C:8D:82'])),
+ expected=dict(
+ value=fqdn1,
+ summary=u'Modified host "%s"' % fqdn1,
+ result=dict(
+ description=[u'Updated host 1'],
+ fqdn=[fqdn1],
+ l=[u'Undisclosed location 1'],
+ krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)],
+ managedby_host=[u'%s' % fqdn1],
+ usercertificate=[base64.b64decode(servercert)],
+ valid_not_before=fuzzy_date,
+ valid_not_after=fuzzy_date,
+ subject=lambda x: DN(x) == \
+ DN(('CN',api.env.host),('O',api.env.realm)),
+ serial_number=fuzzy_digits,
+ md5_fingerprint=fuzzy_hash,
+ sha1_fingerprint=fuzzy_hash,
+ macaddress=[u'00:50:56:30:F6:5F', u'00:50:56:2C:8D:82'],
+ issuer=fuzzy_issuer,
+ has_keytab=False,
+ has_password=False,
+ ),
+ ),
+ ),
+
+
+ dict(
+ desc='Add an illegal MAC address to %r' % fqdn1,
+ command=('host_mod', [fqdn1], dict(macaddress=[u'xx'])),
+ expected=errors.ValidationError(name='macaddress', error='invalid \'macaddress\': Must be of the form HH:HH:HH:HH:HH:HH, where each H is a hexadecimal character.'),
+ ),
+
+
+ dict(
desc='Delete %r' % fqdn1,
command=('host_del', [fqdn1], {}),
expected=dict(