user: PEP8 compliancy and doc fixes (#30895)

This PR includes:
- PEP8 compliancy fixes
- Documentation fixes
This commit is contained in:
Dag Wieers 2017-10-30 01:06:37 +01:00 committed by GitHub
commit 86bb82a220
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 143 additions and 184 deletions

View file

@ -1,22 +1,21 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# (c) 2012, Stephen Fromm <sfromm@gmail.com> # Copyright: (c) 2012, Stephen Fromm <sfromm@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['stableinterface'], 'status': ['stableinterface'],
'supported_by': 'core'} 'supported_by': 'core'}
DOCUMENTATION = ''' DOCUMENTATION = '''
--- ---
module: user module: user
author: "Stephen Fromm (@sfromm)" author:
- Stephen Fromm (@sfromm)
version_added: "0.2" version_added: "0.2"
short_description: Manage user accounts short_description: Manage user accounts
notes: notes:
@ -29,67 +28,56 @@ description:
- For Windows targets, use the M(win_user) module instead. - For Windows targets, use the M(win_user) module instead.
options: options:
name: name:
required: true
aliases: [ "user" ]
description: description:
- Name of the user to create, remove or modify. - Name of the user to create, remove or modify.
required: true
aliases: [ user ]
comment: comment:
required: false
description: description:
- Optionally sets the description (aka I(GECOS)) of user account. - Optionally sets the description (aka I(GECOS)) of user account.
uid: uid:
required: false
description: description:
- Optionally sets the I(UID) of the user. - Optionally sets the I(UID) of the user.
non_unique: non_unique:
required: false
default: "no"
choices: [ "yes", "no" ]
description: description:
- Optionally when used with the -u option, this option allows to - Optionally when used with the -u option, this option allows to
change the user ID to a non-unique value. change the user ID to a non-unique value.
type: bool
default: "no"
version_added: "1.1" version_added: "1.1"
seuser: seuser:
required: false
description: description:
- Optionally sets the seuser type (user_u) on selinux enabled systems. - Optionally sets the seuser type (user_u) on selinux enabled systems.
version_added: "2.1" version_added: "2.1"
group: group:
required: false
description: description:
- Optionally sets the user's primary group (takes a group name). - Optionally sets the user's primary group (takes a group name).
groups: groups:
required: false
description: description:
- Puts the user in list of groups. When set to the empty string ('groups='), - Puts the user in list of groups. When set to the empty string ('groups='),
the user is removed from all groups except the primary group. the user is removed from all groups except the primary group.
- Before version 2.3, the only input format allowed was a 'comma separated string', - Before version 2.3, the only input format allowed was a 'comma separated string',
now it should be able to accept YAML lists also. now it should be able to accept YAML lists also.
append: append:
required: false
default: "no"
choices: [ "yes", "no" ]
description: description:
- If C(yes), will only add groups, not set them to just the list - If C(yes), will only add groups, not set them to just the list
in I(groups). in I(groups).
type: bool
default: "no"
shell: shell:
required: false
description: description:
- Optionally set the user's shell. - Optionally set the user's shell.
- On Mac OS X, before version 2.5, the default shell for non-system users was - On Mac OS X, before version 2.5, the default shell for non-system users was
/usr/bin/false. Since 2.5, the default shell for non-system users on /usr/bin/false. Since 2.5, the default shell for non-system users on
Mac OS X is /bin/bash. Mac OS X is /bin/bash.
home: home:
required: false
description: description:
- Optionally set the user's home directory. - Optionally set the user's home directory.
skeleton: skeleton:
required: false
description: description:
- Optionally set a home skeleton directory. Requires create_home option! - Optionally set a home skeleton directory. Requires create_home option!
version_added: "2.0" version_added: "2.0"
password: password:
required: false
description: description:
- Optionally set the user's password to this crypted value. See - Optionally set the user's password to this crypted value. See
the user example in the github examples directory for what this looks the user example in the github examples directory for what this looks
@ -98,172 +86,157 @@ options:
Note on Darwin system, this value has to be cleartext. Note on Darwin system, this value has to be cleartext.
Beware of security issues. Beware of security issues.
state: state:
required: false
default: "present"
choices: [ present, absent ]
description: description:
- Whether the account should exist or not, taking action if the state is different from what is stated. - Whether the account should exist or not, taking action if the state is different from what is stated.
choices: [ absent, present ]
default: present
create_home: create_home:
description: description:
- Unless set to C(no), a home directory will be made for the user - Unless set to C(no), a home directory will be made for the user
when the account is created or if the home directory does not when the account is created or if the home directory does not
exist. exist.
- Changed from C(createhome) to C(create_home) in version 2.5. - Changed from C(createhome) to C(create_home) in version 2.5.
default: yes
type: bool type: bool
default: 'yes'
aliases: ['createhome'] aliases: ['createhome']
move_home: move_home:
required: false
default: "no"
choices: [ "yes", "no" ]
description: description:
- If set to C(yes) when used with C(home=), attempt to move the - If set to C(yes) when used with C(home=), attempt to move the
user's home directory to the specified directory if it isn't there user's home directory to the specified directory if it isn't there
already. already.
system: type: bool
required: false
default: "no" default: "no"
choices: [ "yes", "no" ] system:
description: description:
- When creating an account, setting this to C(yes) makes the user a - When creating an account, setting this to C(yes) makes the user a
system account. This setting cannot be changed on existing users. system account. This setting cannot be changed on existing users.
force: type: bool
required: false
default: "no" default: "no"
choices: [ "yes", "no" ] force:
description: description:
- When used with C(state=absent), behavior is as with - When used with C(state=absent), behavior is as with C(userdel --force).
C(userdel --force). type: bool
default: "no"
login_class: login_class:
required: false
description: description:
- Optionally sets the user's login class for FreeBSD, OpenBSD and NetBSD systems. - Optionally sets the user's login class for FreeBSD, OpenBSD and NetBSD systems.
remove: remove:
required: false
default: "no"
choices: [ "yes", "no" ]
description: description:
- When used with C(state=absent), behavior is as with - When used with C(state=absent), behavior is as with C(userdel --remove).
C(userdel --remove). type: bool
generate_ssh_key:
required: false
default: "no" default: "no"
choices: [ "yes", "no" ] generate_ssh_key:
version_added: "0.9"
description: description:
- Whether to generate a SSH key for the user in question. - Whether to generate a SSH key for the user in question.
This will B(not) overwrite an existing SSH key. This will B(not) overwrite an existing SSH key.
ssh_key_bits: type: bool
required: false default: "no"
default: default set by ssh-keygen
version_added: "0.9" version_added: "0.9"
ssh_key_bits:
description: description:
- Optionally specify number of bits in SSH key to create. - Optionally specify number of bits in SSH key to create.
ssh_key_type: default: default set by ssh-keygen
required: false
default: rsa
version_added: "0.9" version_added: "0.9"
ssh_key_type:
description: description:
- Optionally specify the type of SSH key to generate. - Optionally specify the type of SSH key to generate.
Available SSH key types will depend on implementation Available SSH key types will depend on implementation
present on target host. present on target host.
ssh_key_file: default: rsa
required: false
default: .ssh/id_rsa
version_added: "0.9" version_added: "0.9"
ssh_key_file:
description: description:
- Optionally specify the SSH key filename. If this is a relative - Optionally specify the SSH key filename. If this is a relative
filename then it will be relative to the user's home directory. filename then it will be relative to the user's home directory.
ssh_key_comment: default: .ssh/id_rsa
required: false
default: ansible-generated on $HOSTNAME
version_added: "0.9" version_added: "0.9"
ssh_key_comment:
description: description:
- Optionally define the comment for the SSH key. - Optionally define the comment for the SSH key.
ssh_key_passphrase: default: ansible-generated on $HOSTNAME
required: false
version_added: "0.9" version_added: "0.9"
ssh_key_passphrase:
description: description:
- Set a passphrase for the SSH key. If no - Set a passphrase for the SSH key. If no
passphrase is provided, the SSH key will default to passphrase is provided, the SSH key will default to
having no passphrase. having no passphrase.
version_added: "0.9"
update_password: update_password:
required: false
default: always
choices: ['always', 'on_create']
version_added: "1.3"
description: description:
- C(always) will update passwords if they differ. C(on_create) will only set the password for newly created users. - C(always) will update passwords if they differ. C(on_create) will only set the password for newly created users.
choices: [ always, on_create ]
default: always
version_added: "1.3"
expires: expires:
version_added: "1.9"
required: false
default: "None"
description: description:
- An expiry time for the user in epoch, it will be ignored on platforms that do not support this. - An expiry time for the user in epoch, it will be ignored on platforms that do not support this.
Currently supported on Linux and FreeBSD. Currently supported on Linux and FreeBSD.
version_added: "1.9"
local: local:
version_added: "2.4"
required: false
default: "False"
description: description:
- Forces the use of "local" command alternatives on platforms that implement it. - Forces the use of "local" command alternatives on platforms that implement it.
This is useful in environments that use centralized authentification when you want to manipulate the local users. This is useful in environments that use centralized authentification when you want to manipulate the local users.
I.E. it uses `luseradd` instead of `useradd`. I.E. it uses `luseradd` instead of `useradd`.
- This requires that these commands exist on the targeted host, otherwise it will be a fatal error. - This requires that these commands exist on the targeted host, otherwise it will be a fatal error.
type: bool
default: 'no'
version_added: "2.4"
''' '''
EXAMPLES = ''' EXAMPLES = '''
# Add the user 'johnd' with a specific uid and a primary group of 'admin' - name: Add the user 'johnd' with a specific uid and a primary group of 'admin'
- user: user:
name: johnd name: johnd
comment: "John Doe" comment: John Doe
uid: 1040 uid: 1040
group: admin group: admin
# Add the user 'james' with a bash shell, appending the group 'admins' and 'developers' to the user's groups - name: Add the user 'james' with a bash shell, appending the group 'admins' and 'developers' to the user's groups
- user: user:
name: james name: james
shell: /bin/bash shell: /bin/bash
groups: admins,developers groups: admins,developers
append: yes append: yes
# Remove the user 'johnd' - name: Remove the user 'johnd'
- user: user:
name: johnd name: johnd
state: absent state: absent
remove: yes remove: yes
# Create a 2048-bit SSH key for user jsmith in ~jsmith/.ssh/id_rsa - name: Create a 2048-bit SSH key for user jsmith in ~jsmith/.ssh/id_rsa
- user: user:
name: jsmith name: jsmith
generate_ssh_key: yes generate_ssh_key: yes
ssh_key_bits: 2048 ssh_key_bits: 2048
ssh_key_file: .ssh/id_rsa ssh_key_file: .ssh/id_rsa
# added a consultant whose account you want to expire - name: Added a consultant whose account you want to expire
- user: user:
name: james18 name: james18
shell: /bin/zsh shell: /bin/zsh
groups: developers groups: developers
expires: 1422403387 expires: 1422403387
''' '''
import os
import pwd
import grp import grp
import os
import platform import platform
import pwd
import shutil
import socket import socket
import time import time
import shutil
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
from ansible.module_utils.basic import load_platform_subclass, AnsibleModule from ansible.module_utils.basic import load_platform_subclass, AnsibleModule
from ansible.module_utils.pycompat24 import get_exception from ansible.module_utils.pycompat24 import get_exception
try: try:
import spwd import spwd
HAVE_SPWD=True HAVE_SPWD = True
except: except:
HAVE_SPWD=False HAVE_SPWD = False
class User(object): class User(object):
""" """
@ -290,31 +263,31 @@ class User(object):
return load_platform_subclass(User, args, kwargs) return load_platform_subclass(User, args, kwargs)
def __init__(self, module): def __init__(self, module):
self.module = module self.module = module
self.state = module.params['state'] self.state = module.params['state']
self.name = module.params['name'] self.name = module.params['name']
self.uid = module.params['uid'] self.uid = module.params['uid']
self.non_unique = module.params['non_unique'] self.non_unique = module.params['non_unique']
self.seuser = module.params['seuser'] self.seuser = module.params['seuser']
self.group = module.params['group'] self.group = module.params['group']
self.comment = module.params['comment'] self.comment = module.params['comment']
self.shell = module.params['shell'] self.shell = module.params['shell']
self.password = module.params['password'] self.password = module.params['password']
self.force = module.params['force'] self.force = module.params['force']
self.remove = module.params['remove'] self.remove = module.params['remove']
self.create_home = module.params['create_home'] self.create_home = module.params['create_home']
self.move_home = module.params['move_home'] self.move_home = module.params['move_home']
self.skeleton = module.params['skeleton'] self.skeleton = module.params['skeleton']
self.system = module.params['system'] self.system = module.params['system']
self.login_class = module.params['login_class'] self.login_class = module.params['login_class']
self.append = module.params['append'] self.append = module.params['append']
self.sshkeygen = module.params['generate_ssh_key'] self.sshkeygen = module.params['generate_ssh_key']
self.ssh_bits = module.params['ssh_key_bits'] self.ssh_bits = module.params['ssh_key_bits']
self.ssh_type = module.params['ssh_key_type'] self.ssh_type = module.params['ssh_key_type']
self.ssh_comment = module.params['ssh_key_comment'] self.ssh_comment = module.params['ssh_key_comment']
self.ssh_passphrase = module.params['ssh_key_passphrase'] self.ssh_passphrase = module.params['ssh_key_passphrase']
self.update_password = module.params['update_password'] self.update_password = module.params['update_password']
self.home = module.params['home'] self.home = module.params['home']
self.expires = None self.expires = None
self.groups = None self.groups = None
self.local = module.params['local'] self.local = module.params['local']
@ -327,18 +300,17 @@ class User(object):
self.expires = time.gmtime(module.params['expires']) self.expires = time.gmtime(module.params['expires'])
except Exception: except Exception:
e = get_exception() e = get_exception()
module.fail_json(msg="Invalid expires time %s: %s" %(self.expires, str(e))) module.fail_json(msg="Invalid expires time %s: %s" % (self.expires, e))
if module.params['ssh_key_file'] is not None: if module.params['ssh_key_file'] is not None:
self.ssh_file = module.params['ssh_key_file'] self.ssh_file = module.params['ssh_key_file']
else: else:
self.ssh_file = os.path.join('.ssh', 'id_%s' % self.ssh_type) self.ssh_file = os.path.join('.ssh', 'id_%s' % self.ssh_type)
def execute_command(self, cmd, use_unsafe_shell=False, data=None, obey_checkmode=True): def execute_command(self, cmd, use_unsafe_shell=False, data=None, obey_checkmode=True):
if self.module.check_mode and obey_checkmode: if self.module.check_mode and obey_checkmode:
self.module.debug('In check mode, would have run: "%s"' % cmd) self.module.debug('In check mode, would have run: "%s"' % cmd)
return (0, '','') return (0, '', '')
else: else:
# cast all args to strings ansible-modules-core/issues/4397 # cast all args to strings ansible-modules-core/issues/4397
cmd = [str(x) for x in cmd] cmd = [str(x) for x in cmd]
@ -438,7 +410,6 @@ class User(object):
cmd.append(self.name) cmd.append(self.name)
return self.execute_command(cmd) return self.execute_command(cmd)
def _check_usermod_append(self): def _check_usermod_append(self):
# check if this version of usermod can append groups # check if this version of usermod can append groups
@ -466,8 +437,6 @@ class User(object):
return False return False
def modify_user_usermod(self): def modify_user_usermod(self):
if self.local: if self.local:
@ -555,7 +524,7 @@ class User(object):
cmd.append(self.name) cmd.append(self.name)
return self.execute_command(cmd) return self.execute_command(cmd)
def group_exists(self,group): def group_exists(self, group):
try: try:
# Try group as a gid first # Try group as a gid first
grp.getgrgid(int(group)) grp.getgrgid(int(group))
@ -693,7 +662,7 @@ class User(object):
ssh_key_file = self.get_ssh_key_path() ssh_key_file = self.get_ssh_key_path()
if not os.path.exists(ssh_key_file): if not os.path.exists(ssh_key_file):
return (1, 'SSH Key file %s does not exist' % ssh_key_file, '') return (1, 'SSH Key file %s does not exist' % ssh_key_file, '')
cmd = [ self.module.get_bin_path('ssh-keygen', True) ] cmd = [self.module.get_bin_path('ssh-keygen', True)]
cmd.append('-l') cmd.append('-l')
cmd.append('-f') cmd.append('-f')
cmd.append(ssh_key_file) cmd.append(ssh_key_file)
@ -835,7 +804,7 @@ class FreeBsdUser(User):
cmd.append(self.login_class) cmd.append(self.login_class)
if self.expires: if self.expires:
days =( time.mktime(self.expires) - time.time() ) // 86400 days = (time.mktime(self.expires) - time.time()) // 86400
cmd.append('-e') cmd.append('-e')
cmd.append(str(int(days))) cmd.append(str(int(days)))
@ -933,7 +902,7 @@ class FreeBsdUser(User):
cmd.append(','.join(new_groups)) cmd.append(','.join(new_groups))
if self.expires: if self.expires:
days = ( time.mktime(self.expires) - time.time() ) // 86400 days = (time.mktime(self.expires) - time.time()) // 86400
cmd.append('-e') cmd.append('-e')
cmd.append(str(int(days))) cmd.append(str(int(days)))
@ -957,7 +926,6 @@ class FreeBsdUser(User):
return (rc, out, err) return (rc, out, err)
# ===========================================
class OpenBSDUser(User): class OpenBSDUser(User):
""" """
@ -1502,7 +1470,7 @@ class SunOS(User):
return (rc, out, err) return (rc, out, err)
# ===========================================
class DarwinUser(User): class DarwinUser(User):
""" """
This is a Darwin Mac OS X User manipulation class. This is a Darwin Mac OS X User manipulation class.
@ -1535,11 +1503,11 @@ class DarwinUser(User):
] ]
def _get_dscl(self): def _get_dscl(self):
return [ self.module.get_bin_path('dscl', True), self.dscl_directory ] return [self.module.get_bin_path('dscl', True), self.dscl_directory]
def _list_user_groups(self): def _list_user_groups(self):
cmd = self._get_dscl() cmd = self._get_dscl()
cmd += [ '-search', '/Groups', 'GroupMembership', self.name ] cmd += ['-search', '/Groups', 'GroupMembership', self.name]
(rc, out, err) = self.execute_command(cmd, obey_checkmode=False) (rc, out, err) = self.execute_command(cmd, obey_checkmode=False)
groups = [] groups = []
for line in out.splitlines(): for line in out.splitlines():
@ -1551,7 +1519,7 @@ class DarwinUser(User):
def _get_user_property(self, property): def _get_user_property(self, property):
'''Return user PROPERTY as given my dscl(1) read or None if not found.''' '''Return user PROPERTY as given my dscl(1) read or None if not found.'''
cmd = self._get_dscl() cmd = self._get_dscl()
cmd += [ '-read', '/Users/%s' % self.name, property ] cmd += ['-read', '/Users/%s' % self.name, property]
(rc, out, err) = self.execute_command(cmd, obey_checkmode=False) (rc, out, err) = self.execute_command(cmd, obey_checkmode=False)
if rc != 0: if rc != 0:
return None return None
@ -1559,12 +1527,12 @@ class DarwinUser(User):
# if property contains embedded spaces, the list will instead be # if property contains embedded spaces, the list will instead be
# displayed one entry per line, starting on the line after the key. # displayed one entry per line, starting on the line after the key.
lines = out.splitlines() lines = out.splitlines()
#sys.stderr.write('*** |%s| %s -> %s\n' % (property, out, lines)) # sys.stderr.write('*** |%s| %s -> %s\n' % (property, out, lines))
if len(lines) == 1: if len(lines) == 1:
return lines[0].split(': ')[1] return lines[0].split(': ')[1]
else: else:
if len(lines) > 2: if len(lines) > 2:
return '\n'.join([ lines[1].strip() ] + lines[2:]) return '\n'.join([lines[1].strip()] + lines[2:])
else: else:
if len(lines) == 2: if len(lines) == 2:
return lines[1].strip() return lines[1].strip()
@ -1614,9 +1582,9 @@ class DarwinUser(User):
# https://gist.github.com/nueh/8252572 # https://gist.github.com/nueh/8252572
cmd = self._get_dscl() cmd = self._get_dscl()
if self.password: if self.password:
cmd += [ '-passwd', '/Users/%s' % self.name, self.password] cmd += ['-passwd', '/Users/%s' % self.name, self.password]
else: else:
cmd += [ '-create', '/Users/%s' % self.name, 'Password', '*'] cmd += ['-create', '/Users/%s' % self.name, 'Password', '*']
(rc, out, err) = self.execute_command(cmd) (rc, out, err) = self.execute_command(cmd)
if rc != 0: if rc != 0:
self.module.fail_json(msg='Error when changing password', err=err, out=out, rc=rc) self.module.fail_json(msg='Error when changing password', err=err, out=out, rc=rc)
@ -1640,7 +1608,7 @@ class DarwinUser(User):
option = '-a' option = '-a'
else: else:
option = '-d' option = '-d'
cmd = [ 'dseditgroup', '-o', 'edit', option, self.name, '-t', 'user', group ] cmd = ['dseditgroup', '-o', 'edit', option, self.name, '-t', 'user', group]
(rc, out, err) = self.execute_command(cmd) (rc, out, err) = self.execute_command(cmd)
if rc != 0: if rc != 0:
self.module.fail_json(msg='Cannot %s user "%s" to group "%s".' self.module.fail_json(msg='Cannot %s user "%s" to group "%s".'
@ -1687,7 +1655,7 @@ class DarwinUser(User):
plist_file = '/Library/Preferences/com.apple.loginwindow.plist' plist_file = '/Library/Preferences/com.apple.loginwindow.plist'
# http://support.apple.com/kb/HT5017?viewlocale=en_US # http://support.apple.com/kb/HT5017?viewlocale=en_US
cmd = [ 'defaults', 'read', plist_file, 'HiddenUsersList' ] cmd = ['defaults', 'read', plist_file, 'HiddenUsersList']
(rc, out, err) = self.execute_command(cmd, obey_checkmode=False) (rc, out, err) = self.execute_command(cmd, obey_checkmode=False)
# returned value is # returned value is
# ( # (
@ -1704,27 +1672,26 @@ class DarwinUser(User):
hidden_users.append(x) hidden_users.append(x)
if self.system: if self.system:
if not self.name in hidden_users: if self.name not in hidden_users:
cmd = [ 'defaults', 'write', plist_file, cmd = ['defaults', 'write', plist_file, 'HiddenUsersList', '-array-add', self.name]
'HiddenUsersList', '-array-add', self.name ]
(rc, out, err) = self.execute_command(cmd) (rc, out, err) = self.execute_command(cmd)
if rc != 0: if rc != 0:
self.module.fail_json( msg='Cannot user "%s" to hidden user list.' % self.name, err=err, out=out, rc=rc) self.module.fail_json(msg='Cannot user "%s" to hidden user list.' % self.name, err=err, out=out, rc=rc)
return 0 return 0
else: else:
if self.name in hidden_users: if self.name in hidden_users:
del(hidden_users[hidden_users.index(self.name)]) del(hidden_users[hidden_users.index(self.name)])
cmd = [ 'defaults', 'write', plist_file, 'HiddenUsersList', '-array' ] + hidden_users cmd = ['defaults', 'write', plist_file, 'HiddenUsersList', '-array'] + hidden_users
(rc, out, err) = self.execute_command(cmd) (rc, out, err) = self.execute_command(cmd)
if rc != 0: if rc != 0:
self.module.fail_json( msg='Cannot remove user "%s" from hidden user list.' % self.name, err=err, out=out, rc=rc) self.module.fail_json(msg='Cannot remove user "%s" from hidden user list.' % self.name, err=err, out=out, rc=rc)
return 0 return 0
def user_exists(self): def user_exists(self):
'''Check is SELF.NAME is a known user on the system.''' '''Check is SELF.NAME is a known user on the system.'''
cmd = self._get_dscl() cmd = self._get_dscl()
cmd += [ '-list', '/Users/%s' % self.name] cmd += ['-list', '/Users/%s' % self.name]
(rc, out, err) = self.execute_command(cmd, obey_checkmode=False) (rc, out, err) = self.execute_command(cmd, obey_checkmode=False)
return rc == 0 return rc == 0
@ -1733,11 +1700,11 @@ class DarwinUser(User):
info = self.user_info() info = self.user_info()
cmd = self._get_dscl() cmd = self._get_dscl()
cmd += [ '-delete', '/Users/%s' % self.name] cmd += ['-delete', '/Users/%s' % self.name]
(rc, out, err) = self.execute_command(cmd) (rc, out, err) = self.execute_command(cmd)
if rc != 0: if rc != 0:
self.module.fail_json( msg='Cannot delete user "%s".' % self.name, err=err, out=out, rc=rc) self.module.fail_json(msg='Cannot delete user "%s".' % self.name, err=err, out=out, rc=rc)
if self.force: if self.force:
if os.path.exists(info[5]): if os.path.exists(info[5]):
@ -1748,11 +1715,10 @@ class DarwinUser(User):
def create_user(self, command_name='dscl'): def create_user(self, command_name='dscl'):
cmd = self._get_dscl() cmd = self._get_dscl()
cmd += [ '-create', '/Users/%s' % self.name] cmd += ['-create', '/Users/%s' % self.name]
(rc, err, out) = self.execute_command(cmd) (rc, err, out) = self.execute_command(cmd)
if rc != 0: if rc != 0:
self.module.fail_json( msg='Cannot create user "%s".' % self.name, err=err, out=out, rc=rc) self.module.fail_json(msg='Cannot create user "%s".' % self.name, err=err, out=out, rc=rc)
self._make_group_numerical() self._make_group_numerical()
if self.uid is None: if self.uid is None:
@ -1776,18 +1742,16 @@ class DarwinUser(User):
if field[0] in self.__dict__ and self.__dict__[field[0]]: if field[0] in self.__dict__ and self.__dict__[field[0]]:
cmd = self._get_dscl() cmd = self._get_dscl()
cmd += [ '-create', '/Users/%s' % self.name, field[1], self.__dict__[field[0]]] cmd += ['-create', '/Users/%s' % self.name, field[1], self.__dict__[field[0]]]
(rc, _err, _out) = self.execute_command(cmd) (rc, _err, _out) = self.execute_command(cmd)
if rc != 0: if rc != 0:
self.module.fail_json( msg='Cannot add property "%s" to user "%s".' self.module.fail_json(msg='Cannot add property "%s" to user "%s".' % (field[0], self.name), err=err, out=out, rc=rc)
% (field[0], self.name), err=err, out=out, rc=rc)
out += _out out += _out
err += _err err += _err
if rc != 0: if rc != 0:
return (rc, _err, _out) return (rc, _err, _out)
(rc, _err, _out) = self._change_user_password() (rc, _err, _out) = self._change_user_password()
out += _out out += _out
err += _err err += _err
@ -1814,7 +1778,7 @@ class DarwinUser(User):
current = self._get_user_property(field[1]) current = self._get_user_property(field[1])
if current is None or current != self.__dict__[field[0]]: if current is None or current != self.__dict__[field[0]]:
cmd = self._get_dscl() cmd = self._get_dscl()
cmd += [ '-create', '/Users/%s' % self.name, field[1], self.__dict__[field[0]]] cmd += ['-create', '/Users/%s' % self.name, field[1], self.__dict__[field[0]]]
(rc, _err, _out) = self.execute_command(cmd) (rc, _err, _out) = self.execute_command(cmd)
if rc != 0: if rc != 0:
self.module.fail_json( self.module.fail_json(
@ -1843,7 +1807,6 @@ class DarwinUser(User):
return (changed, out, err) return (changed, out, err)
# ===========================================
class AIX(User): class AIX(User):
""" """
@ -1990,11 +1953,10 @@ class AIX(User):
(rc2, out2, err2) = (None, '', '') (rc2, out2, err2) = (None, '', '')
if rc is not None: if rc is not None:
return (rc, out+out2, err+err2) return (rc, out + out2, err + err2)
else: else:
return (rc2, out+out2, err+err2) return (rc2, out + out2, err + err2)
# ===========================================
class HPUX(User): class HPUX(User):
""" """
@ -2115,7 +2077,6 @@ class HPUX(User):
new_groups = groups | set(current_groups) new_groups = groups | set(current_groups)
cmd.append(','.join(new_groups)) cmd.append(','.join(new_groups))
if self.comment is not None and info[4] != self.comment: if self.comment is not None and info[4] != self.comment:
cmd.append('-c') cmd.append('-c')
cmd.append(self.comment) cmd.append(self.comment)
@ -2141,49 +2102,48 @@ class HPUX(User):
cmd.append(self.name) cmd.append(self.name)
return self.execute_command(cmd) return self.execute_command(cmd)
# ===========================================
def main(): def main():
ssh_defaults = { ssh_defaults = dict(
'bits': 0, bits=0,
'type': 'rsa', type='rsa',
'passphrase': None, passphrase=None,
'comment': 'ansible-generated on %s' % socket.gethostname() comment='ansible-generated on %s' % socket.gethostname()
} )
module = AnsibleModule( module = AnsibleModule(
argument_spec = dict( argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'], type='str'), state=dict(type='str', default='present', choices=['absent', 'present']),
name=dict(required=True, aliases=['user'], type='str'), name=dict(type='str', required=True, aliases=['user']),
uid=dict(default=None, type='str'), uid=dict(type='str'),
non_unique=dict(default='no', type='bool'), non_unique=dict(type='bool', default=False),
group=dict(default=None, type='str'), group=dict(type='str'),
groups=dict(default=None, type='list'), groups=dict(type='list'),
comment=dict(default=None, type='str'), comment=dict(type='str'),
home=dict(default=None, type='path'), home=dict(type='path'),
shell=dict(default=None, type='str'), shell=dict(type='str'),
password=dict(default=None, type='str', no_log=True), password=dict(type='str', no_log=True),
login_class=dict(default=None, type='str'), login_class=dict(type='str'),
# following options are specific to selinux # following options are specific to selinux
seuser=dict(default=None, type='str'), seuser=dict(type='str'),
# following options are specific to userdel # following options are specific to userdel
force=dict(default='no', type='bool'), force=dict(type='bool', default=False),
remove=dict(default='no', type='bool'), remove=dict(type='bool', default=False),
# following options are specific to useradd # following options are specific to useradd
create_home=dict(default='yes', aliases=['createhome'], type='bool'), create_home=dict(type='bool', default=True, aliases=['createhome']),
skeleton=dict(default=None, type='str'), skeleton=dict(type='str'),
system=dict(default='no', type='bool'), system=dict(type='bool', default=False),
# following options are specific to usermod # following options are specific to usermod
move_home=dict(default='no', type='bool'), move_home=dict(type='bool', default=False),
append=dict(default='no', type='bool'), append=dict(type='bool', default=False),
# following are specific to ssh key generation # following are specific to ssh key generation
generate_ssh_key=dict(type='bool'), generate_ssh_key=dict(type='bool'),
ssh_key_bits=dict(default=ssh_defaults['bits'], type='int'), ssh_key_bits=dict(type='int', default=ssh_defaults['bits']),
ssh_key_type=dict(default=ssh_defaults['type'], type='str'), ssh_key_type=dict(type='str', default=ssh_defaults['type']),
ssh_key_file=dict(default=None, type='path'), ssh_key_file=dict(type='path'),
ssh_key_comment=dict(default=ssh_defaults['comment'], type='str'), ssh_key_comment=dict(type='str', default=ssh_defaults['comment']),
ssh_key_passphrase=dict(default=None, type='str', no_log=True), ssh_key_passphrase=dict(type='str', no_log=True),
update_password=dict(default='always',choices=['always','on_create'],type='str'), update_password=dict(type='str', default='always', choices=['always', 'on_create']),
expires=dict(default=None, type='float'), expires=dict(type='float'),
local=dict(type='bool'), local=dict(type='bool'),
), ),
supports_check_mode=True supports_check_mode=True

View file

@ -362,5 +362,4 @@ lib/ansible/modules/system/solaris_zone.py
lib/ansible/modules/system/svc.py lib/ansible/modules/system/svc.py
lib/ansible/modules/system/timezone.py lib/ansible/modules/system/timezone.py
lib/ansible/modules/system/ufw.py lib/ansible/modules/system/ufw.py
lib/ansible/modules/system/user.py
lib/ansible/playbook/base.py lib/ansible/playbook/base.py