mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 00:55:19 +00:00
Merge pull request #40024 from rallytime/merge-develop
[develop] Merge forward from 2016.11 to develop
This commit is contained in:
commit
3de5280587
@ -4,3 +4,10 @@ Salt 2016.11.4 Release Notes
|
||||
|
||||
Version 2016.11.4 is a bugfix release for :ref:`2016.11.0 <release-2016-11-0>`.
|
||||
|
||||
|
||||
AIX Fixes
|
||||
=========
|
||||
|
||||
Added module execution support for user and group
|
||||
|
||||
|
||||
|
200
salt/modules/aix_group.py
Normal file
200
salt/modules/aix_group.py
Normal file
@ -0,0 +1,200 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Manage groups on Solaris
|
||||
|
||||
.. important::
|
||||
If you feel that Salt should be using this module to manage groups on a
|
||||
minion, and it is using a different module (or gives an error similar to
|
||||
*'group.info' is not available*), see :ref:`here
|
||||
<module-provider-override>`.
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import python libs
|
||||
import logging
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
try:
|
||||
import grp
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Define the module's virtual name
|
||||
__virtualname__ = 'group'
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Set the group module if the kernel is AIX
|
||||
'''
|
||||
if __grains__['kernel'] == 'AIX':
|
||||
return __virtualname__
|
||||
return (False, 'The aix_group execution module failed to load: '
|
||||
'only available on AIX systems.')
|
||||
|
||||
|
||||
def add(name, gid=None, system=False, root=None):
|
||||
'''
|
||||
Add the specified group
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.add foo 3456
|
||||
'''
|
||||
cmd = 'mkgroup '
|
||||
if system and root is not None:
|
||||
cmd += '-a '
|
||||
|
||||
if gid:
|
||||
cmd += 'id={0} '.format(gid)
|
||||
|
||||
cmd += name
|
||||
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
|
||||
return not ret['retcode']
|
||||
|
||||
|
||||
def delete(name):
|
||||
'''
|
||||
Remove the named group
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.delete foo
|
||||
'''
|
||||
ret = __salt__['cmd.run_all']('rmgroup {0}'.format(name), python_shell=False)
|
||||
|
||||
return not ret['retcode']
|
||||
|
||||
|
||||
def info(name):
|
||||
'''
|
||||
Return information about a group
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.info foo
|
||||
'''
|
||||
try:
|
||||
grinfo = grp.getgrnam(name)
|
||||
except KeyError:
|
||||
return {}
|
||||
else:
|
||||
return {'name': grinfo.gr_name,
|
||||
'passwd': grinfo.gr_passwd,
|
||||
'gid': grinfo.gr_gid,
|
||||
'members': grinfo.gr_mem}
|
||||
|
||||
|
||||
def getent(refresh=False):
|
||||
'''
|
||||
Return info on all groups
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.getent
|
||||
'''
|
||||
if 'group.getent' in __context__ and not refresh:
|
||||
return __context__['group.getent']
|
||||
|
||||
ret = []
|
||||
for grinfo in grp.getgrall():
|
||||
ret.append(info(grinfo.gr_name))
|
||||
|
||||
__context__['group.getent'] = ret
|
||||
return ret
|
||||
|
||||
|
||||
def chgid(name, gid):
|
||||
'''
|
||||
Change the gid for a named group
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.chgid foo 4376
|
||||
'''
|
||||
pre_gid = __salt__['file.group_to_gid'](name)
|
||||
if gid == pre_gid:
|
||||
return True
|
||||
cmd = 'chgroup id={0} {1}'.format(gid, name)
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_gid = __salt__['file.group_to_gid'](name)
|
||||
if post_gid != pre_gid:
|
||||
return post_gid == gid
|
||||
return False
|
||||
|
||||
|
||||
def adduser(name, username, root=None):
|
||||
'''
|
||||
Add a user in the group.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.adduser foo bar
|
||||
|
||||
Verifies if a valid username 'bar' as a member of an existing group 'foo',
|
||||
if not then adds it.
|
||||
'''
|
||||
cmd = 'chgrpmem -m + {0} {1}'.format(username, name)
|
||||
|
||||
retcode = __salt__['cmd.retcode'](cmd, python_shell=False)
|
||||
|
||||
return not retcode
|
||||
|
||||
|
||||
def deluser(name, username, root=None):
|
||||
'''
|
||||
Remove a user from the group.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.deluser foo bar
|
||||
|
||||
Removes a member user 'bar' from a group 'foo'. If group is not present
|
||||
then returns True.
|
||||
'''
|
||||
grp_info = __salt__['group.info'](name)
|
||||
try:
|
||||
if username in grp_info['members']:
|
||||
cmd = 'chgrpmem -m - {0} {1}'.format(username, name)
|
||||
ret = __salt__['cmd.run'](cmd, python_shell=False)
|
||||
return not ret['retcode']
|
||||
else:
|
||||
return True
|
||||
except Exception:
|
||||
return True
|
||||
|
||||
|
||||
def members(name, members_list, root=None):
|
||||
'''
|
||||
Replaces members of the group with a provided list.
|
||||
|
||||
CLI Example:
|
||||
|
||||
salt '*' group.members foo 'user1,user2,user3,...'
|
||||
|
||||
Replaces a membership list for a local group 'foo'.
|
||||
foo:x:1234:user1,user2,user3,...
|
||||
'''
|
||||
cmd = 'chgrpmem -m = {0} {1}'.format(members_list, name)
|
||||
retcode = __salt__['cmd.retcode'](cmd, python_shell=False)
|
||||
|
||||
return not retcode
|
@ -806,7 +806,8 @@ def _get_client(timeout=None):
|
||||
- docker.url: URL to the docker service
|
||||
- docker.version: API version to use (default: "auto")
|
||||
'''
|
||||
if 'docker.client' not in __context__:
|
||||
if 'docker.client' not in __context__ \
|
||||
or not hasattr(__context__['docker.client'], 'timeout'):
|
||||
client_kwargs = {}
|
||||
if timeout is not None:
|
||||
client_kwargs['timeout'] = timeout
|
||||
|
@ -15,6 +15,9 @@ Connection module for Amazon S3
|
||||
s3.keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||
s3.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||
|
||||
(Note: this is literally the pillar key 's3.keyid' or the config option 's3.keyid',
|
||||
not "s3:\\n keyid: blah".)
|
||||
|
||||
A service_url may also be specified in the configuration::
|
||||
|
||||
s3.service_url: s3.amazonaws.com
|
||||
@ -117,7 +120,7 @@ def delete(bucket, path=None, action=None, key=None, keyid=None,
|
||||
https_enable=https_enable)
|
||||
|
||||
|
||||
def get(bucket=None, path=None, return_bin=False, action=None,
|
||||
def get(bucket='', path='', return_bin=False, action=None,
|
||||
local_file=None, key=None, keyid=None, service_url=None,
|
||||
verify_ssl=None, kms_keyid=None, location=None, role_arn=None,
|
||||
path_style=None, https_enable=None):
|
||||
@ -201,7 +204,7 @@ def get(bucket=None, path=None, return_bin=False, action=None,
|
||||
https_enable=https_enable)
|
||||
|
||||
|
||||
def head(bucket, path=None, key=None, keyid=None, service_url=None,
|
||||
def head(bucket, path='', key=None, keyid=None, service_url=None,
|
||||
verify_ssl=None, kms_keyid=None, location=None, role_arn=None,
|
||||
path_style=None, https_enable=None):
|
||||
'''
|
||||
|
@ -141,10 +141,27 @@ def _get_zone_etc_timezone():
|
||||
)
|
||||
|
||||
|
||||
def _get_zone_aix():
|
||||
tzfile = '/etc/environment'
|
||||
with salt.utils.fopen(tzfile, 'r') as fp_:
|
||||
for line in fp_:
|
||||
if 'TZ=' in line:
|
||||
zonepart = line.rstrip('\n').split('=')[-1]
|
||||
return zonepart.strip('\'"') or 'UTC'
|
||||
raise CommandExecutionError('Unable to get timezone from ' + tzfile)
|
||||
|
||||
|
||||
def get_zone():
|
||||
'''
|
||||
Get current timezone (i.e. America/Denver)
|
||||
|
||||
.. versionchanged:: 2016.11.4
|
||||
|
||||
.. note::
|
||||
|
||||
On AIX operating systems, Posix values can also be returned
|
||||
'CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00'
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
@ -178,6 +195,8 @@ def get_zone():
|
||||
return _get_zone_etc_localtime()
|
||||
elif 'Solaris' in os_family:
|
||||
return _get_zone_solaris()
|
||||
elif 'AIX' in os_family:
|
||||
return _get_zone_aix()
|
||||
raise CommandExecutionError('Unable to get timezone')
|
||||
|
||||
|
||||
@ -204,8 +223,16 @@ def get_offset():
|
||||
|
||||
salt '*' timezone.get_offset
|
||||
'''
|
||||
if 'AIX' not in __grains__['os_family']:
|
||||
return __salt__['cmd.run'](['date', '+%z'], python_shell=False)
|
||||
|
||||
salt_path = '/opt/salt/bin/date'
|
||||
|
||||
if not os.path.exists(salt_path):
|
||||
return 'date in salt binaries does not exist: {0}'.format(salt_path)
|
||||
|
||||
return __salt__['cmd.run']([salt_path, '+%z'], python_shell=False)
|
||||
|
||||
|
||||
def set_zone(timezone):
|
||||
'''
|
||||
@ -221,6 +248,17 @@ def set_zone(timezone):
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' timezone.set_zone 'America/Denver'
|
||||
|
||||
.. versionchanged:: 2016.11.4
|
||||
|
||||
.. note::
|
||||
|
||||
On AIX operating systems, Posix values are also allowed, see below
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' timezone.set_zone 'CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00'
|
||||
|
||||
'''
|
||||
if salt.utils.which('timedatectl'):
|
||||
try:
|
||||
@ -228,11 +266,12 @@ def set_zone(timezone):
|
||||
except CommandExecutionError:
|
||||
pass
|
||||
|
||||
if 'Solaris' in __grains__['os_family']:
|
||||
if 'Solaris' in __grains__['os_family'] or 'AIX' in __grains__['os_family']:
|
||||
zonepath = '/usr/share/lib/zoneinfo/{0}'.format(timezone)
|
||||
else:
|
||||
zonepath = '/usr/share/zoneinfo/{0}'.format(timezone)
|
||||
if not os.path.exists(zonepath):
|
||||
|
||||
if not os.path.exists(zonepath) and 'AIX' not in __grains__['os_family']:
|
||||
return 'Zone does not exist: {0}'.format(zonepath)
|
||||
|
||||
if os.path.exists('/etc/localtime'):
|
||||
@ -241,6 +280,18 @@ def set_zone(timezone):
|
||||
if 'Solaris' in __grains__['os_family']:
|
||||
__salt__['file.sed'](
|
||||
'/etc/default/init', '^TZ=.*', 'TZ={0}'.format(timezone))
|
||||
elif 'AIX' in __grains__['os_family']:
|
||||
## timezone could be Olson or Posix
|
||||
curtzstring = get_zone()
|
||||
cmd = ['chtz', timezone]
|
||||
result = __salt__['cmd.retcode'](cmd, python_shell=False)
|
||||
if result == 0:
|
||||
return True
|
||||
|
||||
# restore orig timezone, since AIX chtz failure sets UTC
|
||||
cmd = ['chtz', curtzstring]
|
||||
__salt__['cmd.retcode'](cmd, python_shell=False)
|
||||
return False
|
||||
else:
|
||||
os.symlink(zonepath, '/etc/localtime')
|
||||
|
||||
@ -274,13 +325,19 @@ def zone_compare(timezone):
|
||||
|
||||
On Solaris-link operating systems only a string comparison is done.
|
||||
|
||||
.. versionchanged:: 2016.11.4
|
||||
|
||||
.. note::
|
||||
|
||||
On AIX operating systems only a string comparison is done.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' timezone.zone_compare 'America/Denver'
|
||||
'''
|
||||
if 'Solaris' in __grains__['os_family']:
|
||||
if 'Solaris' in __grains__['os_family'] or 'AIX' in __grains__['os_family']:
|
||||
return timezone == get_zone()
|
||||
|
||||
tzfile = _get_etc_localtime_path()
|
||||
@ -398,6 +455,23 @@ def get_hwclock():
|
||||
.format(offset_file, exc.strerror)
|
||||
)
|
||||
|
||||
if 'AIX' in __grains__['os_family']:
|
||||
offset_file = '/etc/environment'
|
||||
try:
|
||||
with salt.utils.fopen(offset_file, 'r') as fp_:
|
||||
for line in fp_:
|
||||
if line.startswith('TZ=UTC'):
|
||||
return 'UTC'
|
||||
return 'localtime'
|
||||
except IOError as exc:
|
||||
if exc.errno == errno.ENOENT:
|
||||
# offset file does not exist
|
||||
return 'UTC'
|
||||
raise CommandExecutionError(
|
||||
'Problem reading offset file {0}: {1}'
|
||||
.format(offset_file, exc.strerror)
|
||||
)
|
||||
|
||||
|
||||
def set_hwclock(clock):
|
||||
'''
|
||||
@ -409,6 +483,13 @@ def set_hwclock(clock):
|
||||
|
||||
salt '*' timezone.set_hwclock UTC
|
||||
'''
|
||||
if 'AIX' in __grains__['os_family']:
|
||||
if clock.lower() != 'utc':
|
||||
raise SaltInvocationError(
|
||||
'UTC is the only permitted value'
|
||||
)
|
||||
return True
|
||||
|
||||
timezone = get_zone()
|
||||
|
||||
if 'Solaris' in __grains__['os_family']:
|
||||
|
@ -33,12 +33,12 @@ __virtualname__ = 'user'
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Set the user module if the kernel is Linux, OpenBSD or NetBSD
|
||||
Set the user module if the kernel is Linux, OpenBSD, NetBSD or AIX
|
||||
'''
|
||||
|
||||
if HAS_PWD and __grains__['kernel'] in ('Linux', 'OpenBSD', 'NetBSD'):
|
||||
if HAS_PWD and __grains__['kernel'] in ('Linux', 'OpenBSD', 'NetBSD', 'AIX'):
|
||||
return __virtualname__
|
||||
return (False, 'useradd execution module not loaded: either pwd python library not available or system not one of Linux, OpenBSD or NetBSD')
|
||||
return (False, 'useradd execution module not loaded: either pwd python library not available or system not one of Linux, OpenBSD, NetBSD or AIX')
|
||||
|
||||
|
||||
def _quote_username(name):
|
||||
@ -94,7 +94,7 @@ def _update_gecos(name, key, value, root=None):
|
||||
|
||||
cmd = ['usermod', '-c', _build_gecos(gecos_data), name]
|
||||
|
||||
if root is not None:
|
||||
if root is not None and __grains__['kernel'] != 'AIX':
|
||||
cmd.extend(('-R', root))
|
||||
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
@ -181,7 +181,7 @@ def add(name,
|
||||
if home is not None:
|
||||
cmd.extend(['-d', home])
|
||||
|
||||
if not unique:
|
||||
if not unique and __grains__['kernel'] != 'AIX':
|
||||
cmd.append('-o')
|
||||
|
||||
if (system
|
||||
@ -195,7 +195,7 @@ def add(name,
|
||||
|
||||
cmd.append(name)
|
||||
|
||||
if root is not None:
|
||||
if root is not None and __grains__['kernel'] != 'AIX':
|
||||
cmd.extend(('-R', root))
|
||||
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
@ -239,12 +239,12 @@ def delete(name, remove=False, force=False, root=None):
|
||||
if remove:
|
||||
cmd.append('-r')
|
||||
|
||||
if force and __grains__['kernel'] != 'OpenBSD':
|
||||
if force and __grains__['kernel'] != 'OpenBSD' and __grains__['kernel'] != 'AIX':
|
||||
cmd.append('-f')
|
||||
|
||||
cmd.append(name)
|
||||
|
||||
if root is not None:
|
||||
if root is not None and __grains__['kernel'] != 'AIX':
|
||||
cmd.extend(('-R', root))
|
||||
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
@ -324,7 +324,7 @@ def chgid(name, gid, root=None):
|
||||
return True
|
||||
cmd = ['usermod', '-g', '{0}'.format(gid), name]
|
||||
|
||||
if root is not None:
|
||||
if root is not None and __grains__['kernel'] != 'AIX':
|
||||
cmd.extend(('-R', root))
|
||||
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
@ -346,7 +346,7 @@ def chshell(name, shell, root=None):
|
||||
return True
|
||||
cmd = ['usermod', '-s', shell, name]
|
||||
|
||||
if root is not None:
|
||||
if root is not None and __grains__['kernel'] != 'AIX':
|
||||
cmd.extend(('-R', root))
|
||||
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
@ -369,7 +369,7 @@ def chhome(name, home, persist=False, root=None):
|
||||
return True
|
||||
cmd = ['usermod', '-d', '{0}'.format(home)]
|
||||
|
||||
if root is not None:
|
||||
if root is not None and __grains__['kernel'] != 'AIX':
|
||||
cmd.extend(('-R', root))
|
||||
|
||||
if persist and __grains__['kernel'] != 'OpenBSD':
|
||||
@ -408,25 +408,27 @@ def chgroups(name, groups, append=False, root=None):
|
||||
cmd = ['usermod']
|
||||
|
||||
if __grains__['kernel'] != 'OpenBSD':
|
||||
if append:
|
||||
if append and __grains__['kernel'] != 'AIX':
|
||||
cmd.append('-a')
|
||||
cmd.append('-G')
|
||||
else:
|
||||
if append:
|
||||
cmd.append('-G')
|
||||
else:
|
||||
cmd.append('-S')
|
||||
|
||||
if __grains__['kernel'] != 'OpenBSD':
|
||||
cmd.append('-G')
|
||||
if append and __grains__['kernel'] == 'AIX':
|
||||
cmd.extend([','.join(ugrps) + ',' + ','.join(groups), name])
|
||||
else:
|
||||
cmd.extend([','.join(groups), name])
|
||||
|
||||
if root is not None:
|
||||
if root is not None and __grains__['kernel'] != 'AIX':
|
||||
cmd.extend(('-R', root))
|
||||
|
||||
result = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
# try to fallback on gpasswd to add user to localgroups
|
||||
# for old lib-pamldap support
|
||||
if __grains__['kernel'] != 'OpenBSD':
|
||||
if __grains__['kernel'] != 'OpenBSD' and __grains__['kernel'] != 'AIX':
|
||||
if result['retcode'] != 0 and 'not found in' in result['stderr']:
|
||||
ret = True
|
||||
for group in groups:
|
||||
@ -652,7 +654,7 @@ def rename(name, new_name, root=None):
|
||||
|
||||
cmd = ['usermod', '-l', '{0}'.format(new_name), '{0}'.format(name)]
|
||||
|
||||
if root is not None:
|
||||
if root is not None and __grains__['kernel'] != 'AIX':
|
||||
cmd.extend(('-R', root))
|
||||
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
|
@ -1516,7 +1516,20 @@ def managed(name,
|
||||
Debian file type ``*.dsc`` files are also supported.
|
||||
|
||||
**Inserting the Source Hash in the SLS Data**
|
||||
Examples:
|
||||
|
||||
The source_hash can be specified as a simple checksum, like so:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
tomdroid-src-0.7.3.tar.gz:
|
||||
file.managed:
|
||||
- name: /tmp/tomdroid-src-0.7.3.tar.gz
|
||||
- source: https://launchpad.net/tomdroid/beta/0.7.3/+download/tomdroid-src-0.7.3.tar.gz
|
||||
- source_hash: 79eef25f9b0b2c642c62b7f737d4f53f
|
||||
|
||||
.. note::
|
||||
Releases prior to 2016.11.0 must also include the hash type, like
|
||||
in the below example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
@ -1526,7 +1539,6 @@ def managed(name,
|
||||
- source: https://launchpad.net/tomdroid/beta/0.7.3/+download/tomdroid-src-0.7.3.tar.gz
|
||||
- source_hash: md5=79eef25f9b0b2c642c62b7f737d4f53f
|
||||
|
||||
|
||||
Known issues:
|
||||
If the remote server URL has the hash file as an apparent
|
||||
sub-directory of the source file, the module will discover that it
|
||||
|
Loading…
Reference in New Issue
Block a user