#
# Copyright (C) 2016  FreeIPA Contributors see COPYING for license
#

# pylint: disable=unused-import
import six

from . import Command, Method, Object
from ipalib import api, parameters, output
from ipalib.parameters import DefaultFrom
from ipalib.plugable import Registry
from ipalib.text import _
from ipapython.dn import DN
from ipapython.dnsutil import DNSName

if six.PY3:
    unicode = str

__doc__ = _("""
Sudo Rules

Sudo (su "do") allows a system administrator to delegate authority to
give certain users (or groups of users) the ability to run some (or all)
commands as root or another user while providing an audit trail of the
commands and their arguments.

FreeIPA provides a means to configure the various aspects of Sudo:
   Users: The user(s)/group(s) allowed to invoke Sudo.
   Hosts: The host(s)/hostgroup(s) which the user is allowed to to invoke Sudo.
   Allow Command: The specific command(s) permitted to be run via Sudo.
   Deny Command: The specific command(s) prohibited to be run via Sudo.
   RunAsUser: The user(s) or group(s) of users whose rights Sudo will be invoked with.
   RunAsGroup: The group(s) whose gid rights Sudo will be invoked with.
   Options: The various Sudoers Options that can modify Sudo's behavior.

An order can be added to a sudorule to control the order in which they
are evaluated (if the client supports it). This order is an integer and
must be unique.

FreeIPA provides a designated binddn to use with Sudo located at:
uid=sudo,cn=sysaccounts,cn=etc,dc=example,dc=com

To enable the binddn run the following command to set the password:
LDAPTLS_CACERT=/etc/ipa/ca.crt /usr/bin/ldappasswd -S -W -h ipa.example.com -ZZ -D "cn=Directory Manager" uid=sudo,cn=sysaccounts,cn=etc,dc=example,dc=com

For more information, see the FreeIPA Documentation to Sudo.
""")

register = Registry()


@register()
class sudorule(Object):
    takes_params = (
        parameters.Str(
            'cn',
            primary_key=True,
            label=_(u'Rule name'),
        ),
        parameters.Str(
            'description',
            required=False,
            label=_(u'Description'),
        ),
        parameters.Bool(
            'ipaenabledflag',
            required=False,
            label=_(u'Enabled'),
        ),
        parameters.Str(
            'usercategory',
            required=False,
            label=_(u'User category'),
            doc=_(u'User category the rule applies to'),
        ),
        parameters.Str(
            'hostcategory',
            required=False,
            label=_(u'Host category'),
            doc=_(u'Host category the rule applies to'),
        ),
        parameters.Str(
            'cmdcategory',
            required=False,
            label=_(u'Command category'),
            doc=_(u'Command category the rule applies to'),
        ),
        parameters.Str(
            'ipasudorunasusercategory',
            required=False,
            label=_(u'RunAs User category'),
            doc=_(u'RunAs User category the rule applies to'),
        ),
        parameters.Str(
            'ipasudorunasgroupcategory',
            required=False,
            label=_(u'RunAs Group category'),
            doc=_(u'RunAs Group category the rule applies to'),
        ),
        parameters.Int(
            'sudoorder',
            required=False,
            label=_(u'Sudo order'),
            doc=_(u'integer to order the Sudo rules'),
        ),
        parameters.Str(
            'memberuser_user',
            required=False,
            label=_(u'Users'),
        ),
        parameters.Str(
            'memberuser_group',
            required=False,
            label=_(u'User Groups'),
        ),
        parameters.Str(
            'memberhost_host',
            required=False,
            label=_(u'Hosts'),
        ),
        parameters.Str(
            'memberhost_hostgroup',
            required=False,
            label=_(u'Host Groups'),
        ),
        parameters.Str(
            'memberallowcmd_sudocmd',
            required=False,
            label=_(u'Sudo Allow Commands'),
        ),
        parameters.Str(
            'memberdenycmd_sudocmd',
            required=False,
            label=_(u'Sudo Deny Commands'),
        ),
        parameters.Str(
            'memberallowcmd_sudocmdgroup',
            required=False,
            label=_(u'Sudo Allow Command Groups'),
        ),
        parameters.Str(
            'memberdenycmd_sudocmdgroup',
            required=False,
            label=_(u'Sudo Deny Command Groups'),
        ),
        parameters.Str(
            'ipasudorunas_user',
            required=False,
            label=_(u'RunAs Users'),
            doc=_(u'Run as a user'),
        ),
        parameters.Str(
            'ipasudorunas_group',
            required=False,
            label=_(u'Groups of RunAs Users'),
            doc=_(u'Run as any user within a specified group'),
        ),
        parameters.Str(
            'externaluser',
            required=False,
            label=_(u'External User'),
            doc=_(u'External User the rule applies to (sudorule-find only)'),
        ),
        parameters.Str(
            'ipasudorunasextuser',
            required=False,
            label=_(u'RunAs External User'),
            doc=_(u'External User the commands can run as (sudorule-find only)'),
        ),
        parameters.Str(
            'ipasudorunasextgroup',
            required=False,
            label=_(u'RunAs External Group'),
            doc=_(u'External Group the commands can run as (sudorule-find only)'),
        ),
        parameters.Str(
            'ipasudoopt',
            required=False,
            label=_(u'Sudo Option'),
        ),
        parameters.Str(
            'ipasudorunasgroup_group',
            required=False,
            label=_(u'RunAs Groups'),
            doc=_(u'Run with the gid of a specified POSIX group'),
        ),
        parameters.Str(
            'externalhost',
            required=False,
            multivalue=True,
            label=_(u'External host'),
        ),
    )


@register()
class sudorule_add(Method):
    __doc__ = _("Create new Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Str(
            'description',
            required=False,
            cli_name='desc',
            label=_(u'Description'),
        ),
        parameters.Bool(
            'ipaenabledflag',
            required=False,
            label=_(u'Enabled'),
            exclude=('cli', 'webui'),
        ),
        parameters.Str(
            'usercategory',
            required=False,
            cli_name='usercat',
            cli_metavar="['all']",
            label=_(u'User category'),
            doc=_(u'User category the rule applies to'),
        ),
        parameters.Str(
            'hostcategory',
            required=False,
            cli_name='hostcat',
            cli_metavar="['all']",
            label=_(u'Host category'),
            doc=_(u'Host category the rule applies to'),
        ),
        parameters.Str(
            'cmdcategory',
            required=False,
            cli_name='cmdcat',
            cli_metavar="['all']",
            label=_(u'Command category'),
            doc=_(u'Command category the rule applies to'),
        ),
        parameters.Str(
            'ipasudorunasusercategory',
            required=False,
            cli_name='runasusercat',
            cli_metavar="['all']",
            label=_(u'RunAs User category'),
            doc=_(u'RunAs User category the rule applies to'),
        ),
        parameters.Str(
            'ipasudorunasgroupcategory',
            required=False,
            cli_name='runasgroupcat',
            cli_metavar="['all']",
            label=_(u'RunAs Group category'),
            doc=_(u'RunAs Group category the rule applies to'),
        ),
        parameters.Int(
            'sudoorder',
            required=False,
            cli_name='order',
            label=_(u'Sudo order'),
            doc=_(u'integer to order the Sudo rules'),
            default=0,
        ),
        parameters.Str(
            'externaluser',
            required=False,
            label=_(u'External User'),
            doc=_(u'External User the rule applies to (sudorule-find only)'),
        ),
        parameters.Str(
            'ipasudorunasextuser',
            required=False,
            cli_name='runasexternaluser',
            label=_(u'RunAs External User'),
            doc=_(u'External User the commands can run as (sudorule-find only)'),
        ),
        parameters.Str(
            'ipasudorunasextgroup',
            required=False,
            cli_name='runasexternalgroup',
            label=_(u'RunAs External Group'),
            doc=_(u'External Group the commands can run as (sudorule-find only)'),
        ),
        parameters.Str(
            'externalhost',
            required=False,
            multivalue=True,
            label=_(u'External host'),
            exclude=('cli', 'webui'),
        ),
        parameters.Str(
            'setattr',
            required=False,
            multivalue=True,
            doc=_(u'Set an attribute to a name/value pair. Format is attr=value.\nFor multi-valued attributes, the command replaces the values already present.'),
            exclude=('webui',),
        ),
        parameters.Str(
            'addattr',
            required=False,
            multivalue=True,
            doc=_(u'Add an attribute/value pair. Format is attr=value. The attribute\nmust be part of the schema.'),
            exclude=('webui',),
        ),
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
    )
    has_output = (
        output.Output(
            'summary',
            (unicode, type(None)),
            doc=_(u'User-friendly description of action performed'),
        ),
        output.Entry(
            'result',
        ),
        output.Output(
            'value',
            unicode,
            doc=_(u"The primary_key value of the entry, e.g. 'jdoe' for a user"),
        ),
    )


@register()
class sudorule_add_allow_command(Method):
    __doc__ = _("Add commands and sudo command groups affected by Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'sudocmd',
            required=False,
            multivalue=True,
            cli_name='sudocmds',
            label=_(u'member sudo command'),
            doc=_(u'comma-separated list of sudo commands to add'),
            alwaysask=True,
        ),
        parameters.Str(
            'sudocmdgroup',
            required=False,
            multivalue=True,
            cli_name='sudocmdgroups',
            label=_(u'member sudo command group'),
            doc=_(u'comma-separated list of sudo command groups to add'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be added'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members added'),
        ),
    )


@register()
class sudorule_add_deny_command(Method):
    __doc__ = _("Add commands and sudo command groups affected by Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'sudocmd',
            required=False,
            multivalue=True,
            cli_name='sudocmds',
            label=_(u'member sudo command'),
            doc=_(u'comma-separated list of sudo commands to add'),
            alwaysask=True,
        ),
        parameters.Str(
            'sudocmdgroup',
            required=False,
            multivalue=True,
            cli_name='sudocmdgroups',
            label=_(u'member sudo command group'),
            doc=_(u'comma-separated list of sudo command groups to add'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be added'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members added'),
        ),
    )


@register()
class sudorule_add_host(Method):
    __doc__ = _("Add hosts and hostgroups affected by Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'host',
            required=False,
            multivalue=True,
            cli_name='hosts',
            label=_(u'member host'),
            doc=_(u'comma-separated list of hosts to add'),
            alwaysask=True,
        ),
        parameters.Str(
            'hostgroup',
            required=False,
            multivalue=True,
            cli_name='hostgroups',
            label=_(u'member host group'),
            doc=_(u'comma-separated list of host groups to add'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be added'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members added'),
        ),
    )


@register()
class sudorule_add_option(Method):
    __doc__ = _("Add an option to the Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Str(
            'ipasudoopt',
            cli_name='sudooption',
            label=_(u'Sudo Option'),
        ),
    )
    has_output = (
        output.Output(
            'result',
        ),
    )


@register()
class sudorule_add_runasgroup(Method):
    __doc__ = _("Add group for Sudo to execute as.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'group',
            required=False,
            multivalue=True,
            cli_name='groups',
            label=_(u'member group'),
            doc=_(u'comma-separated list of groups to add'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be added'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members added'),
        ),
    )


@register()
class sudorule_add_runasuser(Method):
    __doc__ = _("Add users and groups for Sudo to execute as.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'user',
            required=False,
            multivalue=True,
            cli_name='users',
            label=_(u'member user'),
            doc=_(u'comma-separated list of users to add'),
            alwaysask=True,
        ),
        parameters.Str(
            'group',
            required=False,
            multivalue=True,
            cli_name='groups',
            label=_(u'member group'),
            doc=_(u'comma-separated list of groups to add'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be added'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members added'),
        ),
    )


@register()
class sudorule_add_user(Method):
    __doc__ = _("Add users and groups affected by Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'user',
            required=False,
            multivalue=True,
            cli_name='users',
            label=_(u'member user'),
            doc=_(u'comma-separated list of users to add'),
            alwaysask=True,
        ),
        parameters.Str(
            'group',
            required=False,
            multivalue=True,
            cli_name='groups',
            label=_(u'member group'),
            doc=_(u'comma-separated list of groups to add'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be added'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members added'),
        ),
    )


@register()
class sudorule_del(Method):
    __doc__ = _("Delete Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            multivalue=True,
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'continue',
            doc=_(u"Continuous mode: Don't stop on errors."),
            default=False,
            autofill=True,
        ),
    )
    has_output = (
        output.Output(
            'summary',
            (unicode, type(None)),
            doc=_(u'User-friendly description of action performed'),
        ),
        output.Output(
            'result',
            dict,
            doc=_(u'List of deletions that failed'),
        ),
        output.Output(
            'value',
            unicode,
            doc=_(u"The primary_key value of the entry, e.g. 'jdoe' for a user"),
        ),
    )


@register()
class sudorule_disable(Method):
    __doc__ = _("Disable a Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    has_output = (
        output.Output(
            'result',
        ),
    )


@register()
class sudorule_enable(Method):
    __doc__ = _("Enable a Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    has_output = (
        output.Output(
            'result',
        ),
    )


@register()
class sudorule_find(Method):
    __doc__ = _("Search for Sudo Rule.")

    takes_args = (
        parameters.Str(
            'criteria',
            required=False,
            doc=_(u'A string searched in all relevant object attributes'),
        ),
    )
    takes_options = (
        parameters.Str(
            'cn',
            required=False,
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
        parameters.Str(
            'description',
            required=False,
            cli_name='desc',
            label=_(u'Description'),
        ),
        parameters.Bool(
            'ipaenabledflag',
            required=False,
            label=_(u'Enabled'),
            exclude=('cli', 'webui'),
        ),
        parameters.Str(
            'usercategory',
            required=False,
            cli_name='usercat',
            cli_metavar="['all']",
            label=_(u'User category'),
            doc=_(u'User category the rule applies to'),
        ),
        parameters.Str(
            'hostcategory',
            required=False,
            cli_name='hostcat',
            cli_metavar="['all']",
            label=_(u'Host category'),
            doc=_(u'Host category the rule applies to'),
        ),
        parameters.Str(
            'cmdcategory',
            required=False,
            cli_name='cmdcat',
            cli_metavar="['all']",
            label=_(u'Command category'),
            doc=_(u'Command category the rule applies to'),
        ),
        parameters.Str(
            'ipasudorunasusercategory',
            required=False,
            cli_name='runasusercat',
            cli_metavar="['all']",
            label=_(u'RunAs User category'),
            doc=_(u'RunAs User category the rule applies to'),
        ),
        parameters.Str(
            'ipasudorunasgroupcategory',
            required=False,
            cli_name='runasgroupcat',
            cli_metavar="['all']",
            label=_(u'RunAs Group category'),
            doc=_(u'RunAs Group category the rule applies to'),
        ),
        parameters.Int(
            'sudoorder',
            required=False,
            cli_name='order',
            label=_(u'Sudo order'),
            doc=_(u'integer to order the Sudo rules'),
            default=0,
        ),
        parameters.Str(
            'externaluser',
            required=False,
            label=_(u'External User'),
            doc=_(u'External User the rule applies to (sudorule-find only)'),
        ),
        parameters.Str(
            'ipasudorunasextuser',
            required=False,
            cli_name='runasexternaluser',
            label=_(u'RunAs External User'),
            doc=_(u'External User the commands can run as (sudorule-find only)'),
        ),
        parameters.Str(
            'ipasudorunasextgroup',
            required=False,
            cli_name='runasexternalgroup',
            label=_(u'RunAs External Group'),
            doc=_(u'External Group the commands can run as (sudorule-find only)'),
        ),
        parameters.Str(
            'externalhost',
            required=False,
            multivalue=True,
            label=_(u'External host'),
            exclude=('cli', 'webui'),
        ),
        parameters.Int(
            'timelimit',
            required=False,
            label=_(u'Time Limit'),
            doc=_(u'Time limit of search in seconds'),
        ),
        parameters.Int(
            'sizelimit',
            required=False,
            label=_(u'Size Limit'),
            doc=_(u'Maximum number of entries returned'),
        ),
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'pkey_only',
            required=False,
            label=_(u'Primary key only'),
            doc=_(u'Results should contain primary key attribute only ("sudorule-name")'),
            default=False,
            autofill=True,
        ),
    )
    has_output = (
        output.Output(
            'summary',
            (unicode, type(None)),
            doc=_(u'User-friendly description of action performed'),
        ),
        output.ListOfEntries(
            'result',
        ),
        output.Output(
            'count',
            int,
            doc=_(u'Number of entries returned'),
        ),
        output.Output(
            'truncated',
            bool,
            doc=_(u'True if not all results were returned'),
        ),
    )


@register()
class sudorule_mod(Method):
    __doc__ = _("Modify Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Str(
            'description',
            required=False,
            cli_name='desc',
            label=_(u'Description'),
        ),
        parameters.Bool(
            'ipaenabledflag',
            required=False,
            label=_(u'Enabled'),
            exclude=('cli', 'webui'),
        ),
        parameters.Str(
            'usercategory',
            required=False,
            cli_name='usercat',
            cli_metavar="['all']",
            label=_(u'User category'),
            doc=_(u'User category the rule applies to'),
        ),
        parameters.Str(
            'hostcategory',
            required=False,
            cli_name='hostcat',
            cli_metavar="['all']",
            label=_(u'Host category'),
            doc=_(u'Host category the rule applies to'),
        ),
        parameters.Str(
            'cmdcategory',
            required=False,
            cli_name='cmdcat',
            cli_metavar="['all']",
            label=_(u'Command category'),
            doc=_(u'Command category the rule applies to'),
        ),
        parameters.Str(
            'ipasudorunasusercategory',
            required=False,
            cli_name='runasusercat',
            cli_metavar="['all']",
            label=_(u'RunAs User category'),
            doc=_(u'RunAs User category the rule applies to'),
        ),
        parameters.Str(
            'ipasudorunasgroupcategory',
            required=False,
            cli_name='runasgroupcat',
            cli_metavar="['all']",
            label=_(u'RunAs Group category'),
            doc=_(u'RunAs Group category the rule applies to'),
        ),
        parameters.Int(
            'sudoorder',
            required=False,
            cli_name='order',
            label=_(u'Sudo order'),
            doc=_(u'integer to order the Sudo rules'),
            default=0,
        ),
        parameters.Str(
            'externaluser',
            required=False,
            label=_(u'External User'),
            doc=_(u'External User the rule applies to (sudorule-find only)'),
        ),
        parameters.Str(
            'ipasudorunasextuser',
            required=False,
            cli_name='runasexternaluser',
            label=_(u'RunAs External User'),
            doc=_(u'External User the commands can run as (sudorule-find only)'),
        ),
        parameters.Str(
            'ipasudorunasextgroup',
            required=False,
            cli_name='runasexternalgroup',
            label=_(u'RunAs External Group'),
            doc=_(u'External Group the commands can run as (sudorule-find only)'),
        ),
        parameters.Str(
            'externalhost',
            required=False,
            multivalue=True,
            label=_(u'External host'),
            exclude=('cli', 'webui'),
        ),
        parameters.Str(
            'setattr',
            required=False,
            multivalue=True,
            doc=_(u'Set an attribute to a name/value pair. Format is attr=value.\nFor multi-valued attributes, the command replaces the values already present.'),
            exclude=('webui',),
        ),
        parameters.Str(
            'addattr',
            required=False,
            multivalue=True,
            doc=_(u'Add an attribute/value pair. Format is attr=value. The attribute\nmust be part of the schema.'),
            exclude=('webui',),
        ),
        parameters.Str(
            'delattr',
            required=False,
            multivalue=True,
            doc=_(u'Delete an attribute/value pair. The option will be evaluated\nlast, after all sets and adds.'),
            exclude=('webui',),
        ),
        parameters.Flag(
            'rights',
            label=_(u'Rights'),
            doc=_(u'Display the access rights of this entry (requires --all). See ipa man page for details.'),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
    )
    has_output = (
        output.Output(
            'summary',
            (unicode, type(None)),
            doc=_(u'User-friendly description of action performed'),
        ),
        output.Entry(
            'result',
        ),
        output.Output(
            'value',
            unicode,
            doc=_(u"The primary_key value of the entry, e.g. 'jdoe' for a user"),
        ),
    )


@register()
class sudorule_remove_allow_command(Method):
    __doc__ = _("Remove commands and sudo command groups affected by Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'sudocmd',
            required=False,
            multivalue=True,
            cli_name='sudocmds',
            label=_(u'member sudo command'),
            doc=_(u'comma-separated list of sudo commands to remove'),
            alwaysask=True,
        ),
        parameters.Str(
            'sudocmdgroup',
            required=False,
            multivalue=True,
            cli_name='sudocmdgroups',
            label=_(u'member sudo command group'),
            doc=_(u'comma-separated list of sudo command groups to remove'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be removed'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members removed'),
        ),
    )


@register()
class sudorule_remove_deny_command(Method):
    __doc__ = _("Remove commands and sudo command groups affected by Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'sudocmd',
            required=False,
            multivalue=True,
            cli_name='sudocmds',
            label=_(u'member sudo command'),
            doc=_(u'comma-separated list of sudo commands to remove'),
            alwaysask=True,
        ),
        parameters.Str(
            'sudocmdgroup',
            required=False,
            multivalue=True,
            cli_name='sudocmdgroups',
            label=_(u'member sudo command group'),
            doc=_(u'comma-separated list of sudo command groups to remove'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be removed'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members removed'),
        ),
    )


@register()
class sudorule_remove_host(Method):
    __doc__ = _("Remove hosts and hostgroups affected by Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'host',
            required=False,
            multivalue=True,
            cli_name='hosts',
            label=_(u'member host'),
            doc=_(u'comma-separated list of hosts to remove'),
            alwaysask=True,
        ),
        parameters.Str(
            'hostgroup',
            required=False,
            multivalue=True,
            cli_name='hostgroups',
            label=_(u'member host group'),
            doc=_(u'comma-separated list of host groups to remove'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be removed'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members removed'),
        ),
    )


@register()
class sudorule_remove_option(Method):
    __doc__ = _("Remove an option from Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Str(
            'ipasudoopt',
            cli_name='sudooption',
            label=_(u'Sudo Option'),
        ),
    )
    has_output = (
        output.Output(
            'result',
        ),
    )


@register()
class sudorule_remove_runasgroup(Method):
    __doc__ = _("Remove group for Sudo to execute as.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'group',
            required=False,
            multivalue=True,
            cli_name='groups',
            label=_(u'member group'),
            doc=_(u'comma-separated list of groups to remove'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be removed'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members removed'),
        ),
    )


@register()
class sudorule_remove_runasuser(Method):
    __doc__ = _("Remove users and groups for Sudo to execute as.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'user',
            required=False,
            multivalue=True,
            cli_name='users',
            label=_(u'member user'),
            doc=_(u'comma-separated list of users to remove'),
            alwaysask=True,
        ),
        parameters.Str(
            'group',
            required=False,
            multivalue=True,
            cli_name='groups',
            label=_(u'member group'),
            doc=_(u'comma-separated list of groups to remove'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be removed'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members removed'),
        ),
    )


@register()
class sudorule_remove_user(Method):
    __doc__ = _("Remove users and groups affected by Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Str(
            'user',
            required=False,
            multivalue=True,
            cli_name='users',
            label=_(u'member user'),
            doc=_(u'comma-separated list of users to remove'),
            alwaysask=True,
        ),
        parameters.Str(
            'group',
            required=False,
            multivalue=True,
            cli_name='groups',
            label=_(u'member group'),
            doc=_(u'comma-separated list of groups to remove'),
            alwaysask=True,
        ),
    )
    has_output = (
        output.Entry(
            'result',
        ),
        output.Output(
            'failed',
            dict,
            doc=_(u'Members that could not be removed'),
        ),
        output.Output(
            'completed',
            int,
            doc=_(u'Number of members removed'),
        ),
    )


@register()
class sudorule_show(Method):
    __doc__ = _("Display Sudo Rule.")

    takes_args = (
        parameters.Str(
            'cn',
            cli_name='sudorule_name',
            label=_(u'Rule name'),
        ),
    )
    takes_options = (
        parameters.Flag(
            'rights',
            label=_(u'Rights'),
            doc=_(u'Display the access rights of this entry (requires --all). See ipa man page for details.'),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'all',
            doc=_(u'Retrieve and print all attributes from the server. Affects command output.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
        parameters.Flag(
            'raw',
            doc=_(u'Print entries as stored on the server. Only affects output format.'),
            exclude=('webui',),
            default=False,
            autofill=True,
        ),
    )
    has_output = (
        output.Output(
            'summary',
            (unicode, type(None)),
            doc=_(u'User-friendly description of action performed'),
        ),
        output.Entry(
            'result',
        ),
        output.Output(
            'value',
            unicode,
            doc=_(u"The primary_key value of the entry, e.g. 'jdoe' for a user"),
        ),
    )
