From 79544aa51acc6f48117391b1e0ec70e9f4d7d0bb Mon Sep 17 00:00:00 2001 From: Martin Basti Date: Jun 03 2016 13:58:21 +0000 Subject: DNS Location: location-show: return list of servers in location location-show returns list of servers curently assigned to the location https://fedorahosted.org/freeipa/ticket/2008 Reviewed-By: Petr Spacek Reviewed-By: Jan Cholasta --- diff --git a/ACI.txt b/ACI.txt index 2226ecc..a09495e 100644 --- a/ACI.txt +++ b/ACI.txt @@ -226,6 +226,8 @@ dn: cn=usermap,cn=selinux,dc=ipa,dc=example aci: (targetattr = "accesstime || cn || createtimestamp || description || entryusn || hostcategory || ipaenabledflag || ipaselinuxuser || ipauniqueid || member || memberhost || memberuser || modifytimestamp || objectclass || seealso || usercategory")(targetfilter = "(objectclass=ipaselinuxusermap)")(version 3.0;acl "permission:System: Read SELinux User Maps";allow (compare,read,search) userdn = "ldap:///all";) dn: cn=usermap,cn=selinux,dc=ipa,dc=example aci: (targetfilter = "(objectclass=ipaselinuxusermap)")(version 3.0;acl "permission:System: Remove SELinux User Maps";allow (delete) groupdn = "ldap:///cn=System: Remove SELinux User Maps,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=masters,cn=ipa,cn=etc,dc=ipa,dc=example +aci: (targetattr = "cn || createtimestamp || entryusn || ipalocation || ipalocationweight || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaLocationMember)")(version 3.0;acl "permission:System: Read Locations of IPA Servers";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Locations of IPA Servers,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=services,cn=accounts,dc=ipa,dc=example aci: (targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Add Services";allow (add) groupdn = "ldap:///cn=System: Add Services,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=services,cn=accounts,dc=ipa,dc=example diff --git a/API.txt b/API.txt index 9912750..f170930 100644 --- a/API.txt +++ b/API.txt @@ -2837,13 +2837,14 @@ output: Entry('result') output: Output('summary', type=[, ]) output: PrimaryKey('value') command: location_show -args: 1,4,3 +args: 1,4,4 arg: DNSNameParam('idnsname', cli_name='name') option: Flag('all', autofill=True, cli_name='all', default=False) option: Flag('raw', autofill=True, cli_name='raw', default=False) option: Flag('rights', autofill=True, default=False) option: Str('version?') output: Entry('result') +output: Output('servers', type=[]) output: Output('summary', type=[, ]) output: PrimaryKey('value') command: migrate_ds diff --git a/VERSION b/VERSION index 70bd7c9..4ada746 100644 --- a/VERSION +++ b/VERSION @@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000 # # ######################################################## IPA_API_VERSION_MAJOR=2 -IPA_API_VERSION_MINOR=175 -# Last change: mbasti - server-mod: locations added +IPA_API_VERSION_MINOR=176 +# Last change: mbasti - location-show: list servers in the location diff --git a/ipaclient/plugins/location.py b/ipaclient/plugins/location.py new file mode 100644 index 0000000..b3b6026 --- /dev/null +++ b/ipaclient/plugins/location.py @@ -0,0 +1,35 @@ +# +# Copyright (C) 2016 FreeIPA Contributors see COPYING for license +# + +from ipaclient.frontend import MethodOverride +from ipalib import _ +from ipalib.plugable import Registry + + +register = Registry() + + +@register(override=True) +class location_show(MethodOverride): + def output_for_cli(self, textui, output, *keys, **options): + rv = super(location_show, self).output_for_cli( + textui, output, *keys, **options) + + servers = output.get('servers', {}) + first = True + for hostname, details in servers.items(): + if first: + textui.print_indented(_("Servers details:"), indent=1) + first = False + else: + textui.print_line("") + + for param in self.api.Command.server_find.output_params(): + if param.name in details: + textui.print_indented( + u"{}: {}".format( + param.label, u', '.join(details[param.name])), + indent=2) + + return rv diff --git a/ipaserver/plugins/location.py b/ipaserver/plugins/location.py index 35435f4..1edda8e 100644 --- a/ipaserver/plugins/location.py +++ b/ipaserver/plugins/location.py @@ -2,14 +2,18 @@ # Copyright (C) 2016 FreeIPA Contributors see COPYING for license # -from __future__ import absolute_import +from __future__ import ( + absolute_import, + division, +) from ipalib import ( _, ngettext, api, Str, - DNSNameParam + DNSNameParam, + output, ) from ipalib.plugable import Registry from ipaserver.plugins.baseldap import ( @@ -20,6 +24,7 @@ from ipaserver.plugins.baseldap import ( LDAPObject, LDAPUpdate, ) +from ipapython.dn import DN from ipapython.dnsutil import DNSName __doc__ = _(""" @@ -103,6 +108,12 @@ class location(LDAPObject): label=_('Description'), doc=_('IPA Location description'), ), + Str( + 'servers_server*', + label=_('Servers'), + doc=_('Servers that belongs to the IPA location'), + flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'}, + ), ) def get_dn(self, *keys, **options): @@ -147,3 +158,43 @@ class location_find(LDAPSearch): @register() class location_show(LDAPRetrieve): __doc__ = _('Display information about an IPA location.') + + has_output = LDAPRetrieve.has_output + ( + output.Output( + 'servers', + type=dict, + doc=_('Servers in location'), + flags={'no_display'}, # we use customized print to CLI + ), + ) + + def execute(self, *keys, **options): + result = super(location_show, self).execute(*keys, **options) + + servers_additional_info = {} + if not options.get('raw'): + servers_name = [] + weight_sum = 0 + + servers = self.api.Command.server_find( + in_location=keys[0], no_members=False)['result'] + for server in servers: + servers_name.append(server['cn'][0]) + weight = int(server.get('ipalocationweight', [100])[0]) + weight_sum += weight + servers_additional_info[server['cn'][0]] = { + 'cn': server['cn'], + 'ipalocationweight': server.get( + 'ipalocationweight', [u'100']), + } + + for server in servers_additional_info.values(): + server['location_relative_weight'] = [ + u'{:.1f}%'.format( + int(server['ipalocationweight'][0])*100.0/weight_sum) + ] + if servers_name: + result['result']['servers_server'] = servers_name + result['servers'] = servers_additional_info + + return result diff --git a/ipaserver/plugins/server.py b/ipaserver/plugins/server.py index 3192a58..511f813 100644 --- a/ipaserver/plugins/server.py +++ b/ipaserver/plugins/server.py @@ -64,6 +64,16 @@ class server(LDAPObject): 'iparepltopomanagedsuffix': ('Managed', '', 'no_'), 'ipalocation': ('IPA', 'in_', 'not_in_'), } + permission_filter_objectclasses = ['ipaLocationMember'] + managed_permissions = { + 'System: Read Locations of IPA Servers': { + 'ipapermright': {'read', 'search', 'compare'}, + 'ipapermdefaultattr': { + 'objectclass', 'cn', 'ipalocation', 'ipalocationweight', + }, + 'default_privileges': {'DNS Administrators'}, + }, + } takes_params = ( Str( 'cn', @@ -111,6 +121,12 @@ class server(LDAPObject): minvalue=0, maxvalue=65535, flags={'no_search'}, + ), + Str( + 'location_relative_weight', + label=_('Location relative weight'), + doc=_('Location relative weight for server (counts per location)'), + flags={'virtual_attribute','no_create', 'no_update', 'no_search'}, ) )