summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Babej <tbabej@redhat.com>2014-07-31 14:09:05 +0200
committerTomas Babej <tbabej@redhat.com>2014-09-17 14:41:51 +0200
commit719bf0ce45a34de6b67bc073d9bac345770e6c2a (patch)
tree80bd69470934c20f54d4739d4c787569b02e9fa5
parent38f7933e2857ef5dd33386d4c51417c33d1b54c5 (diff)
downloadfreeipa-719bf0ce45a34de6b67bc073d9bac345770e6c2a.tar.gz
freeipa-719bf0ce45a34de6b67bc073d9bac345770e6c2a.tar.xz
freeipa-719bf0ce45a34de6b67bc073d9bac345770e6c2a.zip
idviews: Add ipa idview-apply and idview-unapply commands
Part of: https://fedorahosted.org/freeipa/ticket/3979
-rw-r--r--API.txt19
-rw-r--r--ipalib/plugins/idviews.py179
2 files changed, 195 insertions, 3 deletions
diff --git a/API.txt b/API.txt
index 29f7faefe..08af899bd 100644
--- a/API.txt
+++ b/API.txt
@@ -2199,6 +2199,16 @@ option: Str('version?', exclude='webui')
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: PrimaryKey('value', None, None)
+command: idview_apply
+args: 1,3,4
+arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('host*', cli_name='hosts')
+option: Str('hostgroup*', cli_name='hostgroups')
+option: Str('version?', exclude='webui')
+output: Output('completed', <type 'int'>, None)
+output: Output('failed', <type 'dict'>, None)
+output: Output('succeeded', <type 'dict'>, None)
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
command: idview_del
args: 1,2,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
@@ -2247,6 +2257,15 @@ option: Str('version?', exclude='webui')
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: PrimaryKey('value', None, None)
+command: idview_unapply
+args: 0,3,4
+option: Str('host*', cli_name='hosts')
+option: Str('hostgroup*', cli_name='hostgroups')
+option: Str('version?', exclude='webui')
+output: Output('completed', <type 'int'>, None)
+output: Output('failed', <type 'dict'>, None)
+output: Output('succeeded', <type 'dict'>, None)
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
command: json_metadata
args: 2,4,3
arg: Str('objname?')
diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
index e7a26dea2..c27a014cb 100644
--- a/ipalib/plugins/idviews.py
+++ b/ipalib/plugins/idviews.py
@@ -18,12 +18,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from ipalib.plugins.baseldap import (LDAPObject, LDAPCreate,
+from ipalib.plugins.baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
LDAPDelete, LDAPUpdate, LDAPSearch,
- LDAPRetrieve)
-from ipalib import api, Str, Int, _, ngettext
+ LDAPRetrieve, global_output_params)
+from ipalib.plugins.hostgroup import get_complete_hostgroup_member_list
+from ipalib import api, Str, Int, _, ngettext, errors, output
from ipalib.plugable import Registry
+from ipapython.dn import DN
__doc__ = _("""
ID views
@@ -107,6 +109,177 @@ class idview_show(LDAPRetrieve):
@register()
+class idview_apply(LDAPQuery):
+ __doc__ = _('Applies ID view to specified hosts or current members of '
+ 'specified hostgroups. If any other ID view is applied to '
+ 'the host, it is overriden.')
+
+ member_count_out = (_('ID view applied to %i host.'),
+ _('ID view applied to %i hosts.'))
+
+ msg_summary = 'Applied ID view "%(value)s"'
+
+ takes_options = (
+ Str('host*',
+ cli_name='hosts',
+ doc=_('Hosts to apply the ID view to'),
+ label=_('hosts'),
+ ),
+ Str('hostgroup*',
+ cli_name='hostgroups',
+ doc=_('Hostgroups to whose hosts apply the ID view to. Please note '
+ 'that view is not applied automatically to any hosts added '
+ 'to the hostgroup after running the idview-apply command.'),
+ label=_('hostgroups'),
+ ),
+ )
+
+ has_output = (
+ output.summary,
+ output.Output('succeeded',
+ type=dict,
+ doc=_('Hosts that this ID view was applied to.'),
+ ),
+ output.Output('failed',
+ type=dict,
+ doc=_('Hosts or hostgroups that this ID view could not be '
+ 'applied to.'),
+ ),
+ output.Output('completed',
+ type=int,
+ doc=_('Number of hosts the ID view was applied to:'),
+ ),
+ )
+
+ has_output_params = global_output_params
+
+ def execute(self, *keys, **options):
+ view = keys[-1] if keys else None
+ ldap = self.obj.backend
+
+ # Test if idview actually exists, if it does not, NotFound is raised
+ if not options.get('clear_view', False):
+ view_dn = self.api.Object['idview'].get_dn_if_exists(view)
+ assert isinstance(view_dn, DN)
+ else:
+ # In case we are removing assigned view, we modify the host setting
+ # the ipaAssignedIDView to None
+ view_dn = None
+
+ completed = 0
+ succeeded = {'host': []}
+ failed = {
+ 'host': [],
+ 'hostgroup': [],
+ }
+
+ # Generate a list of all hosts to apply the view to
+ hosts_to_apply = list(options.get('host', []))
+
+ for hostgroup in options.get('hostgroup', ()):
+ try:
+ hosts_to_apply += get_complete_hostgroup_member_list(hostgroup)
+ except errors.NotFound:
+ failed['hostgroup'].append((hostgroup, "not found"))
+ except errors.PublicError as e:
+ failed['hostgroup'].append((hostgroup, "%s : %s" % (
+ e.__class__.__name__, str(e))))
+
+ for host in hosts_to_apply:
+ try:
+ host_dn = api.Object['host'].get_dn_if_exists(host)
+
+ host_entry = ldap.get_entry(host_dn,
+ attrs_list=['ipaassignedidview'])
+ host_entry['ipaassignedidview'] = view_dn
+
+ ldap.update_entry(host_entry)
+
+ # If no exception was raised, view assigment went well
+ completed = completed + 1
+ succeeded['host'].append(host)
+ except errors.EmptyModlist:
+ # If view was already applied, do not complain
+ pass
+ except errors.NotFound:
+ failed['host'].append((host, "not found"))
+ except errors.PublicError as e:
+ failed['host'].append((host, str(e)))
+
+ # Wrap dictionary containing failures in another dictionary under key
+ # 'memberhost', since that is output parameter in global_output_params
+ # and thus we get nice output in the CLI
+ failed = {'memberhost': failed}
+
+ # Sort the list of affected hosts
+ succeeded['host'].sort()
+
+ # Note that we're returning the list of affected hosts even if they
+ # were passed via referencing a hostgroup. This is desired, since we
+ # want to stress the fact that view is applied on all the current
+ # member hosts of the hostgroup and not tied with the hostgroup itself.
+
+ return dict(
+ summary=unicode(_(self.msg_summary % {'value': view})),
+ succeeded=succeeded,
+ completed=completed,
+ failed=failed,
+ )
+
+
+@register()
+class idview_unapply(idview_apply):
+ __doc__ = _('Clears ID view from specified hosts or current members of '
+ 'specified hostgroups.')
+
+ member_count_out = (_('ID view cleared from %i host.'),
+ _('ID view cleared from %i hosts.'))
+
+ msg_summary = 'Cleared ID views'
+
+ takes_options = (
+ Str('host*',
+ cli_name='hosts',
+ doc=_('Hosts to clear (any) ID view from.'),
+ label=_('hosts'),
+ ),
+ Str('hostgroup*',
+ cli_name='hostgroups',
+ doc=_('Hostgroups whose hosts should have ID views cleared. Note '
+ 'that view is not cleared automatically from any host added '
+ 'to the hostgroup after running idview-unapply command.'),
+ label=_('hostgroups'),
+ ),
+ )
+
+ has_output = (
+ output.summary,
+ output.Output('succeeded',
+ type=dict,
+ doc=_('Hosts that ID view was cleared from.'),
+ ),
+ output.Output('failed',
+ type=dict,
+ doc=_('Hosts or hostgroups that ID view could not be cleared '
+ 'from.'),
+ ),
+ output.Output('completed',
+ type=int,
+ doc=_('Number of hosts that had a ID view was unset:'),
+ ),
+ )
+
+ # Take no arguments, since ID View reference is not needed to clear
+ # the hosts
+ def get_args(self):
+ return ()
+
+ def execute(self, *keys, **options):
+ options['clear_view'] = True
+ return super(idview_unapply, self).execute(*keys, **options)
+
+
+@register()
class idoverride(LDAPObject):
"""
ID override object.