mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge branch 'nitrogen' into 'develop'
Conflicts: - salt/states/keystone.py
This commit is contained in:
commit
2cb4f2baa9
@ -1584,6 +1584,7 @@ class LocalClient(object):
|
||||
expect_minions=(verbose or show_timeout),
|
||||
**kwargs
|
||||
):
|
||||
log.debug('return event: %s', ret)
|
||||
return_count = return_count + 1
|
||||
if progress:
|
||||
for id_, min_ret in six.iteritems(ret):
|
||||
|
@ -42,12 +42,12 @@ Example of usage
|
||||
|
||||
.. code:: txt
|
||||
|
||||
08:33:57 @gtmanfred » !ping
|
||||
08:33:57 gtmanbot » gtmanfred: pong
|
||||
08:34:02 @gtmanfred » !echo ping
|
||||
08:34:02 gtmanbot » ping
|
||||
08:34:17 @gtmanfred » !event test/tag/ircbot irc is usefull
|
||||
08:34:17 gtmanbot » gtmanfred: TaDa!
|
||||
08:33:57 @gtmanfred > !ping
|
||||
08:33:57 gtmanbot > gtmanfred: pong
|
||||
08:34:02 @gtmanfred > !echo ping
|
||||
08:34:02 gtmanbot > ping
|
||||
08:34:17 @gtmanfred > !event test/tag/ircbot irc is usefull
|
||||
08:34:17 gtmanbot > gtmanfred: TaDa!
|
||||
|
||||
.. code:: txt
|
||||
|
||||
|
@ -28,7 +28,7 @@ of the following fields:
|
||||
10. raw (the raw event data forwarded from the device)
|
||||
|
||||
The topic title can consist of any of the combination of above fields,
|
||||
but the topic has to start with ‘jnpr/syslog’.
|
||||
but the topic has to start with 'jnpr/syslog'.
|
||||
So, we can have different combinations:
|
||||
- jnpr/syslog/hostip/daemon/event
|
||||
- jnpr/syslog/daemon/severity
|
||||
@ -37,7 +37,7 @@ The corresponding dynamic topic sent on salt event bus would look something like
|
||||
|
||||
- jnpr/syslog/1.1.1.1/mgd/UI_COMMIT_COMPLETED
|
||||
- jnpr/syslog/sshd/7
|
||||
The default topic title is ‘jnpr/syslog/hostname/event’.
|
||||
The default topic title is 'jnpr/syslog/hostname/event'.
|
||||
|
||||
The user can choose the type of data he/she wants of the event bus.
|
||||
Like, if one wants only events pertaining to a particular daemon, he/she can
|
||||
|
@ -592,20 +592,37 @@ class Client(object):
|
||||
destfp = None
|
||||
try:
|
||||
# Tornado calls streaming_callback on redirect response bodies.
|
||||
# But we need streaming to support fetching large files (> RAM avail).
|
||||
# Here we working this around by disabling recording the body for redirections.
|
||||
# The issue is fixed in Tornado 4.3.0 so on_header callback could be removed
|
||||
# when we'll deprecate Tornado<4.3.0.
|
||||
# See #27093 and #30431 for details.
|
||||
# But we need streaming to support fetching large files (> RAM
|
||||
# avail). Here we are working around this by disabling recording
|
||||
# the body for redirections. The issue is fixed in Tornado 4.3.0
|
||||
# so on_header callback could be removed when we'll deprecate
|
||||
# Tornado<4.3.0. See #27093 and #30431 for details.
|
||||
|
||||
# Use list here to make it writable inside the on_header callback. Simple bool doesn't
|
||||
# work here: on_header creates a new local variable instead. This could be avoided in
|
||||
# Py3 with 'nonlocal' statement. There is no Py2 alternative for this.
|
||||
# Use list here to make it writable inside the on_header callback.
|
||||
# Simple bool doesn't work here: on_header creates a new local
|
||||
# variable instead. This could be avoided in Py3 with 'nonlocal'
|
||||
# statement. There is no Py2 alternative for this.
|
||||
#
|
||||
# write_body[0] is used by the on_chunk callback to tell it whether
|
||||
# or not we need to write the body of the request to disk. For
|
||||
# 30x redirects we set this to False because we don't want to
|
||||
# write the contents to disk, as we will need to wait until we
|
||||
# get to the redirected URL.
|
||||
#
|
||||
# write_body[1] will contain a tornado.httputil.HTTPHeaders
|
||||
# instance that we will use to parse each header line. We
|
||||
# initialize this to False, and after we parse the status line we
|
||||
# will replace it with the HTTPHeaders instance. If/when we have
|
||||
# found the encoding used in the request, we set this value to
|
||||
# False to signify that we are done parsing.
|
||||
#
|
||||
# write_body[2] is where the encoding will be stored
|
||||
write_body = [None, False, None]
|
||||
|
||||
def on_header(hdr):
|
||||
if write_body[1] is not False and write_body[2] is None:
|
||||
# Try to find out what content type encoding is used if this is a text file
|
||||
# Try to find out what content type encoding is used if
|
||||
# this is a text file
|
||||
write_body[1].parse_line(hdr) # pylint: disable=no-member
|
||||
if 'Content-Type' in write_body[1]:
|
||||
content_type = write_body[1].get('Content-Type') # pylint: disable=no-member
|
||||
@ -621,17 +638,22 @@ class Client(object):
|
||||
# We have found our encoding. Stop processing headers.
|
||||
write_body[1] = False
|
||||
|
||||
if write_body[0] is not None:
|
||||
# We already parsed the first line. No need to run the code below again
|
||||
return
|
||||
# If write_body[0] is False, this means that this
|
||||
# header is a 30x redirect, so we need to reset
|
||||
# write_body[0] to None so that we parse the HTTP
|
||||
# status code from the redirect target.
|
||||
if write_body[0] is write_body[1] is False:
|
||||
write_body[0] = None
|
||||
|
||||
try:
|
||||
hdr = parse_response_start_line(hdr)
|
||||
except HTTPInputError:
|
||||
# Not the first line, do nothing
|
||||
return
|
||||
write_body[0] = hdr.code not in [301, 302, 303, 307]
|
||||
write_body[1] = HTTPHeaders()
|
||||
# Check the status line of the HTTP request
|
||||
if write_body[0] is None:
|
||||
try:
|
||||
hdr = parse_response_start_line(hdr)
|
||||
except HTTPInputError:
|
||||
# Not the first line, do nothing
|
||||
return
|
||||
write_body[0] = hdr.code not in [301, 302, 303, 307]
|
||||
write_body[1] = HTTPHeaders()
|
||||
|
||||
if no_cache:
|
||||
result = []
|
||||
|
@ -1538,6 +1538,7 @@ class Minion(MinionBase):
|
||||
else:
|
||||
data['ret'] = opts['return']
|
||||
|
||||
log.debug('minion return: %s', ret)
|
||||
# TODO: make a list? Seems odd to split it this late :/
|
||||
if data['ret'] and isinstance(data['ret'], six.string_types):
|
||||
if 'ret_config' in data:
|
||||
|
@ -296,7 +296,7 @@ def ec2_credentials_list(user_id=None, name=None, profile=None,
|
||||
return ret
|
||||
|
||||
|
||||
def endpoint_get(service, region=None, profile=None, **connection_args):
|
||||
def endpoint_get(service, region=None, profile=None, interface=None, **connection_args):
|
||||
'''
|
||||
Return a specific endpoint (keystone endpoint-get)
|
||||
|
||||
@ -304,7 +304,9 @@ def endpoint_get(service, region=None, profile=None, **connection_args):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' keystone.endpoint_get nova [region=RegionOne]
|
||||
salt 'v2' keystone.endpoint_get nova [region=RegionOne]
|
||||
|
||||
salt 'v3' keystone.endpoint_get nova interface=admin [region=RegionOne]
|
||||
'''
|
||||
auth(profile, **connection_args)
|
||||
services = service_list(profile, **connection_args)
|
||||
@ -315,12 +317,13 @@ def endpoint_get(service, region=None, profile=None, **connection_args):
|
||||
|
||||
e = [_f for _f in [e
|
||||
if e['service_id'] == service_id and
|
||||
(e['region'] == region if region else True) else None for e in endpoints.values()] if _f]
|
||||
(e['region'] == region if region else True) and
|
||||
(e['interface'] == interface if interface else True)
|
||||
else None for e in endpoints.values()] if _f]
|
||||
if len(e) > 1:
|
||||
return {'Error': 'Multiple endpoints found ({0}) for the {1} service. Please specify region.'.format(e, service)}
|
||||
if len(e) == 1:
|
||||
return e[0]
|
||||
#log.debug('Could not find endpoint for the specified service {0}, service_id: {3} and region {1} in endpoints {2}'.format(service, region, endpoints.values(), service_id))
|
||||
return {'Error': 'Could not find endpoint for the specified service'}
|
||||
|
||||
|
||||
@ -374,10 +377,10 @@ def endpoint_create(service, publicurl=None, internalurl=None, adminurl=None,
|
||||
publicurl=publicurl,
|
||||
adminurl=adminurl,
|
||||
internalurl=internalurl)
|
||||
return endpoint_get(service, region, profile, **connection_args)
|
||||
return endpoint_get(service, region, profile, interface, **connection_args)
|
||||
|
||||
|
||||
def endpoint_delete(service, region=None, profile=None, **connection_args):
|
||||
def endpoint_delete(service, region=None, profile=None, interface=None, **connection_args):
|
||||
'''
|
||||
Delete endpoints of an Openstack service
|
||||
|
||||
@ -385,14 +388,16 @@ def endpoint_delete(service, region=None, profile=None, **connection_args):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' keystone.endpoint_delete nova [region=RegionOne]
|
||||
salt 'v2' keystone.endpoint_delete nova [region=RegionOne]
|
||||
|
||||
salt 'v3' keystone.endpoint_delete nova interface=admin [region=RegionOne]
|
||||
'''
|
||||
kstone = auth(profile, **connection_args)
|
||||
endpoint = endpoint_get(service, region, profile, **connection_args)
|
||||
endpoint = endpoint_get(service, region, profile, interface, **connection_args)
|
||||
if not endpoint or 'Error' in endpoint:
|
||||
return {'Error': 'Could not find any endpoints for the service'}
|
||||
kstone.endpoints.delete(endpoint['id'])
|
||||
endpoint = endpoint_get(service, region, profile, **connection_args)
|
||||
endpoint = endpoint_get(service, region, profile, interface, **connection_args)
|
||||
if not endpoint or 'Error' in endpoint:
|
||||
return True
|
||||
|
||||
|
@ -117,8 +117,12 @@ def bin_pkg_info(path, saltenv='base'):
|
||||
output,
|
||||
osarch=__grains__['osarch']
|
||||
)
|
||||
for field in pkginfo._fields:
|
||||
ret[field] = getattr(pkginfo, field)
|
||||
try:
|
||||
for field in pkginfo._fields:
|
||||
ret[field] = getattr(pkginfo, field)
|
||||
except AttributeError:
|
||||
# pkginfo is None
|
||||
return None
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -5,6 +5,7 @@ Module for running arbitrary tests
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Python libs
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
@ -27,6 +28,8 @@ __func_alias__ = {
|
||||
'false_': 'false'
|
||||
}
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@depends('non_existantmodulename')
|
||||
def missing_func():
|
||||
@ -112,6 +115,7 @@ def ping():
|
||||
'''
|
||||
|
||||
if not salt.utils.is_proxy():
|
||||
log.debug('test.ping received for minion \'%s\'', __opts__.get('id'))
|
||||
return True
|
||||
else:
|
||||
ping_cmd = __opts__['proxy']['proxytype'] + '.ping'
|
||||
|
@ -981,21 +981,24 @@ def create_crl( # pylint: disable=too-many-arguments,too-many-locals
|
||||
OpenSSL.crypto.FILETYPE_PEM,
|
||||
get_pem_entry(signing_private_key))
|
||||
|
||||
export_kwargs = {
|
||||
'cert': cert,
|
||||
'key': key,
|
||||
'type': OpenSSL.crypto.FILETYPE_PEM,
|
||||
'days': days_valid
|
||||
}
|
||||
if digest:
|
||||
export_kwargs['digest'] = bytes(digest)
|
||||
else:
|
||||
log.warning('No digest specified. The default md5 digest will be used.')
|
||||
|
||||
try:
|
||||
crltext = crl.export(
|
||||
cert,
|
||||
key,
|
||||
OpenSSL.crypto.FILETYPE_PEM,
|
||||
days=days_valid,
|
||||
digest=bytes(digest))
|
||||
except TypeError:
|
||||
crltext = crl.export(**export_kwargs)
|
||||
except (TypeError, ValueError):
|
||||
log.warning(
|
||||
'Error signing crl with specified digest. Are you using pyopenssl 0.15 or newer? The default md5 digest will be used.')
|
||||
crltext = crl.export(
|
||||
cert,
|
||||
key,
|
||||
OpenSSL.crypto.FILETYPE_PEM,
|
||||
days=days_valid)
|
||||
export_kwargs.pop('digest', None)
|
||||
crltext = crl.export(**export_kwargs)
|
||||
|
||||
if text:
|
||||
return crltext
|
||||
|
@ -82,10 +82,10 @@ from __future__ import absolute_import
|
||||
import yaml
|
||||
import pprint
|
||||
import logging
|
||||
import urllib
|
||||
|
||||
# pylint: disable=import-error,no-name-in-module,redefined-builtin
|
||||
import salt.ext.six.moves.http_client
|
||||
from salt.ext.six.moves.urllib.parse import urlencode as _urlencode
|
||||
# pylint: enable=import-error,no-name-in-module,redefined-builtin
|
||||
|
||||
# Import Salt Libs
|
||||
@ -168,7 +168,7 @@ def _post_message(channel,
|
||||
api_key=api_key,
|
||||
method='POST',
|
||||
header_dict={'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
data=urllib.urlencode(parameters))
|
||||
data=_urlencode(parameters))
|
||||
|
||||
log.debug('result {0}'.format(result))
|
||||
if result:
|
||||
|
@ -55,7 +55,6 @@ def _ping(tgt, tgt_type, timeout, gather_job_timeout):
|
||||
tgt_type,
|
||||
gather_job_timeout=gather_job_timeout):
|
||||
|
||||
log.debug('fn_ret: %s', fn_ret)
|
||||
if fn_ret:
|
||||
for mid, _ in six.iteritems(fn_ret):
|
||||
log.debug('minion \'%s\' returned from ping', mid)
|
||||
|
@ -24,6 +24,7 @@ from salt.ext.six.moves.urllib.parse import urlparse as _urlparse # pylint: dis
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.files
|
||||
import salt.utils.url
|
||||
from salt.exceptions import CommandExecutionError, CommandNotFoundError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -888,7 +889,9 @@ def extracted(name,
|
||||
ret['result'] = None
|
||||
ret['comment'] = (
|
||||
'Archive {0} would be downloaded to cache and checked to '
|
||||
'discover if extraction is necessary'.format(source_match)
|
||||
'discover if extraction is necessary'.format(
|
||||
salt.utils.url.redact_http_basic_auth(source_match)
|
||||
)
|
||||
)
|
||||
return ret
|
||||
|
||||
@ -918,18 +921,27 @@ def extracted(name,
|
||||
|
||||
try:
|
||||
if not file_result['result']:
|
||||
log.debug('failed to download {0}'.format(source_match))
|
||||
log.debug(
|
||||
'failed to download %s',
|
||||
salt.utils.url.redact_http_basic_auth(source_match)
|
||||
)
|
||||
return file_result
|
||||
except TypeError:
|
||||
if not file_result:
|
||||
log.debug('failed to download {0}'.format(source_match))
|
||||
log.debug(
|
||||
'failed to download %s',
|
||||
salt.utils.url.redact_http_basic_auth(source_match)
|
||||
)
|
||||
return file_result
|
||||
|
||||
if source_hash:
|
||||
_update_checksum(cached_source)
|
||||
|
||||
else:
|
||||
log.debug('Archive %s is already in cache', source_match)
|
||||
log.debug(
|
||||
'Archive %s is already in cache',
|
||||
salt.utils.url.redact_http_basic_auth(source_match)
|
||||
)
|
||||
|
||||
if archive_format == 'zip' and not password:
|
||||
log.debug('Checking %s to see if it is password-protected',
|
||||
@ -950,7 +962,7 @@ def extracted(name,
|
||||
ret['comment'] = (
|
||||
'Archive {0} is password-protected, but no password was '
|
||||
'specified. Please set the \'password\' argument.'.format(
|
||||
source_match
|
||||
salt.utils.url.redact_http_basic_auth(source_match)
|
||||
)
|
||||
)
|
||||
return ret
|
||||
@ -1138,7 +1150,7 @@ def extracted(name,
|
||||
ret['result'] = None
|
||||
ret['comment'] = \
|
||||
'Archive {0} would be extracted to {1}'.format(
|
||||
source_match,
|
||||
salt.utils.url.redact_http_basic_auth(source_match),
|
||||
name
|
||||
)
|
||||
if clean and contents is not None:
|
||||
@ -1421,13 +1433,18 @@ def extracted(name,
|
||||
if created_destdir:
|
||||
ret['changes']['directories_created'] = [name]
|
||||
ret['changes']['extracted_files'] = files
|
||||
ret['comment'] = '{0} extracted to {1}'.format(source_match, name)
|
||||
ret['comment'] = '{0} extracted to {1}'.format(
|
||||
salt.utils.url.redact_http_basic_auth(source_match),
|
||||
name,
|
||||
)
|
||||
_add_explanation(ret, source_hash_trigger, contents_missing)
|
||||
ret['result'] = True
|
||||
|
||||
else:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Can\'t extract content of {0}'.format(source_match)
|
||||
ret['comment'] = 'No files were extracted from {0}'.format(
|
||||
salt.utils.url.redact_http_basic_auth(source_match)
|
||||
)
|
||||
else:
|
||||
ret['result'] = True
|
||||
if if_missing_path_exists:
|
||||
|
@ -656,6 +656,7 @@ def endpoint_present(name,
|
||||
|
||||
endpoint = __salt__['keystone.endpoint_get'](name, region,
|
||||
profile=profile,
|
||||
interface=interface,
|
||||
**connection_args)
|
||||
|
||||
def _changes(desc):
|
||||
@ -750,7 +751,7 @@ def endpoint_present(name,
|
||||
ret['changes']['internalurl'] = internalurl
|
||||
|
||||
if ret['comment']: # changed
|
||||
__salt__['keystone.endpoint_delete'](name, region, profile=profile, **connection_args)
|
||||
__salt__['keystone.endpoint_delete'](name, region, profile=profile, interface=interface, **connection_args)
|
||||
_create_endpoint()
|
||||
ret['comment'] += 'Endpoint for service "{0}" has been updated'.format(name)
|
||||
|
||||
@ -765,26 +766,34 @@ def endpoint_present(name,
|
||||
ret['comment'] = 'Endpoint for service "{0}" has been added'.format(name)
|
||||
|
||||
if ret['comment'] == '': # => no changes
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'Endpoint for service "{0}" already exists'.format(name)
|
||||
return ret
|
||||
|
||||
|
||||
def endpoint_absent(name, region=None, profile=None, **connection_args):
|
||||
def endpoint_absent(name, region=None, profile=None, interface=None, **connection_args):
|
||||
'''
|
||||
Ensure that the endpoint for a service doesn't exist in Keystone catalog
|
||||
|
||||
name
|
||||
The name of the service whose endpoints should not exist
|
||||
|
||||
region (optional)
|
||||
The region of the endpoint. Defaults to ``RegionOne``.
|
||||
|
||||
interface
|
||||
The interface type, which describes the visibility
|
||||
of the endpoint. (for V3 API)
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': 'Endpoint for service "{0}" is already absent'.format(name)}
|
||||
'comment': 'Endpoint for service "{0}"{1} is already absent'.format(name,
|
||||
', interface "{0}",'.format(interface) if interface is not None else '')}
|
||||
|
||||
# Check if service is present
|
||||
endpoint = __salt__['keystone.endpoint_get'](name, region,
|
||||
profile=profile,
|
||||
interface=interface,
|
||||
**connection_args)
|
||||
if not endpoint:
|
||||
return ret
|
||||
@ -796,7 +805,9 @@ def endpoint_absent(name, region=None, profile=None, **connection_args):
|
||||
# Delete service
|
||||
__salt__['keystone.endpoint_delete'](name, region,
|
||||
profile=profile,
|
||||
interface=interface,
|
||||
**connection_args)
|
||||
ret['comment'] = 'Endpoint for service "{0}" has been deleted'.format(name)
|
||||
ret['comment'] = 'Endpoint for service "{0}"{1} has been deleted'.format(name,
|
||||
', interface "{0}",'.format(interface) if interface is not None else '')
|
||||
ret['changes']['endpoint'] = 'Deleted'
|
||||
return ret
|
||||
|
@ -784,10 +784,13 @@ def _find_install_targets(name=None,
|
||||
' and are at the desired version' if version_spec and not sources
|
||||
else ''
|
||||
)
|
||||
return {'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': msg}
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': msg}
|
||||
if warnings:
|
||||
ret.setdefault('warnings', []).extend(warnings)
|
||||
return ret
|
||||
|
||||
return (desired, targets, to_unpurge, to_reinstall, altered_files,
|
||||
warnings, was_refreshed)
|
||||
@ -1529,7 +1532,7 @@ def installed(
|
||||
'result': False,
|
||||
'comment': 'lowpkg.unpurge not implemented'}
|
||||
if warnings:
|
||||
ret['comment'] += '.' + '. '.join(warnings) + '.'
|
||||
ret.setdefault('warnings', []).extend(warnings)
|
||||
return ret
|
||||
|
||||
# Remove any targets not returned by _find_install_targets
|
||||
@ -1592,7 +1595,7 @@ def installed(
|
||||
'result': None,
|
||||
'comment': '\n'.join(comment)}
|
||||
if warnings:
|
||||
ret['comment'] += '\n' + '. '.join(warnings) + '.'
|
||||
ret.setdefault('warnings', []).extend(warnings)
|
||||
return ret
|
||||
|
||||
changes = {'installed': {}}
|
||||
@ -1627,7 +1630,7 @@ def installed(
|
||||
ret['comment'] = ('An error was encountered while installing '
|
||||
'package(s): {0}'.format(exc))
|
||||
if warnings:
|
||||
ret['comment'] += '\n\n' + '. '.join(warnings) + '.'
|
||||
ret.setdefault('warnings', []).extend(warnings)
|
||||
return ret
|
||||
|
||||
if refresh:
|
||||
@ -1662,7 +1665,7 @@ def installed(
|
||||
'result': False,
|
||||
'comment': '\n'.join(comment)}
|
||||
if warnings:
|
||||
ret['comment'] += '.' + '. '.join(warnings) + '.'
|
||||
ret.setdefault('warnings', []).extend(warnings)
|
||||
return ret
|
||||
else:
|
||||
if 'result' in hold_ret and not hold_ret['result']:
|
||||
@ -1673,7 +1676,7 @@ def installed(
|
||||
'holding/unholding package(s): {0}'
|
||||
.format(hold_ret['comment'])}
|
||||
if warnings:
|
||||
ret['comment'] += '.' + '. '.join(warnings) + '.'
|
||||
ret.setdefault('warnings', []).extend(warnings)
|
||||
return ret
|
||||
else:
|
||||
modified_hold = [hold_ret[x] for x in hold_ret
|
||||
@ -1863,7 +1866,7 @@ def installed(
|
||||
'result': result,
|
||||
'comment': '\n'.join(comment)}
|
||||
if warnings:
|
||||
ret['comment'] += '\n' + '. '.join(warnings) + '.'
|
||||
ret.setdefault('warnings', []).extend(warnings)
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -14,7 +14,6 @@ import logging
|
||||
import os.path
|
||||
import pprint
|
||||
import socket
|
||||
import urllib
|
||||
import yaml
|
||||
|
||||
import ssl
|
||||
@ -55,6 +54,7 @@ import salt.ext.six.moves.http_cookiejar
|
||||
import salt.ext.six.moves.urllib.request as urllib_request
|
||||
from salt.ext.six.moves.urllib.error import URLError
|
||||
from salt.ext.six.moves.urllib.parse import splitquery
|
||||
from salt.ext.six.moves.urllib.parse import urlencode as _urlencode
|
||||
# pylint: enable=import-error,no-name-in-module
|
||||
|
||||
# Don't need a try/except block, since Salt depends on tornado
|
||||
@ -438,7 +438,7 @@ def query(url,
|
||||
'not valid: {0}'.format(cert))
|
||||
|
||||
if isinstance(data, dict):
|
||||
data = urllib.urlencode(data)
|
||||
data = _urlencode(data)
|
||||
|
||||
if verify_ssl:
|
||||
req_kwargs['ca_certs'] = ca_bundle
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:copyright: © 2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
:copyright: Copyright 2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
||||
:copyright: © 2015 by the SaltStack Team, see AUTHORS for more details.
|
||||
:copyright: Copyright 2015 by the SaltStack Team, see AUTHORS for more details.
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
||||
:copyright: © 2016 by the SaltStack Team, see AUTHORS for more details.
|
||||
:copyright: Copyright 2016 by the SaltStack Team, see AUTHORS for more details.
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
|
||||
|
||||
|
@ -6,15 +6,25 @@ import os
|
||||
import uuid
|
||||
import shutil
|
||||
import hashlib
|
||||
import logging
|
||||
import psutil
|
||||
import shutil
|
||||
import signal
|
||||
import tempfile
|
||||
import textwrap
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.case import ModuleCase
|
||||
from tests.support.helpers import get_unused_localhost_port, skip_if_not_root
|
||||
from tests.support.unit import skipIf
|
||||
import tests.support.paths as paths
|
||||
|
||||
# Import salt libs
|
||||
import salt.ext.six as six
|
||||
import salt.utils
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CPModuleTest(ModuleCase):
|
||||
'''
|
||||
@ -415,6 +425,83 @@ class CPModuleTest(ModuleCase):
|
||||
with salt.utils.fopen(ret, 'r') as cp_:
|
||||
self.assertEqual(cp_.read(), 'foo')
|
||||
|
||||
@skipIf(not salt.utils.which('nginx'), 'nginx not installed')
|
||||
@skip_if_not_root
|
||||
def test_cache_remote_file(self):
|
||||
'''
|
||||
cp.cache_file
|
||||
'''
|
||||
nginx_port = get_unused_localhost_port()
|
||||
url_prefix = 'http://localhost:{0}/'.format(nginx_port)
|
||||
temp_dir = tempfile.mkdtemp(dir=paths.TMP)
|
||||
self.addCleanup(shutil.rmtree, temp_dir, ignore_errors=True)
|
||||
nginx_root_dir = os.path.join(temp_dir, 'root')
|
||||
nginx_conf_dir = os.path.join(temp_dir, 'conf')
|
||||
nginx_conf = os.path.join(nginx_conf_dir, 'nginx.conf')
|
||||
nginx_pidfile = os.path.join(nginx_conf_dir, 'nginx.pid')
|
||||
file_contents = 'Hello world!'
|
||||
|
||||
for dirname in (nginx_root_dir, nginx_conf_dir):
|
||||
os.mkdir(dirname)
|
||||
|
||||
# Write the temp file
|
||||
with salt.utils.fopen(os.path.join(nginx_root_dir, 'actual_file'), 'w') as fp_:
|
||||
fp_.write(file_contents)
|
||||
|
||||
# Write the nginx config
|
||||
with salt.utils.fopen(nginx_conf, 'w') as fp_:
|
||||
fp_.write(textwrap.dedent(
|
||||
'''\
|
||||
user root;
|
||||
worker_processes 1;
|
||||
error_log {nginx_conf_dir}/server_error.log;
|
||||
pid {nginx_pidfile};
|
||||
|
||||
events {{
|
||||
worker_connections 1024;
|
||||
}}
|
||||
|
||||
http {{
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
access_log {nginx_conf_dir}/access.log;
|
||||
error_log {nginx_conf_dir}/error.log;
|
||||
|
||||
server {{
|
||||
listen {nginx_port} default_server;
|
||||
server_name cachefile.local;
|
||||
root {nginx_root_dir};
|
||||
|
||||
location ~ ^/301$ {{
|
||||
return 301 /actual_file;
|
||||
}}
|
||||
|
||||
location ~ ^/302$ {{
|
||||
return 302 /actual_file;
|
||||
}}
|
||||
}}
|
||||
}}'''.format(**locals())
|
||||
))
|
||||
|
||||
self.run_function(
|
||||
'cmd.run',
|
||||
[['nginx', '-c', nginx_conf]],
|
||||
python_shell=False
|
||||
)
|
||||
with salt.utils.fopen(nginx_pidfile) as fp_:
|
||||
nginx_pid = int(fp_.read().strip())
|
||||
nginx_proc = psutil.Process(pid=nginx_pid)
|
||||
self.addCleanup(nginx_proc.send_signal, signal.SIGQUIT)
|
||||
|
||||
for code in ('', '301', '302'):
|
||||
url = url_prefix + (code or 'actual_file')
|
||||
log.debug('attempting to cache %s', url)
|
||||
ret = self.run_function('cp.cache_file', [url])
|
||||
with salt.utils.fopen(ret) as fp_:
|
||||
cached_contents = fp_.read()
|
||||
self.assertEqual(cached_contents, file_contents)
|
||||
|
||||
def test_list_states(self):
|
||||
'''
|
||||
cp.list_states
|
||||
|
@ -22,6 +22,7 @@ def _find_new_locale(current_locale):
|
||||
|
||||
|
||||
@skipIf(salt.utils.is_windows(), 'minion is windows')
|
||||
@skipIf(salt.utils.is_darwin(), 'locale method is not supported on mac')
|
||||
@requires_salt_modules('locale')
|
||||
class LocaleModuleTest(ModuleCase):
|
||||
def test_get_locale(self):
|
||||
|
@ -99,10 +99,13 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
'''
|
||||
test archive.extracted with user and group set to "root"
|
||||
'''
|
||||
r_group = 'root'
|
||||
if salt.utils.is_darwin():
|
||||
r_group = 'wheel'
|
||||
ret = self.run_state('archive.extracted', name=ARCHIVE_DIR,
|
||||
source=self.archive_tar_source, archive_format='tar',
|
||||
source_hash=ARCHIVE_TAR_HASH,
|
||||
user='root', group='root')
|
||||
user='root', group=r_group)
|
||||
log.debug('ret = %s', ret)
|
||||
if 'Timeout' in ret:
|
||||
self.skipTest('Timeout talking to local tornado server.')
|
||||
|
@ -545,6 +545,9 @@ class FileTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
'''
|
||||
Test file.managed passing a basic check_cmd kwarg. See Issue #38111.
|
||||
'''
|
||||
r_group = 'root'
|
||||
if salt.utils.is_darwin():
|
||||
r_group = 'wheel'
|
||||
if not salt.utils.which('visudo'):
|
||||
self.fail('sudo is missing')
|
||||
try:
|
||||
@ -552,7 +555,7 @@ class FileTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
'file.managed',
|
||||
name='/tmp/sudoers',
|
||||
user='root',
|
||||
group='root',
|
||||
group=r_group,
|
||||
mode=440,
|
||||
check_cmd='visudo -c -s -f'
|
||||
)
|
||||
|
@ -104,7 +104,8 @@ class UserTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
ret = self.run_state('user.present', name=self.user_name,
|
||||
home=self.user_home)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
self.assertTrue(os.path.isdir(self.user_home))
|
||||
if not salt.utils.is_darwin():
|
||||
self.assertTrue(os.path.isdir(self.user_home))
|
||||
|
||||
@requires_system_grains
|
||||
def test_user_present_gid_from_name_default(self, grains=None):
|
||||
@ -127,7 +128,8 @@ class UserTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
self.assertReturnNonEmptySaltType(ret)
|
||||
group_name = grp.getgrgid(ret['gid']).gr_name
|
||||
|
||||
self.assertTrue(os.path.isdir(self.user_home))
|
||||
if not salt.utils.is_darwin():
|
||||
self.assertTrue(os.path.isdir(self.user_home))
|
||||
if grains['os_family'] in ('Suse',):
|
||||
self.assertEqual(group_name, 'users')
|
||||
elif grains['os_family'] == 'MacOS':
|
||||
@ -151,7 +153,8 @@ class UserTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
self.assertReturnNonEmptySaltType(ret)
|
||||
group_name = grp.getgrgid(ret['gid']).gr_name
|
||||
|
||||
self.assertTrue(os.path.isdir(self.user_home))
|
||||
if not salt.utils.is_darwin():
|
||||
self.assertTrue(os.path.isdir(self.user_home))
|
||||
self.assertEqual(group_name, self.user_name)
|
||||
ret = self.run_state('user.absent', name=self.user_name)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
|
@ -771,11 +771,11 @@ class TestDaemon(TestProgram):
|
||||
if not self._shutdown:
|
||||
try:
|
||||
pid = self.wait_for_daemon_pid(timeout)
|
||||
terminate_process(pid=pid)
|
||||
terminate_process(pid=pid, kill_children=True)
|
||||
except TimeoutError:
|
||||
pass
|
||||
if self.process:
|
||||
terminate_process(pid=self.process.pid)
|
||||
terminate_process(pid=self.process.pid, kill_children=True)
|
||||
self.process.wait()
|
||||
self.process = None
|
||||
self._shutdown = True
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:copyright: © 2013-2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
:copyright: Copyright 2013-2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
Salt Tests CLI access classes
|
||||
|
||||
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
||||
:copyright: © 2013-2017 by the SaltStack Team, see AUTHORS for more details
|
||||
:copyright: Copyright 2013-2017 by the SaltStack Team, see AUTHORS for more details
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
'''
|
||||
# pylint: disable=repr-flag-used-in-string
|
||||
|
@ -6,7 +6,7 @@
|
||||
Code coverage aware testing parser
|
||||
|
||||
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
||||
:copyright: © 2013 by the SaltStack Team, see AUTHORS for more details.
|
||||
:copyright: Copyright 2013 by the SaltStack Team, see AUTHORS for more details.
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
'''
|
||||
# pylint: disable=repr-flag-used-in-string
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
||||
:copyright: © 2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
:copyright: Copyright 2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:copyright: © 2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
:copyright: Copyright 2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
||||
:copyright: © 2014 by the SaltStack Team, see AUTHORS for more details.
|
||||
:copyright: Copyright 2014 by the SaltStack Team, see AUTHORS for more details.
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
||||
:copyright: © 2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
:copyright: Copyright 2017 by the SaltStack Team, see AUTHORS for more details.
|
||||
|
||||
|
||||
tests.unit.beacons.test_status
|
||||
|
@ -314,7 +314,7 @@ class KeystoneTestCase(TestCase, LoaderModuleMockMixin):
|
||||
'keystone.endpoint_create': mock}):
|
||||
|
||||
comt = ('Endpoint for service "{0}" already exists'.format(name))
|
||||
ret.update({'comment': comt, 'result': None, 'changes': {}})
|
||||
ret.update({'comment': comt, 'result': True, 'changes': {}})
|
||||
self.assertDictEqual(keystone.endpoint_present(name), ret)
|
||||
|
||||
with patch.dict(keystone.__opts__, {'test': True}):
|
||||
@ -323,7 +323,7 @@ class KeystoneTestCase(TestCase, LoaderModuleMockMixin):
|
||||
self.assertDictEqual(keystone.endpoint_present(name), ret)
|
||||
|
||||
comt = ('Endpoint for service "{0}" already exists'.format(name))
|
||||
ret.update({'comment': comt, 'result': None, 'changes': {}})
|
||||
ret.update({'comment': comt, 'result': True, 'changes': {}})
|
||||
self.assertDictEqual(keystone.endpoint_present(name), ret)
|
||||
|
||||
with patch.dict(keystone.__opts__, {'test': False}):
|
||||
|
Loading…
Reference in New Issue
Block a user