Merge branch '2016.11' into '2017.7'

Conflicts:
  - salt/modules/win_pkg.py
This commit is contained in:
rallytime 2017-08-10 14:51:27 -04:00
commit 08bbcf5790
11 changed files with 137 additions and 59 deletions

View File

@ -110,7 +110,7 @@ To pass through a file that contains jinja + yaml templating (the default):
method='POST', method='POST',
data_file='/srv/salt/somefile.jinja', data_file='/srv/salt/somefile.jinja',
data_render=True, data_render=True,
template_data={'key1': 'value1', 'key2': 'value2'} template_dict={'key1': 'value1', 'key2': 'value2'}
) )
To pass through a file that contains mako templating: To pass through a file that contains mako templating:
@ -123,7 +123,7 @@ To pass through a file that contains mako templating:
data_file='/srv/salt/somefile.mako', data_file='/srv/salt/somefile.mako',
data_render=True, data_render=True,
data_renderer='mako', data_renderer='mako',
template_data={'key1': 'value1', 'key2': 'value2'} template_dict={'key1': 'value1', 'key2': 'value2'}
) )
Because this function uses Salt's own rendering system, any Salt renderer can Because this function uses Salt's own rendering system, any Salt renderer can
@ -140,7 +140,7 @@ However, this can be changed to ``master`` if necessary.
method='POST', method='POST',
data_file='/srv/salt/somefile.jinja', data_file='/srv/salt/somefile.jinja',
data_render=True, data_render=True,
template_data={'key1': 'value1', 'key2': 'value2'}, template_dict={'key1': 'value1', 'key2': 'value2'},
opts=__opts__ opts=__opts__
) )
@ -149,7 +149,7 @@ However, this can be changed to ``master`` if necessary.
method='POST', method='POST',
data_file='/srv/salt/somefile.jinja', data_file='/srv/salt/somefile.jinja',
data_render=True, data_render=True,
template_data={'key1': 'value1', 'key2': 'value2'}, template_dict={'key1': 'value1', 'key2': 'value2'},
node='master' node='master'
) )
@ -170,11 +170,11 @@ a Python dict.
header_file='/srv/salt/headers.jinja', header_file='/srv/salt/headers.jinja',
header_render=True, header_render=True,
header_renderer='jinja', header_renderer='jinja',
template_data={'key1': 'value1', 'key2': 'value2'} template_dict={'key1': 'value1', 'key2': 'value2'}
) )
Because much of the data that would be templated between headers and data may be Because much of the data that would be templated between headers and data may be
the same, the ``template_data`` is the same for both. Correcting possible the same, the ``template_dict`` is the same for both. Correcting possible
variable name collisions is up to the user. variable name collisions is up to the user.
Authentication Authentication

View File

@ -405,8 +405,6 @@ class SyncClientMixin(object):
) )
data['success'] = False data['success'] = False
namespaced_event.fire_event(data, 'ret')
if self.store_job: if self.store_job:
try: try:
salt.utils.job.store_job( salt.utils.job.store_job(
@ -424,6 +422,9 @@ class SyncClientMixin(object):
log.error('Could not store job cache info. ' log.error('Could not store job cache info. '
'Job details for this run may be unavailable.') 'Job details for this run may be unavailable.')
# Outputters _can_ mutate data so write to the job cache first!
namespaced_event.fire_event(data, 'ret')
# if we fired an event, make sure to delete the event object. # if we fired an event, make sure to delete the event object.
# This will ensure that we call destroy, which will do the 0MQ linger # This will ensure that we call destroy, which will do the 0MQ linger
log.info('Runner completed: {0}'.format(data['jid'])) log.info('Runner completed: {0}'.format(data['jid']))

View File

@ -1927,7 +1927,7 @@ def list_policy_versions(policy_name,
return ret.get('list_policy_versions_response', {}).get('list_policy_versions_result', {}).get('versions') return ret.get('list_policy_versions_response', {}).get('list_policy_versions_result', {}).get('versions')
except boto.exception.BotoServerError as e: except boto.exception.BotoServerError as e:
log.debug(e) log.debug(e)
msg = 'Failed to list {0} policy vesions.' msg = 'Failed to list {0} policy versions.'
log.error(msg.format(policy_name)) log.error(msg.format(policy_name))
return [] return []

View File

@ -1978,6 +1978,8 @@ def acl_create(consul_url=None, **kwargs):
Create a new ACL token. Create a new ACL token.
:param consul_url: The Consul server URL. :param consul_url: The Consul server URL.
:param id: Unique identifier for the ACL to create
leave it blank to let consul server generate one
:param name: Meaningful indicator of the ACL's purpose. :param name: Meaningful indicator of the ACL's purpose.
:param type: Type is either client or management. A management :param type: Type is either client or management. A management
token is comparable to a root user and has the token is comparable to a root user and has the
@ -2008,6 +2010,9 @@ def acl_create(consul_url=None, **kwargs):
else: else:
raise SaltInvocationError('Required argument "name" is missing.') raise SaltInvocationError('Required argument "name" is missing.')
if 'id' in kwargs:
data['ID'] = kwargs['id']
if 'type' in kwargs: if 'type' in kwargs:
data['Type'] = kwargs['type'] data['Type'] = kwargs['type']
@ -2126,7 +2131,7 @@ def acl_delete(consul_url=None, **kwargs):
ret['res'] = False ret['res'] = False
return ret return ret
function = 'acl/delete/{0}'.format(kwargs['id']) function = 'acl/destroy/{0}'.format(kwargs['id'])
res = _query(consul_url=consul_url, res = _query(consul_url=consul_url,
data=data, data=data,
method='PUT', method='PUT',

View File

@ -218,7 +218,7 @@ def uptime():
with salt.utils.fopen(ut_path) as rfh: with salt.utils.fopen(ut_path) as rfh:
seconds = int(float(rfh.read().split()[0])) seconds = int(float(rfh.read().split()[0]))
elif salt.utils.is_sunos(): elif salt.utils.is_sunos():
# note: some flavors/vesions report the host uptime inside a zone # note: some flavors/versions report the host uptime inside a zone
# https://support.oracle.com/epmos/faces/BugDisplay?id=15611584 # https://support.oracle.com/epmos/faces/BugDisplay?id=15611584
res = __salt__['cmd.run_all']('kstat -p unix:0:system_misc:boot_time') res = __salt__['cmd.run_all']('kstat -p unix:0:system_misc:boot_time')
if res['retcode'] > 0: if res['retcode'] > 0:

View File

@ -945,27 +945,63 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
packages listed under ``pkgs`` will be installed via a single packages listed under ``pkgs`` will be installed via a single
command. command.
You can specify a version by passing the item as a dict:
CLI Example:
.. code-block:: bash
# will install the latest version of foo and bar
salt '*' pkg.install pkgs='["foo", "bar"]'
# will install the latest version of foo and version 1.2.3 of bar
salt '*' pkg.install pkgs='["foo", {"bar": "1.2.3"}]'
Kwargs: Kwargs:
version (str): version (str):
The specific version to install. If omitted, the latest version The specific version to install. If omitted, the latest version will
will be installed. If passed with multiple install, the version be installed. Recommend for use when installing a single package.
will apply to all packages. Recommended for single installation
only. If passed with a list of packages in the ``pkgs`` parameter, the
version will be ignored.
CLI Example:
.. code-block:: bash
# Version is ignored
salt '*' pkg.install pkgs="['foo', 'bar']" version=1.2.3
If passed with a comma seperated list in the ``name`` parameter, the
version will apply to all packages in the list.
CLI Example:
.. code-block:: bash
# Version 1.2.3 will apply to packages foo and bar
salt '*' pkg.install foo,bar version=1.2.3
cache_file (str): cache_file (str):
A single file to copy down for use with the installer. Copied to A single file to copy down for use with the installer. Copied to the
the same location as the installer. Use this over ``cache_dir`` if same location as the installer. Use this over ``cache_dir`` if there
there are many files in the directory and you only need a specific are many files in the directory and you only need a specific file
file and don't want to cache additional files that may reside in and don't want to cache additional files that may reside in the
the installer directory. Only applies to files on ``salt://`` installer directory. Only applies to files on ``salt://``
cache_dir (bool): cache_dir (bool):
True will copy the contents of the installer directory. This is True will copy the contents of the installer directory. This is
useful for installations that are not a single file. Only applies useful for installations that are not a single file. Only applies to
to directories on ``salt://`` directories on ``salt://``
saltenv (str): Salt environment. Default 'base' extra_install_flags (str):
Additional install flags that will be appended to the
``install_flags`` defined in the software definition file. Only
applies when single package is passed.
saltenv (str):
Salt environment. Default 'base'
report_reboot_exit_codes (bool): report_reboot_exit_codes (bool):
If the installer exits with a recognized exit code indicating that If the installer exits with a recognized exit code indicating that
@ -1061,13 +1097,22 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
# "sources" argument # "sources" argument
pkg_params = __salt__['pkg_resource.parse_targets'](name, pkgs, **kwargs)[0] pkg_params = __salt__['pkg_resource.parse_targets'](name, pkgs, **kwargs)[0]
if len(pkg_params) > 1:
if kwargs.get('extra_install_flags') is not None:
log.warning('\'extra_install_flags\' argument will be ignored for '
'multiple package targets')
# Windows expects an Options dictionary containing 'version'
for pkg in pkg_params:
pkg_params[pkg] = {'version': pkg_params[pkg]}
if pkg_params is None or len(pkg_params) == 0: if pkg_params is None or len(pkg_params) == 0:
log.error('No package definition found') log.error('No package definition found')
return {} return {}
if not pkgs and len(pkg_params) == 1: if not pkgs and len(pkg_params) == 1:
# Only use the 'version' param if 'name' was not specified as a # Only use the 'version' param if a single item was passed to the 'name'
# comma-separated list # parameter
pkg_params = { pkg_params = {
name: { name: {
'version': kwargs.get('version'), 'version': kwargs.get('version'),

View File

@ -1,9 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
''' '''
Microsoft certificate management via the Pki PowerShell module. Microsoft certificate management via the PKI Client PowerShell module.
https://technet.microsoft.com/en-us/itpro/powershell/windows/pkiclient/pkiclient
The PKI Client PowerShell module is only available on Windows 8+ and Windows
Server 2012+.
https://technet.microsoft.com/en-us/library/hh848636(v=wps.620).aspx
:platform: Windows :platform: Windows
:depends:
- PowerShell 4
- PKI Client Module (Windows 8+ / Windows Server 2012+)
.. versionadded:: 2016.11.0 .. versionadded:: 2016.11.0
''' '''
# Import python libs # Import python libs
@ -29,11 +38,17 @@ __virtualname__ = 'win_pki'
def __virtual__(): def __virtual__():
''' '''
Only works on Windows systems with the PKI PowerShell module installed. Requires Windows
Requires Windows 8+ / Windows Server 2012+
Requires PowerShell
Requires PKI Client PowerShell module installed.
''' '''
if not salt.utils.is_windows(): if not salt.utils.is_windows():
return False, 'Only available on Windows Systems' return False, 'Only available on Windows Systems'
if salt.utils.version_cmp(__grains__['osversion'], '6.2.9200') == -1:
return False, 'Only available on Windows 8+ / Windows Server 2012 +'
if not __salt__['cmd.shell_info']('powershell')['installed']: if not __salt__['cmd.shell_info']('powershell')['installed']:
return False, 'Powershell not available' return False, 'Powershell not available'

View File

@ -1138,13 +1138,22 @@ def latest(name,
password=password, password=password,
https_user=https_user, https_user=https_user,
https_pass=https_pass) https_pass=https_pass)
comments.append( if fetch_url is None:
'Remote \'{0}\' changed from {1} to {2}'.format( comments.append(
remote, 'Remote \'{0}\' set to {1}'.format(
salt.utils.url.redact_http_basic_auth(fetch_url), remote,
redacted_fetch_url redacted_fetch_url
)
)
ret['changes']['new'] = name + ' => ' + remote
else:
comments.append(
'Remote \'{0}\' changed from {1} to {2}'.format(
remote,
salt.utils.url.redact_http_basic_auth(fetch_url),
redacted_fetch_url
)
) )
)
if remote_rev is not None: if remote_rev is not None:
if __opts__['test']: if __opts__['test']:

View File

@ -120,13 +120,13 @@ def volume_present(name, bricks, stripe=False, replica=False, device_vg=False,
.. code-block:: yaml .. code-block:: yaml
myvolume: myvolume:
glusterfs.created: glusterfs.volume_present:
- bricks: - bricks:
- host1:/srv/gluster/drive1 - host1:/srv/gluster/drive1
- host2:/srv/gluster/drive2 - host2:/srv/gluster/drive2
Replicated Volume: Replicated Volume:
glusterfs.created: glusterfs.volume_present:
- name: volume2 - name: volume2
- bricks: - bricks:
- host1:/srv/gluster/drive2 - host1:/srv/gluster/drive2

View File

@ -1264,8 +1264,11 @@ def installed(
``NOTE:`` For :mod:`apt <salt.modules.aptpkg>`, ``NOTE:`` For :mod:`apt <salt.modules.aptpkg>`,
:mod:`ebuild <salt.modules.ebuild>`, :mod:`ebuild <salt.modules.ebuild>`,
:mod:`pacman <salt.modules.pacman>`, :mod:`yumpkg <salt.modules.yumpkg>`, :mod:`pacman <salt.modules.pacman>`,
and :mod:`zypper <salt.modules.zypper>`, version numbers can be specified :mod:`winrepo <salt.modules.win_pkg>`,
:mod:`yumpkg <salt.modules.yumpkg>`, and
:mod:`zypper <salt.modules.zypper>`,
version numbers can be specified
in the ``pkgs`` argument. For example: in the ``pkgs`` argument. For example:
.. code-block:: yaml .. code-block:: yaml

View File

@ -810,21 +810,21 @@ def wait_for_winexesvc(host, port, username, password, timeout=900):
log.debug('winexe connected...') log.debug('winexe connected...')
return True return True
log.debug('Return code was {0}'.format(ret_code)) log.debug('Return code was {0}'.format(ret_code))
time.sleep(1)
except socket.error as exc: except socket.error as exc:
log.debug('Caught exception in wait_for_winexesvc: {0}'.format(exc)) log.debug('Caught exception in wait_for_winexesvc: {0}'.format(exc))
time.sleep(1)
if time.time() - start > timeout: if time.time() - start > timeout:
log.error('winexe connection timed out: {0}'.format(timeout)) log.error('winexe connection timed out: {0}'.format(timeout))
return False return False
log.debug( log.debug(
'Retrying winexe connection to host {0} on port {1} ' 'Retrying winexe connection to host {0} on port {1} '
'(try {2})'.format( '(try {2})'.format(
host, host,
port, port,
try_count try_count
)
) )
)
time.sleep(1)
def wait_for_winrm(host, port, username, password, timeout=900, use_ssl=True): def wait_for_winrm(host, port, username, password, timeout=900, use_ssl=True):
@ -853,19 +853,19 @@ def wait_for_winrm(host, port, username, password, timeout=900, use_ssl=True):
log.debug('WinRM session connected...') log.debug('WinRM session connected...')
return s return s
log.debug('Return code was {0}'.format(r.status_code)) log.debug('Return code was {0}'.format(r.status_code))
time.sleep(1)
except WinRMTransportError as exc: except WinRMTransportError as exc:
log.debug('Caught exception in wait_for_winrm: {0}'.format(exc)) log.debug('Caught exception in wait_for_winrm: {0}'.format(exc))
if time.time() - start > timeout:
log.error('WinRM connection timed out: {0}'.format(timeout)) if time.time() - start > timeout:
return None log.error('WinRM connection timed out: {0}'.format(timeout))
log.debug( return None
'Retrying WinRM connection to host {0} on port {1} ' log.debug(
'(try {2})'.format( 'Retrying WinRM connection to host {0} on port {1} '
host, port, trycount '(try {2})'.format(
) host, port, trycount
) )
time.sleep(1) )
time.sleep(1)
def validate_windows_cred(host, def validate_windows_cred(host,