freeipa/ipalib/plugins/host.py
2009-09-28 15:00:27 -06:00

214 lines
6.4 KiB
Python

# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@redhat.com>
#
# Copyright (C) 2008 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Hosts/Machines (Identity)
"""
import platform
import os
import sys
from ipalib import api, errors, util
from ipalib import Str, Flag
from ipalib.plugins.baseldap import *
from ipalib.plugins.service import split_principal
def validate_host(ugettext, fqdn):
"""
Require at least one dot in the hostname (to support localhost.localdomain)
"""
if fqdn.index('.') == -1:
return 'Fully-qualified hostname required'
return None
class host(LDAPObject):
"""
Host object.
"""
container_dn = api.env.container_host
object_name = 'host'
object_name_plural = 'hosts'
object_class = ['ipaobject', 'nshost', 'ipahost', 'pkiuser']
# object_class_config = 'ipahostobjectclasses'
default_attributes = [
'fqdn', 'description', 'localityname', 'nshostlocation',
'nshardwareplatform', 'nsosversion'
]
uuid_attribute = 'ipauniqueid'
attribute_names = {
'cn': 'name',
'fqdn': 'hostname',
'localityname': 'locality',
'nshostlocation': 'location',
'nshardwareplatform': 'platform',
'nsosversion': 'operating system',
'serverhostname': 'server hostname',
'enrolledby user': 'enrolled by',
'krbprincipalname': 'kerberos principal',
}
attribute_members = {
'enrolledby': ['user'],
}
takes_params = (
Str('fqdn', validate_host,
cli_name='hostname',
doc='Hostname',
primary_key=True,
normalizer=lambda value: value.lower(),
),
Str('description?',
cli_name='desc',
doc='Description of the host',
),
Str('localityname?',
cli_name='locality',
doc='Locality of the host (Baltimore, MD)',
),
Str('nshostlocation?',
cli_name='location',
doc='Location of the host (e.g. Lab 2)',
),
Str('nshardwareplatform?',
cli_name='platform',
doc='Hardware platform of the host (e.g. Lenovo T61)',
),
Str('nsosversion?',
cli_name='os',
doc='Operating System and version of the host (e.g. Fedora 9)',
),
Str('userpassword?',
cli_name='password',
doc='Password used in bulk enrollment',
),
)
def get_dn(self, *keys, **options):
if keys[-1].endswith('.'):
keys[-1] = keys[-1][:-1]
dn = super(host, self).get_dn(*keys, **options)
try:
self.backend.get_entry(dn, [''])
except errors.NotFound:
try:
(dn, entry_attrs) = self.backend.find_entry_by_attr(
'serverhostname', keys[-1], self.object_class, [''],
self.container_dn
)
except errors.NotFound:
pass
return dn
api.register(host)
class host_add(LDAPCreate):
"""
Create new host.
"""
def pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
entry_attrs['cn'] = keys[-1]
entry_attrs['serverhostname'] = keys[-1].split('.', 1)[0]
# FIXME: do DNS lookup to ensure host exists
if 'userpassword' not in entry_attrs:
entry_attrs['krbprincipalname'] = 'host/%s@%s' % (
keys[-1], self.api.env.realm
)
if 'krbprincipalaux' not in entry_attrs['objectclass']:
entry_attrs['objectclass'].append('krbprincipalaux')
entry_attrs['objectclass'].append('krbprincipal')
elif 'krbprincipalaux' in entry_attrs['objectclass']:
entry_attrs['objectclass'].remove('krbprincipalaux')
return dn
api.register(host_add)
class host_del(LDAPDelete):
"""
Delete host.
"""
def pre_callback(self, ldap, dn, *keys, **options):
# Remove all service records for this host
truncated = True
while truncated:
try:
(services, truncated) = api.Command['service_find'](keys[-1])
except errors.NotFound:
break
else:
for (dn_, entry_attrs) in services:
principal = entry_attrs['krbprincipalname'][0]
(service, hostname, realm) = split_principal(principal)
if hostname.lower() == keys[-1]:
api.Command['service_del'](principal)
return dn
api.register(host_del)
class host_mod(LDAPUpdate):
"""
Modify host.
"""
takes_options = LDAPUpdate.takes_options + (
Str('krbprincipalname?',
cli_name='principalname',
doc='Kerberos principal name for this host',
attribute=True,
),
)
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
# Once a principal name is set it cannot be changed
if 'krbprincipalname' in entry_attrs:
(dn, entry_attrs_old) = ldap.get_entry(
dn, ['objectclass', 'krbprincipalname']
)
if 'krbprincipalname' in entry_attrs_old:
msg = 'Principal name already set, it is unchangeable.'
raise errors.ACIError(info=msg)
obj_classes = entry_attrs_old['objectclass']
if 'krbprincipalaux' not in obj_classes:
obj_classes.append('krbprincipalaux')
entry_attrs['objectclass'] = obj_classes
return dn
api.register(host_mod)
class host_find(LDAPSearch):
"""
Search for hosts.
"""
api.register(host_find)
class host_show(LDAPRetrieve):
"""
Display host.
"""
api.register(host_show)