Merge branch '2018.3' into fix_47559

This commit is contained in:
Nicole Thomas 2018-05-31 11:28:30 -04:00 committed by GitHub
commit 0d229c6182
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
117 changed files with 8787 additions and 743 deletions

2
.gitignore vendored
View file

@ -11,6 +11,8 @@ MANIFEST
*.wpr
*.wpu
*.DS_Store
.pytest_cache
Pipfile.lock
# virtualenv
# - ignores directories of a virtualenv when you create it right on

View file

@ -2,8 +2,8 @@
source 'https://rubygems.org'
gem 'test-kitchen', :git => 'https://github.com/gtmanfred/test-kitchen.git'
gem 'kitchen-salt', :git => 'https://github.com/saltstack/kitchen-salt.git'
gem 'test-kitchen', '~>1.21'
gem 'kitchen-salt', '~>0.2'
gem 'kitchen-sync'
gem 'git'
@ -20,7 +20,7 @@ group :windows do
gem 'vagrant-wrapper'
gem 'kitchen-vagrant'
gem 'winrm', '~>2.0'
gem 'winrm-fs', :git => 'https://github.com/gtmanfred/winrm-fs.git'
gem 'winrm-fs', :git => 'https://github.com/WinRb/winrm-fs.git'
end
group :ec2 do

40
Pipfile Normal file
View file

@ -0,0 +1,40 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
Jinja2 = "*"
msgpack-python = ">0.3,!=0.5.5"
PyYAML = "*"
MarkupSafe = "*"
requests = ">=1.0.0"
tornado = ">=4.2.1,<5.0"
pycrypto = ">=2.6.1"
pyzmq = ">=2.2.0"
[dev-packages]
mock = ">=2.0.0"
apache-libcloud = ">=0.14.0"
boto = ">=2.32.1"
boto3 = ">=1.2.1"
moto = ">=0.3.6"
SaltPyLint = ">=v2017.3.6"
pytest = ">=3.5.0"
[packages.futures]
# Required by Tornado to handle threads stuff.
version = ">=2.0"
markers = "python_version < '3.0'"
[dev-packages.pytest-salt]
git = "git://github.com/saltstack/pytest-salt.git"
ref = "master"
[dev-packages.httpretty]
# httpretty Needs to be here for now even though it's a dependency of boto.
# A pip install on a fresh system will decide to target httpretty 0.8.10 to
# satisfy other requirements, and httpretty 0.8.10 has bugs in setup.py that
# prevent it from being successfully installed (at least on Python 3.4).
version = "*"
markers = "python_version >= '3.4'"

View file

@ -538,6 +538,10 @@
# targeted with the normal -N argument to salt-ssh.
#ssh_list_nodegroups: {}
# salt-ssh has the ability to update the flat roster file if a minion is not
# found in the roster. Set this to True to enable it.
#ssh_update_roster: False
##### Master Module Management #####
##########################################
# Manage how master side modules are loaded.

View file

@ -1,6 +1,6 @@
=====================
==================
salt.modules.swarm
=====================
==================
.. automodule:: salt.modules.swarm
:memebers:
:members:

View file

@ -44,7 +44,7 @@ at ``/etc/salt/cloud.profiles`` or in the ``/etc/salt/cloud.profiles.d/`` direct
linode_1024:
provider: my-linode-config
size: Linode 2048
size: Linode 2GB
image: CentOS 7
location: London, England, UK
@ -77,12 +77,14 @@ command:
----------
linode:
----------
Linode 1024:
Linode 2GB:
----------
AVAIL:
----------
10:
500
11:
500
2:
500
3:
@ -100,11 +102,19 @@ command:
CORES:
1
DISK:
24
50
HOURLY:
0.015
LABEL:
Linode 1024
Linode 2GB
PLANID:
2
PRICE:
10.0
RAM:
2048
XFER:
2000
...SNIP...

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,17 @@
===========================
In Progress: Salt 2017.7.7 Release Notes
===========================
Version 2017.7.7 is an **unreleased** bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.
This release is still in progress and has not been released yet.
New win_snmp behavior
---------------------
`win_snmp.get_community_names` now returns the SNMP settings actually in effect
on the box. If settings are managed via GroupPolicy, those settings will be
returned. Otherwise, normal settings are returned.
`win_snmp.set_community_names` now raises a CommandExecutionError when SNMP
settings are being managed by GroupPolicy

File diff suppressed because it is too large Load diff

165
pkg/windows/sign.bat Normal file
View file

@ -0,0 +1,165 @@
:: ############################################################################
::
:: FILE: sign.bat
::
:: DESCRIPTION: Signing and Hashing script for Salt builds on Windows.
:: Requires an official Code Signing Certificate and drivers
:: installed to sign the files. Generates hashes in MD5 and
:: SHA256 in a file of the same name with a `.md5` or
:: `.sha256` extension.
::
:: NOTE: This script is used internally by SaltStack to sign and
:: hash Windows Installer builds and uses resources not
:: available to the community, such as SaltStack's Code
:: Signing Certificate. It is placed here for version
:: control.
::
:: COPYRIGHT: (c) 2012-2018 by the SaltStack Team
::
:: LICENSE: Apache 2.0
:: ORGANIZATION: SaltStack, Inc (saltstack.com)
:: CREATED: 2017
::
:: ############################################################################
::
:: USAGE: The script must be located in a directory that has the installer
:: files in a subfolder named with the major version, ie: `2018.3`.
:: Insert the key fob that contains the code signing certificate. Run
:: the script passing the full version: `.\sign.bat 2018.3.1`.
::
:: The script will sign the installers and generate the corresponding
:: hash files. These can then be uploaded to the salt repo.
::
:: The files must be in the following format:
:: <Series>\Salt-Minion-<Version>-<Python Version>-<System Architecture>-Setup.exe
:: So, for a Salt Minion installer for 2018.3.1 on AMD64 for Python 3
:: file would be placed in a subdirectory named `2018.3` and the file
:: would be named: `Salt-Minion-2018.3.1-Py3-AMD64-Setup.exe`. This
:: is how the file is created by the NSI Script anyway.
::
:: ############################################################################
@ echo off
if [%1]==[] (
echo You must pass a version
goto quit
) else (
set "Version=%~1"
)
for /F "tokens=1,2 delims=." %%a in ("%Version%") do (set Series=%%a.%%b)
:: Sign Installer Files
echo ===========================================================================
echo Signing...
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
signtool.exe sign /t http://timestamp.digicert.com ^
"%Series%\Salt-Minion-%Version%-AMD64-Setup.exe" ^
"%Series%\Salt-Minion-%Version%-x86-Setup.exe" ^
"%Series%\Salt-%Version%-AMD64-Setup.exe" ^
"%Series%\Salt-%Version%-x86-Setup.exe" ^
"%Series%\Salt-%Version%-Py2-AMD64-Setup.exe" ^
"%Series%\Salt-%Version%-Py2-x86-Setup.exe" ^
"%Series%\Salt-%Version%-Py3-AMD64-Setup.exe" ^
"%Series%\Salt-%Version%-Py3-x86-Setup.exe" ^
"%Series%\Salt-Minion-%Version%-Py2-AMD64-Setup.exe" ^
"%Series%\Salt-Minion-%Version%-Py2-x86-Setup.exe" ^
"%Series%\Salt-Minion-%Version%-Py3-AMD64-Setup.exe" ^
"%Series%\Salt-Minion-%Version%-Py3-x86-Setup.exe"
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo Signing Complete
echo ===========================================================================
:: Create Hash files
echo ===========================================================================
echo Creating Hashes...
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
set "file_name=Salt-Minion-%Version%-AMD64-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-Minion-%Version%-x86-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-%Version%-AMD64-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-%Version%-x86-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-%Version%-Py2-AMD64-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-%Version%-Py2-x86-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-%Version%-Py3-AMD64-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-%Version%-Py3-x86-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-Minion-%Version%-Py2-AMD64-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-Minion-%Version%-Py2-x86-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-Minion-%Version%-Py3-AMD64-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
set "file_name=Salt-Minion-%Version%-Py3-x86-Setup.exe"
set "file=.\%Series%\%file_name%"
if exist "%file%" (
echo - %file_name%
powershell -c "$hash = (Get-FileHash -Algorithm MD5 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.md5\""
powershell -c "$hash = (Get-FileHash -Algorithm SHA256 \"%file%\").Hash; Out-File -InputObject $hash\" %file_name%\" -FilePath \"%file%.sha256\"")
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo Hashing Complete
echo ===========================================================================
:quit

4
pytest.ini Normal file
View file

@ -0,0 +1,4 @@
[pytest]
addopts = --ssh-tests -ra -sv
testpaths = tests
norecursedirs = tests/kitchen

View file

@ -1,4 +0,0 @@
-r base.txt
# Required by Tornado to handle threads stuff.
futures>=2.0

View file

@ -1 +0,0 @@
-r base.txt

View file

@ -5,6 +5,8 @@ msgpack>=0.5,!=0.5.5
PyYAML
MarkupSafe
requests>=1.0.0
tornado>=4.2.1,<5.0
tornado>=4.2.1,<6.0; python_version < '3'
tornado>=4.2.1,<5.0; python_version >= '3.4'
# Required by Tornado to handle threads stuff.
futures>=2.0
futures>=2.0; python_version < '3.0'

17
requirements/dev.txt Normal file
View file

@ -0,0 +1,17 @@
-r base.txt
mock>=2.0.0
apache-libcloud>=0.14.0
boto>=2.32.1
boto3>=1.2.1
moto>=0.3.6
SaltPyLint>=v2017.3.6
pytest>=3.5.0
git+https://github.com/saltstack/pytest-salt.git@master#egg=pytest-salt
testinfra>=1.7.0
# httpretty Needs to be here for now even though it's a dependency of boto.
# A pip install on a fresh system will decide to target httpretty 0.8.10 to
# satisfy other requirements, and httpretty 0.8.10 has bugs in setup.py that
# prevent it from being successfully installed (at least on Python 3.4).
httpretty; python_version >= '3.4'

View file

@ -1,12 +1,2 @@
-r base-py2.txt
mock>=2.0.0
apache-libcloud>=0.14.0
boto>=2.32.1
boto3>=1.2.1
moto>=0.3.6
SaltPyLint>=v2017.3.6
pytest>=3.5.0
git+https://github.com/eisensheng/pytest-catchlog.git@develop#egg=Pytest-catchlog
git+https://github.com/saltstack/pytest-salt.git@master#egg=pytest-salt
testinfra>=1.7.0
# This is a legacy file, use dev.txt
-r dev.txt

View file

@ -1,17 +1,2 @@
-r base-py3.txt
mock>=2.0.0
apache-libcloud>=0.14.0
boto>=2.32.1
boto3>=1.2.1
moto>=0.3.6
# httpretty Needs to be here for now even though it's a dependency of boto.
# A pip install on a fresh system will decide to target httpretty 0.8.10 to
# satisfy other requirements, and httpretty 0.8.10 has bugs in setup.py that
# prevent it from being successfully installed (at least on Python 3.4).
httpretty
SaltPyLint>=v2017.2.29
pytest>=3.5.0
git+https://github.com/saltstack/pytest-salt.git@master#egg=pytest-salt
git+https://github.com/eisensheng/pytest-catchlog.git@develop#egg=Pytest-catchlog
testinfra>=1.7.0
# This is a legacy file, use dev.txt
-r dev.txt

View file

@ -410,7 +410,7 @@ class SSH(object):
'host': hostname,
'user': user,
}
if not self.opts.get('ssh_skip_roster'):
if self.opts.get('ssh_update_roster'):
self._update_roster()
def get_pubkey(self):

View file

@ -1916,7 +1916,7 @@ class Map(Cloud):
pmap = self.map_providers_parallel(cached=cached)
exist = set()
defined = set()
for profile_name, nodes in six.iteritems(self.rendered_map):
for profile_name, nodes in six.iteritems(copy.deepcopy(self.rendered_map)):
if profile_name not in self.opts['profiles']:
msg = (
'The required profile, \'{0}\', defined in the map '
@ -1937,13 +1937,13 @@ class Map(Cloud):
# Get associated provider data, in case something like size
# or image is specified in the provider file. See issue #32510.
alias, driver = profile_data.get('provider').split(':')
provider_details = self.opts['providers'][alias][driver].copy()
provider_details = copy.deepcopy(self.opts['providers'][alias][driver])
del provider_details['profiles']
# Update the provider details information with profile data
# Profile data should override provider data, if defined.
# This keeps map file data definitions consistent with -p usage.
provider_details.update(profile_data)
salt.utils.dictupdate.update(provider_details, profile_data)
profile_data = provider_details
for nodename, overrides in six.iteritems(nodes):

View file

@ -993,6 +993,59 @@ def get_password(vm_):
)
def _decode_linode_plan_label(label):
'''
Attempts to decode a user-supplied Linode plan label
into the format in Linode API output
label
The label, or name, of the plan to decode.
Example:
`Linode 2048` will decode to `Linode 2GB`
'''
sizes = avail_sizes()
if label not in sizes:
if 'GB' in label:
raise SaltCloudException(
'Invalid Linode plan ({}) specified - call avail_sizes() for all available options'.format(label)
)
else:
plan = label.split()
if len(plan) != 2:
raise SaltCloudException(
'Invalid Linode plan ({}) specified - call avail_sizes() for all available options'.format(label)
)
plan_type = plan[0]
try:
plan_size = int(plan[1])
except TypeError:
plan_size = 0
log.debug('Failed to decode Linode plan label in Cloud Profile: %s', label)
if plan_type == 'Linode' and plan_size == 1024:
plan_type = 'Nanode'
plan_size = plan_size/1024
new_label = "{} {}GB".format(plan_type, plan_size)
if new_label not in sizes:
raise SaltCloudException(
'Invalid Linode plan ({}) specified - call avail_sizes() for all available options'.format(new_label)
)
log.warning('An outdated Linode plan label was detected in your Cloud Profile ({}).'
' Please update the profile to use'
' the new label format ({}) for the requested Linode plan size.'.format(label, new_label))
label = new_label
return sizes[label]['PLANID']
def get_plan_id(kwargs=None, call=None):
'''
Returns the Linode Plan ID.
@ -1020,7 +1073,9 @@ def get_plan_id(kwargs=None, call=None):
'The get_plan_id function requires a \'label\'.'
)
return avail_sizes()[label]['PLANID']
label = _decode_linode_plan_label(label)
return label
def get_private_ip(vm_):

View file

@ -597,6 +597,7 @@ def _clean_create_kwargs(**kwargs):
'volume_size': int,
'nat_destination': six.string_types,
'group': six.string_types,
'userdata': six.string_types,
}
extra = kwargs.pop('extra', {})
for key, value in six.iteritems(kwargs.copy()):

View file

@ -47,6 +47,7 @@ from salt.ext.six.moves.urllib.parse import urlparse, urlunparse
# pylint: enable=no-name-in-module,import-error
log = logging.getLogger(__name__)
MAX_FILENAME_LENGTH = 255
def get_file_client(opts, pillar=False):
@ -831,6 +832,9 @@ class Client(object):
else:
file_name = url_data.path
if len(file_name) > MAX_FILENAME_LENGTH:
file_name = salt.utils.hashutils.sha256_digest(file_name)
return salt.utils.path.join(
cachedir,
'extrn_files',
@ -1396,14 +1400,12 @@ class RemoteClient(Client):
'''
Return the metadata derived from the master_tops system
'''
salt.utils.versions.warn_until(
'Magnesium',
'The _ext_nodes master function has '
'been renamed to _master_tops. To ensure '
'compatibility when using older Salt masters '
'we continue to pass the function as _ext_nodes.'
log.debug(
'The _ext_nodes master function has been renamed to _master_tops. '
'To ensure compatibility when using older Salt masters we will '
'continue to invoke the function as _ext_nodes until the '
'Magnesium release.'
)
# TODO: Change back to _master_tops
# for Magnesium release
load = {'cmd': '_ext_nodes',

View file

@ -850,7 +850,8 @@ class FSChan(object):
self.opts['__fs_update'] = True
else:
self.fs.update()
self.cmd_stub = {'master_tops': {}}
self.cmd_stub = {'master_tops': {},
'ext_nodes': {}}
def send(self, load, tries=None, timeout=None, raw=False): # pylint: disable=unused-argument
'''

View file

@ -253,7 +253,7 @@ def file_hash(load, fnd):
except OSError:
pass
return file_hash(load, fnd)
if os.path.getmtime(path) == mtime:
if str(os.path.getmtime(path)) == mtime:
# check if mtime changed
ret['hsum'] = hsum
return ret

View file

@ -451,7 +451,11 @@ def _bsd_memdata(osdata):
if osdata['kernel'] in ['OpenBSD', 'NetBSD']:
swapctl = salt.utils.path.which('swapctl')
swap_total = __salt__['cmd.run']('{0} -sk'.format(swapctl)).split(' ')[1]
swap_data = __salt__['cmd.run']('{0} -sk'.format(swapctl))
if swap_data == 'no swap devices configured':
swap_total = 0
else:
swap_total = swap_data.split(' ')[1]
else:
swap_total = __salt__['cmd.run']('{0} -n vm.swap_total'.format(sysctl))
grains['swap_total'] = int(swap_total) // 1024 // 1024
@ -2305,9 +2309,9 @@ def _hw_data(osdata):
product_regexes = [
re.compile(r) for r in [
r'(?im)^\s*System\s+Configuration:\s*.*?sun\d\S+\s(.*)', # prtdiag
r'(?im)^\s*banner-name:\s*(.*)', # prtconf
r'(?im)^\s*product-name:\s*(.*)', # prtconf
r'(?im)^\s*System\s+Configuration:\s*.*?sun\d\S+[^\S\r\n]*(.*)', # prtdiag
r'(?im)^[^\S\r\n]*banner-name:[^\S\r\n]*(.*)', # prtconf
r'(?im)^[^\S\r\n]*product-name:[^\S\r\n]*(.*)', # prtconf
]
]
@ -2374,8 +2378,11 @@ def _hw_data(osdata):
for regex in product_regexes:
res = regex.search(data)
if res and len(res.groups()) >= 1:
grains['product'] = res.group(1).strip().replace("'", "")
break
t_productname = res.group(1).strip().replace("'", "")
if t_productname:
grains['product'] = t_productname
grains['productname'] = t_productname
break
return grains

View file

@ -53,7 +53,6 @@ import time
# Import Salt libs
from salt.exceptions import SaltInvocationError, CommandExecutionError
import salt.utils.boto3
import salt.utils.compat
import salt.utils.versions

View file

@ -54,7 +54,6 @@ import logging
import time
# Import Salt libs
import salt.utils.boto3
import salt.utils.compat
import salt.utils.versions
from salt.exceptions import SaltInvocationError
@ -646,6 +645,10 @@ def disassociate_vpc_from_hosted_zone(HostedZoneId=None, Name=None, VPCId=None,
r = conn.disassociate_vpc_from_hosted_zone(**args)
return _wait_for_sync(r['ChangeInfo']['Id'], conn)
except ClientError as e:
if e.response.get('Error', {}).get('Code') == 'VPCAssociationNotFound':
log.debug('No VPC Association exists.')
# return True since the current state is the desired one
return True
if tries and e.response.get('Error', {}).get('Code') == 'Throttling':
log.debug('Throttled by AWS API.')
time.sleep(3)

View file

@ -82,7 +82,6 @@ import datetime
# Import Salt libs
from salt.ext import six
import salt.utils.boto3
import salt.utils.compat
import salt.utils.json
import salt.utils.versions
@ -182,7 +181,7 @@ def _find_apis_by_name(name, description=None,
apis = _filter_apis_desc(description, apis)
return {'restapi': [_convert_datetime_str(api) for api in apis]}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_apis(name=None, description=None, region=None, key=None, keyid=None, profile=None):
@ -251,7 +250,7 @@ def create_api(name, description, cloneFrom=None,
api = _convert_datetime_str(api)
return {'created': True, 'restapi': api} if api else {'created': False}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete_api(name, description=None, region=None, key=None, keyid=None, profile=None):
@ -282,7 +281,7 @@ def delete_api(name, description=None, region=None, key=None, keyid=None, profil
else:
return {'deleted': False}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def describe_api_resources(restApiId, region=None, key=None, keyid=None, profile=None):
@ -303,7 +302,7 @@ def describe_api_resources(restApiId, region=None, key=None, keyid=None, profile
return {'resources': resources}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_api_resource(restApiId, path,
@ -364,7 +363,7 @@ def create_api_resources(restApiId, path,
else:
return {'created': False, 'error': 'unexpected error.'}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete_api_resources(restApiId, path,
@ -393,7 +392,7 @@ def delete_api_resources(restApiId, path,
else:
return {'deleted': False, 'error': 'no resource found by {0}'.format(path)}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def describe_api_resource_method(restApiId, resourcePath, httpMethod,
@ -421,7 +420,7 @@ def describe_api_resource_method(restApiId, resourcePath, httpMethod,
method = conn.get_method(restApiId=restApiId, resourceId=resource['id'], httpMethod=httpMethod)
return {'method': method}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_api_key(apiKey, region=None, key=None, keyid=None, profile=None):
@ -440,7 +439,7 @@ def describe_api_key(apiKey, region=None, key=None, keyid=None, profile=None):
response = conn.get_api_key(apiKey=apiKey)
return {'apiKey': _convert_datetime_str(response)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_api_keys(region=None, key=None, keyid=None, profile=None):
@ -460,7 +459,7 @@ def describe_api_keys(region=None, key=None, keyid=None, profile=None):
return {'apiKeys': [_convert_datetime_str(apikey) for apikey in apikeys]}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create_api_key(name, description, enabled=True, stageKeys=None,
@ -498,7 +497,7 @@ def create_api_key(name, description, enabled=True, stageKeys=None,
return {'created': True, 'apiKey': _convert_datetime_str(response)}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete_api_key(apiKey, region=None, key=None, keyid=None, profile=None):
@ -517,7 +516,7 @@ def delete_api_key(apiKey, region=None, key=None, keyid=None, profile=None):
conn.delete_api_key(apiKey=apiKey)
return {'deleted': True}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def _api_key_patch_replace(conn, apiKey, path, value):
@ -570,7 +569,7 @@ def update_api_key_description(apiKey, description, region=None, key=None, keyid
response = _api_key_patch_replace(conn, apiKey, '/description', description)
return {'updated': True, 'apiKey': _convert_datetime_str(response)}
except ClientError as e:
return {'updated': False, 'error': salt.utils.boto3.get_error(e)}
return {'updated': False, 'error': __utils__['boto3.get_error'](e)}
def enable_api_key(apiKey, region=None, key=None, keyid=None, profile=None):
@ -589,7 +588,7 @@ def enable_api_key(apiKey, region=None, key=None, keyid=None, profile=None):
response = _api_key_patch_replace(conn, apiKey, '/enabled', 'True')
return {'apiKey': _convert_datetime_str(response)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def disable_api_key(apiKey, region=None, key=None, keyid=None, profile=None):
@ -608,7 +607,7 @@ def disable_api_key(apiKey, region=None, key=None, keyid=None, profile=None):
response = _api_key_patch_replace(conn, apiKey, '/enabled', 'False')
return {'apiKey': _convert_datetime_str(response)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def associate_api_key_stagekeys(apiKey, stagekeyslist, region=None, key=None, keyid=None, profile=None):
@ -629,7 +628,7 @@ def associate_api_key_stagekeys(apiKey, stagekeyslist, region=None, key=None, ke
response = _api_key_patch_add(conn, apiKey, pvlist)
return {'associated': True, 'apiKey': _convert_datetime_str(response)}
except ClientError as e:
return {'associated': False, 'error': salt.utils.boto3.get_error(e)}
return {'associated': False, 'error': __utils__['boto3.get_error'](e)}
def disassociate_api_key_stagekeys(apiKey, stagekeyslist, region=None, key=None, keyid=None, profile=None):
@ -650,7 +649,7 @@ def disassociate_api_key_stagekeys(apiKey, stagekeyslist, region=None, key=None,
response = _api_key_patch_remove(conn, apiKey, pvlist)
return {'disassociated': True}
except ClientError as e:
return {'disassociated': False, 'error': salt.utils.boto3.get_error(e)}
return {'disassociated': False, 'error': __utils__['boto3.get_error'](e)}
def describe_api_deployments(restApiId, region=None, key=None, keyid=None, profile=None):
@ -678,7 +677,7 @@ def describe_api_deployments(restApiId, region=None, key=None, keyid=None, profi
return {'deployments': [_convert_datetime_str(deployment) for deployment in deployments]}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_api_deployment(restApiId, deploymentId, region=None, key=None, keyid=None, profile=None):
@ -697,7 +696,7 @@ def describe_api_deployment(restApiId, deploymentId, region=None, key=None, keyi
deployment = conn.get_deployment(restApiId=restApiId, deploymentId=deploymentId)
return {'deployment': _convert_datetime_str(deployment)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def activate_api_deployment(restApiId, stageName, deploymentId,
@ -720,7 +719,7 @@ def activate_api_deployment(restApiId, stageName, deploymentId,
'value': deploymentId}])
return {'set': True, 'response': _convert_datetime_str(response)}
except ClientError as e:
return {'set': False, 'error': salt.utils.boto3.get_error(e)}
return {'set': False, 'error': __utils__['boto3.get_error'](e)}
def create_api_deployment(restApiId, stageName, stageDescription='', description='', cacheClusterEnabled=False,
@ -747,7 +746,7 @@ def create_api_deployment(restApiId, stageName, stageDescription='', description
variables=variables)
return {'created': True, 'deployment': _convert_datetime_str(deployment)}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete_api_deployment(restApiId, deploymentId, region=None, key=None, keyid=None, profile=None):
@ -766,7 +765,7 @@ def delete_api_deployment(restApiId, deploymentId, region=None, key=None, keyid=
conn.delete_deployment(restApiId=restApiId, deploymentId=deploymentId)
return {'deleted': True}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def overwrite_api_stage_variables(restApiId, stageName, variables, region=None, key=None, keyid=None, profile=None):
@ -812,7 +811,7 @@ def overwrite_api_stage_variables(restApiId, stageName, variables, region=None,
return {'overwrite': True, 'stage': _convert_datetime_str(stage)}
except ClientError as e:
return {'overwrite': False, 'error': salt.utils.boto3.get_error(e)}
return {'overwrite': False, 'error': __utils__['boto3.get_error'](e)}
def describe_api_stage(restApiId, stageName, region=None, key=None, keyid=None, profile=None):
@ -831,7 +830,7 @@ def describe_api_stage(restApiId, stageName, region=None, key=None, keyid=None,
stage = conn.get_stage(restApiId=restApiId, stageName=stageName)
return {'stage': _convert_datetime_str(stage)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_api_stages(restApiId, deploymentId, region=None, key=None, keyid=None, profile=None):
@ -850,7 +849,7 @@ def describe_api_stages(restApiId, deploymentId, region=None, key=None, keyid=No
stages = conn.get_stages(restApiId=restApiId, deploymentId=deploymentId)
return {'stages': [_convert_datetime_str(stage) for stage in stages['item']]}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create_api_stage(restApiId, stageName, deploymentId, description='',
@ -876,7 +875,7 @@ def create_api_stage(restApiId, stageName, deploymentId, description='',
cacheClusterSize=cacheClusterSize, variables=variables)
return {'created': True, 'stage': _convert_datetime_str(stage)}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete_api_stage(restApiId, stageName, region=None, key=None, keyid=None, profile=None):
@ -895,7 +894,7 @@ def delete_api_stage(restApiId, stageName, region=None, key=None, keyid=None, pr
conn.delete_stage(restApiId=restApiId, stageName=stageName)
return {'deleted': True}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def flush_api_stage_cache(restApiId, stageName, region=None, key=None, keyid=None, profile=None):
@ -914,7 +913,7 @@ def flush_api_stage_cache(restApiId, stageName, region=None, key=None, keyid=Non
conn.flush_stage_cache(restApiId=restApiId, stageName=stageName)
return {'flushed': True}
except ClientError as e:
return {'flushed': False, 'error': salt.utils.boto3.get_error(e)}
return {'flushed': False, 'error': __utils__['boto3.get_error'](e)}
def create_api_method(restApiId, resourcePath, httpMethod, authorizationType,
@ -946,7 +945,7 @@ def create_api_method(restApiId, resourcePath, httpMethod, authorizationType,
return {'created': False, 'error': 'Failed to create method'}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def describe_api_method(restApiId, resourcePath, httpMethod, region=None, key=None, keyid=None, profile=None):
@ -969,7 +968,7 @@ def describe_api_method(restApiId, resourcePath, httpMethod, region=None, key=No
return {'method': _convert_datetime_str(method)}
return {'error': 'get API method failed: no such resource'}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def delete_api_method(restApiId, resourcePath, httpMethod, region=None, key=None, keyid=None, profile=None):
@ -992,7 +991,7 @@ def delete_api_method(restApiId, resourcePath, httpMethod, region=None, key=None
return {'deleted': True}
return {'deleted': False, 'error': 'get API method failed: no such resource'}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def create_api_method_response(restApiId, resourcePath, httpMethod, statusCode, responseParameters=None,
@ -1022,7 +1021,7 @@ def create_api_method_response(restApiId, resourcePath, httpMethod, statusCode,
return {'created': True, 'response': response}
return {'created': False, 'error': 'no such resource'}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete_api_method_response(restApiId, resourcePath, httpMethod, statusCode,
@ -1047,7 +1046,7 @@ def delete_api_method_response(restApiId, resourcePath, httpMethod, statusCode,
return {'deleted': True}
return {'deleted': False, 'error': 'no such resource'}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def describe_api_method_response(restApiId, resourcePath, httpMethod, statusCode,
@ -1072,7 +1071,7 @@ def describe_api_method_response(restApiId, resourcePath, httpMethod, statusCode
return {'response': _convert_datetime_str(response)}
return {'error': 'no such resource'}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_api_models(restApiId, region=None, key=None, keyid=None, profile=None):
@ -1091,7 +1090,7 @@ def describe_api_models(restApiId, region=None, key=None, keyid=None, profile=No
models = _multi_call(conn.get_models, 'items', restApiId=restApiId)
return {'models': [_convert_datetime_str(model) for model in models]}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_api_model(restApiId, modelName, flatten=True, region=None, key=None, keyid=None, profile=None):
@ -1110,7 +1109,7 @@ def describe_api_model(restApiId, modelName, flatten=True, region=None, key=None
model = conn.get_model(restApiId=restApiId, modelName=modelName, flatten=flatten)
return {'model': _convert_datetime_str(model)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def api_model_exists(restApiId, modelName, region=None, key=None, keyid=None, profile=None):
@ -1154,7 +1153,7 @@ def update_api_model_schema(restApiId, modelName, schema, region=None, key=None,
response = _api_model_patch_replace(conn, restApiId, modelName, '/schema', schema_json)
return {'updated': True, 'model': _convert_datetime_str(response)}
except ClientError as e:
return {'updated': False, 'error': salt.utils.boto3.get_error(e)}
return {'updated': False, 'error': __utils__['boto3.get_error'](e)}
def delete_api_model(restApiId, modelName, region=None, key=None, keyid=None, profile=None):
@ -1173,7 +1172,7 @@ def delete_api_model(restApiId, modelName, region=None, key=None, keyid=None, pr
conn.delete_model(restApiId=restApiId, modelName=modelName)
return {'deleted': True}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def create_api_model(restApiId, modelName, modelDescription, schema, contentType='application/json',
@ -1196,7 +1195,7 @@ def create_api_model(restApiId, modelName, modelDescription, schema, contentType
schema=schema_json, contentType=contentType)
return {'created': True, 'model': _convert_datetime_str(model)}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def describe_api_integration(restApiId, resourcePath, httpMethod, region=None, key=None, keyid=None, profile=None):
@ -1219,7 +1218,7 @@ def describe_api_integration(restApiId, resourcePath, httpMethod, region=None, k
return {'integration': _convert_datetime_str(integration)}
return {'error': 'no such resource'}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_api_integration_response(restApiId, resourcePath, httpMethod, statusCode,
@ -1244,7 +1243,7 @@ def describe_api_integration_response(restApiId, resourcePath, httpMethod, statu
return {'response': _convert_datetime_str(response)}
return {'error': 'no such resource'}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def delete_api_integration(restApiId, resourcePath, httpMethod, region=None, key=None, keyid=None, profile=None):
@ -1267,7 +1266,7 @@ def delete_api_integration(restApiId, resourcePath, httpMethod, region=None, key
return {'deleted': True}
return {'deleted': False, 'error': 'no such resource'}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def delete_api_integration_response(restApiId, resourcePath, httpMethod, statusCode,
@ -1292,7 +1291,7 @@ def delete_api_integration_response(restApiId, resourcePath, httpMethod, statusC
return {'deleted': True}
return {'deleted': False, 'error': 'no such resource'}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def _get_role_arn(name, region=None, key=None, keyid=None, profile=None):
@ -1349,7 +1348,7 @@ def create_api_integration(restApiId, resourcePath, httpMethod, integrationType,
return {'created': True, 'integration': integration}
return {'created': False, 'error': 'no such resource'}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def create_api_integration_response(restApiId, resourcePath, httpMethod, statusCode, selectionPattern,
@ -1382,7 +1381,7 @@ def create_api_integration_response(restApiId, resourcePath, httpMethod, statusC
return {'created': True, 'response': response}
return {'created': False, 'error': 'no such resource'}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def _filter_plans(attr, name, plans):
@ -1418,7 +1417,7 @@ def describe_usage_plans(name=None, plan_id=None, region=None, key=None, keyid=N
return {'plans': [_convert_datetime_str(plan) for plan in plans]}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def _validate_throttle(throttle):
@ -1497,7 +1496,7 @@ def create_usage_plan(name, description=None, throttle=None, quota=None, region=
res = conn.create_usage_plan(**values)
return {'created': True, 'result': res}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
except (TypeError, ValueError) as e:
return {'error': six.text_type(e)}
@ -1571,7 +1570,7 @@ def update_usage_plan(plan_id, throttle=None, quota=None, region=None, key=None,
return {'updated': False}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
except (TypeError, ValueError) as e:
return {'error': six.text_type(e)}
@ -1600,7 +1599,7 @@ def delete_usage_plan(plan_id, region=None, key=None, keyid=None, profile=None):
res = conn.delete_usage_plan(usagePlanId=plan_id)
return {'deleted': True, 'usagePlanId': plan_id}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def _update_usage_plan_apis(plan_id, apis, op, region=None, key=None, keyid=None, profile=None):
@ -1634,7 +1633,7 @@ def _update_usage_plan_apis(plan_id, apis, op, region=None, key=None, keyid=None
patchOperations=patchOperations)
return {'success': True, 'result': res}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
except Exception as e:
return {'error': e}

View file

@ -74,7 +74,6 @@ except ImportError:
# Import Salt libs
import salt.utils.boto3
import salt.utils.compat
import salt.utils.json
import salt.utils.odict as odict
@ -885,7 +884,7 @@ def enter_standby(name, instance_ids, should_decrement_desired_capacity=False,
AutoScalingGroupName=name,
ShouldDecrementDesiredCapacity=should_decrement_desired_capacity)
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'exists': False}
return {'error': err}
@ -911,7 +910,7 @@ def exit_standby(name, instance_ids, should_decrement_desired_capacity=False,
InstanceIds=instance_ids,
AutoScalingGroupName=name)
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'exists': False}
return {'error': err}

View file

@ -55,7 +55,6 @@ import logging
# Import Salt libs
from salt.ext import six
import salt.utils.boto3
import salt.utils.compat
import salt.utils.versions
@ -117,7 +116,7 @@ def exists(Name,
conn.get_trail_status(Name=Name)
return {'exists': True}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'TrailNotFoundException':
return {'exists': False}
return {'error': err}
@ -167,7 +166,7 @@ def create(Name,
log.warning('Trail was not created')
return {'created': False}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete(Name,
@ -191,7 +190,7 @@ def delete(Name,
conn.delete_trail(Name=Name)
return {'deleted': True}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def describe(Name,
@ -224,10 +223,10 @@ def describe(Name,
else:
return {'trail': None}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'TrailNotFoundException':
return {'trail': None}
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def status(Name,
@ -265,10 +264,10 @@ def status(Name,
else:
return {'trail': None}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'TrailNotFoundException':
return {'trail': None}
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def list(region=None, key=None, keyid=None, profile=None):
@ -293,7 +292,7 @@ def list(region=None, key=None, keyid=None, profile=None):
log.warning('No trails found')
return {'trails': trails.get('trailList', [])}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def update(Name,
@ -340,7 +339,7 @@ def update(Name,
log.warning('Trail was not created')
return {'updated': False}
except ClientError as e:
return {'updated': False, 'error': salt.utils.boto3.get_error(e)}
return {'updated': False, 'error': __utils__['boto3.get_error'](e)}
def start_logging(Name,
@ -364,7 +363,7 @@ def start_logging(Name,
conn.start_logging(Name=Name)
return {'started': True}
except ClientError as e:
return {'started': False, 'error': salt.utils.boto3.get_error(e)}
return {'started': False, 'error': __utils__['boto3.get_error'](e)}
def stop_logging(Name,
@ -388,7 +387,7 @@ def stop_logging(Name,
conn.stop_logging(Name=Name)
return {'stopped': True}
except ClientError as e:
return {'stopped': False, 'error': salt.utils.boto3.get_error(e)}
return {'stopped': False, 'error': __utils__['boto3.get_error'](e)}
def _get_trail_arn(name, region=None, key=None, keyid=None, profile=None):
@ -433,7 +432,7 @@ def add_tags(Name,
profile=profile), TagsList=tagslist)
return {'tagged': True}
except ClientError as e:
return {'tagged': False, 'error': salt.utils.boto3.get_error(e)}
return {'tagged': False, 'error': __utils__['boto3.get_error'](e)}
def remove_tags(Name,
@ -464,7 +463,7 @@ def remove_tags(Name,
profile=profile), TagsList=tagslist)
return {'tagged': True}
except ClientError as e:
return {'tagged': False, 'error': salt.utils.boto3.get_error(e)}
return {'tagged': False, 'error': __utils__['boto3.get_error'](e)}
def list_tags(Name,
@ -497,4 +496,4 @@ def list_tags(Name,
tagdict[tag.get('Key')] = tag.get('Value')
return {'tags': tagdict}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}

View file

@ -81,7 +81,6 @@ from __future__ import absolute_import, print_function, unicode_literals
import logging
# Import Salt libs
import salt.utils.boto3
import salt.utils.compat
import salt.utils.versions
@ -131,7 +130,7 @@ def _find_identity_pool_ids(name, pool_id, conn):
'''
ids = []
if pool_id is None:
for pools in salt.utils.boto3.paged_call(conn.list_identity_pools,
for pools in __utils__['boto3.paged_call'](conn.list_identity_pools,
marker_flag='NextToken', marker_arg='NextToken', MaxResults=25):
for pool in pools['IdentityPools']:
if pool['IdentityPoolName'] == name:
@ -174,7 +173,7 @@ def describe_identity_pools(IdentityPoolName, IdentityPoolId=None,
else:
return {'identity_pools': None}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create_identity_pool(IdentityPoolName,
@ -216,7 +215,7 @@ def create_identity_pool(IdentityPoolName,
return {'created': True, 'identity_pool': response}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete_identity_pools(IdentityPoolName, IdentityPoolId=None,
@ -250,7 +249,7 @@ def delete_identity_pools(IdentityPoolName, IdentityPoolId=None,
else:
return {'deleted': False, 'count': count}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def get_identity_pool_roles(IdentityPoolName, IdentityPoolId=None,
@ -284,7 +283,7 @@ def get_identity_pool_roles(IdentityPoolName, IdentityPoolId=None,
else:
return {'identity_pool_roles': None}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def _get_role_arn(name, **conn_params):
@ -349,7 +348,7 @@ def set_identity_pool_roles(IdentityPoolId, AuthenticatedRole=None, Unauthentica
return {'set': True, 'roles': Roles}
except ClientError as e:
return {'set': False, 'error': salt.utils.boto3.get_error(e)}
return {'set': False, 'error': __utils__['boto3.get_error'](e)}
def update_identity_pool(IdentityPoolId,
@ -420,4 +419,4 @@ def update_identity_pool(IdentityPoolId,
return {'updated': True, 'identity_pool': response}
except ClientError as e:
return {'updated': False, 'error': salt.utils.boto3.get_error(e)}
return {'updated': False, 'error': __utils__['boto3.get_error'](e)}

View file

@ -56,6 +56,7 @@ import salt.utils.data
import salt.utils.json
import salt.utils.versions
from salt.ext import six
from salt.ext.six.moves import map
from salt.exceptions import SaltInvocationError, CommandExecutionError
# Import third party libs
@ -65,6 +66,7 @@ try:
import boto.ec2
# pylint: enable=unused-import
from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
from boto.ec2.networkinterface import NetworkInterfaceSpecification, NetworkInterfaceCollection
HAS_BOTO = True
except ImportError:
HAS_BOTO = False
@ -1003,14 +1005,19 @@ def run(image_id, name=None, tags=None, key_name=None, security_groups=None,
return False
security_group_ids += [r]
if all((network_interface_id, network_interface_name)):
raise SaltInvocationError('Only one of network_interface_id or '
'network_interface_name may be provided.')
network_interface_args = list(map(int, [network_interface_id is not None,
network_interface_name is not None,
network_interfaces is not None]))
if sum(network_interface_args) > 1:
raise SaltInvocationError('Only one of network_interface_id, '
'network_interface_name or '
'network_interfaces may be provided.')
if network_interface_name:
result = get_network_interface_id(network_interface_name,
region=region, key=key,
keyid=keyid,
profile=profile)
region=region, key=key,
keyid=keyid,
profile=profile)
network_interface_id = result['result']
if not network_interface_id:
log.warning(
@ -1019,17 +1026,20 @@ def run(image_id, name=None, tags=None, key_name=None, security_groups=None,
)
if network_interface_id:
interface = boto.ec2.networkinterface.NetworkInterfaceSpecification(
interface = NetworkInterfaceSpecification(
network_interface_id=network_interface_id,
device_index=0
)
device_index=0)
else:
interface = boto.ec2.networkinterface.NetworkInterfaceSpecification(
interface = NetworkInterfaceSpecification(
subnet_id=subnet_id,
groups=security_group_ids,
device_index=0
)
interfaces = boto.ec2.networkinterface.NetworkInterfaceCollection(interface)
device_index=0)
if network_interfaces:
interfaces_specs = [NetworkInterfaceSpecification(**x) for x in network_interfaces]
interfaces = NetworkInterfaceCollection(*interfaces_specs)
else:
interfaces = NetworkInterfaceCollection(interface)
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)

View file

@ -80,7 +80,6 @@ import logging
# Import Salt libs
from salt.ext import six
import salt.utils.boto3
import salt.utils.compat
import salt.utils.json
import salt.utils.versions
@ -148,7 +147,7 @@ def exists(DomainName,
except ClientError as e:
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'exists': False}
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def status(DomainName,
@ -179,7 +178,7 @@ def status(DomainName,
else:
return {'domain': None}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe(DomainName,
@ -208,7 +207,7 @@ def describe(DomainName,
else:
return {'domain': None}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create(DomainName, ElasticsearchClusterConfig=None, EBSOptions=None,
@ -262,7 +261,7 @@ def create(DomainName, ElasticsearchClusterConfig=None, EBSOptions=None,
log.warning('Domain was not created')
return {'created': False}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete(DomainName, region=None, key=None, keyid=None, profile=None):
@ -285,7 +284,7 @@ def delete(DomainName, region=None, key=None, keyid=None, profile=None):
conn.delete_elasticsearch_domain(DomainName=DomainName)
return {'deleted': True}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def update(DomainName, ElasticsearchClusterConfig=None, EBSOptions=None,
@ -335,7 +334,7 @@ def update(DomainName, ElasticsearchClusterConfig=None, EBSOptions=None,
return {'updated': False}
return {'updated': True}
except ClientError as e:
return {'updated': False, 'error': salt.utils.boto3.get_error(e)}
return {'updated': False, 'error': __utils__['boto3.get_error'](e)}
def add_tags(DomainName=None, ARN=None,
@ -378,7 +377,7 @@ def add_tags(DomainName=None, ARN=None,
conn.add_tags(ARN=ARN, TagList=tagslist)
return {'tagged': True}
except ClientError as e:
return {'tagged': False, 'error': salt.utils.boto3.get_error(e)}
return {'tagged': False, 'error': __utils__['boto3.get_error'](e)}
def remove_tags(TagKeys, DomainName=None, ARN=None,
@ -417,7 +416,7 @@ def remove_tags(TagKeys, DomainName=None, ARN=None,
TagKeys=TagKeys)
return {'tagged': True}
except ClientError as e:
return {'tagged': False, 'error': salt.utils.boto3.get_error(e)}
return {'tagged': False, 'error': __utils__['boto3.get_error'](e)}
def list_tags(DomainName=None, ARN=None,
@ -462,4 +461,4 @@ def list_tags(DomainName=None, ARN=None,
tagdict[tag.get('Key')] = tag.get('Value')
return {'tags': tagdict}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}

View file

@ -54,7 +54,6 @@ import salt.utils.versions
# Import third-party libs
try:
# pylint: disable=unused-import
import salt.utils.boto3
import boto3
import botocore
# pylint: enable=unused-import

View file

@ -55,7 +55,6 @@ import logging
import datetime
# Import Salt libs
import salt.utils.boto3
import salt.utils.compat
import salt.utils.json
import salt.utils.versions
@ -125,7 +124,7 @@ def thing_type_exists(thingTypeName,
else:
return {'exists': False}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'exists': False}
return {'error': err}
@ -162,7 +161,7 @@ def describe_thing_type(thingTypeName,
else:
return {'thing_type': None}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'thing_type': None}
return {'error': err}
@ -207,7 +206,7 @@ def create_thing_type(thingTypeName, thingTypeDescription,
log.warning('thing type was not created')
return {'created': False}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def deprecate_thing_type(thingTypeName, undoDeprecate=False,
@ -238,7 +237,7 @@ def deprecate_thing_type(thingTypeName, undoDeprecate=False,
deprecated = True if undoDeprecate is False else False
return {'deprecated': deprecated}
except ClientError as e:
return {'deprecated': False, 'error': salt.utils.boto3.get_error(e)}
return {'deprecated': False, 'error': __utils__['boto3.get_error'](e)}
def delete_thing_type(thingTypeName,
@ -264,7 +263,7 @@ def delete_thing_type(thingTypeName,
conn.delete_thing_type(thingTypeName=thingTypeName)
return {'deleted': True}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'deleted': True}
return {'deleted': False, 'error': err}
@ -291,7 +290,7 @@ def policy_exists(policyName,
conn.get_policy(policyName=policyName)
return {'exists': True}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'exists': False}
return {'error': err}
@ -331,7 +330,7 @@ def create_policy(policyName, policyDocument,
log.warning('Policy was not created')
return {'created': False}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete_policy(policyName,
@ -355,7 +354,7 @@ def delete_policy(policyName,
conn.delete_policy(policyName=policyName)
return {'deleted': True}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def describe_policy(policyName,
@ -383,10 +382,10 @@ def describe_policy(policyName,
else:
return {'policy': None}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'policy': None}
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def policy_version_exists(policyName, policyVersionId,
@ -411,10 +410,10 @@ def policy_version_exists(policyName, policyVersionId,
policyversionId=policyVersionId)
return {'exists': bool(policy)}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'exists': False}
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create_policy_version(policyName, policyDocument, setAsDefault=False,
@ -449,7 +448,7 @@ def create_policy_version(policyName, policyDocument, setAsDefault=False,
log.warning('Policy version was not created')
return {'created': False}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def delete_policy_version(policyName, policyVersionId,
@ -474,7 +473,7 @@ def delete_policy_version(policyName, policyVersionId,
policyVersionId=policyVersionId)
return {'deleted': True}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def describe_policy_version(policyName, policyVersionId,
@ -503,10 +502,10 @@ def describe_policy_version(policyName, policyVersionId,
else:
return {'policy': None}
except ClientError as e:
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'ResourceNotFoundException':
return {'policy': None}
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def list_policies(region=None, key=None, keyid=None, profile=None):
@ -533,7 +532,7 @@ def list_policies(region=None, key=None, keyid=None, profile=None):
try:
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
policies = []
for ret in salt.utils.boto3.paged_call(conn.list_policies,
for ret in __utils__['boto3.paged_call'](conn.list_policies,
marker_flag='nextMarker',
marker_arg='marker'):
policies.extend(ret['policies'])
@ -541,7 +540,7 @@ def list_policies(region=None, key=None, keyid=None, profile=None):
log.warning('No policies found')
return {'policies': policies}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def list_policy_versions(policyName,
@ -567,7 +566,7 @@ def list_policy_versions(policyName,
try:
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
vers = []
for ret in salt.utils.boto3.paged_call(conn.list_policy_versions,
for ret in __utils__['boto3.paged_call'](conn.list_policy_versions,
marker_flag='nextMarker',
marker_arg='marker',
policyName=policyName):
@ -576,7 +575,7 @@ def list_policy_versions(policyName,
log.warning('No versions found')
return {'policyVersions': vers}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def set_default_policy_version(policyName, policyVersionId,
@ -603,7 +602,7 @@ def set_default_policy_version(policyName, policyVersionId,
policyVersionId=str(policyVersionId)) # future lint: disable=blacklisted-function
return {'changed': True}
except ClientError as e:
return {'changed': False, 'error': salt.utils.boto3.get_error(e)}
return {'changed': False, 'error': __utils__['boto3.get_error'](e)}
def list_principal_policies(principal,
@ -629,7 +628,7 @@ def list_principal_policies(principal,
try:
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
vers = []
for ret in salt.utils.boto3.paged_call(conn.list_principal_policies,
for ret in __utils__['boto3.paged_call'](conn.list_principal_policies,
principal=principal,
marker_flag='nextMarker',
marker_arg='marker'):
@ -638,7 +637,7 @@ def list_principal_policies(principal,
log.warning('No policies found')
return {'policies': vers}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def attach_principal_policy(policyName, principal,
@ -664,7 +663,7 @@ def attach_principal_policy(policyName, principal,
principal=principal)
return {'attached': True}
except ClientError as e:
return {'attached': False, 'error': salt.utils.boto3.get_error(e)}
return {'attached': False, 'error': __utils__['boto3.get_error'](e)}
def detach_principal_policy(policyName, principal,
@ -689,7 +688,7 @@ def detach_principal_policy(policyName, principal,
principal=principal)
return {'detached': True}
except ClientError as e:
return {'detached': False, 'error': salt.utils.boto3.get_error(e)}
return {'detached': False, 'error': __utils__['boto3.get_error'](e)}
def topic_rule_exists(ruleName,
@ -718,10 +717,10 @@ def topic_rule_exists(ruleName,
# use, it's more useful to assume lack of existence than to assume a
# genuine authorization problem; authorization problems should not be
# the common case.
err = salt.utils.boto3.get_error(e)
err = __utils__['boto3.get_error'](e)
if e.response.get('Error', {}).get('Code') == 'UnauthorizedException':
return {'exists': False}
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create_topic_rule(ruleName, sql, actions, description,
@ -754,7 +753,7 @@ def create_topic_rule(ruleName, sql, actions, description,
})
return {'created': True}
except ClientError as e:
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
def replace_topic_rule(ruleName, sql, actions, description,
@ -787,7 +786,7 @@ def replace_topic_rule(ruleName, sql, actions, description,
})
return {'replaced': True}
except ClientError as e:
return {'replaced': False, 'error': salt.utils.boto3.get_error(e)}
return {'replaced': False, 'error': __utils__['boto3.get_error'](e)}
def delete_topic_rule(ruleName,
@ -811,7 +810,7 @@ def delete_topic_rule(ruleName,
conn.delete_topic_rule(ruleName=ruleName)
return {'deleted': True}
except ClientError as e:
return {'deleted': False, 'error': salt.utils.boto3.get_error(e)}
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
def describe_topic_rule(ruleName,
@ -840,7 +839,7 @@ def describe_topic_rule(ruleName,
else:
return {'rule': None}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def list_topic_rules(topic=None, ruleDisabled=None,
@ -873,7 +872,7 @@ def list_topic_rules(topic=None, ruleDisabled=None,
if ruleDisabled is not None:
kwargs['ruleDisabled'] = ruleDisabled
rules = []
for ret in salt.utils.boto3.paged_call(conn.list_topic_rules,
for ret in __utils__['boto3.paged_call'](conn.list_topic_rules,
marker_flag='nextToken',
marker_arg='nextToken',
**kwargs):
@ -882,4 +881,4 @@ def list_topic_rules(topic=None, ruleDisabled=None,
log.warning('No rules found')
return {'rules': rules}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}

View file

@ -53,7 +53,6 @@ import logging
import time
# Import Salt libs
import salt.utils.boto3
import salt.utils.compat
import salt.utils.odict as odict
import salt.utils.versions
@ -153,7 +152,7 @@ def exists(name, tags=None, region=None, key=None, keyid=None, profile=None):
rds = conn.describe_db_instances(DBInstanceIdentifier=name)
return {'exists': bool(rds)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def option_group_exists(name, tags=None, region=None, key=None, keyid=None,
@ -171,7 +170,7 @@ def option_group_exists(name, tags=None, region=None, key=None, keyid=None,
rds = conn.describe_option_groups(OptionGroupName=name)
return {'exists': bool(rds)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def parameter_group_exists(name, tags=None, region=None, key=None, keyid=None,
@ -193,7 +192,7 @@ def parameter_group_exists(name, tags=None, region=None, key=None, keyid=None,
resp = {}
if e.response['Error']['Code'] == 'DBParameterGroupNotFound':
resp['exists'] = False
resp['error'] = salt.utils.boto3.get_error(e)
resp['error'] = __utils__['boto3.get_error'](e)
return resp
@ -218,7 +217,7 @@ def subnet_group_exists(name, tags=None, region=None, key=None, keyid=None,
if "DBSubnetGroupNotFoundFault" in e.message:
return {'exists': False}
else:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create(name, allocated_storage, db_instance_class, engine,
@ -317,7 +316,7 @@ def create(name, allocated_storage, db_instance_class, engine,
log.info('Instance status after 10 seconds is: %s', stat)
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create_read_replica(name, source_name, db_instance_class=None,
@ -375,7 +374,7 @@ def create_read_replica(name, source_name, db_instance_class=None,
return {'exists': bool(rds_replica)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create_option_group(name, engine_name, major_engine_version,
@ -408,7 +407,7 @@ def create_option_group(name, engine_name, major_engine_version,
return {'exists': bool(rds)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create_parameter_group(name, db_parameter_group_family, description,
@ -444,7 +443,7 @@ def create_parameter_group(name, db_parameter_group_family, description,
return {'exists': bool(rds), 'message':
'Created RDS parameter group {0}'.format(name)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def create_subnet_group(name, description, subnet_ids, tags=None,
@ -475,7 +474,7 @@ def create_subnet_group(name, description, subnet_ids, tags=None,
return {'created': bool(rds)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def update_parameter_group(name, parameters, apply_method="pending-reboot",
@ -520,7 +519,7 @@ def update_parameter_group(name, parameters, apply_method="pending-reboot",
Parameters=param_list)
return {'results': bool(res)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe(name, tags=None, region=None, key=None, keyid=None,
@ -568,7 +567,7 @@ def describe(name, tags=None, region=None, key=None, keyid=None,
else:
return {'rds': None}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
except IndexError:
return {'rds': None}
@ -597,7 +596,7 @@ def describe_db_instances(name=None, filters=None, jmespath='DBInstances',
except ClientError as e:
code = getattr(e, 'response', {}).get('Error', {}).get('Code')
if code != 'DBInstanceNotFound':
log.error(salt.utils.boto3.get_error(e))
log.error(__utils__['boto3.get_error'](e))
return []
@ -647,7 +646,7 @@ def get_endpoint(name, tags=None, region=None, key=None, keyid=None,
return endpoint
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
return endpoint
@ -706,7 +705,7 @@ def delete(name, skip_final_snapshot=None, final_db_snapshot_identifier=None,
'deleted.', timeout, name)
time.sleep(10)
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def delete_option_group(name, region=None, key=None, keyid=None, profile=None):
@ -731,7 +730,7 @@ def delete_option_group(name, region=None, key=None, keyid=None, profile=None):
return {'deleted': bool(res), 'message':
'Deleted RDS option group {0}.'.format(name)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def delete_parameter_group(name, region=None, key=None, keyid=None,
@ -753,7 +752,7 @@ def delete_parameter_group(name, region=None, key=None, keyid=None,
return {'deleted': bool(r), 'message':
'Deleted RDS parameter group {0}.'.format(name)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def delete_subnet_group(name, region=None, key=None, keyid=None,
@ -775,7 +774,7 @@ def delete_subnet_group(name, region=None, key=None, keyid=None,
return {'deleted': bool(r), 'message':
'Deleted RDS subnet group {0}.'.format(name)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_parameter_group(name, Filters=None, MaxRecords=None, Marker=None,
@ -817,7 +816,7 @@ def describe_parameter_group(name, Filters=None, MaxRecords=None, Marker=None,
return {'results': bool(info), 'message':
'Got RDS descrition for group {0}.'.format(name)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def describe_parameters(name, Source=None, MaxRecords=None, Marker=None,
@ -873,7 +872,7 @@ def describe_parameters(name, Source=None, MaxRecords=None, Marker=None,
ret['parameters'] = parameters
return ret
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def modify_db_instance(name,
@ -950,7 +949,7 @@ def modify_db_instance(name,
'Modified RDS db instance {0}.'.format(name),
'results': dict(info)}
except ClientError as e:
return {'error': salt.utils.boto3.get_error(e)}
return {'error': __utils__['boto3.get_error'](e)}
def _tag_doc(tags):

View file

@ -473,6 +473,9 @@ def authorize(name=None, source_group_name=None,
log.error(msg)
return False
except boto.exception.EC2ResponseError as e:
# if we are trying to add the same rule then we are already in the desired state, return true
if e.error_code == 'InvalidPermission.Duplicate':
return True
msg = ('Failed to add rule to security group {0} with id {1}.'
.format(group.name, group.id))
log.error(msg)

View file

@ -134,8 +134,6 @@ import time
import random
# Import Salt libs
import salt.utils.boto
import salt.utils.boto3
import salt.utils.compat
import salt.utils.versions
from salt.exceptions import SaltInvocationError, CommandExecutionError
@ -279,7 +277,7 @@ def _create_resource(resource, name=None, tags=None, region=None, key=None,
log.warning(e)
return {'created': False, 'error': {'message': e}}
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
def _delete_resource(resource, name=None, resource_id=None, region=None,
@ -323,7 +321,7 @@ def _delete_resource(resource, name=None, resource_id=None, region=None,
e = '{0} was not deleted.'.format(resource)
return {'deleted': False, 'error': {'message': e}}
except BotoServerError as e:
return {'deleted': False, 'error': salt.utils.boto.get_error(e)}
return {'deleted': False, 'error': __utils__['boto.get_error'](e)}
def _get_resource(resource, name=None, resource_id=None, region=None,
@ -451,7 +449,7 @@ def get_resource_id(resource, name=None, resource_id=None, region=None,
return {'id': _get_resource_id(resource, name, region=region, key=key,
keyid=keyid, profile=profile)}
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
def resource_exists(resource, name=None, resource_id=None, tags=None,
@ -478,7 +476,7 @@ def resource_exists(resource, name=None, resource_id=None, tags=None,
key=key, keyid=keyid,
profile=profile))}
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
def _find_vpcs(vpc_id=None, vpc_name=None, cidr=None, tags=None,
@ -570,7 +568,7 @@ def get_id(name=None, cidr=None, tags=None, region=None, key=None, keyid=None,
return {'id': _get_id(vpc_name=name, cidr=cidr, tags=tags, region=region,
key=key, keyid=keyid, profile=profile)}
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
def exists(vpc_id=None, name=None, cidr=None, tags=None, region=None, key=None,
@ -593,7 +591,7 @@ def exists(vpc_id=None, name=None, cidr=None, tags=None, region=None, key=None,
vpc_ids = _find_vpcs(vpc_id=vpc_id, vpc_name=name, cidr=cidr, tags=tags,
region=region, key=key, keyid=keyid, profile=profile)
except BotoServerError as err:
boto_err = salt.utils.boto.get_error(err)
boto_err = __utils__['boto.get_error'](err)
if boto_err.get('aws', {}).get('code') == 'InvalidVpcID.NotFound':
# VPC was not found: handle the error and return False.
return {'exists': False}
@ -643,7 +641,7 @@ def create(cidr_block, instance_tenancy=None, vpc_name=None,
log.warning('VPC was not created')
return {'created': False}
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
def delete(vpc_id=None, name=None, vpc_name=None, tags=None,
@ -693,7 +691,7 @@ def delete(vpc_id=None, name=None, vpc_name=None, tags=None,
log.warning('VPC %s was not deleted.', vpc_id)
return {'deleted': False}
except BotoServerError as e:
return {'deleted': False, 'error': salt.utils.boto.get_error(e)}
return {'deleted': False, 'error': __utils__['boto.get_error'](e)}
def describe(vpc_id=None, vpc_name=None, region=None, key=None,
@ -722,7 +720,7 @@ def describe(vpc_id=None, vpc_name=None, region=None, key=None,
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
vpc_id = check_vpc(vpc_id, vpc_name, region, key, keyid, profile)
except BotoServerError as err:
boto_err = salt.utils.boto.get_error(err)
boto_err = __utils__['boto.get_error'](err)
if boto_err.get('aws', {}).get('code') == 'InvalidVpcID.NotFound':
# VPC was not found: handle the error and return None.
return {'vpc': None}
@ -736,7 +734,7 @@ def describe(vpc_id=None, vpc_name=None, region=None, key=None,
try:
vpcs = conn.get_all_vpcs(**filter_parameters)
except BotoServerError as err:
return {'error': salt.utils.boto.get_error(err)}
return {'error': __utils__['boto.get_error'](err)}
if vpcs:
vpc = vpcs[0] # Found!
@ -806,7 +804,7 @@ def describe_vpcs(vpc_id=None, name=None, cidr=None, tags=None,
return {'vpcs': []}
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
def _find_subnets(subnet_name=None, vpc_id=None, cidr=None, tags=None, conn=None):
@ -871,7 +869,7 @@ def create_subnet(vpc_id=None, cidr_block=None, vpc_name=None,
if not vpc_id:
return {'created': False, 'error': {'message': 'VPC {0} does not exist.'.format(vpc_name or vpc_id)}}
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
return _create_resource('subnet', name=subnet_name, tags=tags, vpc_id=vpc_id,
availability_zone=availability_zone,
@ -934,7 +932,7 @@ def subnet_exists(subnet_id=None, name=None, subnet_name=None, cidr=None,
try:
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
except BotoServerError as err:
return {'error': salt.utils.boto.get_error(err)}
return {'error': __utils__['boto.get_error'](err)}
filter_parameters = {'filters': {}}
if subnet_id:
@ -952,7 +950,7 @@ def subnet_exists(subnet_id=None, name=None, subnet_name=None, cidr=None,
try:
subnets = conn.get_all_subnets(**filter_parameters)
except BotoServerError as err:
boto_err = salt.utils.boto.get_error(err)
boto_err = __utils__['boto.get_error'](err)
if boto_err.get('aws', {}).get('code') == 'InvalidSubnetID.NotFound':
# Subnet was not found: handle the error and return False.
return {'exists': False}
@ -995,7 +993,7 @@ def get_subnet_association(subnets, region=None, key=None, keyid=None,
# subnet_ids=subnets can accept either a string or a list
subnets = conn.get_all_subnets(subnet_ids=subnets)
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
# using a set to store vpc_ids - the use of set prevents duplicate
# vpc_id values
@ -1035,7 +1033,7 @@ def describe_subnet(subnet_id=None, subnet_name=None, region=None,
subnet = _get_resource('subnet', name=subnet_name, resource_id=subnet_id,
region=region, key=key, keyid=keyid, profile=profile)
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
if not subnet:
return {'subnet': None}
@ -1116,7 +1114,7 @@ def describe_subnets(subnet_ids=None, subnet_names=None, vpc_id=None, cidr=None,
return {'subnets': subnets_list}
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
def create_internet_gateway(internet_gateway_name=None, vpc_id=None,
@ -1158,7 +1156,7 @@ def create_internet_gateway(internet_gateway_name=None, vpc_id=None,
)
return r
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
def delete_internet_gateway(internet_gateway_id=None,
@ -1212,7 +1210,7 @@ def delete_internet_gateway(internet_gateway_id=None,
region=region, key=key, keyid=keyid,
profile=profile)
except BotoServerError as e:
return {'deleted': False, 'error': salt.utils.boto.get_error(e)}
return {'deleted': False, 'error': __utils__['boto.get_error'](e)}
def _find_nat_gateways(nat_gateway_id=None, subnet_id=None, subnet_name=None, vpc_id=None, vpc_name=None,
@ -1253,7 +1251,7 @@ def _find_nat_gateways(nat_gateway_id=None, subnet_id=None, subnet_name=None, vp
conn3 = _get_conn3(region=region, key=key, keyid=keyid, profile=profile)
nat_gateways = []
for ret in salt.utils.boto3.paged_call(conn3.describe_nat_gateways,
for ret in __utils__['boto3.paged_call'](conn3.describe_nat_gateways,
marker_flag='NextToken', marker_arg='NextToken',
**filter_parameters):
for gw in ret.get('NatGateways', []):
@ -1376,7 +1374,7 @@ def create_nat_gateway(subnet_id=None,
r = conn3.create_nat_gateway(SubnetId=subnet_id, AllocationId=allocation_id)
return {'created': True, 'id': r.get('NatGateway', {}).get('NatGatewayId')}
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
def delete_nat_gateway(nat_gateway_id,
@ -1452,7 +1450,7 @@ def delete_nat_gateway(nat_gateway_id,
conn3.release_address(AllocationId=addr.get('AllocationId'))
return {'deleted': True}
except BotoServerError as e:
return {'deleted': False, 'error': salt.utils.boto.get_error(e)}
return {'deleted': False, 'error': __utils__['boto.get_error'](e)}
def create_customer_gateway(vpn_connection_type, ip_address, bgp_asn,
@ -1573,7 +1571,7 @@ def create_dhcp_options(domain_name=None, domain_name_servers=None, ntp_servers=
)
return r
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
def get_dhcp_options(dhcp_options_name=None, dhcp_options_id=None,
@ -1604,7 +1602,7 @@ def get_dhcp_options(dhcp_options_name=None, dhcp_options_id=None,
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
r = conn.get_all_dhcp_options(dhcp_options_ids=[dhcp_options_id])
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
if not r:
return {'dhcp_options': None}
@ -1667,7 +1665,7 @@ def associate_dhcp_options_to_vpc(dhcp_options_id, vpc_id=None, vpc_name=None,
dhcp_options_id, vpc_id)
return {'associated': False, 'error': {'message': 'DHCP options could not be associated.'}}
except BotoServerError as e:
return {'associated': False, 'error': salt.utils.boto.get_error(e)}
return {'associated': False, 'error': __utils__['boto.get_error'](e)}
def dhcp_options_exists(dhcp_options_id=None, name=None, dhcp_options_name=None,
@ -1720,7 +1718,7 @@ def create_network_acl(vpc_id=None, vpc_name=None, network_acl_name=None,
try:
vpc_id = check_vpc(vpc_id, vpc_name, region, key, keyid, profile)
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
if not vpc_id:
return {'created': False,
@ -1751,7 +1749,7 @@ def create_network_acl(vpc_id=None, vpc_name=None, network_acl_name=None,
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
association_id = conn.associate_network_acl(r['id'], subnet_id)
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
r['association_id'] = association_id
return r
@ -1866,7 +1864,7 @@ def associate_network_acl_to_subnet(network_acl_id=None, subnet_id=None,
network_acl_id, subnet_id)
return {'associated': False, 'error': {'message': 'ACL could not be assocaited.'}}
except BotoServerError as e:
return {'associated': False, 'error': salt.utils.boto.get_error(e)}
return {'associated': False, 'error': __utils__['boto.get_error'](e)}
def disassociate_network_acl(subnet_id=None, vpc_id=None, subnet_name=None, vpc_name=None,
@ -1905,7 +1903,7 @@ def disassociate_network_acl(subnet_id=None, vpc_id=None, subnet_name=None, vpc_
association_id = conn.disassociate_network_acl(subnet_id, vpc_id=vpc_id)
return {'disassociated': True, 'association_id': association_id}
except BotoServerError as e:
return {'disassociated': False, 'error': salt.utils.boto.get_error(e)}
return {'disassociated': False, 'error': __utils__['boto.get_error'](e)}
def _create_network_acl_entry(network_acl_id=None, rule_number=None, protocol=None,
@ -1958,7 +1956,7 @@ def _create_network_acl_entry(network_acl_id=None, rule_number=None, protocol=No
log.warning('Network ACL entry was not %s', rkey)
return {rkey: created}
except BotoServerError as e:
return {rkey: False, 'error': salt.utils.boto.get_error(e)}
return {rkey: False, 'error': __utils__['boto.get_error'](e)}
def create_network_acl_entry(network_acl_id=None, rule_number=None, protocol=None,
@ -2041,7 +2039,7 @@ def delete_network_acl_entry(network_acl_id=None, rule_number=None, egress=None,
log.warning('Network ACL was not deleted')
return {'deleted': deleted}
except BotoServerError as e:
return {'deleted': False, 'error': salt.utils.boto.get_error(e)}
return {'deleted': False, 'error': __utils__['boto.get_error'](e)}
def create_route_table(vpc_id=None, vpc_name=None, route_table_name=None,
@ -2177,7 +2175,7 @@ def route_exists(destination_cidr_block, route_table_name=None, route_table_id=N
log.warning('Route %s does not exist.', destination_cidr_block)
return {'exists': False}
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
def associate_route_table(route_table_id=None, subnet_id=None,
@ -2229,7 +2227,7 @@ def associate_route_table(route_table_id=None, subnet_id=None,
route_table_id, subnet_id)
return {'association_id': association_id}
except BotoServerError as e:
return {'associated': False, 'error': salt.utils.boto.get_error(e)}
return {'associated': False, 'error': __utils__['boto.get_error'](e)}
def disassociate_route_table(association_id, region=None, key=None, keyid=None, profile=None):
@ -2256,7 +2254,7 @@ def disassociate_route_table(association_id, region=None, key=None, keyid=None,
log.warning('Route table with association id %s has not been disassociated.', association_id)
return {'disassociated': False}
except BotoServerError as e:
return {'disassociated': False, 'error': salt.utils.boto.get_error(e)}
return {'disassociated': False, 'error': __utils__['boto.get_error'](e)}
def replace_route_table_association(association_id, route_table_id, region=None, key=None, keyid=None, profile=None):
@ -2278,7 +2276,7 @@ def replace_route_table_association(association_id, route_table_id, region=None,
route_table_id, association_id)
return {'replaced': True, 'association_id': association_id}
except BotoServerError as e:
return {'replaced': False, 'error': salt.utils.boto.get_error(e)}
return {'replaced': False, 'error': __utils__['boto.get_error'](e)}
def create_route(route_table_id=None, destination_cidr_block=None,
@ -2359,7 +2357,7 @@ def create_route(route_table_id=None, destination_cidr_block=None,
nat_gateway_id = gws[0]['NatGatewayId']
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
if not nat_gateway_id:
return _create_resource('route', route_table_id=route_table_id,
@ -2375,7 +2373,7 @@ def create_route(route_table_id=None, destination_cidr_block=None,
NatGatewayId=nat_gateway_id)
return {'created': True, 'id': ret.get('NatGatewayId')}
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
def delete_route(route_table_id=None, destination_cidr_block=None,
@ -2408,7 +2406,7 @@ def delete_route(route_table_id=None, destination_cidr_block=None,
return {'created': False,
'error': {'message': 'route table {0} does not exist.'.format(route_table_name)}}
except BotoServerError as e:
return {'created': False, 'error': salt.utils.boto.get_error(e)}
return {'created': False, 'error': __utils__['boto.get_error'](e)}
return _delete_resource(resource='route', resource_id=route_table_id,
destination_cidr_block=destination_cidr_block,
@ -2464,7 +2462,7 @@ def replace_route(route_table_id=None, destination_cidr_block=None,
)
return {'replaced': False}
except BotoServerError as e:
return {'replaced': False, 'error': salt.utils.boto.get_error(e)}
return {'replaced': False, 'error': __utils__['boto.get_error'](e)}
def describe_route_table(route_table_id=None, route_table_name=None,
@ -2525,7 +2523,7 @@ def describe_route_table(route_table_id=None, route_table_name=None,
return route_table
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
def describe_route_tables(route_table_id=None, route_table_name=None,
@ -2611,7 +2609,7 @@ def describe_route_tables(route_table_id=None, route_table_name=None,
return tables
except BotoServerError as e:
return {'error': salt.utils.boto.get_error(e)}
return {'error': __utils__['boto.get_error'](e)}
def _create_dhcp_options(conn, domain_name=None, domain_name_servers=None, ntp_servers=None, netbios_name_servers=None,
@ -2821,7 +2819,7 @@ def request_vpc_peering_connection(requester_vpc_id=None, requester_vpc_name=Non
return {'msg': msg}
except botocore.exceptions.ClientError as err:
log.error('Got an error while trying to request vpc peering')
return {'error': salt.utils.boto.get_error(err)}
return {'error': __utils__['boto.get_error'](err)}
def _get_peering_connection_ids(name, conn):
@ -2948,7 +2946,7 @@ def accept_vpc_peering_connection( # pylint: disable=too-many-arguments
return {'msg': 'VPC peering connection accepted.'}
except botocore.exceptions.ClientError as err:
log.error('Got an error while trying to accept vpc peering')
return {'error': salt.utils.boto.get_error(err)}
return {'error': __utils__['boto.get_error'](err)}
def _vpc_peering_conn_id_for_name(name, conn):
@ -3026,7 +3024,7 @@ def delete_vpc_peering_connection(conn_id=None, conn_name=None, region=None,
conn.delete_vpc_peering_connection(DryRun=dry_run, VpcPeeringConnectionId=conn_id)
return {'msg': 'VPC peering connection deleted.'}
except botocore.exceptions.ClientError as err:
e = salt.utils.boto.get_error(err)
e = __utils__['boto.get_error'](err)
log.error('Failed to delete VPC peering %s: %s', conn_name or conn_id, e)
return {'error': e}

View file

@ -14,8 +14,8 @@ from __future__ import absolute_import, print_function, unicode_literals
import datetime
import difflib
import errno
import fileinput
import fnmatch
import io
import itertools
import logging
import operator
@ -2535,10 +2535,16 @@ def blockreplace(path,
if not os.path.exists(path):
raise SaltInvocationError('File not found: {0}'.format(path))
if not __utils__['files.is_text'](path):
raise SaltInvocationError(
'Cannot perform string replacements on a binary file: {0}'
.format(path)
try:
file_encoding = __utils__['files.get_encoding'](path)
except CommandExecutionError:
file_encoding = None
if __utils__['files.is_binary'](path):
if not file_encoding:
raise SaltInvocationError(
'Cannot perform string replacements on a binary file: {0}'
.format(path)
)
if append_newline is None and not content.endswith((os.linesep, '\n')):
@ -2593,18 +2599,9 @@ def blockreplace(path,
# We do not use in-place editing to avoid file attrs modifications when
# no changes are required and to avoid any file access on a partially
# written file.
#
# We could also use salt.utils.filebuffer.BufferedReader
try:
fi_file = fileinput.input(
path,
inplace=False,
backup=False,
bufsize=1,
mode='rb')
fi_file = io.open(path, mode='r', encoding=file_encoding, newline='')
for line in fi_file:
line = salt.utils.stringutils.to_unicode(line)
write_line_to_new_file = True
if linesep is None:
@ -2709,7 +2706,7 @@ def blockreplace(path,
try:
fh_ = salt.utils.atomicfile.atomic_open(path, 'wb')
for line in new_file:
fh_.write(salt.utils.stringutils.to_bytes(line))
fh_.write(salt.utils.stringutils.to_bytes(line, encoding=file_encoding))
finally:
fh_.close()

View file

@ -35,7 +35,7 @@ In case both are provided the `file` entry is preferred.
.. warning::
Configuration options will change in Flourine. All options above will be replaced by:
Configuration options will change in Fluorine. All options above will be replaced by:
- kubernetes.kubeconfig or kubernetes.kubeconfig-data
- kubernetes.context

View file

@ -14,7 +14,6 @@ import salt.utils.files
import salt.utils.path
import salt.utils.platform
import salt.utils.stringutils
import salt.utils.mac_utils
from salt.exceptions import CommandExecutionError
from salt.utils.versions import LooseVersion as _LooseVersion
@ -62,7 +61,7 @@ def _get_service(name):
:return: The service information for the service, otherwise an Error
:rtype: dict
'''
services = salt.utils.mac_utils.available_services()
services = __utils__['mac_utils.available_services']()
name = name.lower()
if name in services:
@ -127,7 +126,7 @@ def launchctl(sub_cmd, *args, **kwargs):
salt '*' service.launchctl debug org.cups.cupsd
'''
return salt.utils.mac_utils.launchctl(sub_cmd, *args, **kwargs)
return __utils__['mac_utils.launchctl'](sub_cmd, *args, **kwargs)
def list_(name=None, runas=None):
@ -158,13 +157,11 @@ def list_(name=None, runas=None):
return launchctl('list',
label,
return_stdout=True,
output_loglevel='trace',
runas=runas)
# Collect information on all services: will raise an error if it fails
return launchctl('list',
return_stdout=True,
output_loglevel='trace',
runas=runas)
@ -412,7 +409,7 @@ def enabled(name, runas=None):
return False
def disabled(name, runas=None):
def disabled(name, runas=None, domain='system'):
'''
Check if the specified service is not enabled. This is the opposite of
``service.enabled``
@ -421,6 +418,8 @@ def disabled(name, runas=None):
:param str runas: User to run launchctl commands
:param str domain: domain to check for disabled services. Default is system.
:return: True if the specified service is NOT enabled, otherwise False
:rtype: bool
@ -430,8 +429,22 @@ def disabled(name, runas=None):
salt '*' service.disabled org.cups.cupsd
'''
# A service is disabled if it is not enabled
return not enabled(name, runas=runas)
ret = False
disabled = launchctl('print-disabled',
domain,
return_stdout=True,
output_loglevel='trace',
runas=runas)
for service in disabled.split("\n"):
if name in service:
srv_name = service.split("=>")[0].split("\"")[1]
status = service.split("=>")[1]
if name != srv_name:
pass
else:
return True if 'true' in status.lower() else False
return False
def get_all(runas=None):
@ -454,7 +467,7 @@ def get_all(runas=None):
enabled = get_enabled(runas=runas)
# Get list of all services
available = list(salt.utils.mac_utils.available_services().keys())
available = list(__utils__['mac_utils.available_services']().keys())
# Return composite list
return sorted(set(enabled + available))

View file

@ -74,8 +74,7 @@ def _atrun_enabled():
# Collect information on service: will raise an error if it fails
salt.utils.mac_utils.launchctl('list',
label,
return_stdout=True,
output_loglevel='quiet')
return_stdout=True)
return True
except CommandExecutionError:
return False
@ -111,9 +110,8 @@ def _enable_atrun():
return False
salt.utils.mac_utils.launchctl('enable',
'system/{0}'.format(label),
output_loglevel='quiet')
salt.utils.mac_utils.launchctl('load', path, output_loglevel='quiet')
'system/{0}'.format(label))
salt.utils.mac_utils.launchctl('load', path)
return _atrun_enabled()

View file

@ -627,7 +627,7 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
'''
if 'no_chown' in kwargs:
salt.utils.versions.warn_until(
'Flourine',
'Fluorine',
'The no_chown argument has been deprecated and is no longer used. '
'Its functionality was removed in Boron.')
kwargs.pop('no_chown')

View file

@ -181,7 +181,9 @@ def latest_version(*names, **kwargs):
out = __salt__['cmd.run'](cmd, output_loglevel='trace')
for line in out.splitlines():
p = line.split(',' if _supports_parsing() else None)
if line.startswith('No results found for'):
return pkglist
p = line.split(';' if _supports_parsing() else None)
if p and p[0] in ('=:', '<:', '>:', ''):
# These are explanation comments
@ -190,7 +192,7 @@ def latest_version(*names, **kwargs):
s = _splitpkg(p[0])
if s:
if not s[0] in pkglist:
if len(p) > 1 and p[1] == '<':
if len(p) > 1 and p[1] in ('<', '', '='):
pkglist[s[0]] = s[1]
else:
pkglist[s[0]] = ''
@ -669,7 +671,6 @@ def file_dict(*packages):
for package in packages:
cmd = ['pkg_info', '-qL', package]
ret = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
files[package] = []
for line in ret['stderr'].splitlines():
errors.append(line)
@ -681,7 +682,7 @@ def file_dict(*packages):
continue # unexpected string
ret = {'errors': errors, 'files': files}
for field in ret:
for field in list(ret):
if not ret[field] or ret[field] == '':
del ret[field]
return ret

View file

@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
"""
'''
Docker Swarm Module using Docker's Python SDK
=============================================
@ -18,12 +17,17 @@ Dependencies
Docker Python SDK
-----------------
pip install -U docker
.. code-block:: bash
pip install -U docker
More information: https://docker-py.readthedocs.io/en/stable/
"""
'''
# Import python libraries
from __future__ import absolute_import, unicode_literals, print_function
# Import Salt libs
import salt.utils.json
try:
@ -41,7 +45,7 @@ def __virtual__():
'''
if HAS_DOCKER:
return __virtualname__
return False, 'The swarm module failed to load: Docker python module is not avaialble.'
return False, 'The swarm module failed to load: Docker python module is not available.'
def __init__(self):
@ -58,7 +62,7 @@ def swarm_tokens():
.. code-block:: bash
salt '*' swarm.swarm_tokens
salt '*' swarm.swarm_tokens
'''
client = docker.APIClient(base_url='unix://var/run/docker.sock')
service = client.inspect_swarm()
@ -72,37 +76,39 @@ def swarm_init(advertise_addr=str,
Initalize Docker on Minion as a Swarm Manager
advertise_addr
The ip of the manager
The ip of the manager
listen_addr
Listen address used for inter-manager communication,
as well as determining the networking interface used
for the VXLAN Tunnel Endpoint (VTEP).
This can either be an address/port combination in
the form 192.168.1.1:4567,
or an interface followed by a port number,
like eth0:4567
Listen address used for inter-manager communication,
as well as determining the networking interface used
for the VXLAN Tunnel Endpoint (VTEP).
This can either be an address/port combination in
the form 192.168.1.1:4567,
or an interface followed by a port number,
like eth0:4567
force_new_cluster
Force a new cluster if True is passed
Force a new cluster if True is passed
CLI Example:
.. code-block:: bash
salt '*' swarm.swarm_init advertise_addr='192.168.50.10' listen_addr='0.0.0.0' force_new_cluster=False
salt '*' swarm.swarm_init advertise_addr='192.168.50.10' listen_addr='0.0.0.0' force_new_cluster=False
'''
try:
salt_return = {}
__context__['client'].swarm.init(advertise_addr,
listen_addr,
force_new_cluster)
output = 'Docker swarm has been Initalized on '+ __context__['server_name'] + ' and the worker/manager Join token is below'
output = 'Docker swarm has been initialized on {0} ' \
'and the worker/manager Join token is below'.format(__context__['server_name'])
salt_return.update({'Comment': output,
'Tokens': swarm_tokens()})
except TypeError:
salt_return = {}
salt_return.update({'Error': 'Please make sure your passing advertise_addr, listen_addr and force_new_cluster correctly.'})
salt_return.update({'Error': 'Please make sure you are passing advertise_addr, '
'listen_addr and force_new_cluster correctly.'})
return salt_return
@ -113,21 +119,22 @@ def joinswarm(remote_addr=int,
Join a Swarm Worker to the cluster
remote_addr
The manager node you want to connect to for the swarm
The manager node you want to connect to for the swarm
listen_addr
Listen address used for inter-manager communication if the node gets promoted to manager,
as well as determining the networking interface used for the VXLAN Tunnel Endpoint (VTEP)
Listen address used for inter-manager communication if the node gets promoted to manager,
as well as determining the networking interface used for the VXLAN Tunnel Endpoint (VTEP)
token
Either the manager join token or the worker join token.
You can get the worker or manager token via `salt '*' swarm.swarm_tokens`
Either the manager join token or the worker join token.
You can get the worker or manager token via ``salt '*' swarm.swarm_tokens``
CLI Example:
.. code-block:: bash
salt '*' swarm.joinswarm remote_addr=192.168.50.10 listen_addr='0.0.0.0' token='SWMTKN-1-64tux2g0701r84ofq93zppcih0pe081akq45owe9ts61f30x4t-06trjugdu7x2z47j938s54il'
salt '*' swarm.joinswarm remote_addr=192.168.50.10 listen_addr='0.0.0.0' \
token='SWMTKN-1-64tux2g0701r84ofq93zppcih0pe081akq45owe9ts61f30x4t-06trjugdu7x2z47j938s54il'
'''
try:
salt_return = {}
@ -138,7 +145,8 @@ def joinswarm(remote_addr=int,
salt_return.update({'Comment': output, 'Manager_Addr': remote_addr})
except TypeError:
salt_return = {}
salt_return.update({'Error': 'Please make sure this minion is not part of a swarm and your passing remote_addr, listen_addr and token correctly.'})
salt_return.update({'Error': 'Please make sure this minion is not part of a swarm and you are '
'passing remote_addr, listen_addr and token correctly.'})
return salt_return
@ -147,13 +155,13 @@ def leave_swarm(force=bool):
Force the minion to leave the swarm
force
Will force the minion/worker/manager to leave the swarm
Will force the minion/worker/manager to leave the swarm
CLI Example:
.. code-block:: bash
salt '*' swarm.leave_swarm force=False
salt '*' swarm.leave_swarm force=False
'''
salt_return = {}
__context__['client'].swarm.leave(force=force)
@ -173,30 +181,32 @@ def service_create(image=str,
Create Docker Swarm Service Create
image
The docker image
The docker image
name
Is the service name
Is the service name
command
The docker command to run in the container at launch
The docker command to run in the container at launch
hostname
The hostname of the containers
The hostname of the containers
replicas
How many replicas you want running in the swarm
How many replicas you want running in the swarm
target_port
The target port on the container
The target port on the container
published_port
port thats published on the host/os
port thats published on the host/os
CLI Example:
.. code-block:: bash
salt '*' swarm.service_create image=httpd name=Test_Service command=None hostname=salthttpd replicas=6 target_port=80 published_port=80
salt '*' swarm.service_create image=httpd name=Test_Service \
command=None hostname=salthttpd replicas=6 target_port=80 published_port=80
'''
try:
salt_return = {}
@ -219,7 +229,8 @@ def service_create(image=str,
'Published_Port': published_port})
except TypeError:
salt_return = {}
salt_return.update({'Error': 'Please make sure your passing arguments correctly [image, name, command, hostname, replicas, target_port and published_port]'})
salt_return.update({'Error': 'Please make sure you are passing arguments correctly '
'[image, name, command, hostname, replicas, target_port and published_port]'})
return salt_return
@ -228,12 +239,13 @@ def swarm_service_info(service_name=str):
Swarm Service Information
service_name
The name of the service that you want information on about the service
The name of the service that you want information on about the service
CLI Example:
.. code-block:: bash
salt '*' swarm.swarm_service_info service_name=Test_Service
salt '*' swarm.swarm_service_info service_name=Test_Service
'''
try:
salt_return = {}
@ -282,12 +294,13 @@ def remove_service(service=str):
Remove Swarm Service
service
The name of the service
The name of the service
CLI Example:
.. code-block:: bash
salt '*' swarm.remove_service service=Test_Service
salt '*' swarm.remove_service service=Test_Service
'''
try:
salt_return = {}
@ -306,12 +319,13 @@ def node_ls(server=str):
Displays Information about Swarm Nodes with passing in the server
server
The minion/server name
The minion/server name
CLI Example:
.. code-block:: bash
salt '*' swarm.node_ls server=minion1
salt '*' swarm.node_ls server=minion1
'''
try:
salt_return = {}
@ -327,7 +341,7 @@ def node_ls(server=str):
role = items['Spec']['Role']
availability = items['Spec']['Availability']
status = items['Status']
Version = items['Version']['Index']
version = items['Version']['Index']
salt_return.update({'Docker Version': docker_version,
'Platform': platform,
'Hostname': hostnames,
@ -335,7 +349,7 @@ def node_ls(server=str):
'Roles': role,
'Availability': availability,
'Status': status,
'Version': Version})
'Version': version})
except TypeError:
salt_return = {}
salt_return.update({'Error': 'The server arg is missing or you not targeting a Manager node?'})
@ -347,15 +361,16 @@ def remove_node(node_id=str, force=bool):
Remove a node from a swarm and the target needs to be a swarm manager
node_id
The node id from the return of swarm.node_ls
The node id from the return of swarm.node_ls
force
Forcefully remove the node/minion from the service
Forcefully remove the node/minion from the service
CLI Example:
.. code-block:: bash
salt '*' swarm.remove_node node_id=z4gjbe9rwmqahc2a91snvolm5 force=false
salt '*' swarm.remove_node node_id=z4gjbe9rwmqahc2a91snvolm5 force=false
'''
client = docker.APIClient(base_url='unix://var/run/docker.sock')
try:
@ -380,24 +395,26 @@ def update_node(availability=str,
Updates docker swarm nodes/needs to target a manager node/minion
availability
Drain or Active
Drain or Active
node_name
minion/node
minion/node
role
role of manager or worker
role of manager or worker
node_id
The Id and that can be obtained via swarm.node_ls
The Id and that can be obtained via swarm.node_ls
version
Is obtained by swarm.node_ls
Is obtained by swarm.node_ls
CLI Example:
.. code-block:: bash
salt '*' docker_util.update_node availability=drain node_name=minion2 role=worker node_id=3k9x7t8m4pel9c0nqr3iajnzp version=19
salt '*' docker_util.update_node availability=drain node_name=minion2 \
role=worker node_id=3k9x7t8m4pel9c0nqr3iajnzp version=19
'''
client = docker.APIClient(base_url='unix://var/run/docker.sock')
try:

View file

@ -30,7 +30,7 @@ import shutil # do not remove, used in imported file.py functions
import re # do not remove, used in imported file.py functions
import string # do not remove, used in imported file.py functions
import sys # do not remove, used in imported file.py functions
import fileinput # do not remove, used in imported file.py functions
import io # do not remove, used in imported file.py functions
import fnmatch # do not remove, used in imported file.py functions
import mmap # do not remove, used in imported file.py functions
import glob # do not remove, used in imported file.py functions

View file

@ -35,7 +35,7 @@ Current known limitations
- lxml
- uuid
- struct
- salt.modules.reg
- salt.utils.win_reg
'''
# Import Python libs
from __future__ import absolute_import, unicode_literals, print_function
@ -98,7 +98,7 @@ try:
import lxml
import struct
from lxml import etree
from salt.modules.reg import Registry as Registry
from salt.utils.win_reg import Registry
HAS_WINDOWS_MODULES = True
TRUE_VALUE_XPATH = etree.XPath('.//*[local-name() = "trueValue"]')
FALSE_VALUE_XPATH = etree.XPath('.//*[local-name() = "falseValue"]')
@ -2672,9 +2672,11 @@ def __virtual__():
'''
Only works on Windows systems
'''
if salt.utils.platform.is_windows() and HAS_WINDOWS_MODULES:
return __virtualname__
return False
if not salt.utils.platform.is_windows():
return False, 'win_lgpo: Not a Windows System'
if not HAS_WINDOWS_MODULES:
return False, 'win_lgpo: Required modules failed to load'
return __virtualname__
def _updateNamespace(item, new_namespace):
@ -5372,7 +5374,7 @@ def set_(computer_policy=None, user_policy=None,
else:
raise SaltInvocationError(msg)
if policy_namespace and policy_name in _admTemplateData[policy_namespace] and the_policy is not None:
log.debug('setting == %s', _admTemplateData[policy_namespace][policy_name].lower())
log.debug('setting == %s', six.text_type(_admTemplateData[policy_namespace][policy_name]).lower())
log.debug(six.text_type(_admTemplateData[policy_namespace][policy_name]).lower())
if six.text_type(_admTemplateData[policy_namespace][policy_name]).lower() != 'disabled' \
and six.text_type(_admTemplateData[policy_namespace][policy_name]).lower() != 'not configured':

View file

@ -9,16 +9,20 @@ import logging
# Import Salt libs
import salt.utils.platform
from salt.exceptions import SaltInvocationError
from salt.exceptions import SaltInvocationError, CommandExecutionError
# Import 3rd party libs
from salt.ext import six
_HKEY = 'HKLM'
_SNMP_KEY = r'SYSTEM\CurrentControlSet\Services\SNMP\Parameters'
_AGENT_KEY = r'{0}\RFC1156Agent'.format(_SNMP_KEY)
_COMMUNITIES_KEY = r'{0}\ValidCommunities'.format(_SNMP_KEY)
_SNMP_GPO_KEY = r'SOFTWARE\Policies\SNMP\Parameters'
_COMMUNITIES_GPO_KEY = r'{0}\ValidCommunities'.format(_SNMP_GPO_KEY)
_PERMISSION_TYPES = {'None': 1,
'Notify': 2,
'Read Only': 4,
@ -284,6 +288,21 @@ def get_community_names():
'''
Get the current accepted SNMP community names and their permissions.
If community names are being managed by Group Policy, those values will be
returned instead like this:
.. code-block:: bash
TestCommunity:
Managed by GPO
Community names managed normally will denote the permission instead:
.. code-block:: bash
TestCommunity:
Read Only
Returns:
dict: A dictionary of community names and permissions.
@ -294,25 +313,69 @@ def get_community_names():
salt '*' win_snmp.get_community_names
'''
ret = dict()
current_values = __salt__['reg.list_values'](
_HKEY, _COMMUNITIES_KEY, include_default=False)
# The communities are stored as the community name with a numeric permission
# value. Convert the numeric value to the text equivalent, as present in the
# Windows SNMP service GUI.
if isinstance(current_values, list):
for current_value in current_values:
# Look in GPO settings first
if __salt__['reg.key_exists'](_HKEY, _COMMUNITIES_GPO_KEY):
# Ignore error values
if not isinstance(current_value, dict):
continue
_LOG.debug('Loading communities from Group Policy settings')
permissions = six.text_type()
for permission_name in _PERMISSION_TYPES:
if current_value['vdata'] == _PERMISSION_TYPES[permission_name]:
permissions = permission_name
break
ret[current_value['vname']] = permissions
current_values = __salt__['reg.list_values'](
_HKEY, _COMMUNITIES_GPO_KEY, include_default=False)
# GPO settings are different in that they do not designate permissions
# They are a numbered list of communities like so:
#
# {1: "community 1",
# 2: "community 2"}
#
# Denote that it is being managed by Group Policy.
#
# community 1:
# Managed by GPO
# community 2:
# Managed by GPO
if isinstance(current_values, list):
for current_value in current_values:
# Ignore error values
if not isinstance(current_value, dict):
continue
ret[current_value['vdata']] = 'Managed by GPO'
if not ret:
_LOG.debug('Loading communities from SNMP settings')
current_values = __salt__['reg.list_values'](
_HKEY, _COMMUNITIES_KEY, include_default=False)
# The communities are stored as the community name with a numeric
# permission value. Like this (4 = Read Only):
#
# {"community 1": 4,
# "community 2": 4}
#
# Convert the numeric value to the text equivalent, as present in the
# Windows SNMP service GUI.
#
# community 1:
# Read Only
# community 2:
# Read Only
if isinstance(current_values, list):
for current_value in current_values:
# Ignore error values
if not isinstance(current_value, dict):
continue
permissions = six.text_type()
for permission_name in _PERMISSION_TYPES:
if current_value['vdata'] == _PERMISSION_TYPES[permission_name]:
permissions = permission_name
break
ret[current_value['vname']] = permissions
if not ret:
_LOG.debug('Unable to find existing communities.')
@ -323,6 +386,11 @@ def set_community_names(communities):
'''
Manage the SNMP accepted community names and their permissions.
.. note::
Settings managed by Group Policy will always take precedence over those
set using the SNMP interface. Therefore if this function finds Group
Policy settings it will raise a CommandExecutionError
Args:
communities (dict): A dictionary of SNMP community names and
permissions. The possible permissions can be found via
@ -331,6 +399,10 @@ def set_community_names(communities):
Returns:
bool: True if successful, otherwise False
Raises:
CommandExecutionError:
If SNMP settings are being managed by Group Policy
CLI Example:
.. code-block:: bash
@ -339,6 +411,11 @@ def set_community_names(communities):
'''
values = dict()
if __salt__['reg.key_exists'](_HKEY, _COMMUNITIES_GPO_KEY):
_LOG.debug('Communities on this system are managed by Group Policy')
raise CommandExecutionError(
'Communities on this system are managed by Group Policy')
current_communities = get_community_names()
if communities == current_communities:

View file

@ -511,7 +511,7 @@ def get_system_info():
.. code-block:: bash
salt 'minion-id' system.get_info
salt 'minion-id' system.get_system_info
'''
os_type = {1: 'Work Station',
2: 'Domain Controller',

View file

@ -92,6 +92,7 @@ def _strip_headers(output, *args):
if not args:
args_lc = ('installed packages',
'available packages',
'available upgrades',
'updated packages',
'upgraded packages')
else:

View file

@ -853,7 +853,7 @@ def _get_configured_repos():
'''
repos_cfg = configparser.ConfigParser()
repos_cfg.read([REPOS + '/' + fname for fname in os.listdir(REPOS)])
repos_cfg.read([REPOS + '/' + fname for fname in os.listdir(REPOS) if fname.endswith(".repo")])
return repos_cfg

View file

@ -6,8 +6,10 @@ for managing outputters.
# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
import errno
import logging
import io
import os
import re
import sys
@ -168,7 +170,7 @@ def get_printout(out, opts=None, **kwargs):
'''
try:
fileno = sys.stdout.fileno()
except AttributeError:
except (AttributeError, io.UnsupportedOperation):
fileno = -1 # sys.stdout is StringIO or fake
return not os.isatty(fileno)

View file

@ -1,6 +1,17 @@
# -*- coding: utf-8 -*-
'''
A convenience system to manage reactors
Beginning in the 2017.7 release, the reactor runner requires that the reactor
system is running. This is accomplished one of two ways, either
by having reactors configured or by including ``reactor`` in the
engine configuration for the Salt master.
.. code-block:: yaml
engines:
- reactor
'''
# Import python libs
from __future__ import absolute_import, print_function, unicode_literals

View file

@ -85,15 +85,28 @@ def serialize(obj, **options):
raise SerializationError(error)
def _read_dict(configparser, dictionary):
def _is_defaultsect(section_name):
if six.PY3:
return section_name == configparser.DEFAULTSECT
else: # in py2 the check is done against lowercased section name
return section_name.upper() == configparser.DEFAULTSECT
def _read_dict(cp, dictionary):
'''
Cribbed from python3's ConfigParser.read_dict function.
'''
for section, keys in dictionary.items():
section = six.text_type(section)
configparser.add_section(section)
if _is_defaultsect(section):
if six.PY2:
section = configparser.DEFAULTSECT
else:
cp.add_section(section)
for key, value in keys.items():
key = configparser.optionxform(six.text_type(key))
key = cp.optionxform(six.text_type(key))
if value is not None:
value = six.text_type(value)
configparser.set(section, key, value)
cp.set(section, key, value)

View file

@ -261,11 +261,21 @@ def find_sls_ids(sls, high):
'''
ret = []
for nid, item in six.iteritems(high):
if item['__sls__'] == sls:
for st_ in item:
if st_.startswith('__'):
continue
ret.append((nid, st_))
try:
sls_tgt = item['__sls__']
except TypeError:
if nid != '__exclude__':
log.error(
'Invalid non-dict item \'%s\' in high data. Value: %r',
nid, item
)
continue
else:
if sls_tgt == sls:
for st_ in item:
if st_.startswith('__'):
continue
ret.append((nid, st_))
return ret

View file

@ -275,9 +275,10 @@ def index_template_present(name, definition, check_definition=False):
ret['comment'] = 'Cannot create index template {0}, {1}'.format(name, output)
else:
if check_definition:
definition_parsed = salt.utils.json.loads(definition)
definition_to_diff = {'aliases': {}, 'mappings': {}, 'settings': {}}
definition_to_diff.update(definition)
current_template = __salt__['elasticsearch.index_template_get'](name=name)[name]
diff = __utils__['dictdiffer.deep_diff'](current_template, definition_parsed)
diff = __utils__['dictdiffer.deep_diff'](current_template, definition_to_diff)
if len(diff) != 0:
if __opts__['test']:
ret['comment'] = 'Index template {0} exist but need to be updated'.format(name)

View file

@ -8,7 +8,7 @@ salt.modules.kubernetes for more information.
.. warning::
Configuration options will change in Flourine.
Configuration options will change in Fluorine.
The kubernetes module is used to manage different kubernetes resources.

View file

@ -586,7 +586,7 @@ def installed(name,
'''
if 'no_chown' in kwargs:
salt.utils.versions.warn_until(
'Flourine',
'Fluorine',
'The no_chown argument has been deprecated and is no longer used. '
'Its functionality was removed in Boron.')
kwargs.pop('no_chown')

View file

@ -2512,13 +2512,21 @@ def latest(
'result': None,
'comment': '\n'.join(comments)}
# Build updated list of pkgs to exclude non-targeted ones
targeted_pkgs = list(targets.keys()) if pkgs else None
if salt.utils.platform.is_windows():
# pkg.install execution module on windows ensures the software
# package is installed when no version is specified, it does not
# upgrade the software to the latest. This is per the design.
# Build updated list of pkgs *with verion number*, exclude
# non-targeted ones
targeted_pkgs = [{x: targets[x]} for x in targets]
else:
# Build updated list of pkgs to exclude non-targeted ones
targeted_pkgs = list(targets)
# No need to refresh, if a refresh was necessary it would have been
# performed above when pkg.latest_version was run.
try:
# No need to refresh, if a refresh was necessary it would have been
# performed above when pkg.latest_version was run.
changes = __salt__['pkg.install'](name,
changes = __salt__['pkg.install'](name=None,
refresh=False,
fromrepo=fromrepo,
skip_verify=skip_verify,

View file

@ -581,6 +581,9 @@ def function(
m_ret = mdata['ret']
m_func = (not fail_function and True) or __salt__[fail_function](m_ret)
if m_ret is False:
m_func = False
if not m_func:
if minion not in fail_minions:
fail.add(minion)

View file

@ -137,7 +137,7 @@ def managed(name,
'''
if 'no_chown' in kwargs:
salt.utils.versions.warn_until(
'Flourine',
'Fluorine',
'The no_chown argument has been deprecated and is no longer used. '
'Its functionality was removed in Boron.')
kwargs.pop('no_chown')

View file

@ -115,10 +115,10 @@ def installed(name,
'''
if 'force' in kwargs:
salt.utils.versions.warn_until(
'Flourine',
'Fluorine',
'Parameter \'force\' has been detected in the argument list. This'
'parameter is no longer used and has been replaced by \'recurse\''
'as of Salt 2018.3.0. This warning will be removed in Salt Flourine.'
'as of Salt 2018.3.0. This warning will be removed in Salt Fluorine.'
)
kwargs.pop('force')

View file

@ -63,7 +63,8 @@ States for managing zpools
.. warning::
The layout will never be updated, it will only be used at time of creation.
It's a whole lot of work to figure out if a devices needs to be detached, removed, ... this is best done by the sysadmin on a case per case basis.
It's a whole lot of work to figure out if a devices needs to be detached, removed,
etc. This is best done by the sysadmin on a case per case basis.
Filesystem properties are also not updated, this should be managed by the zfs state module.
@ -90,7 +91,7 @@ def __virtual__():
if __grains__['zfs_support']:
return __virtualname__
else:
return (False, "The zpool state cannot be loaded: zfs not supported")
return False, 'The zpool state cannot be loaded: zfs not supported'
def _layout_to_vdev(layout, device_dir=None):
@ -186,7 +187,8 @@ def present(name, properties=None, filesystem_properties=None, layout=None, conf
The following configuration properties can be toggled in the config parameter.
- import (true) - try to import the pool before creating it if absent
- import_dirs (None) - specify additional locations to scan for devices on import (comma-seperated)
- device_dir (None, SunOS=/dev/dsk, Linux=/dev) - specify device directory to prepend for none absolute device paths
- device_dir (None, SunOS=/dev/dsk, Linux=/dev) - specify device directory to prepend for none
absolute device paths
- force (false) - try to force the import or creation
.. note::
@ -240,7 +242,8 @@ def present(name, properties=None, filesystem_properties=None, layout=None, conf
zpool create mypool mirror /tmp/vdisk0 /tmp/vdisk1 /tmp/vdisk2
Creating a 3-way mirror! While you probably expect it to be mirror root vdev with 2 devices + a root vdev of 1 device!
Creating a 3-way mirror! While you probably expect it to be mirror
root vdev with 2 devices + a root vdev of 1 device!
'''
ret = {'name': name,
@ -248,7 +251,7 @@ def present(name, properties=None, filesystem_properties=None, layout=None, conf
'result': None,
'comment': ''}
## config defaults
# config defaults
default_config = {
'import': True,
'import_dirs': None,
@ -260,12 +263,12 @@ def present(name, properties=None, filesystem_properties=None, layout=None, conf
elif __grains__['kernel'] == 'Linux':
default_config['device_dir'] = '/dev'
## merge state config
# merge state config
if config:
default_config.update(config)
config = default_config
## ensure properties are zfs values
# ensure properties are zfs values
if properties:
properties = __utils__['zfs.from_auto_dict'](properties)
elif properties is None:
@ -275,25 +278,21 @@ def present(name, properties=None, filesystem_properties=None, layout=None, conf
elif filesystem_properties is None:
filesystem_properties = {}
## parse layout
# parse layout
vdevs = _layout_to_vdev(layout, config['device_dir'])
if vdevs:
vdevs.insert(0, name)
## log configuration
log.debug('zpool.present::%s::config - %s',
name, config)
log.debug('zpool.present::%s::vdevs - %s',
name, vdevs)
log.debug('zpool.present::%s::properties - %s',
name, properties)
log.debug('zpool.present::%s::filesystem_properties - %s',
name, filesystem_properties)
# log configuration
log.debug('zpool.present::%s::config - %s', name, config)
log.debug('zpool.present::%s::vdevs - %s', name, vdevs)
log.debug('zpool.present::%s::properties - %s', name, properties)
log.debug('zpool.present::%s::filesystem_properties - %s', name, filesystem_properties)
## ensure the pool is present
# ensure the pool is present
ret['result'] = False
## NOTE: don't do anything because this is a test
# don't do anything because this is a test
if __opts__['test']:
ret['result'] = True
if __salt__['zpool.exists'](name):
@ -302,26 +301,27 @@ def present(name, properties=None, filesystem_properties=None, layout=None, conf
ret['changes'][name] = 'imported' if config['import'] else 'created'
ret['comment'] = 'storage pool {0} was {1}'.format(name, ret['changes'][name])
## NOTE: update pool
# update pool
elif __salt__['zpool.exists'](name):
ret['result'] = True
## NOTE: fetch current pool properties
# fetch current pool properties
properties_current = __salt__['zpool.get'](name, parsable=True)
## NOTE: build list of properties to update
# build list of properties to update
properties_update = []
for prop in properties:
## NOTE: skip unexisting properties
if prop not in properties_current:
log.warning('zpool.present::%s::update - unknown property: %s', name, prop)
continue
if properties:
for prop in properties:
# skip unexisting properties
if prop not in properties_current:
log.warning('zpool.present::%s::update - unknown property: %s', name, prop)
continue
## NOTE: compare current and wanted value
if properties_current[prop] != properties[prop]:
properties_update.append(prop)
# compare current and wanted value
if properties_current[prop] != properties[prop]:
properties_update.append(prop)
## NOTE: update pool properties
# update pool properties
for prop in properties_update:
res = __salt__['zpool.set'](name, prop, properties[prop])
@ -338,9 +338,9 @@ def present(name, properties=None, filesystem_properties=None, layout=None, conf
if ret['result']:
ret['comment'] = 'properties updated' if ret['changes'] else 'no update needed'
## NOTE: import or create the pool (at least try to anyway)
# import or create the pool (at least try to anyway)
else:
## NOTE: import pool
# import pool
if config['import']:
mod_res = __salt__['zpool.import'](
name,
@ -353,11 +353,11 @@ def present(name, properties=None, filesystem_properties=None, layout=None, conf
ret['changes'][name] = 'imported'
ret['comment'] = 'storage pool {0} was imported'.format(name)
## NOTE: create pool
# create pool
if not ret['result'] and vdevs:
log.debug('zpool.present::%s::creating', name)
## NOTE: execute zpool.create
# execute zpool.create
mod_res = __salt__['zpool.create'](
*vdevs,
force=config['force'],
@ -374,7 +374,7 @@ def present(name, properties=None, filesystem_properties=None, layout=None, conf
else:
ret['comment'] = 'could not create storage pool {0}'.format(name)
## NOTE: give up, we cannot import the pool and we do not have a layout to create it
# give up, we cannot import the pool and we do not have a layout to create it
if not ret['result'] and not vdevs:
ret['comment'] = 'storage pool {0} was not imported, no (valid) layout specified for creation'.format(name)
@ -398,13 +398,11 @@ def absent(name, export=False, force=False):
'result': None,
'comment': ''}
## log configuration
log.debug('zpool.absent::%s::config::force = %s',
name, force)
log.debug('zpool.absent::%s::config::export = %s',
name, export)
# log configuration
log.debug('zpool.absent::%s::config::force = %s', name, force)
log.debug('zpool.absent::%s::config::export = %s', name, export)
## ensure the pool is absent
# ensure the pool is absent
if __salt__['zpool.exists'](name): # looks like we need to do some work
mod_res = {}
ret['result'] = False

View file

@ -603,23 +603,22 @@ class TCPReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt.tra
self.payload_handler = payload_handler
self.io_loop = io_loop
self.serial = salt.payload.Serial(self.opts)
if USE_LOAD_BALANCER:
self.req_server = LoadBalancerWorker(self.socket_queue,
self.handle_message,
io_loop=self.io_loop,
ssl_options=self.opts.get('ssl'))
else:
if salt.utils.platform.is_windows():
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
_set_tcp_keepalive(self._socket, self.opts)
self._socket.setblocking(0)
self._socket.bind((self.opts['interface'], int(self.opts['ret_port'])))
self.req_server = SaltMessageServer(self.handle_message,
io_loop=self.io_loop,
ssl_options=self.opts.get('ssl'))
self.req_server.add_socket(self._socket)
self._socket.listen(self.backlog)
with salt.utils.async.current_ioloop(self.io_loop):
if USE_LOAD_BALANCER:
self.req_server = LoadBalancerWorker(self.socket_queue,
self.handle_message,
ssl_options=self.opts.get('ssl'))
else:
if salt.utils.platform.is_windows():
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
_set_tcp_keepalive(self._socket, self.opts)
self._socket.setblocking(0)
self._socket.bind((self.opts['interface'], int(self.opts['ret_port'])))
self.req_server = SaltMessageServer(self.handle_message,
ssl_options=self.opts.get('ssl'))
self.req_server.add_socket(self._socket)
self._socket.listen(self.backlog)
salt.transport.mixins.auth.AESReqServerMixin.post_fork(self, payload_handler, io_loop)
@tornado.gen.coroutine
@ -704,6 +703,7 @@ class SaltMessageServer(tornado.tcpserver.TCPServer, object):
'''
def __init__(self, message_handler, *args, **kwargs):
super(SaltMessageServer, self).__init__(*args, **kwargs)
self.io_loop = tornado.ioloop.IOLoop.current()
self.clients = []
self.message_handler = message_handler
@ -807,7 +807,9 @@ class TCPClientKeepAlive(tornado.tcpclient.TCPClient):
stream = tornado.iostream.IOStream(
sock,
max_buffer_size=max_buffer_size)
return stream.connect(addr)
if tornado.version_info < (5,):
return stream.connect(addr)
return stream, stream.connect(addr)
class SaltMessageClientPool(salt.transport.MessageClientPool):
@ -891,33 +893,33 @@ class SaltMessageClient(object):
return
self._closing = True
if hasattr(self, '_stream') and not self._stream.closed():
self._stream.close()
if self._read_until_future is not None:
# This will prevent this message from showing up:
# '[ERROR ] Future exception was never retrieved:
# StreamClosedError'
# This happens because the logic is always waiting to read
# the next message and the associated read future is marked
# 'StreamClosedError' when the stream is closed.
self._read_until_future.exception()
if (not self._stream_return_future.done() and
self.io_loop != tornado.ioloop.IOLoop.current(
instance=False)):
# If _stream_return() hasn't completed, it means the IO
# Loop is stopped (such as when using
# 'salt.utils.async.SyncWrapper'). Ensure that
# _stream_return() completes by restarting the IO Loop.
# This will prevent potential errors on shutdown.
orig_loop = tornado.ioloop.IOLoop.current()
self.io_loop.make_current()
try:
# If _stream_return() hasn't completed, it means the IO
# Loop is stopped (such as when using
# 'salt.utils.async.SyncWrapper'). Ensure that
# _stream_return() completes by restarting the IO Loop.
# This will prevent potential errors on shutdown.
try:
orig_loop = tornado.ioloop.IOLoop.current()
self.io_loop.make_current()
self._stream.close()
if self._read_until_future is not None:
# This will prevent this message from showing up:
# '[ERROR ] Future exception was never retrieved:
# StreamClosedError'
# This happens because the logic is always waiting to read
# the next message and the associated read future is marked
# 'StreamClosedError' when the stream is closed.
self._read_until_future.exception()
if (not self._stream_return_future.done() and
self.io_loop != tornado.ioloop.IOLoop.current(
instance=False)):
self.io_loop.add_future(
self._stream_return_future,
lambda future: self.io_loop.stop()
)
self.io_loop.start()
finally:
orig_loop.make_current()
finally:
orig_loop.make_current()
self._tcp_client.close()
# Clear callback references to allow the object that they belong to
# to be deleted.
@ -970,7 +972,8 @@ class SaltMessageClient(object):
with salt.utils.async.current_ioloop(self.io_loop):
self._stream = yield self._tcp_client.connect(self.host,
self.port,
ssl_options=self.opts.get('ssl'))
ssl_options=self.opts.get('ssl'),
**kwargs)
self._connecting_future.set_result(True)
break
except Exception as e:

View file

@ -19,8 +19,6 @@ Example Usage:
.. code-block:: python
import salt.utils.boto3
def __virtual__():
# only required in 2015.2
salt.utils.compat.pack_dunder(__name__)
@ -68,13 +66,18 @@ except ImportError:
log = logging.getLogger(__name__)
__virtualname__ = 'boto3'
def __virtual__():
'''
Only load if boto libraries exist and if boto libraries are greater than
a given version.
'''
return salt.utils.versions.check_boto_reqs()
has_boto = salt.utils.versions.check_boto_reqs()
if has_boto is True:
return __virtualname__
return has_boto
def _option(value):

View file

@ -19,8 +19,6 @@ Example Usage:
.. code-block:: python
import salt.utils.boto
def __virtual__():
# only required in 2015.2
salt.utils.compat.pack_dunder(__name__)
@ -66,6 +64,7 @@ except ImportError:
log = logging.getLogger(__name__)
__salt__ = None
__virtualname__ = 'boto'
def __virtual__():
@ -78,6 +77,7 @@ def __virtual__():
global __salt__
if not __salt__:
__salt__ = minion_mods(__opts__)
return __virtualname__
return has_boto_requirements

View file

@ -2733,9 +2733,9 @@ def cache_nodes_ip(opts, base=None):
addresses. Returns a dict.
'''
salt.utils.versions.warn_until(
'Flourine',
'Fluorine',
'This function is incomplete and non-functional '
'and will be removed in Salt Flourine.'
'and will be removed in Salt Fluorine.'
)
if base is None:
base = opts['cachedir']

View file

@ -6,6 +6,7 @@ Functions for working with files
from __future__ import absolute_import, unicode_literals, print_function
# Import Python libs
import codecs
import contextlib
import errno
import logging
@ -777,3 +778,102 @@ def backup_minion(path, bkroot):
if not salt.utils.platform.is_windows():
os.chown(bkpath, fstat.st_uid, fstat.st_gid)
os.chmod(bkpath, fstat.st_mode)
def get_encoding(path):
'''
Detect a file's encoding using the following:
- Check for ascii
- Check for Byte Order Marks (BOM)
- Check for UTF-8 Markers
- Check System Encoding
Args:
path (str): The path to the file to check
Returns:
str: The encoding of the file
Raises:
CommandExecutionError: If the encoding cannot be detected
'''
def check_ascii(_data):
# If all characters can be decoded to ASCII, then it's ASCII
try:
_data.decode('ASCII')
log.debug('Found ASCII')
except UnicodeDecodeError:
return False
else:
return True
def check_bom(_data):
# Supported Python Codecs
# https://docs.python.org/2/library/codecs.html
# https://docs.python.org/3/library/codecs.html
boms = [
('UTF-32-BE', salt.utils.stringutils.to_bytes(codecs.BOM_UTF32_BE)),
('UTF-32-LE', salt.utils.stringutils.to_bytes(codecs.BOM_UTF32_LE)),
('UTF-16-BE', salt.utils.stringutils.to_bytes(codecs.BOM_UTF16_BE)),
('UTF-16-LE', salt.utils.stringutils.to_bytes(codecs.BOM_UTF16_LE)),
('UTF-8', salt.utils.stringutils.to_bytes(codecs.BOM_UTF8)),
('UTF-7', salt.utils.stringutils.to_bytes('\x2b\x2f\x76\x38\x2D')),
('UTF-7', salt.utils.stringutils.to_bytes('\x2b\x2f\x76\x38')),
('UTF-7', salt.utils.stringutils.to_bytes('\x2b\x2f\x76\x39')),
('UTF-7', salt.utils.stringutils.to_bytes('\x2b\x2f\x76\x2b')),
('UTF-7', salt.utils.stringutils.to_bytes('\x2b\x2f\x76\x2f')),
]
for _encoding, bom in boms:
if _data.startswith(bom):
log.debug('Found BOM for %s', _encoding)
return _encoding
return False
def check_utf8_markers(_data):
try:
decoded = _data.decode('UTF-8')
except UnicodeDecodeError:
return False
else:
# Reject surrogate characters in Py2 (Py3 behavior)
if six.PY2:
for char in decoded:
if 0xD800 <= ord(char) <= 0xDFFF:
return False
return True
def check_system_encoding(_data):
try:
_data.decode(__salt_system_encoding__)
except UnicodeDecodeError:
return False
else:
return True
if not os.path.isfile(path):
raise CommandExecutionError('Not a file')
try:
with fopen(path, 'rb') as fp_:
data = fp_.read(2048)
except os.error:
raise CommandExecutionError('Failed to open file')
# Check for ASCII first
if check_ascii(data):
return 'ASCII'
# Check for Unicode BOM
encoding = check_bom(data)
if encoding:
return encoding
# Check for UTF-8 markers
if check_utf8_markers(data):
return 'UTF-8'
# Check system encoding
if check_system_encoding(data):
return __salt_system_encoding__
raise CommandExecutionError('Could not detect file encoding')

View file

@ -36,6 +36,11 @@ log = logging.getLogger(__name__)
__virtualname__ = 'mac_utils'
__salt__ = {
'cmd.run_all': salt.modules.cmdmod._run_all_quiet,
'cmd.run': salt.modules.cmdmod._run_quiet,
}
def __virtual__():
'''
@ -267,7 +272,8 @@ def launchctl(sub_cmd, *args, **kwargs):
# Run command
kwargs['python_shell'] = False
ret = salt.modules.cmdmod.run_all(cmd, **kwargs)
kwargs = salt.utils.args.clean_kwargs(**kwargs)
ret = __salt__['cmd.run_all'](cmd, **kwargs)
# Raise an error or return successful result
if ret['retcode']:
@ -321,7 +327,7 @@ def _available_services():
# the system provided plutil program to do the conversion
cmd = '/usr/bin/plutil -convert xml1 -o - -- "{0}"'.format(
true_path)
plist_xml = salt.modules.cmdmod.run(cmd, output_loglevel='quiet')
plist_xml = __salt__['cmd.run'](cmd)
if six.PY2:
plist = plistlib.readPlistFromString(plist_xml)
else:

View file

@ -3078,11 +3078,11 @@ class SaltSSHOptionParser(six.with_metaclass(OptionParserMeta,
help='Run command via sudo.'
)
auth_group.add_option(
'--skip-roster',
dest='ssh_skip_roster',
'--update-roster',
dest='ssh_update_roster',
default=False,
action='store_true',
help='If hostname is not found in the roster, do not store the information'
help='If hostname is not found in the roster, store the information'
'into the default roster file (flat).'
)
self.add_option_group(auth_group)

View file

@ -103,6 +103,14 @@ def pytest_addoption(parser):
'SSH server on your machine. In certain environments, this '
'may be insecure! Default: False'
)
test_selection_group.addoption(
'--proxy',
'--proxy-tests',
dest='proxy',
action='store_true',
default=False,
help='Run proxy tests'
)
test_selection_group.addoption(
'--run-destructive',
action='store_true',
@ -641,7 +649,8 @@ def test_daemon(request):
('sysinfo', request.config.getoption('--sysinfo')),
('no_colors', request.config.getoption('--no-colors')),
('output_columns', request.config.getoption('--output-columns')),
('ssh', request.config.getoption('--ssh')))
('ssh', request.config.getoption('--ssh')),
('proxy', request.config.getoption('--proxy')))
options = namedtuple('options', [n for n, v in values])(*[v for n, v in values])
fake_parser = namedtuple('parser', 'options')(options)

View file

@ -10,27 +10,27 @@ import yaml
# Import Salt Libs
from salt.config import cloud_providers_config
import salt.utils.cloud
import salt.utils.files
# Import Salt Testing Libs
from tests.support.case import ShellCase
from tests.support.paths import FILES
from tests.support.helpers import expensiveTest, generate_random_name
from tests.support.unit import expectedFailure
from tests.support.unit import expectedFailure, skipIf
from tests.support import win_installer
# Create the cloud instance name to be used throughout the tests
INSTANCE_NAME = generate_random_name('CLOUD-TEST-')
PROVIDER_NAME = 'ec2'
EC2_TIMEOUT = 1000
HAS_WINRM = salt.utils.cloud.HAS_WINRM and salt.utils.cloud.HAS_SMB
TIMEOUT = 1200
class EC2Test(ShellCase):
'''
Integration tests for the EC2 cloud provider in Salt-Cloud
'''
TIMEOUT = 1000
def _installer_name(self):
'''
@ -172,19 +172,17 @@ class EC2Test(ShellCase):
'''
# create the instance
rename = INSTANCE_NAME + '-rename'
instance = self.run_cloud('-p ec2-test {0} --no-deploy'.format(INSTANCE_NAME),
timeout=EC2_TIMEOUT)
instance = self.run_cloud('-p ec2-test {0} --no-deploy'.format(INSTANCE_NAME), timeout=TIMEOUT)
ret_str = '{0}:'.format(INSTANCE_NAME)
# check if instance returned
try:
self.assertIn(ret_str, instance)
except AssertionError:
self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME),
timeout=EC2_TIMEOUT)
self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME), timeout=TIMEOUT)
raise
change_name = self.run_cloud('-a rename {0} newname={1} --assume-yes'.format(INSTANCE_NAME, rename), timeout=EC2_TIMEOUT)
change_name = self.run_cloud('-a rename {0} newname={1} --assume-yes'.format(INSTANCE_NAME, rename), timeout=TIMEOUT)
check_rename = self.run_cloud('-a show_instance {0} --assume-yes'.format(rename), [rename])
exp_results = [' {0}:'.format(rename), ' size:',
@ -193,13 +191,11 @@ class EC2Test(ShellCase):
for result in exp_results:
self.assertIn(result, check_rename[0])
except AssertionError:
self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME),
timeout=EC2_TIMEOUT)
self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME), timeout=TIMEOUT)
raise
# delete the instance
delete = self.run_cloud('-d {0} --assume-yes'.format(rename),
timeout=EC2_TIMEOUT)
delete = self.run_cloud('-d {0} --assume-yes'.format(rename), timeout=TIMEOUT)
ret_str = ' shutting-down'
# check if deletion was performed appropriately
@ -227,8 +223,9 @@ class EC2Test(ShellCase):
'win_installer': self.copy_file(self.INSTALLER),
},
)
self._test_instance('ec2-win2012r2-test', debug=True, timeout=500)
self._test_instance('ec2-win2012r2-test', debug=True, timeout=TIMEOUT)
@skipIf(not HAS_WINRM, 'Skip when winrm dependencies are missing')
def test_win2012r2_winrm(self):
'''
Tests creating and deleting a Windows 2012r2 instance on EC2 using
@ -240,10 +237,11 @@ class EC2Test(ShellCase):
'userdata_file': self.copy_file('windows-firewall.ps1'),
'win_installer': self.copy_file(self.INSTALLER),
'winrm_ssl_verify': False,
'use_winrm': True,
}
)
self._test_instance('ec2-win2012r2-test', debug=True, timeout=500)
self._test_instance('ec2-win2012r2-test', debug=True, timeout=TIMEOUT)
@expectedFailure
def test_win2016_winexe(self):
@ -261,8 +259,9 @@ class EC2Test(ShellCase):
'win_installer': self.copy_file(self.INSTALLER),
},
)
self._test_instance('ec2-win2016-test', debug=True, timeout=500)
self._test_instance('ec2-win2016-test', debug=True, timeout=TIMEOUT)
@skipIf(not HAS_WINRM, 'Skip when winrm dependencies are missing')
def test_win2016_winrm(self):
'''
Tests creating and deleting a Windows 2016 instance on EC2 using winrm
@ -274,10 +273,11 @@ class EC2Test(ShellCase):
'userdata_file': self.copy_file('windows-firewall.ps1'),
'win_installer': self.copy_file(self.INSTALLER),
'winrm_ssl_verify': False,
'use_winrm': True,
}
)
self._test_instance('ec2-win2016-test', debug=True, timeout=500)
self._test_instance('ec2-win2016-test', debug=True, timeout=TIMEOUT)
def tearDown(self):
'''
@ -288,4 +288,4 @@ class EC2Test(ShellCase):
# if test instance is still present, delete it
if ret_str in query:
self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME), timeout=self.TIMEOUT)
self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME), timeout=TIMEOUT)

View file

@ -1,12 +1,12 @@
ec2-test:
provider: ec2-config
image: ami-98aa1cf0
size: t1.micro
size: m1.large
sh_username: ec2-user
script_args: '-P -Z'
ec2-win2012r2-test:
provider: ec2-config
size: t2.micro
size: m1.large
image: ami-eb1ecd96
smb_port: 445
win_installer: ''
@ -16,11 +16,10 @@ ec2-win2012r2-test:
userdata_template: False
use_winrm: True
winrm_verify_ssl: False
ssh_interface: private_ips
deploy: True
ec2-win2016-test:
provider: ec2-config
size: t2.micro
size: m1.large
image: ami-ed14c790
smb_port: 445
win_installer: ''
@ -30,5 +29,4 @@ ec2-win2016-test:
userdata_template: False
use_winrm: True
winrm_verify_ssl: False
ssh_interface: private_ips
deploy: True

View file

@ -1,5 +1,5 @@
linode-test:
provider: linode-config
size: Linode 2048
size: Linode 2GB
image: Ubuntu 14.04 LTS
script_args: '-P -Z'

View file

@ -0,0 +1,2 @@
slsfile1-nop:
test.nop

View file

@ -0,0 +1,2 @@
slsfile2-nop:
test.nop

View file

@ -0,0 +1,2 @@
include:
- issue-47182.stateA.newer

View file

@ -0,0 +1,6 @@
exclude:
- sls: issue-47182.stateA
somestuff:
cmd.run:
- name: echo This supersedes the stuff previously done in issue-47182.stateA

View file

@ -0,0 +1,10 @@
include:
- issue-47182.slsfile1
- issue-47182.slsfile2
some-state:
test.nop:
- require:
- sls: issue-47182.slsfile1
- require_in:
- sls: issue-47182.slsfile2

View file

@ -0,0 +1,4 @@
base:
'*':
- issue-47182.stateA
- issue-47182.stateB

View file

@ -0,0 +1,4 @@
deploy_check:
salt.function:
- name: test.false
- tgt: minion

View file

@ -0,0 +1,24 @@
{% set versions = {'18':['05', '03', '01'], '16':['04', '03', '02', '00'], '9':['20']} %}
Zzip:
{% for major, subversions in versions.items() %}
{% for minor in subversions %}
'{{major}}.{{minor}}.00.0':
{% if grains['cpuarch'] == 'AMD64' %}
full_name: '7-Zip {{major}}.{{minor}} (x64 edition)'
installer: 'http://d.7-zip.org/a/7z{{major}}{{minor}}-x64.msi'
uninstaller: 'http://d.7-zip.org/a/7z{{major}}{{minor}}-x64.msi'
arch: x64
{% else %}
full_name: '7-Zip {{major}}.{{minor}}'
installer: 'http://d.7-zip.org/a/7z{{major}}{{minor}}.msi'
uninstaller: 'http://d.7-zip.org/a/7z{{major}}{{minor}}.msi'
arch: x86
{% endif %}
install_flags: '/qn /norestart'
uninstall_flags: '/qn /norestart'
msiexec: True
locale: en_US
reboot: False
{% endfor %}
{% endfor %}

View file

@ -12,7 +12,8 @@ from tests.support.case import ModuleCase
from tests.support.helpers import (
destructiveTest,
skip_if_binaries_missing,
skip_if_not_root
skip_if_not_root,
this_user,
)
from tests.support.paths import TMP
from tests.support.unit import skipIf
@ -257,12 +258,7 @@ class CMDModuleTest(ModuleCase):
cmd = '''echo 'SELECT * FROM foo WHERE bar="baz"' '''
expected_result = 'SELECT * FROM foo WHERE bar="baz"'
try:
runas = os.getlogin()
except: # pylint: disable=W0702
# On some distros (notably Gentoo) os.getlogin() fails
import pwd
runas = pwd.getpwuid(os.getuid())[0]
runas = this_user()
result = self.run_function('cmd.run_stdout', [cmd],
runas=runas).strip()

View file

@ -16,6 +16,7 @@ from tests.support.helpers import destructiveTest, skip_if_not_root
# Import Salt Libs
import salt.utils.files
from salt.exceptions import CommandExecutionError
import salt.ext.six as six
# Import 3rd-party libs
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin

View file

@ -335,16 +335,28 @@ class PkgModuleTest(ModuleCase, SaltReturnAssertsMixin):
check that pkg.latest_version returns the latest version of the uninstalled package (it does not install the package, just checking the version)
'''
grains = self.run_function('grains.items')
cmd_info = self.run_function('pkg.info_installed', ['htop'])
if cmd_info != 'ERROR: package htop is not installed':
cmd_remove = self.run_function('pkg.remove', ['htop'])
remove = False
if salt.utils.platform.is_windows():
cmd_info = self.run_function('pkg.version', [self.pkg])
remove = False if cmd_info == '' else True
else:
cmd_info = self.run_function('pkg.info_installed', [self.pkg])
if cmd_info != 'ERROR: package {0} is not installed'.format(self.pkg):
remove = True
# remove package if its installed
if remove:
cmd_remove = self.run_function('pkg.remove', [self.pkg])
if grains['os_family'] == 'RedHat':
cmd_htop = self.run_function('cmd.run', ['yum list htop'])
cmd_pkg = self.run_function('cmd.run', ['yum list {0}'.format(self.pkg)])
elif salt.utils.platform.is_windows():
cmd_pkg = self.run_function('pkg.list_available', [self.pkg])
elif grains['os_family'] == 'Debian':
cmd_htop = self.run_function('cmd.run', ['apt list htop'])
cmd_pkg = self.run_function('cmd.run', ['apt list {0}'.format(self.pkg)])
elif grains['os_family'] == 'Arch':
cmd_htop = self.run_function('cmd.run', ['pacman -Si htop'])
cmd_pkg = self.run_function('cmd.run', ['pacman -Si {0}'.format(self.pkg)])
elif grains['os_family'] == 'Suse':
cmd_htop = self.run_function('cmd.run', ['zypper info htop'])
pkg_latest = self.run_function('pkg.latest_version', ['htop'])
self.assertIn(pkg_latest, cmd_htop)
cmd_pkg = self.run_function('cmd.run', ['zypper info {0}'.format(self.pkg)])
pkg_latest = self.run_function('pkg.latest_version', [self.pkg])
self.assertIn(pkg_latest, cmd_pkg)

View file

@ -194,7 +194,18 @@ class SaltUtilSyncPillarTest(ModuleCase):
'''))
self.run_function('saltutil.refresh_pillar')
self.run_function('test.sleep', [5])
pillar = False
timeout = time.time() + 30
while not pillar:
post_pillar = self.run_function('pillar.raw')
try:
self.assertIn(pillar_key, post_pillar.get(pillar_key, 'didnotwork'))
pillar = True
except AssertionError:
if time.time() > timeout:
self.assertIn(pillar_key, post_pillar.get(pillar_key, 'didnotwork'))
continue
post_pillar = self.run_function('pillar.raw')
self.assertIn(pillar_key, post_pillar.get(pillar_key, 'didnotwork'))

View file

@ -11,6 +11,7 @@ from tests.support.unit import skipIf
# Import Salt libs
import salt.utils.path
import salt.utils.platform
import salt.utils.systemd
@destructiveTest
@ -100,7 +101,38 @@ class ServiceModuleTest(ModuleCase):
self.assertTrue(self.run_function('service.enable', [self.service_name]))
self.assertTrue(self.run_function('service.disable', [self.service_name]))
self.assertIn(self.service_name, self.run_function('service.get_disabled'))
if salt.utils.platform.is_darwin():
self.assertTrue(self.run_function('service.disabled', [self.service_name]))
else:
self.assertIn(self.service_name, self.run_function('service.get_disabled'))
def test_service_disable_doesnot_exist(self):
'''
test service.get_disabled and service.disable module
when service name does not exist
'''
# enable service before test
srv_name = 'doesnotexist'
enable = self.run_function('service.enable', [srv_name])
systemd = salt.utils.systemd.booted()
# check service was not enabled
if systemd or salt.utils.platform.is_windows():
self.assertIn('ERROR', enable)
else:
self.assertFalse(enable)
# check service was not disabled
if tuple(self.run_function('grains.item', ['osrelease_info'])['osrelease_info']) == (14, 0o4) and not systemd:
# currently upstart does not have a mechanism to report if disabling a service fails if does not exist
self.assertTrue(self.run_function('service.disable', [srv_name]))
else:
self.assertFalse(self.run_function('service.disable', [srv_name]))
if salt.utils.platform.is_darwin():
self.assertFalse(self.run_function('service.disabled', [srv_name]))
else:
self.assertNotIn(srv_name, self.run_function('service.get_disabled'))
@skipIf(not salt.utils.platform.is_windows(), 'Windows Only Test')
def test_service_get_service_name(self):

View file

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Import Python libs
from __future__ import absolute_import
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
from tests.support.helpers import destructiveTest
# Import Salt libs
import salt.utils.platform
@skipIf(not salt.utils.platform.is_windows(), 'windows test only')
class WinDNSTest(ModuleCase):
'''
Test for salt.modules.win_dns_client
'''
@destructiveTest
def test_add_remove_dns(self):
'''
Test add and removing a dns server
'''
dns = '8.8.8.8'
interface = 'Ethernet'
# add dns server
self.assertTrue(self.run_function('win_dns_client.add_dns', [dns, interface], index=42))
srvs = self.run_function('win_dns_client.get_dns_servers', interface=interface)
self.assertIn(dns, srvs)
# remove dns server
self.assertTrue(self.run_function('win_dns_client.rm_dns', [dns], interface=interface))
srvs = self.run_function('win_dns_client.get_dns_servers', interface=interface)
self.assertNotIn(dns, srvs)

View file

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Import Python libs
from __future__ import absolute_import
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
# Import Salt libs
import salt.utils.platform
@skipIf(not salt.utils.platform.is_windows(), 'windows test only')
class WinServermanagerTest(ModuleCase):
'''
Test for salt.modules.win_servermanager
'''
def test_list_available(self):
'''
Test list available features to install
'''
cmd = self.run_function('win_servermanager.list_available')
self.assertIn('DNS', cmd)
self.assertIn('NetworkController', cmd)
self.assertIn('RemoteAccess', cmd)

View file

@ -257,6 +257,33 @@ class StateRunnerTest(ShellCase):
self.assertEqual(count('Succeeded: 1', ret), 1)
self.assertEqual(count('Failed: 0', ret), 1)
def test_orchestrate_salt_function_return_false_failure(self):
'''
Ensure that functions that only return False in the return
are flagged as failed when run as orchestrations.
See https://github.com/saltstack/salt/issues/30367
'''
self.run_run('saltutil.sync_modules')
ret = salt.utils.json.loads(
'\n'.join(
self.run_run('state.orchestrate orch.issue30367 --out=json')
)
)
# Drill down to the changes dict
state_result = ret['data']['master']['salt_|-deploy_check_|-test.false_|-function']['result']
func_ret = ret['data']['master']['salt_|-deploy_check_|-test.false_|-function']['changes']
self.assertEqual(
state_result,
False,
)
self.assertEqual(
func_ret,
{'out': 'highstate', 'ret': {'minion': False}}
)
@skipIf(salt.utils.platform.is_windows(), '*NIX-only test')
class OrchEventTest(ShellCase):

View file

@ -2275,57 +2275,64 @@ class FileTest(ModuleCase, SaltReturnAssertsMixin):
class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
marker_start = '# start'
marker_end = '# end'
content = textwrap.dedent('''\
Line 1 of block
Line 2 of block
''')
without_block = textwrap.dedent('''\
Hello world!
# comment here
''')
with_non_matching_block = textwrap.dedent('''\
Hello world!
# start
No match here
# end
# comment here
''')
with_non_matching_block_and_marker_end_not_after_newline = textwrap.dedent('''\
Hello world!
# start
No match here# end
# comment here
''')
with_matching_block = textwrap.dedent('''\
Hello world!
# start
Line 1 of block
Line 2 of block
# end
# comment here
''')
with_matching_block_and_extra_newline = textwrap.dedent('''\
Hello world!
# start
Line 1 of block
Line 2 of block
# end
# comment here
''')
with_matching_block_and_marker_end_not_after_newline = textwrap.dedent('''\
Hello world!
# start
Line 1 of block
Line 2 of block# end
# comment here
''')
content = os.linesep.join([
'Line 1 of block',
'Line 2 of block',
''
])
without_block = os.linesep.join([
'Hello world!',
'',
'# comment here',
''
])
with_non_matching_block = os.linesep.join([
'Hello world!',
'',
'# start',
'No match here',
'# end',
'# comment here',
''
])
with_non_matching_block_and_marker_end_not_after_newline = os.linesep.join([
'Hello world!',
'',
'# start',
'No match here# end',
'# comment here',
''
])
with_matching_block = os.linesep.join([
'Hello world!',
'',
'# start',
'Line 1 of block',
'Line 2 of block',
'# end',
'# comment here',
''
])
with_matching_block_and_extra_newline = os.linesep.join([
'Hello world!',
'',
'# start',
'Line 1 of block',
'Line 2 of block',
'',
'# end',
'# comment here',
''
])
with_matching_block_and_marker_end_not_after_newline = os.linesep.join([
'Hello world!',
'',
'# start',
'Line 1 of block',
'Line 2 of block# end',
'# comment here',
''
])
content_explicit_posix_newlines = ('Line 1 of block\n'
'Line 2 of block\n')
content_explicit_windows_newlines = ('Line 1 of block\r\n'

View file

@ -40,7 +40,7 @@ _PKG_TARGETS = {
'FreeBSD': ['aalib', 'pth'],
'Suse': ['aalib', 'rpm-python'],
'MacOS': ['libpng', 'jpeg'],
'Windows': ['firefox', '7zip'],
'Windows': ['putty', '7zip'],
}
_PKG_CAP_TARGETS = {
@ -167,7 +167,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
self.run_function('pkg.refresh_db')
__testcontext__['refresh'] = True
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_001_installed(self, grains=None):
'''
@ -198,7 +197,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_002_installed_with_version(self, grains=None):
'''
@ -246,7 +244,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_003_installed_multipkg(self, grains=None):
'''
@ -268,7 +265,10 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
# If this assert fails, we need to find new targets, this test needs to
# be able to test successful installation of packages, so these
# packages need to not be installed before we run the states below
self.assertFalse(any(version.values()))
try:
self.assertFalse(any(version.values()))
except AssertionError:
self.assertSaltTrueReturn(self.run_state('pkg.removed', name=None, pkgs=pkg_targets))
ret = self.run_state('pkg.installed',
name=None,
@ -278,7 +278,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_state('pkg.removed', name=None, pkgs=pkg_targets)
self.assertSaltTrueReturn(ret)
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_004_installed_multipkg_with_version(self, grains=None):
'''
@ -327,7 +326,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_state('pkg.removed', name=None, pkgs=pkg_targets)
self.assertSaltTrueReturn(ret)
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_005_installed_32bit(self, grains=None):
'''
@ -364,7 +362,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_006_installed_32bit_with_version(self, grains=None):
'''
@ -412,7 +409,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_007_with_dot_in_pkgname(self, grains=None):
'''
@ -443,7 +439,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_008_epoch_in_version(self, grains=None):
'''
@ -494,7 +489,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
refresh=False)
self.assertSaltTrueReturn(ret)
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_salt_modules('pkg.info_installed')
def test_pkg_010_latest_with_epoch_and_info_installed(self):
'''
@ -514,7 +508,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_function('pkg.info_installed', [package])
self.assertTrue(pkgquery in six.text_type(ret))
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_011_latest(self, grains=None):
'''
@ -546,7 +539,6 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_012_latest_only_upgrade(self, grains=None):
'''

View file

@ -44,12 +44,6 @@ class UserTest(ModuleCase, SaltReturnAssertsMixin):
user_name = 'salt_test'
user_home = '/var/lib/salt_test'
def setUp(self):
if salt.utils.platform.is_darwin():
#on mac we need to add user, because there is
#no creationtime for nobody user.
add_user = self.run_function('user.add', [USER], gid=GID)
def test_user_absent(self):
ret = self.run_state('user.absent', name='unpossible')
self.assertSaltTrueReturn(ret)

View file

@ -59,8 +59,12 @@ from tests.support.paths import FILES, TMP
import salt.utils.files
import salt.utils.platform
log = logging.getLogger(__name__)
if salt.utils.platform.is_windows():
import salt.utils.win_functions
else:
import pwd
log = logging.getLogger(__name__)
HAS_SYMLINKS = None
@ -1159,7 +1163,6 @@ def skip_if_not_root(func):
func.__unittest_skip__ = True
func.__unittest_skip_why__ = 'You must be logged in as root to run this test'
else:
import salt.utils.win_functions
current_user = salt.utils.win_functions.get_current_user()
if current_user != 'SYSTEM':
if not salt.utils.win_functions.is_admin(current_user):
@ -1592,3 +1595,12 @@ def win32_kill_process_tree(pid, sig=signal.SIGTERM, include_parent=True,
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)
def this_user():
'''
Get the user associated with the current process.
'''
if salt.utils.platform.is_windows():
return salt.utils.win_functions.get_current_user()
return pwd.getpwuid(os.getuid())[0]

View file

@ -50,6 +50,8 @@ SYS_TMP_DIR = os.path.abspath(os.path.realpath(
))
TMP = os.path.join(SYS_TMP_DIR, 'salt-tests-tmpdir')
FILES = os.path.join(INTEGRATION_TEST_DIR, 'files')
BASE_FILES = os.path.join(FILES, 'file', 'base')
PROD_FILES = os.path.join(FILES, 'file', 'prod')
PYEXEC = 'python{0}.{1}'.format(*sys.version_info)
MOCKBIN = os.path.join(INTEGRATION_TEST_DIR, 'mockbin')
SCRIPT_DIR = os.path.join(CODE_DIR, 'scripts')

View file

@ -49,7 +49,6 @@
# Import Python modules
from __future__ import absolute_import, print_function
import os
import sys
import shutil
import logging
import multiprocessing
@ -58,6 +57,7 @@ import salt.utils.json
# Import tests support libs
import tests.support.paths as paths
import tests.support.helpers
# Import 3rd-party libs
from salt.ext import six
@ -104,12 +104,9 @@ try:
except ImportError:
pass
if sys.platform.startswith('win'):
import win32api # pylint: disable=import-error
RUNNING_TESTS_USER = win32api.GetUserName()
else:
import pwd
RUNNING_TESTS_USER = pwd.getpwuid(os.getuid()).pw_name
RUNNING_TESTS_USER = tests.support.helpers.this_user()
log = logging.getLogger(__name__)

View file

@ -54,7 +54,8 @@ def latest_version(repo=REPO):
'''
Return the latest version found on the salt repository webpage.
'''
for name, md5 in iter_installers(requests.get(repo).content):
content = requests.get(repo).content.decode('utf-8')
for name, md5 in iter_installers(content):
pass
return split_installer(name)[0]

View file

@ -15,7 +15,7 @@ import tornado.ioloop
import logging
import stat
try:
import pwd
import pwd # pylint: disable=unused-import
except ImportError:
pass

View file

@ -0,0 +1,3 @@
Oracle Solaris 11.3 SPARC
Copyright (c) 1983, 2017, Oracle and/or its affiliates. All rights reserved.
Assembled 05 October 2017

View file

@ -0,0 +1,24 @@
System Configuration: Oracle Corporation sun4v
Memory size: 16384 Megabytes
System Peripherals (PROM Nodes):
Node 0xfffffffff
scsi-initiator-id: 00000007
idprom: 00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000
pcie-ari-supported:
#priqs-per-pcibus: 00000010
#priqs-per-cpu: 00000010
priq-eq-sizes: 00000003
non-ios-perf-counters: 'ORCL,sn-non-ios-pr'
ios-perf-counters: 'ORCL,sn-ios-pr'
storage-variant: '8dbp'
product-name: 'SPARC S7-2'
banner-name: 'SPARC S7-2'
name: 'ORCL,SPARC-S7-2'
stick-frequency: 3b9aca00
hv-api-groups: 00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.000000060.00000000.00000000
breakpoint-trap: 0000007f
device_type: 'sun4v'
compatible: 'sun4v'
#address-cells: 00000002
#size-cells: 00000002

Some files were not shown because too many files have changed in this diff Show more