Merge branch '2018.3' into 'develop'

Conflicts:
  - salt/cloud/__init__.py
  - tests/integration/cloud/providers/test_ec2.py
  - tests/support/paths.py
This commit is contained in:
rallytime 2018-05-29 11:28:06 -04:00
commit d9096653f7
No known key found for this signature in database
GPG Key ID: E8F1A4B90D0DEA19
59 changed files with 2876 additions and 512 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

@ -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 ``/etc/salt/cloud.profiles.d/*.conf``:
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

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

@ -7,4 +7,4 @@ MarkupSafe
requests>=1.0.0
tornado>=4.2.1,<6.0
# 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

@ -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

@ -85,7 +85,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
@ -184,7 +183,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):
@ -252,7 +251,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):
@ -283,7 +282,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):
@ -304,7 +303,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,
@ -365,7 +364,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,
@ -394,7 +393,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,
@ -422,7 +421,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):
@ -441,7 +440,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):
@ -461,7 +460,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,
@ -499,7 +498,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):
@ -518,7 +517,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):
@ -571,7 +570,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):
@ -590,7 +589,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):
@ -609,7 +608,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):
@ -630,7 +629,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):
@ -651,7 +650,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):
@ -679,7 +678,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):
@ -698,7 +697,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,
@ -721,7 +720,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,
@ -748,7 +747,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):
@ -767,7 +766,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):
@ -813,7 +812,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):
@ -832,7 +831,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):
@ -851,7 +850,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='',
@ -877,7 +876,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):
@ -896,7 +895,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):
@ -915,7 +914,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,
@ -947,7 +946,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):
@ -970,7 +969,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):
@ -993,7 +992,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,
@ -1023,7 +1022,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,
@ -1048,7 +1047,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,
@ -1073,7 +1072,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):
@ -1092,7 +1091,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):
@ -1111,7 +1110,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):
@ -1155,7 +1154,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):
@ -1174,7 +1173,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',
@ -1197,7 +1196,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):
@ -1220,7 +1219,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,
@ -1245,7 +1244,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):
@ -1268,7 +1267,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,
@ -1293,7 +1292,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):
@ -1350,7 +1349,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,
@ -1383,7 +1382,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):
@ -1419,7 +1418,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):
@ -1498,7 +1497,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)}
@ -1572,7 +1571,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)}
@ -1601,7 +1600,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):
@ -1635,7 +1634,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
@ -886,7 +885,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}
@ -912,7 +911,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)}
subnet_object_dict = _create_resource('subnet', name=subnet_name, tags=tags, vpc_id=vpc_id,
availability_zone=availability_zone,
@ -939,7 +937,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:
@ -957,7 +955,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}
@ -1000,7 +998,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
@ -1040,7 +1038,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}
@ -1121,7 +1119,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,
@ -1163,7 +1161,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,
@ -1217,7 +1215,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,
@ -1258,7 +1256,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', []):
@ -1381,7 +1379,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,
@ -1457,7 +1455,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,
@ -1578,7 +1576,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,
@ -1609,7 +1607,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}
@ -1672,7 +1670,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,
@ -1725,7 +1723,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,
@ -1756,7 +1754,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
@ -1871,7 +1869,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,
@ -1910,7 +1908,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,
@ -1963,7 +1961,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,
@ -2046,7 +2044,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,
@ -2182,7 +2180,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,
@ -2234,7 +2232,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):
@ -2261,7 +2259,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):
@ -2283,7 +2281,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,
@ -2364,7 +2362,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,
@ -2380,7 +2378,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,
@ -2413,7 +2411,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,
@ -2469,7 +2467,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,
@ -2530,7 +2528,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,
@ -2616,7 +2614,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,
@ -2826,7 +2824,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):
@ -2953,7 +2951,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):
@ -3031,7 +3029,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

@ -532,7 +532,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``
@ -541,6 +541,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
@ -550,8 +552,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):

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

@ -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

@ -862,7 +862,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

@ -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

@ -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

@ -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

@ -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

@ -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,26 +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 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 = 1000
class EC2Test(ShellCase):
'''
Integration tests for the EC2 cloud provider in Salt-Cloud
'''
TIMEOUT = 1000
def _installer_name(self):
'''
@ -173,19 +174,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:',
@ -194,13 +193,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 +224,9 @@ class EC2Test(ShellCase):
'win_installer': self.copy_file(self.INSTALLER),
},
)
self._test_instance('ec2-win2012r2-test', debug=True, timeout=800)
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 +238,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)
def test_win2016_psexec(self):
'''
@ -260,8 +259,9 @@ class EC2Test(ShellCase):
'win_installer': self.copy_file(self.INSTALLER),
},
)
self._test_instance('ec2-win2016-test', debug=True, timeout=800)
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
@ -273,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):
'''
@ -287,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,7 +1,7 @@
ec2-test:
provider: ec2-config
image: ami-98aa1cf0
size: t1.micro
size: m1.small
sh_username: ec2-user
script_args: '-P -Z'
ec2-win2012r2-test:
@ -16,7 +16,6 @@ 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
@ -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

@ -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

@ -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
@ -103,7 +104,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:
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

@ -2282,57 +2282,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

@ -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

@ -235,7 +235,10 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
'grains': {},
},
'__grains__': {'kernel': 'Linux'},
'__utils__': {'files.is_text': MagicMock(return_value=True)},
'__utils__': {
'files.is_binary': MagicMock(return_value=False),
'files.get_encoding': MagicMock(return_value='utf-8')
},
}
}
@ -266,11 +269,13 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
quis leo.
''')
MULTILINE_STRING = os.linesep.join(MULTILINE_STRING.splitlines())
def setUp(self):
self.tfile = tempfile.NamedTemporaryFile(delete=False,
prefix='blockrepltmp',
mode='w+')
self.tfile.write(self.MULTILINE_STRING)
mode='w+b')
self.tfile.write(salt.utils.stringutils.to_bytes(self.MULTILINE_STRING))
self.tfile.close()
def tearDown(self):

View File

@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Megan Wilhite<mwilhite@saltstack.com>`
'''
# Import Python libs
from __future__ import absolute_import
# Import Salt Libs
import salt.modules.mac_service as mac_service
# Import Salt Testing Libs
from tests.support.mixins import LoaderModuleMockMixin
from tests.support.unit import skipIf, TestCase
from tests.support.mock import (
MagicMock,
patch,
NO_MOCK,
NO_MOCK_REASON
)
@skipIf(NO_MOCK, NO_MOCK_REASON)
class MacServiceTestCase(TestCase, LoaderModuleMockMixin):
'''
TestCase for salt.modules.mac_service module
'''
def setup_loader_modules(self):
return {mac_service: {}}
def test_service_disabled_when_enabled(self):
'''
test service.disabled when service is enabled
'''
srv_name = 'com.apple.atrun'
cmd = 'disabled services = {\n\t"com.saltstack.salt.minion" => false\n\t"com.apple.atrun" => false\n{'
with patch.object(mac_service, 'launchctl', MagicMock(return_value=cmd)):
self.assertFalse(mac_service.disabled(srv_name))
def test_service_disabled_when_disabled(self):
'''
test service.disabled when service is disabled
'''
srv_name = 'com.apple.atrun'
cmd = 'disabled services = {\n\t"com.saltstack.salt.minion" => false\n\t"com.apple.atrun" => true\n{'
with patch.object(mac_service, 'launchctl', MagicMock(return_value=cmd)):
self.assertTrue(mac_service.disabled(srv_name))
def test_service_disabled_srvname_wrong(self):
'''
test service.disabled when service is just slightly wrong
'''
srv_names = ['com.apple.atru', 'com', 'apple']
cmd = 'disabled services = {\n\t"com.saltstack.salt.minion" => false\n\t"com.apple.atrun" => true\n}'
for name in srv_names:
with patch.object(mac_service, 'launchctl', MagicMock(return_value=cmd)):
self.assertFalse(mac_service.disabled(name))
def test_service_disabled_status_upper_case(self):
'''
test service.disabled when disabled status is uppercase
'''
srv_name = 'com.apple.atrun'
cmd = 'disabled services = {\n\t"com.saltstack.salt.minion" => false\n\t"com.apple.atrun" => True\n{'
with patch.object(mac_service, 'launchctl', MagicMock(return_value=cmd)):
self.assertTrue(mac_service.disabled(srv_name))

View File

@ -14,7 +14,8 @@ from tests.support.paths import TESTS_DIR
# Import Salt libs
import salt.utils.boto
import salt.config
import salt.utils.botomod as botomod
from salt.ext import six
from salt.utils.versions import LooseVersion
import salt.states.boto_vpc as boto_vpc
@ -100,7 +101,7 @@ class BotoVpcStateTestCaseBase(TestCase, LoaderModuleMockMixin):
'__states__': self.salt_states,
'__serializers__': serializers,
},
salt.utils.boto: {}
botomod: {}
}
@classmethod
@ -137,7 +138,7 @@ class BotoVpcTestCase(BotoVpcStateTestCaseBase, BotoVpcTestCaseMixin):
'''
Tests present on a VPC that does not exist.
'''
with patch.dict(salt.utils.boto.__salt__, self.funcs):
with patch.dict(botomod.__salt__, self.funcs):
vpc_present_result = self.salt_states['boto_vpc.present']('test', cidr_block)
self.assertTrue(vpc_present_result['result'])
@ -163,7 +164,7 @@ class BotoVpcTestCase(BotoVpcStateTestCaseBase, BotoVpcTestCaseMixin):
'''
Tests absent on a VPC that does not exist.
'''
with patch.dict(salt.utils.boto.__salt__, self.funcs):
with patch.dict(botomod.__salt__, self.funcs):
vpc_absent_result = self.salt_states['boto_vpc.absent']('test')
self.assertTrue(vpc_absent_result['result'])
self.assertEqual(vpc_absent_result['changes'], {})
@ -171,7 +172,7 @@ class BotoVpcTestCase(BotoVpcStateTestCaseBase, BotoVpcTestCaseMixin):
@mock_ec2_deprecated
def test_absent_when_vpc_exists(self):
vpc = self._create_vpc(name='test')
with patch.dict(salt.utils.boto.__salt__, self.funcs):
with patch.dict(botomod.__salt__, self.funcs):
vpc_absent_result = self.salt_states['boto_vpc.absent']('test')
self.assertTrue(vpc_absent_result['result'])
self.assertEqual(vpc_absent_result['changes']['new']['vpc'], None)
@ -202,7 +203,7 @@ class BotoVpcResourceTestCaseMixin(BotoVpcTestCaseMixin):
Tests present on a resource that does not exist.
'''
vpc = self._create_vpc(name='test')
with patch.dict(salt.utils.boto.__salt__, self.funcs):
with patch.dict(botomod.__salt__, self.funcs):
resource_present_result = self.salt_states['boto_vpc.{0}_present'.format(self.resource_type)](
name='test', vpc_name='test', **self.extra_kwargs)
@ -215,7 +216,7 @@ class BotoVpcResourceTestCaseMixin(BotoVpcTestCaseMixin):
def test_present_when_resource_exists(self):
vpc = self._create_vpc(name='test')
resource = self._create_resource(vpc_id=vpc.id, name='test')
with patch.dict(salt.utils.boto.__salt__, self.funcs):
with patch.dict(botomod.__salt__, self.funcs):
resource_present_result = self.salt_states['boto_vpc.{0}_present'.format(self.resource_type)](
name='test', vpc_name='test', **self.extra_kwargs)
self.assertTrue(resource_present_result['result'])
@ -237,7 +238,7 @@ class BotoVpcResourceTestCaseMixin(BotoVpcTestCaseMixin):
'''
Tests absent on a resource that does not exist.
'''
with patch.dict(salt.utils.boto.__salt__, self.funcs):
with patch.dict(botomod.__salt__, self.funcs):
resource_absent_result = self.salt_states['boto_vpc.{0}_absent'.format(self.resource_type)]('test')
self.assertTrue(resource_absent_result['result'])
self.assertEqual(resource_absent_result['changes'], {})
@ -247,7 +248,7 @@ class BotoVpcResourceTestCaseMixin(BotoVpcTestCaseMixin):
vpc = self._create_vpc(name='test')
self._create_resource(vpc_id=vpc.id, name='test')
with patch.dict(salt.utils.boto.__salt__, self.funcs):
with patch.dict(botomod.__salt__, self.funcs):
resource_absent_result = self.salt_states['boto_vpc.{0}_absent'.format(self.resource_type)]('test')
self.assertTrue(resource_absent_result['result'])
self.assertEqual(resource_absent_result['changes']['new'][self.resource_type], None)
@ -335,7 +336,7 @@ class BotoVpcRouteTableTestCase(BotoVpcStateTestCaseBase, BotoVpcResourceTestCas
vpc = self._create_vpc(name='test')
igw = self._create_internet_gateway(name='test', vpc_id=vpc.id)
with patch.dict(salt.utils.boto.__salt__, self.funcs):
with patch.dict(botomod.__salt__, self.funcs):
route_table_present_result = self.salt_states['boto_vpc.route_table_present'](
name='test', vpc_name='test', routes=[{'destination_cidr_block': '0.0.0.0/0',
'gateway_id': igw.id},

View File

@ -7,6 +7,7 @@
from __future__ import absolute_import, print_function, unicode_literals
import copy
import os
import shutil
import tempfile
# Import Salt Testing libs
@ -18,6 +19,7 @@ from tests.support.mock import (
MagicMock,
patch)
from tests.support.mixins import AdaptedConfigurationTestCaseMixin
from tests.support.paths import BASE_FILES
# Import Salt libs
import salt.exceptions
@ -76,9 +78,9 @@ class StateCompilerTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
class HighStateTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
def setUp(self):
root_dir = tempfile.mkdtemp(dir=integration.TMP)
state_tree_dir = os.path.join(root_dir, 'state_tree')
self.state_tree_dir = os.path.join(root_dir, 'state_tree')
cache_dir = os.path.join(root_dir, 'cachedir')
for dpath in (root_dir, state_tree_dir, cache_dir):
for dpath in (root_dir, self.state_tree_dir, cache_dir):
if not os.path.isdir(dpath):
os.makedirs(dpath)
@ -87,7 +89,7 @@ class HighStateTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
overrides['state_events'] = False
overrides['id'] = 'match'
overrides['file_client'] = 'local'
overrides['file_roots'] = dict(base=[state_tree_dir])
overrides['file_roots'] = dict(base=[self.state_tree_dir])
overrides['cachedir'] = cache_dir
overrides['test'] = False
self.config = self.get_temp_config('minion', **overrides)
@ -148,6 +150,28 @@ class HighStateTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
self.assertEqual(state_usage_dict['base']['used'], ['state.a', 'state.b'])
self.assertEqual(state_usage_dict['base']['unused'], ['state.c'])
def test_find_sls_ids_with_exclude(self):
'''
See https://github.com/saltstack/salt/issues/47182
'''
sls_dir = 'issue-47182'
shutil.copytree(
os.path.join(BASE_FILES, sls_dir),
os.path.join(self.state_tree_dir, sls_dir)
)
shutil.move(
os.path.join(self.state_tree_dir, sls_dir, 'top.sls'),
self.state_tree_dir
)
# Manually compile the high data. We don't have to worry about all of
# the normal error checking we do here since we know that all the SLS
# files exist and there is no whitelist/blacklist being used.
top = self.highstate.get_top() # pylint: disable=assignment-from-none
matches = self.highstate.top_matches(top)
high, _ = self.highstate.render_highstate(matches)
ret = salt.state.find_sls_ids('issue-47182.stateA.newer', high)
self.assertEqual(ret, [('somestuff', 'cmd')])
class TopFileMergeTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
'''

View File

@ -11,8 +11,8 @@ from tests.support.mock import NO_MOCK, NO_MOCK_REASON, patch, MagicMock
from tests.support.paths import TESTS_DIR
# Import Salt libs
import salt.utils.boto
import salt.utils.boto3
import salt.utils.botomod as botomod
import salt.utils.boto3mod as boto3mod
from salt.ext import six
from salt.exceptions import SaltInvocationError
from salt.utils.versions import LooseVersion
@ -141,29 +141,29 @@ class BotoUtilsTestCaseBase(TestCase, LoaderModuleMockMixin):
module_globals = {
'__salt__': {'config.option': MagicMock(return_value='dummy_opt')}
}
return {salt.utils.boto: module_globals, salt.utils.boto3: module_globals}
return {botomod: module_globals, boto3mod: module_globals}
class BotoUtilsCacheIdTestCase(BotoUtilsTestCaseBase):
def test_set_and_get_with_no_auth_params(self):
salt.utils.boto.cache_id(service, resource_name, resource_id=resource_id)
self.assertEqual(salt.utils.boto.cache_id(service, resource_name), resource_id)
botomod.cache_id(service, resource_name, resource_id=resource_id)
self.assertEqual(botomod.cache_id(service, resource_name), resource_id)
def test_set_and_get_with_explicit_auth_params(self):
salt.utils.boto.cache_id(service, resource_name, resource_id=resource_id, **conn_parameters)
self.assertEqual(salt.utils.boto.cache_id(service, resource_name, **conn_parameters), resource_id)
botomod.cache_id(service, resource_name, resource_id=resource_id, **conn_parameters)
self.assertEqual(botomod.cache_id(service, resource_name, **conn_parameters), resource_id)
def test_set_and_get_with_different_region_returns_none(self):
salt.utils.boto.cache_id(service, resource_name, resource_id=resource_id, region='us-east-1')
self.assertEqual(salt.utils.boto.cache_id(service, resource_name, region='us-west-2'), None)
botomod.cache_id(service, resource_name, resource_id=resource_id, region='us-east-1')
self.assertEqual(botomod.cache_id(service, resource_name, region='us-west-2'), None)
def test_set_and_get_after_invalidation_returns_none(self):
salt.utils.boto.cache_id(service, resource_name, resource_id=resource_id)
salt.utils.boto.cache_id(service, resource_name, resource_id=resource_id, invalidate=True)
self.assertEqual(salt.utils.boto.cache_id(service, resource_name), None)
botomod.cache_id(service, resource_name, resource_id=resource_id)
botomod.cache_id(service, resource_name, resource_id=resource_id, invalidate=True)
self.assertEqual(botomod.cache_id(service, resource_name), None)
def test_partial(self):
cache_id = salt.utils.boto.cache_id_func(service)
cache_id = botomod.cache_id_func(service)
cache_id(resource_name, resource_id=resource_id)
self.assertEqual(cache_id(resource_name), resource_id)
@ -178,33 +178,33 @@ class BotoUtilsGetConnTestCase(BotoUtilsTestCaseBase):
@mock_ec2
def test_conn_is_cached(self):
conn = salt.utils.boto.get_connection(service, **conn_parameters)
self.assertTrue(conn in salt.utils.boto.__context__.values())
conn = botomod.get_connection(service, **conn_parameters)
self.assertTrue(conn in botomod.__context__.values())
@mock_ec2
def test_conn_is_cache_with_profile(self):
conn = salt.utils.boto.get_connection(service, profile=conn_parameters)
self.assertTrue(conn in salt.utils.boto.__context__.values())
conn = botomod.get_connection(service, profile=conn_parameters)
self.assertTrue(conn in botomod.__context__.values())
@mock_ec2
def test_get_conn_with_no_auth_params_raises_invocation_error(self):
with patch('boto.{0}.connect_to_region'.format(service),
side_effect=boto.exception.NoAuthHandlerFound()):
with self.assertRaises(SaltInvocationError):
salt.utils.boto.get_connection(service)
botomod.get_connection(service)
@mock_ec2
def test_get_conn_error_raises_command_execution_error(self):
with patch('boto.{0}.connect_to_region'.format(service),
side_effect=BotoServerError(400, 'Mocked error', body=error_body)):
with self.assertRaises(BotoServerError):
salt.utils.boto.get_connection(service)
botomod.get_connection(service)
@mock_ec2
def test_partial(self):
get_conn = salt.utils.boto.get_connection_func(service)
get_conn = botomod.get_connection_func(service)
conn = get_conn(**conn_parameters)
self.assertTrue(conn in salt.utils.boto.__context__.values())
self.assertTrue(conn in botomod.__context__.values())
@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
@ -214,7 +214,7 @@ class BotoUtilsGetConnTestCase(BotoUtilsTestCaseBase):
class BotoUtilsGetErrorTestCase(BotoUtilsTestCaseBase):
def test_error_message(self):
e = BotoServerError('400', 'Mocked error', body=error_body)
r = salt.utils.boto.get_error(e)
r = botomod.get_error(e)
expected = {'aws': {'code': 'Error code text',
'message': 'Error message',
'reason': 'Mocked error',
@ -224,7 +224,7 @@ class BotoUtilsGetErrorTestCase(BotoUtilsTestCaseBase):
def test_exception_message_with_no_body(self):
e = BotoServerError('400', 'Mocked error')
r = salt.utils.boto.get_error(e)
r = botomod.get_error(e)
expected = {'aws': {'reason': 'Mocked error',
'status': '400'},
'message': 'Mocked error'}
@ -232,7 +232,7 @@ class BotoUtilsGetErrorTestCase(BotoUtilsTestCaseBase):
def test_exception_message_with_no_error_in_body(self):
e = BotoServerError('400', 'Mocked error', body=no_error_body)
r = salt.utils.boto.get_error(e)
r = botomod.get_error(e)
expected = {'aws': {'reason': 'Mocked error', 'status': '400'},
'message': 'Mocked error'}
self.assertEqual(r, expected)
@ -249,14 +249,14 @@ class BotoUtilsGetErrorTestCase(BotoUtilsTestCaseBase):
class BotoBoto3CacheContextCollisionTest(BotoUtilsTestCaseBase):
def test_context_conflict_between_boto_and_boto3_utils(self):
salt.utils.boto.assign_funcs(__name__, 'ec2')
salt.utils.boto3.assign_funcs(__name__, 'ec2', get_conn_funcname="_get_conn3")
botomod.assign_funcs(__name__, 'ec2')
boto3mod.assign_funcs(__name__, 'ec2', get_conn_funcname="_get_conn3")
boto_ec2_conn = salt.utils.boto.get_connection('ec2',
boto_ec2_conn = botomod.get_connection('ec2',
region=region,
key=secret_key,
keyid=access_key)
boto3_ec2_conn = salt.utils.boto3.get_connection('ec2',
boto3_ec2_conn = boto3mod.get_connection('ec2',
region=region,
key=secret_key,
keyid=access_key)