summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Basti <mbasti@redhat.com>2016-05-11 18:27:37 +0200
committerMartin Basti <mbasti@redhat.com>2016-06-03 15:58:21 +0200
commit15abfcf0f77664f426ba50ebf20e0f6c2a6f8275 (patch)
tree2fd3033f5dc66618e3e1968a81bf2b9a8540a9fd
parent121e34b90e890285c480a0c89e833d1369d61401 (diff)
downloadfreeipa-15abfcf0f77664f426ba50ebf20e0f6c2a6f8275.tar.gz
freeipa-15abfcf0f77664f426ba50ebf20e0f6c2a6f8275.tar.xz
freeipa-15abfcf0f77664f426ba50ebf20e0f6c2a6f8275.zip
DNS Locations: extend server-* command with locations
Server find, server show, server mod should work with IPA locations. https://fedorahosted.org/freeipa/ticket/2008 Reviewed-By: Petr Spacek <pspacek@redhat.com> Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-rw-r--r--API.txt20
-rw-r--r--VERSION4
-rw-r--r--ipaserver/plugins/location.py2
-rw-r--r--ipaserver/plugins/server.py104
4 files changed, 121 insertions, 9 deletions
diff --git a/API.txt b/API.txt
index bfdb9043d..991275079 100644
--- a/API.txt
+++ b/API.txt
@@ -4006,14 +4006,16 @@ output: Output('result', type=[<type 'dict'>])
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: ListOfPrimaryKeys('value')
command: server_find
-args: 1,12,4
+args: 1,14,4
arg: Str('criteria?')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('cn?', autofill=False, cli_name='name')
+option: DNSNameParam('in_location*', cli_name='in_locations')
option: Int('ipamaxdomainlevel?', autofill=False, cli_name='maxlevel')
option: Int('ipamindomainlevel?', autofill=False, cli_name='minlevel')
option: Flag('no_members', autofill=True, default=True)
option: Str('no_topologysuffix*', cli_name='no_topologysuffixes')
+option: DNSNameParam('not_in_location*', cli_name='not_in_locations')
option: Flag('pkey_only?', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
option: Int('sizelimit?', autofill=False)
@@ -4024,6 +4026,22 @@ output: Output('count', type=[<type 'int'>])
output: ListOfEntries('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: Output('truncated', type=[<type 'bool'>])
+command: server_mod
+args: 1,10,3
+arg: Str('cn', cli_name='name')
+option: Str('addattr*', cli_name='addattr')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Str('delattr*', cli_name='delattr')
+option: DNSNameParam('ipalocation_location?', autofill=False, cli_name='location')
+option: Int('ipalocationweight?', autofill=False, cli_name='location_weight')
+option: Flag('no_members', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Flag('rights', autofill=True, default=False)
+option: Str('setattr*', cli_name='setattr')
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
command: server_show
args: 1,5,3
arg: Str('cn', cli_name='name')
diff --git a/VERSION b/VERSION
index de7ad35f9..70bd7c91c 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
# #
########################################################
IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=174
-# Last change: mbasti - location-* commands
+IPA_API_VERSION_MINOR=175
+# Last change: mbasti - server-mod: locations added
diff --git a/ipaserver/plugins/location.py b/ipaserver/plugins/location.py
index 7c0aab174..35435f451 100644
--- a/ipaserver/plugins/location.py
+++ b/ipaserver/plugins/location.py
@@ -106,7 +106,7 @@ class location(LDAPObject):
)
def get_dn(self, *keys, **options):
- loc = keys[-1]
+ loc = keys[0]
assert isinstance(loc, DNSName)
loc_a = loc.ToASCII()
diff --git a/ipaserver/plugins/server.py b/ipaserver/plugins/server.py
index 6faaf8ec5..3192a588b 100644
--- a/ipaserver/plugins/server.py
+++ b/ipaserver/plugins/server.py
@@ -6,16 +6,21 @@ import dbus
import dbus.mainloop.glib
from ipalib import api, crud, errors, messages
-from ipalib import Int, Str
+from ipalib import Int, Str, DNSNameParam
from ipalib.plugable import Registry
from .baseldap import (
LDAPSearch,
LDAPRetrieve,
LDAPDelete,
- LDAPObject)
+ LDAPObject,
+ LDAPUpdate,
+)
from ipalib.request import context
from ipalib import _, ngettext
from ipalib import output
+from ipapython.dn import DN
+from ipapython.dnsutil import DNSName
+
__doc__ = _("""
IPA servers
@@ -43,18 +48,21 @@ class server(LDAPObject):
object_name = _('server')
object_name_plural = _('servers')
object_class = ['top']
+ possible_objectclasses = ['ipaLocationMember']
search_attributes = ['cn']
default_attributes = [
'cn', 'iparepltopomanagedsuffix', 'ipamindomainlevel',
- 'ipamaxdomainlevel'
+ 'ipamaxdomainlevel', 'ipalocation', 'ipalocationweight'
]
label = _('IPA Servers')
label_singular = _('IPA Server')
attribute_members = {
'iparepltopomanagedsuffix': ['topologysuffix'],
+ 'ipalocation': ['location'],
}
relationships = {
'iparepltopomanagedsuffix': ('Managed', '', 'no_'),
+ 'ipalocation': ('IPA', 'in_', 'not_in_'),
}
takes_params = (
Str(
@@ -87,6 +95,23 @@ class server(LDAPObject):
doc=_('Maximum domain level'),
flags={'no_create', 'no_update'},
),
+ DNSNameParam(
+ 'ipalocation_location?',
+ cli_name='location',
+ label=_('Location'),
+ doc=_('Server location'),
+ only_relative=True,
+ flags={'no_search'},
+ ),
+ Int(
+ 'ipalocationweight?',
+ cli_name='location_weight',
+ label=_('Location weight'),
+ doc=_('Location weight for server'),
+ minvalue=0,
+ maxvalue=65535,
+ flags={'no_search'},
+ )
)
def _get_suffixes(self):
@@ -105,6 +130,67 @@ class server(LDAPObject):
suffixes.get(m, m) for m in entry['iparepltopomanagedsuffix']
]
+ def normalize_location(self, kw, **options):
+ """
+ Return the DN of location
+ """
+ if 'ipalocation_location' in kw:
+ location = kw.pop('ipalocation_location')
+ kw['ipalocation'] = (
+ [self.api.Object.location.get_dn(location)]
+ if location is not None else location
+ )
+
+ def convert_location(self, entry_attrs, **options):
+ """
+ Return a location name from DN
+ """
+ if options.get('raw'):
+ return
+
+ converted_locations = [
+ DNSName(location_dn['idnsname']) for
+ location_dn in entry_attrs.pop('ipalocation', [])
+ ]
+
+ if converted_locations:
+ entry_attrs['ipalocation_location'] = converted_locations
+
+
+@register()
+class server_mod(LDAPUpdate):
+ __doc__ = _('Modify information about an IPA server.')
+
+ msg_summary = _('Modified IPA server "%(value)s"')
+
+ def args_options_2_entry(self, *args, **options):
+ kw = super(server_mod, self).args_options_2_entry(
+ *args, **options)
+ self.obj.normalize_location(kw, **options)
+ return kw
+
+ def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+ assert isinstance(dn, DN)
+
+ if entry_attrs.get('ipalocation'):
+ if not ldap.entry_exists(entry_attrs['ipalocation'][0]):
+ self.api.Object.location.handle_not_found(
+ options['ipalocation_location'])
+
+ if 'ipalocation' or 'ipalocationweight' in entry_attrs:
+ server_entry = ldap.get_entry(dn, ['objectclass'])
+
+ # we need to extend object with ipaLocationMember objectclass
+ entry_attrs['objectclass'] = (
+ server_entry['objectclass'] + ['ipalocationmember']
+ )
+
+ return dn
+
+ def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+ assert isinstance(dn, DN)
+ self.obj.convert_location(entry_attrs, **options)
+ return dn
@register()
class server_find(LDAPSearch):
@@ -114,7 +200,13 @@ class server_find(LDAPSearch):
'%(count)d IPA server matched',
'%(count)d IPA servers matched', 0
)
- member_attributes = ['iparepltopomanagedsuffix']
+ member_attributes = ['iparepltopomanagedsuffix', 'ipalocation']
+
+ def args_options_2_entry(self, *args, **options):
+ kw = super(server_find, self).args_options_2_entry(
+ *args, **options)
+ self.obj.normalize_location(kw, **options)
+ return kw
def get_options(self):
for option in super(server_find, self).get_options():
@@ -173,6 +265,8 @@ class server_find(LDAPSearch):
for entry in entries:
self.obj._apply_suffixes(entry, suffixes)
+ for entry in entries:
+ self.obj.convert_location(entry, **options)
return truncated
@@ -184,7 +278,7 @@ class server_show(LDAPRetrieve):
if not options.get('raw', False):
suffixes = self.obj._get_suffixes()
self.obj._apply_suffixes(entry, suffixes)
-
+ self.obj.convert_location(entry, **options)
return dn