mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
updated boto_lambda execution module with 'lambda environment variables'
This commit is contained in:
parent
781c15de1c
commit
dc8344f0c2
@ -73,7 +73,7 @@ Connection module for Amazon Lambda
|
||||
|
||||
'''
|
||||
# keep lint from choking on _get_conn and _cache_id
|
||||
#pylint: disable=E0602
|
||||
# pylint: disable=E0602
|
||||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
@ -97,11 +97,12 @@ log = logging.getLogger(__name__)
|
||||
|
||||
# pylint: disable=import-error
|
||||
try:
|
||||
#pylint: disable=unused-import
|
||||
# pylint: disable=unused-import
|
||||
import boto
|
||||
import boto3
|
||||
#pylint: enable=unused-import
|
||||
# pylint: enable=unused-import
|
||||
from botocore.exceptions import ClientError
|
||||
from botocore import __version__ as found_botocore_version
|
||||
logging.getLogger('boto').setLevel(logging.CRITICAL)
|
||||
logging.getLogger('boto3').setLevel(logging.CRITICAL)
|
||||
HAS_BOTO = True
|
||||
@ -117,9 +118,11 @@ def __virtual__():
|
||||
'''
|
||||
required_boto_version = '2.8.0'
|
||||
required_boto3_version = '1.2.5'
|
||||
required_botocore_version = '1.5.2'
|
||||
# the boto_lambda execution module relies on the connect_to_region() method
|
||||
# which was added in boto 2.8.0
|
||||
# https://github.com/boto/boto/commit/33ac26b416fbb48a60602542b4ce15dcc7029f12
|
||||
# botocore version >= 1.5.2 is required due to lambda environment variables
|
||||
if not HAS_BOTO:
|
||||
return (False, 'The boto_lambda module could not be loaded: '
|
||||
'boto libraries not found')
|
||||
@ -129,6 +132,9 @@ def __virtual__():
|
||||
elif _LooseVersion(boto3.__version__) < _LooseVersion(required_boto3_version):
|
||||
return (False, 'The boto_lambda module could not be loaded: '
|
||||
'boto version {0} or later must be installed.'.format(required_boto3_version))
|
||||
elif _LooseVersion(found_botocore_version) < _LooseVersion(required_botocore_version):
|
||||
return (False, 'The boto_apigateway module could not be loaded: '
|
||||
'botocore version {0} or later must be installed.'.format(required_botocore_version))
|
||||
else:
|
||||
return True
|
||||
|
||||
@ -140,8 +146,7 @@ def __init__(opts):
|
||||
|
||||
|
||||
def _find_function(name,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Given function name, find and return matching Lambda information.
|
||||
'''
|
||||
@ -155,7 +160,7 @@ def _find_function(name,
|
||||
|
||||
|
||||
def function_exists(FunctionName, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
keyid=None, profile=None):
|
||||
'''
|
||||
Given a function name, check to see if the given function name exists.
|
||||
|
||||
@ -172,7 +177,7 @@ def function_exists(FunctionName, region=None, key=None,
|
||||
|
||||
try:
|
||||
func = _find_function(FunctionName,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
return {'exists': bool(func)}
|
||||
except ClientError as e:
|
||||
return {'error': salt.utils.boto3.get_error(e)}
|
||||
@ -201,10 +206,22 @@ def create_function(FunctionName, Runtime, Role, Handler, ZipFile=None,
|
||||
S3Bucket=None, S3Key=None, S3ObjectVersion=None,
|
||||
Description="", Timeout=3, MemorySize=128, Publish=False,
|
||||
WaitForRole=False, RoleRetries=5,
|
||||
region=None, key=None, keyid=None, profile=None, VpcConfig=None):
|
||||
region=None, key=None, keyid=None, profile=None,
|
||||
VpcConfig=None, Environment=None):
|
||||
'''
|
||||
Given a valid config, create a function.
|
||||
|
||||
Environment
|
||||
The parent object that contains your environment's configuration
|
||||
settings. This is a dictionary of the form:
|
||||
{
|
||||
'Variables': {
|
||||
'VariableName': 'VariableValue'
|
||||
}
|
||||
}
|
||||
|
||||
.. versionadded:: Nitrogen
|
||||
|
||||
Returns {created: true} if the function was created and returns
|
||||
{created: False} if the function was not created.
|
||||
|
||||
@ -216,29 +233,32 @@ def create_function(FunctionName, Runtime, Role, Handler, ZipFile=None,
|
||||
|
||||
'''
|
||||
|
||||
role_arn = _get_role_arn(Role, region=region, key=key, keyid=keyid, profile=profile)
|
||||
role_arn = _get_role_arn(Role, region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
try:
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
if ZipFile:
|
||||
if S3Bucket or S3Key or S3ObjectVersion:
|
||||
raise SaltInvocationError('Either ZipFile must be specified, or '
|
||||
'S3Bucket and S3Key must be provided.')
|
||||
'S3Bucket and S3Key must be provided.')
|
||||
code = {
|
||||
'ZipFile': _filedata(ZipFile),
|
||||
'ZipFile': _filedata(ZipFile),
|
||||
}
|
||||
else:
|
||||
if not S3Bucket or not S3Key:
|
||||
raise SaltInvocationError('Either ZipFile must be specified, or '
|
||||
'S3Bucket and S3Key must be provided.')
|
||||
'S3Bucket and S3Key must be provided.')
|
||||
code = {
|
||||
'S3Bucket': S3Bucket,
|
||||
'S3Key': S3Key,
|
||||
'S3Bucket': S3Bucket,
|
||||
'S3Key': S3Key,
|
||||
}
|
||||
if S3ObjectVersion:
|
||||
code['S3ObjectVersion'] = S3ObjectVersion
|
||||
kwargs = {}
|
||||
if VpcConfig is not None:
|
||||
kwargs['VpcConfig'] = VpcConfig
|
||||
if Environment is not None:
|
||||
kwargs['Environment'] = Environment
|
||||
if WaitForRole:
|
||||
retrycount = RoleRetries
|
||||
else:
|
||||
@ -246,20 +266,23 @@ def create_function(FunctionName, Runtime, Role, Handler, ZipFile=None,
|
||||
for retry in range(retrycount, 0, -1):
|
||||
try:
|
||||
func = conn.create_function(FunctionName=FunctionName, Runtime=Runtime, Role=role_arn, Handler=Handler,
|
||||
Code=code, Description=Description, Timeout=Timeout, MemorySize=MemorySize,
|
||||
Publish=Publish, **kwargs)
|
||||
Code=code, Description=Description, Timeout=Timeout, MemorySize=MemorySize,
|
||||
Publish=Publish, **kwargs)
|
||||
except ClientError as e:
|
||||
if retry > 1 and e.response.get('Error', {}).get('Code') == 'InvalidParameterValueException':
|
||||
log.info('Function not created but IAM role may not have propagated, will retry')
|
||||
log.info(
|
||||
'Function not created but IAM role may not have propagated, will retry')
|
||||
# exponential backoff
|
||||
time.sleep((2 ** (RoleRetries - retry)) + (random.randint(0, 1000) / 1000))
|
||||
time.sleep((2 ** (RoleRetries - retry)) +
|
||||
(random.randint(0, 1000) / 1000))
|
||||
continue
|
||||
else:
|
||||
raise
|
||||
else:
|
||||
break
|
||||
if func:
|
||||
log.info('The newly created function name is {0}'.format(func['FunctionName']))
|
||||
log.info('The newly created function name is {0}'.format(
|
||||
func['FunctionName']))
|
||||
|
||||
return {'created': True, 'name': func['FunctionName']}
|
||||
else:
|
||||
@ -287,7 +310,8 @@ def delete_function(FunctionName, Qualifier=None, region=None, key=None, keyid=N
|
||||
try:
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
if Qualifier:
|
||||
conn.delete_function(FunctionName=FunctionName, Qualifier=Qualifier)
|
||||
conn.delete_function(
|
||||
FunctionName=FunctionName, Qualifier=Qualifier)
|
||||
else:
|
||||
conn.delete_function(FunctionName=FunctionName)
|
||||
return {'deleted': True}
|
||||
@ -296,7 +320,7 @@ def delete_function(FunctionName, Qualifier=None, region=None, key=None, keyid=N
|
||||
|
||||
|
||||
def describe_function(FunctionName, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
keyid=None, profile=None):
|
||||
'''
|
||||
Given a function name describe its properties.
|
||||
|
||||
@ -312,11 +336,11 @@ def describe_function(FunctionName, region=None, key=None,
|
||||
|
||||
try:
|
||||
func = _find_function(FunctionName,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
if func:
|
||||
keys = ('FunctionName', 'Runtime', 'Role', 'Handler', 'CodeSha256',
|
||||
'CodeSize', 'Description', 'Timeout', 'MemorySize', 'FunctionArn',
|
||||
'LastModified', 'VpcConfig')
|
||||
'CodeSize', 'Description', 'Timeout', 'MemorySize',
|
||||
'FunctionArn', 'LastModified', 'VpcConfig', 'Environment')
|
||||
return {'function': dict([(k, func.get(k)) for k in keys])}
|
||||
else:
|
||||
return {'function': None}
|
||||
@ -325,12 +349,24 @@ def describe_function(FunctionName, region=None, key=None,
|
||||
|
||||
|
||||
def update_function_config(FunctionName, Role=None, Handler=None,
|
||||
Description=None, Timeout=None, MemorySize=None,
|
||||
region=None, key=None, keyid=None, profile=None, VpcConfig=None,
|
||||
WaitForRole=False, RoleRetries=5):
|
||||
Description=None, Timeout=None, MemorySize=None,
|
||||
region=None, key=None, keyid=None, profile=None,
|
||||
VpcConfig=None, WaitForRole=False, RoleRetries=5,
|
||||
Environment=None):
|
||||
'''
|
||||
Update the named lambda function to the configuration.
|
||||
|
||||
Environment
|
||||
The parent object that contains your environment's configuration
|
||||
settings. This is a dictionary of the form:
|
||||
{
|
||||
'Variables': {
|
||||
'VariableName': 'VariableValue'
|
||||
}
|
||||
}
|
||||
|
||||
.. versionadded:: Nitrogen
|
||||
|
||||
Returns {updated: true} if the function was updated and returns
|
||||
{updated: False} if the function was not updated.
|
||||
|
||||
@ -347,7 +383,8 @@ def update_function_config(FunctionName, Role=None, Handler=None,
|
||||
'Description': Description,
|
||||
'Timeout': Timeout,
|
||||
'MemorySize': MemorySize,
|
||||
'VpcConfig': VpcConfig}
|
||||
'VpcConfig': VpcConfig,
|
||||
'Environment': Environment}
|
||||
|
||||
for val, var in six.iteritems(options):
|
||||
if var:
|
||||
@ -366,9 +403,11 @@ def update_function_config(FunctionName, Role=None, Handler=None,
|
||||
r = conn.update_function_configuration(**args)
|
||||
except ClientError as e:
|
||||
if retry > 1 and e.response.get('Error', {}).get('Code') == 'InvalidParameterValueException':
|
||||
log.info('Function not updated but IAM role may not have propagated, will retry')
|
||||
log.info(
|
||||
'Function not updated but IAM role may not have propagated, will retry')
|
||||
# exponential backoff
|
||||
time.sleep((2 ** (RoleRetries - retry)) + (random.randint(0, 1000) / 1000))
|
||||
time.sleep((2 ** (RoleRetries - retry)) +
|
||||
(random.randint(0, 1000) / 1000))
|
||||
continue
|
||||
else:
|
||||
raise
|
||||
@ -376,8 +415,8 @@ def update_function_config(FunctionName, Role=None, Handler=None,
|
||||
break
|
||||
if r:
|
||||
keys = ('FunctionName', 'Runtime', 'Role', 'Handler', 'CodeSha256',
|
||||
'CodeSize', 'Description', 'Timeout', 'MemorySize', 'FunctionArn',
|
||||
'LastModified', 'VpcConfig')
|
||||
'CodeSize', 'Description', 'Timeout', 'MemorySize',
|
||||
'FunctionArn', 'LastModified', 'VpcConfig', 'Environment')
|
||||
return {'updated': True, 'function': dict([(k, r.get(k)) for k in keys])}
|
||||
else:
|
||||
log.warning('Function was not updated')
|
||||
@ -387,8 +426,8 @@ def update_function_config(FunctionName, Role=None, Handler=None,
|
||||
|
||||
|
||||
def update_function_code(FunctionName, ZipFile=None, S3Bucket=None, S3Key=None,
|
||||
S3ObjectVersion=None, Publish=False,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
S3ObjectVersion=None, Publish=False,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Upload the given code to the named lambda function.
|
||||
|
||||
@ -408,14 +447,14 @@ def update_function_code(FunctionName, ZipFile=None, S3Bucket=None, S3Key=None,
|
||||
if ZipFile:
|
||||
if S3Bucket or S3Key or S3ObjectVersion:
|
||||
raise SaltInvocationError('Either ZipFile must be specified, or '
|
||||
'S3Bucket and S3Key must be provided.')
|
||||
'S3Bucket and S3Key must be provided.')
|
||||
r = conn.update_function_code(FunctionName=FunctionName,
|
||||
ZipFile=_filedata(ZipFile),
|
||||
Publish=Publish)
|
||||
ZipFile=_filedata(ZipFile),
|
||||
Publish=Publish)
|
||||
else:
|
||||
if not S3Bucket or not S3Key:
|
||||
raise SaltInvocationError('Either ZipFile must be specified, or '
|
||||
'S3Bucket and S3Key must be provided.')
|
||||
'S3Bucket and S3Key must be provided.')
|
||||
args = {
|
||||
'S3Bucket': S3Bucket,
|
||||
'S3Key': S3Key,
|
||||
@ -423,11 +462,11 @@ def update_function_code(FunctionName, ZipFile=None, S3Bucket=None, S3Key=None,
|
||||
if S3ObjectVersion:
|
||||
args['S3ObjectVersion'] = S3ObjectVersion
|
||||
r = conn.update_function_code(FunctionName=FunctionName,
|
||||
Publish=Publish, **args)
|
||||
Publish=Publish, **args)
|
||||
if r:
|
||||
keys = ('FunctionName', 'Runtime', 'Role', 'Handler', 'CodeSha256',
|
||||
'CodeSize', 'Description', 'Timeout', 'MemorySize', 'FunctionArn',
|
||||
'LastModified', 'VpcConfig')
|
||||
'CodeSize', 'Description', 'Timeout', 'MemorySize',
|
||||
'FunctionArn', 'LastModified', 'VpcConfig', 'Environment')
|
||||
return {'updated': True, 'function': dict([(k, r.get(k)) for k in keys])}
|
||||
else:
|
||||
log.warning('Function was not updated')
|
||||
@ -462,15 +501,15 @@ def add_permission(FunctionName, StatementId, Action, Principal, SourceArn=None,
|
||||
if locals()[key] is not None:
|
||||
kwargs[key] = str(locals()[key])
|
||||
conn.add_permission(FunctionName=FunctionName, StatementId=StatementId,
|
||||
Action=Action, Principal=str(Principal),
|
||||
**kwargs)
|
||||
Action=Action, Principal=str(Principal),
|
||||
**kwargs)
|
||||
return {'updated': True}
|
||||
except ClientError as e:
|
||||
return {'updated': False, 'error': salt.utils.boto3.get_error(e)}
|
||||
|
||||
|
||||
def remove_permission(FunctionName, StatementId, Qualifier=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Remove a permission from a lambda function.
|
||||
|
||||
@ -491,7 +530,7 @@ def remove_permission(FunctionName, StatementId, Qualifier=None,
|
||||
if Qualifier is not None:
|
||||
kwargs['Qualifier'] = Qualifier
|
||||
conn.remove_permission(FunctionName=FunctionName, StatementId=StatementId,
|
||||
**kwargs)
|
||||
**kwargs)
|
||||
return {'updated': True}
|
||||
except ClientError as e:
|
||||
return {'updated': False, 'error': salt.utils.boto3.get_error(e)}
|
||||
@ -521,7 +560,7 @@ def get_permissions(FunctionName, Qualifier=None,
|
||||
# The get_policy call is not symmetric with add/remove_permissions. So
|
||||
# massage it until it is, for better ease of use.
|
||||
policy = conn.get_policy(FunctionName=FunctionName,
|
||||
**kwargs)
|
||||
**kwargs)
|
||||
policy = policy.get('Policy', {})
|
||||
if isinstance(policy, six.string_types):
|
||||
policy = json.loads(policy)
|
||||
@ -540,9 +579,11 @@ def get_permissions(FunctionName, Qualifier=None,
|
||||
'Principal': principal,
|
||||
}
|
||||
if 'ArnLike' in condition:
|
||||
permission['SourceArn'] = condition['ArnLike'].get('AWS:SourceArn')
|
||||
permission['SourceArn'] = condition[
|
||||
'ArnLike'].get('AWS:SourceArn')
|
||||
if 'StringEquals' in condition:
|
||||
permission['SourceAccount'] = condition['StringEquals'].get('AWS:SourceAccount')
|
||||
permission['SourceAccount'] = condition[
|
||||
'StringEquals'].get('AWS:SourceAccount')
|
||||
permissions[statement.get('Sid')] = permission
|
||||
return {'permissions': permissions}
|
||||
except ClientError as e:
|
||||
@ -553,7 +594,7 @@ def get_permissions(FunctionName, Qualifier=None,
|
||||
|
||||
|
||||
def list_function_versions(FunctionName,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
List the versions available for the given function.
|
||||
|
||||
@ -572,7 +613,7 @@ def list_function_versions(FunctionName,
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
vers = []
|
||||
for ret in salt.utils.boto3.paged_call(conn.list_versions_by_function,
|
||||
FunctionName=FunctionName):
|
||||
FunctionName=FunctionName):
|
||||
vers.extend(ret['Versions'])
|
||||
if not bool(vers):
|
||||
log.warning('No versions found')
|
||||
@ -582,7 +623,7 @@ def list_function_versions(FunctionName,
|
||||
|
||||
|
||||
def create_alias(FunctionName, Name, FunctionVersion, Description="",
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Given a valid config, create an alias to a function.
|
||||
|
||||
@ -599,9 +640,10 @@ def create_alias(FunctionName, Name, FunctionVersion, Description="",
|
||||
try:
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
alias = conn.create_alias(FunctionName=FunctionName, Name=Name,
|
||||
FunctionVersion=FunctionVersion, Description=Description)
|
||||
FunctionVersion=FunctionVersion, Description=Description)
|
||||
if alias:
|
||||
log.info('The newly created alias name is {0}'.format(alias['Name']))
|
||||
log.info(
|
||||
'The newly created alias name is {0}'.format(alias['Name']))
|
||||
|
||||
return {'created': True, 'name': alias['Name']}
|
||||
else:
|
||||
@ -635,8 +677,7 @@ def delete_alias(FunctionName, Name, region=None, key=None, keyid=None, profile=
|
||||
|
||||
|
||||
def _find_alias(FunctionName, Name, FunctionVersion=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Given function name and alias name, find and return matching alias information.
|
||||
'''
|
||||
@ -656,7 +697,7 @@ def _find_alias(FunctionName, Name, FunctionVersion=None,
|
||||
|
||||
|
||||
def alias_exists(FunctionName, Name, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
keyid=None, profile=None):
|
||||
'''
|
||||
Given a function name and alias name, check to see if the given alias exists.
|
||||
|
||||
@ -673,14 +714,14 @@ def alias_exists(FunctionName, Name, region=None, key=None,
|
||||
|
||||
try:
|
||||
alias = _find_alias(FunctionName, Name,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
return {'exists': bool(alias)}
|
||||
except ClientError as e:
|
||||
return {'error': salt.utils.boto3.get_error(e)}
|
||||
|
||||
|
||||
def describe_alias(FunctionName, Name, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
keyid=None, profile=None):
|
||||
'''
|
||||
Given a function name and alias name describe the properties of the alias.
|
||||
|
||||
@ -696,7 +737,7 @@ def describe_alias(FunctionName, Name, region=None, key=None,
|
||||
|
||||
try:
|
||||
alias = _find_alias(FunctionName, Name,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
if alias:
|
||||
keys = ('AliasArn', 'Name', 'FunctionVersion', 'Description')
|
||||
return {'alias': dict([(k, alias.get(k)) for k in keys])}
|
||||
@ -707,7 +748,7 @@ def describe_alias(FunctionName, Name, region=None, key=None,
|
||||
|
||||
|
||||
def update_alias(FunctionName, Name, FunctionVersion=None, Description=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Update the named alias to the configuration.
|
||||
|
||||
@ -741,8 +782,8 @@ def update_alias(FunctionName, Name, FunctionVersion=None, Description=None,
|
||||
|
||||
|
||||
def create_event_source_mapping(EventSourceArn, FunctionName, StartingPosition,
|
||||
Enabled=True, BatchSize=100,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
Enabled=True, BatchSize=100,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Identifies a stream as an event source for a Lambda function. It can be
|
||||
either an Amazon Kinesis stream or an Amazon DynamoDB stream. AWS Lambda
|
||||
@ -766,7 +807,8 @@ def create_event_source_mapping(EventSourceArn, FunctionName, StartingPosition,
|
||||
BatchSize=BatchSize,
|
||||
StartingPosition=StartingPosition)
|
||||
if obj:
|
||||
log.info('The newly created event source mapping ID is {0}'.format(obj['UUID']))
|
||||
log.info(
|
||||
'The newly created event source mapping ID is {0}'.format(obj['UUID']))
|
||||
|
||||
return {'created': True, 'id': obj['UUID']}
|
||||
else:
|
||||
@ -777,7 +819,7 @@ def create_event_source_mapping(EventSourceArn, FunctionName, StartingPosition,
|
||||
|
||||
|
||||
def get_event_source_mapping_ids(EventSourceArn, FunctionName,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Given an event source and function name, return a list of mapping IDs
|
||||
|
||||
@ -793,28 +835,29 @@ def get_event_source_mapping_ids(EventSourceArn, FunctionName,
|
||||
try:
|
||||
mappings = []
|
||||
for maps in salt.utils.boto3.paged_call(conn.list_event_source_mappings,
|
||||
EventSourceArn=EventSourceArn,
|
||||
FunctionName=FunctionName):
|
||||
mappings.extend([mapping['UUID'] for mapping in maps['EventSourceMappings']])
|
||||
EventSourceArn=EventSourceArn,
|
||||
FunctionName=FunctionName):
|
||||
mappings.extend([mapping['UUID']
|
||||
for mapping in maps['EventSourceMappings']])
|
||||
return mappings
|
||||
except ClientError as e:
|
||||
return {'error': salt.utils.boto3.get_error(e)}
|
||||
|
||||
|
||||
def _get_ids(UUID=None, EventSourceArn=None, FunctionName=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
if UUID:
|
||||
if EventSourceArn or FunctionName:
|
||||
raise SaltInvocationError('Either UUID must be specified, or '
|
||||
'EventSourceArn and FunctionName must be provided.')
|
||||
'EventSourceArn and FunctionName must be provided.')
|
||||
return [UUID]
|
||||
else:
|
||||
if not EventSourceArn or not FunctionName:
|
||||
raise SaltInvocationError('Either UUID must be specified, or '
|
||||
'EventSourceArn and FunctionName must be provided.')
|
||||
'EventSourceArn and FunctionName must be provided.')
|
||||
return get_event_source_mapping_ids(EventSourceArn=EventSourceArn,
|
||||
FunctionName=FunctionName,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
|
||||
def delete_event_source_mapping(UUID=None, EventSourceArn=None, FunctionName=None,
|
||||
@ -834,7 +877,7 @@ def delete_event_source_mapping(UUID=None, EventSourceArn=None, FunctionName=Non
|
||||
|
||||
'''
|
||||
ids = _get_ids(UUID, EventSourceArn=EventSourceArn,
|
||||
FunctionName=FunctionName)
|
||||
FunctionName=FunctionName)
|
||||
try:
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
for id in ids:
|
||||
@ -845,8 +888,8 @@ def delete_event_source_mapping(UUID=None, EventSourceArn=None, FunctionName=Non
|
||||
|
||||
|
||||
def event_source_mapping_exists(UUID=None, EventSourceArn=None,
|
||||
FunctionName=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
FunctionName=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Given an event source mapping ID or an event source ARN and FunctionName,
|
||||
check whether the mapping exists.
|
||||
@ -873,8 +916,8 @@ def event_source_mapping_exists(UUID=None, EventSourceArn=None,
|
||||
|
||||
|
||||
def describe_event_source_mapping(UUID=None, EventSourceArn=None,
|
||||
FunctionName=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
FunctionName=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Given an event source mapping ID or an event source ARN and FunctionName,
|
||||
obtain the current settings of that mapping.
|
||||
@ -890,7 +933,7 @@ def describe_event_source_mapping(UUID=None, EventSourceArn=None,
|
||||
'''
|
||||
|
||||
ids = _get_ids(UUID, EventSourceArn=EventSourceArn,
|
||||
FunctionName=FunctionName)
|
||||
FunctionName=FunctionName)
|
||||
if len(ids) < 1:
|
||||
return {'event_source_mapping': None}
|
||||
|
||||
@ -910,8 +953,8 @@ def describe_event_source_mapping(UUID=None, EventSourceArn=None,
|
||||
|
||||
|
||||
def update_event_source_mapping(UUID,
|
||||
FunctionName=None, Enabled=None, BatchSize=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
FunctionName=None, Enabled=None, BatchSize=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Update the event source mapping identified by the UUID.
|
||||
|
||||
|
@ -37,6 +37,7 @@ import os
|
||||
try:
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
from botocore import __version__ as found_botocore_version
|
||||
HAS_BOTO = True
|
||||
except ImportError:
|
||||
HAS_BOTO = False
|
||||
@ -51,17 +52,19 @@ if 'SuSE' in platform.dist():
|
||||
# which was added in boto 2.8.0
|
||||
# https://github.com/boto/boto/commit/33ac26b416fbb48a60602542b4ce15dcc7029f12
|
||||
required_boto3_version = '1.2.1'
|
||||
required_botocore_version = '1.5.2'
|
||||
|
||||
region = 'us-east-1'
|
||||
access_key = 'GKTADJGHEIQSXMKKRBJ08H'
|
||||
secret_key = 'askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs'
|
||||
conn_parameters = {'region': region, 'key': access_key, 'keyid': secret_key, 'profile': {}}
|
||||
conn_parameters = {'region': region, 'key': access_key,
|
||||
'keyid': secret_key, 'profile': {}}
|
||||
error_message = 'An error occurred (101) when calling the {0} operation: Test-defined error'
|
||||
error_content = {
|
||||
'Error': {
|
||||
'Code': 101,
|
||||
'Message': "Test-defined error"
|
||||
}
|
||||
'Error': {
|
||||
'Code': 101,
|
||||
'Message': "Test-defined error"
|
||||
}
|
||||
}
|
||||
function_ret = dict(FunctionName='testfunction',
|
||||
Runtime='python2.7',
|
||||
@ -74,7 +77,8 @@ function_ret = dict(FunctionName='testfunction',
|
||||
CodeSize=199,
|
||||
FunctionArn='arn:lambda:us-east-1:1234:Something',
|
||||
LastModified='yes',
|
||||
VpcConfig=None)
|
||||
VpcConfig=None,
|
||||
Environment=None)
|
||||
alias_ret = dict(AliasArn='arn:lambda:us-east-1:1234:Something',
|
||||
Name='testalias',
|
||||
FunctionVersion='3',
|
||||
@ -108,6 +112,8 @@ def _has_required_boto():
|
||||
return False
|
||||
elif LooseVersion(boto3.__version__) < LooseVersion(required_boto3_version):
|
||||
return False
|
||||
elif LooseVersion(found_botocore_version) < LooseVersion(required_botocore_version):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
@ -127,7 +133,8 @@ class BotoLambdaTestCaseBase(TestCase):
|
||||
# connections keep getting cached from prior tests, can't find the
|
||||
# correct context object to clear it. So randomize the cache key, to prevent any
|
||||
# cache hits
|
||||
conn_parameters['key'] = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(50))
|
||||
conn_parameters['key'] = ''.join(random.choice(
|
||||
string.ascii_lowercase + string.digits) for _ in range(50))
|
||||
|
||||
self.patcher = patch('boto3.session.Session')
|
||||
self.addCleanup(self.patcher.stop)
|
||||
@ -139,6 +146,7 @@ class BotoLambdaTestCaseBase(TestCase):
|
||||
|
||||
|
||||
class TempZipFile(object):
|
||||
|
||||
def __enter__(self):
|
||||
with NamedTemporaryFile(suffix='.zip', prefix='salt_test_', delete=False) as tmp:
|
||||
to_write = '###\n'
|
||||
@ -166,7 +174,8 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
Tests checking lambda function existence when the lambda function already exists
|
||||
'''
|
||||
self.conn.list_functions.return_value = {'Functions': [function_ret]}
|
||||
func_exists_result = boto_lambda.function_exists(FunctionName=function_ret['FunctionName'], **conn_parameters)
|
||||
func_exists_result = boto_lambda.function_exists(
|
||||
FunctionName=function_ret['FunctionName'], **conn_parameters)
|
||||
|
||||
self.assertTrue(func_exists_result['exists'])
|
||||
|
||||
@ -175,7 +184,8 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
Tests checking lambda function existence when the lambda function does not exist
|
||||
'''
|
||||
self.conn.list_functions.return_value = {'Functions': [function_ret]}
|
||||
func_exists_result = boto_lambda.function_exists(FunctionName='myfunc', **conn_parameters)
|
||||
func_exists_result = boto_lambda.function_exists(
|
||||
FunctionName='myfunc', **conn_parameters)
|
||||
|
||||
self.assertFalse(func_exists_result['exists'])
|
||||
|
||||
@ -183,10 +193,13 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
'''
|
||||
Tests checking lambda function existence when boto returns an error
|
||||
'''
|
||||
self.conn.list_functions.side_effect = ClientError(error_content, 'list_functions')
|
||||
func_exists_result = boto_lambda.function_exists(FunctionName='myfunc', **conn_parameters)
|
||||
self.conn.list_functions.side_effect = ClientError(
|
||||
error_content, 'list_functions')
|
||||
func_exists_result = boto_lambda.function_exists(
|
||||
FunctionName='myfunc', **conn_parameters)
|
||||
|
||||
self.assertEqual(func_exists_result.get('error', {}).get('message'), error_message.format('list_functions'))
|
||||
self.assertEqual(func_exists_result.get('error', {}).get(
|
||||
'message'), error_message.format('list_functions'))
|
||||
|
||||
def test_that_when_creating_a_function_from_zipfile_succeeds_the_create_function_method_returns_true(self):
|
||||
'''
|
||||
@ -196,11 +209,11 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
with TempZipFile() as zipfile:
|
||||
self.conn.create_function.return_value = function_ret
|
||||
lambda_creation_result = boto_lambda.create_function(FunctionName='testfunction',
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
ZipFile=zipfile,
|
||||
**conn_parameters)
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
ZipFile=zipfile,
|
||||
**conn_parameters)
|
||||
|
||||
self.assertTrue(lambda_creation_result['created'])
|
||||
|
||||
@ -211,12 +224,12 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.create_function.return_value = function_ret
|
||||
lambda_creation_result = boto_lambda.create_function(FunctionName='testfunction',
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
S3Bucket='bucket',
|
||||
S3Key='key',
|
||||
**conn_parameters)
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
S3Bucket='bucket',
|
||||
S3Key='key',
|
||||
**conn_parameters)
|
||||
|
||||
self.assertTrue(lambda_creation_result['created'])
|
||||
|
||||
@ -226,12 +239,12 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
with self.assertRaisesRegexp(SaltInvocationError,
|
||||
'Either ZipFile must be specified, or S3Bucket and S3Key must be provided.'):
|
||||
'Either ZipFile must be specified, or S3Bucket and S3Key must be provided.'):
|
||||
lambda_creation_result = boto_lambda.create_function(FunctionName='testfunction',
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
**conn_parameters)
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
**conn_parameters)
|
||||
|
||||
def test_that_when_creating_a_function_with_zipfile_and_s3_raises_a_salt_invocation_error(self):
|
||||
'''
|
||||
@ -239,31 +252,33 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
with self.assertRaisesRegexp(SaltInvocationError,
|
||||
'Either ZipFile must be specified, or S3Bucket and S3Key must be provided.'):
|
||||
'Either ZipFile must be specified, or S3Bucket and S3Key must be provided.'):
|
||||
with TempZipFile() as zipfile:
|
||||
lambda_creation_result = boto_lambda.create_function(FunctionName='testfunction',
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
ZipFile=zipfile,
|
||||
S3Bucket='bucket',
|
||||
S3Key='key',
|
||||
**conn_parameters)
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
ZipFile=zipfile,
|
||||
S3Bucket='bucket',
|
||||
S3Key='key',
|
||||
**conn_parameters)
|
||||
|
||||
def test_that_when_creating_a_function_fails_the_create_function_method_returns_error(self):
|
||||
'''
|
||||
tests False function not created.
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.create_function.side_effect = ClientError(error_content, 'create_function')
|
||||
self.conn.create_function.side_effect = ClientError(
|
||||
error_content, 'create_function')
|
||||
with TempZipFile() as zipfile:
|
||||
lambda_creation_result = boto_lambda.create_function(FunctionName='testfunction',
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
ZipFile=zipfile,
|
||||
**conn_parameters)
|
||||
self.assertEqual(lambda_creation_result.get('error', {}).get('message'), error_message.format('create_function'))
|
||||
Runtime='python2.7',
|
||||
Role='myrole',
|
||||
Handler='file.method',
|
||||
ZipFile=zipfile,
|
||||
**conn_parameters)
|
||||
self.assertEqual(lambda_creation_result.get('error', {}).get(
|
||||
'message'), error_message.format('create_function'))
|
||||
|
||||
def test_that_when_deleting_a_function_succeeds_the_delete_function_method_returns_true(self):
|
||||
'''
|
||||
@ -271,8 +286,8 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
result = boto_lambda.delete_function(FunctionName='testfunction',
|
||||
Qualifier=1,
|
||||
**conn_parameters)
|
||||
Qualifier=1,
|
||||
**conn_parameters)
|
||||
|
||||
self.assertTrue(result['deleted'])
|
||||
|
||||
@ -281,9 +296,10 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
tests False function not deleted.
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.delete_function.side_effect = ClientError(error_content, 'delete_function')
|
||||
self.conn.delete_function.side_effect = ClientError(
|
||||
error_content, 'delete_function')
|
||||
result = boto_lambda.delete_function(FunctionName='testfunction',
|
||||
**conn_parameters)
|
||||
**conn_parameters)
|
||||
self.assertFalse(result['deleted'])
|
||||
|
||||
def test_that_when_describing_function_it_returns_the_dict_of_properties_returns_true(self):
|
||||
@ -293,7 +309,8 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
self.conn.list_functions.return_value = {'Functions': [function_ret]}
|
||||
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
result = boto_lambda.describe_function(FunctionName=function_ret['FunctionName'], **conn_parameters)
|
||||
result = boto_lambda.describe_function(
|
||||
FunctionName=function_ret['FunctionName'], **conn_parameters)
|
||||
|
||||
self.assertEqual(result, {'function': function_ret})
|
||||
|
||||
@ -303,7 +320,8 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
'''
|
||||
self.conn.list_functions.return_value = {'Functions': []}
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
result = boto_lambda.describe_function(FunctionName='testfunction', **conn_parameters)
|
||||
result = boto_lambda.describe_function(
|
||||
FunctionName='testfunction', **conn_parameters)
|
||||
|
||||
self.assertFalse(result['function'])
|
||||
|
||||
@ -311,8 +329,10 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
'''
|
||||
Tests describing parameters failure
|
||||
'''
|
||||
self.conn.list_functions.side_effect = ClientError(error_content, 'list_functions')
|
||||
result = boto_lambda.describe_function(FunctionName='testfunction', **conn_parameters)
|
||||
self.conn.list_functions.side_effect = ClientError(
|
||||
error_content, 'list_functions')
|
||||
result = boto_lambda.describe_function(
|
||||
FunctionName='testfunction', **conn_parameters)
|
||||
self.assertTrue('error' in result)
|
||||
|
||||
def test_that_when_updating_a_function_succeeds_the_update_function_method_returns_true(self):
|
||||
@ -321,7 +341,8 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.update_function_config.return_value = function_ret
|
||||
result = boto_lambda.update_function_config(FunctionName=function_ret['FunctionName'], Role='myrole', **conn_parameters)
|
||||
result = boto_lambda.update_function_config(
|
||||
FunctionName=function_ret['FunctionName'], Role='myrole', **conn_parameters)
|
||||
|
||||
self.assertTrue(result['updated'])
|
||||
|
||||
@ -330,11 +351,13 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
tests False function not updated.
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.update_function_configuration.side_effect = ClientError(error_content, 'update_function')
|
||||
self.conn.update_function_configuration.side_effect = ClientError(
|
||||
error_content, 'update_function')
|
||||
result = boto_lambda.update_function_config(FunctionName='testfunction',
|
||||
Role='myrole',
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'), error_message.format('update_function'))
|
||||
Role='myrole',
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'),
|
||||
error_message.format('update_function'))
|
||||
|
||||
def test_that_when_updating_function_code_from_zipfile_succeeds_the_update_function_method_returns_true(self):
|
||||
'''
|
||||
@ -343,7 +366,8 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
with TempZipFile() as zipfile:
|
||||
self.conn.update_function_code.return_value = function_ret
|
||||
result = boto_lambda.update_function_code(FunctionName=function_ret['FunctionName'], ZipFile=zipfile, **conn_parameters)
|
||||
result = boto_lambda.update_function_code(
|
||||
FunctionName=function_ret['FunctionName'], ZipFile=zipfile, **conn_parameters)
|
||||
|
||||
self.assertTrue(result['updated'])
|
||||
|
||||
@ -354,9 +378,9 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.update_function_code.return_value = function_ret
|
||||
result = boto_lambda.update_function_code(FunctionName='testfunction',
|
||||
S3Bucket='bucket',
|
||||
S3Key='key',
|
||||
**conn_parameters)
|
||||
S3Bucket='bucket',
|
||||
S3Key='key',
|
||||
**conn_parameters)
|
||||
|
||||
self.assertTrue(result['updated'])
|
||||
|
||||
@ -366,30 +390,33 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
with self.assertRaisesRegexp(SaltInvocationError,
|
||||
'Either ZipFile must be specified, or S3Bucket and S3Key must be provided.'):
|
||||
'Either ZipFile must be specified, or S3Bucket and S3Key must be provided.'):
|
||||
result = boto_lambda.update_function_code(FunctionName='testfunction',
|
||||
**conn_parameters)
|
||||
**conn_parameters)
|
||||
|
||||
def test_that_when_updating_function_code_fails_the_update_function_method_returns_error(self):
|
||||
'''
|
||||
tests False function not updated.
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.update_function_code.side_effect = ClientError(error_content, 'update_function_code')
|
||||
self.conn.update_function_code.side_effect = ClientError(
|
||||
error_content, 'update_function_code')
|
||||
result = boto_lambda.update_function_code(FunctionName='testfunction',
|
||||
S3Bucket='bucket',
|
||||
S3Key='key',
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'), error_message.format('update_function_code'))
|
||||
S3Bucket='bucket',
|
||||
S3Key='key',
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'),
|
||||
error_message.format('update_function_code'))
|
||||
|
||||
def test_that_when_listing_function_versions_succeeds_the_list_function_versions_method_returns_true(self):
|
||||
'''
|
||||
tests True function versions listed.
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.list_versions_by_function.return_value = {'Versions': [function_ret]}
|
||||
self.conn.list_versions_by_function.return_value = {
|
||||
'Versions': [function_ret]}
|
||||
result = boto_lambda.list_function_versions(FunctionName='testfunction',
|
||||
**conn_parameters)
|
||||
**conn_parameters)
|
||||
|
||||
self.assertTrue(result['Versions'])
|
||||
|
||||
@ -400,7 +427,7 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.list_versions_by_function.return_value = {'Versions': []}
|
||||
result = boto_lambda.list_function_versions(FunctionName='testfunction',
|
||||
**conn_parameters)
|
||||
**conn_parameters)
|
||||
self.assertFalse(result['Versions'])
|
||||
|
||||
def test_that_when_listing_function_versions_fails_the_list_function_versions_method_returns_error(self):
|
||||
@ -408,10 +435,12 @@ class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin
|
||||
tests False function versions error.
|
||||
'''
|
||||
with patch.dict(boto_lambda.__salt__, {'boto_iam.get_account_id': MagicMock(return_value='1234')}):
|
||||
self.conn.list_versions_by_function.side_effect = ClientError(error_content, 'list_versions_by_function')
|
||||
self.conn.list_versions_by_function.side_effect = ClientError(
|
||||
error_content, 'list_versions_by_function')
|
||||
result = boto_lambda.list_function_versions(FunctionName='testfunction',
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'), error_message.format('list_versions_by_function'))
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'),
|
||||
error_message.format('list_versions_by_function'))
|
||||
|
||||
|
||||
@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
|
||||
@ -423,15 +452,17 @@ class BotoLambdaAliasTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin):
|
||||
'''
|
||||
TestCase for salt.modules.boto_lambda module aliases
|
||||
'''
|
||||
|
||||
def test_that_when_creating_an_alias_succeeds_the_create_alias_method_returns_true(self):
|
||||
'''
|
||||
tests True alias created.
|
||||
'''
|
||||
self.conn.create_alias.return_value = alias_ret
|
||||
result = boto_lambda.create_alias(FunctionName='testfunction',
|
||||
Name=alias_ret['Name'],
|
||||
FunctionVersion=alias_ret['FunctionVersion'],
|
||||
**conn_parameters)
|
||||
Name=alias_ret['Name'],
|
||||
FunctionVersion=alias_ret[
|
||||
'FunctionVersion'],
|
||||
**conn_parameters)
|
||||
|
||||
self.assertTrue(result['created'])
|
||||
|
||||
@ -439,12 +470,15 @@ class BotoLambdaAliasTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin):
|
||||
'''
|
||||
tests False alias not created.
|
||||
'''
|
||||
self.conn.create_alias.side_effect = ClientError(error_content, 'create_alias')
|
||||
self.conn.create_alias.side_effect = ClientError(
|
||||
error_content, 'create_alias')
|
||||
result = boto_lambda.create_alias(FunctionName='testfunction',
|
||||
Name=alias_ret['Name'],
|
||||
FunctionVersion=alias_ret['FunctionVersion'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'), error_message.format('create_alias'))
|
||||
Name=alias_ret['Name'],
|
||||
FunctionVersion=alias_ret[
|
||||
'FunctionVersion'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get(
|
||||
'message'), error_message.format('create_alias'))
|
||||
|
||||
def test_that_when_deleting_an_alias_succeeds_the_delete_alias_method_returns_true(self):
|
||||
'''
|
||||
@ -460,7 +494,8 @@ class BotoLambdaAliasTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin):
|
||||
'''
|
||||
tests False alias not deleted.
|
||||
'''
|
||||
self.conn.delete_alias.side_effect = ClientError(error_content, 'delete_alias')
|
||||
self.conn.delete_alias.side_effect = ClientError(
|
||||
error_content, 'delete_alias')
|
||||
result = boto_lambda.delete_alias(FunctionName='testfunction',
|
||||
Name=alias_ret['Name'],
|
||||
**conn_parameters)
|
||||
@ -491,12 +526,14 @@ class BotoLambdaAliasTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin):
|
||||
'''
|
||||
Tests checking lambda alias existence when boto returns an error
|
||||
'''
|
||||
self.conn.list_aliases.side_effect = ClientError(error_content, 'list_aliases')
|
||||
self.conn.list_aliases.side_effect = ClientError(
|
||||
error_content, 'list_aliases')
|
||||
result = boto_lambda.alias_exists(FunctionName='testfunction',
|
||||
Name=alias_ret['Name'],
|
||||
**conn_parameters)
|
||||
|
||||
self.assertEqual(result.get('error', {}).get('message'), error_message.format('list_aliases'))
|
||||
self.assertEqual(result.get('error', {}).get(
|
||||
'message'), error_message.format('list_aliases'))
|
||||
|
||||
def test_that_when_describing_alias_it_returns_the_dict_of_properties_returns_true(self):
|
||||
'''
|
||||
@ -525,7 +562,8 @@ class BotoLambdaAliasTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin):
|
||||
'''
|
||||
Tests describing parameters failure
|
||||
'''
|
||||
self.conn.list_aliases.side_effect = ClientError(error_content, 'list_aliases')
|
||||
self.conn.list_aliases.side_effect = ClientError(
|
||||
error_content, 'list_aliases')
|
||||
result = boto_lambda.describe_alias(FunctionName='testfunction',
|
||||
Name=alias_ret['Name'],
|
||||
**conn_parameters)
|
||||
@ -547,11 +585,13 @@ class BotoLambdaAliasTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin):
|
||||
'''
|
||||
tests False alias not updated.
|
||||
'''
|
||||
self.conn.update_alias.side_effect = ClientError(error_content, 'update_alias')
|
||||
self.conn.update_alias.side_effect = ClientError(
|
||||
error_content, 'update_alias')
|
||||
result = boto_lambda.update_alias(FunctionName='testfunction',
|
||||
Name=alias_ret['Name'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'), error_message.format('update_alias'))
|
||||
self.assertEqual(result.get('error', {}).get(
|
||||
'message'), error_message.format('update_alias'))
|
||||
|
||||
|
||||
@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
|
||||
@ -563,16 +603,17 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
TestCase for salt.modules.boto_lambda module mappings
|
||||
'''
|
||||
|
||||
def test_that_when_creating_a_mapping_succeeds_the_create_event_source_mapping_method_returns_true(self):
|
||||
'''
|
||||
tests True mapping created.
|
||||
'''
|
||||
self.conn.create_event_source_mapping.return_value = event_source_mapping_ret
|
||||
result = boto_lambda.create_event_source_mapping(
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
StartingPosition='LATEST',
|
||||
**conn_parameters)
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
StartingPosition='LATEST',
|
||||
**conn_parameters)
|
||||
|
||||
self.assertTrue(result['created'])
|
||||
|
||||
@ -580,12 +621,13 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
tests False mapping not created.
|
||||
'''
|
||||
self.conn.create_event_source_mapping.side_effect = ClientError(error_content, 'create_event_source_mapping')
|
||||
self.conn.create_event_source_mapping.side_effect = ClientError(
|
||||
error_content, 'create_event_source_mapping')
|
||||
result = boto_lambda.create_event_source_mapping(
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
StartingPosition='LATEST',
|
||||
**conn_parameters)
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
StartingPosition='LATEST',
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'),
|
||||
error_message.format('create_event_source_mapping'))
|
||||
|
||||
@ -593,11 +635,12 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
tests True mapping ids listed.
|
||||
'''
|
||||
self.conn.list_event_source_mappings.return_value = {'EventSourceMappings': [event_source_mapping_ret]}
|
||||
self.conn.list_event_source_mappings.return_value = {
|
||||
'EventSourceMappings': [event_source_mapping_ret]}
|
||||
result = boto_lambda.get_event_source_mapping_ids(
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
|
||||
self.assertTrue(result)
|
||||
|
||||
@ -605,31 +648,34 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
tests False no mapping ids listed.
|
||||
'''
|
||||
self.conn.list_event_source_mappings.return_value = {'EventSourceMappings': []}
|
||||
self.conn.list_event_source_mappings.return_value = {
|
||||
'EventSourceMappings': []}
|
||||
result = boto_lambda.get_event_source_mapping_ids(
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_that_when_listing_event_source_mapping_ids_fails_the_get_event_source_mapping_ids_method_returns_error(self):
|
||||
'''
|
||||
tests False mapping ids error.
|
||||
'''
|
||||
self.conn.list_event_source_mappings.side_effect = ClientError(error_content, 'list_event_source_mappings')
|
||||
self.conn.list_event_source_mappings.side_effect = ClientError(
|
||||
error_content, 'list_event_source_mappings')
|
||||
result = boto_lambda.get_event_source_mapping_ids(
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'), error_message.format('list_event_source_mappings'))
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'),
|
||||
error_message.format('list_event_source_mappings'))
|
||||
|
||||
def test_that_when_deleting_an_event_source_mapping_by_UUID_succeeds_the_delete_event_source_mapping_method_returns_true(self):
|
||||
'''
|
||||
tests True mapping deleted.
|
||||
'''
|
||||
result = boto_lambda.delete_event_source_mapping(
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
self.assertTrue(result['deleted'])
|
||||
|
||||
@skipIf(True, 'This appears to leak memory and crash the unit test suite')
|
||||
@ -637,11 +683,12 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
tests True mapping deleted.
|
||||
'''
|
||||
self.conn.list_event_source_mappings.return_value = {'EventSourceMappings': [event_source_mapping_ret]}
|
||||
self.conn.list_event_source_mappings.return_value = {
|
||||
'EventSourceMappings': [event_source_mapping_ret]}
|
||||
result = boto_lambda.delete_event_source_mapping(
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
EventSourceArn=event_source_mapping_ret['EventSourceArn'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
self.assertTrue(result['deleted'])
|
||||
|
||||
def test_that_when_deleting_an_event_source_mapping_without_identifier_the_delete_event_source_mapping_method_raises_saltinvocationexception(self):
|
||||
@ -656,9 +703,10 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
tests False mapping not deleted.
|
||||
'''
|
||||
self.conn.delete_event_source_mapping.side_effect = ClientError(error_content, 'delete_event_source_mapping')
|
||||
self.conn.delete_event_source_mapping.side_effect = ClientError(
|
||||
error_content, 'delete_event_source_mapping')
|
||||
result = boto_lambda.delete_event_source_mapping(UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
**conn_parameters)
|
||||
self.assertFalse(result['deleted'])
|
||||
|
||||
def test_that_when_checking_if_an_event_source_mapping_exists_and_the_event_source_mapping_exists_the_event_source_mapping_exists_method_returns_true(self):
|
||||
@ -668,8 +716,8 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
self.conn.get_event_source_mapping.return_value = event_source_mapping_ret
|
||||
result = boto_lambda.event_source_mapping_exists(
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
self.assertTrue(result['exists'])
|
||||
|
||||
def test_that_when_checking_if_an_event_source_mapping_exists_and_the_event_source_mapping_does_not_exist_the_event_source_mapping_exists_method_returns_false(self):
|
||||
@ -679,19 +727,21 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
self.conn.get_event_source_mapping.return_value = None
|
||||
result = boto_lambda.event_source_mapping_exists(
|
||||
UUID='other_UUID',
|
||||
**conn_parameters)
|
||||
UUID='other_UUID',
|
||||
**conn_parameters)
|
||||
self.assertFalse(result['exists'])
|
||||
|
||||
def test_that_when_checking_if_an_event_source_mapping_exists_and_boto3_returns_an_error_the_event_source_mapping_exists_method_returns_error(self):
|
||||
'''
|
||||
Tests checking lambda event_source_mapping existence when boto returns an error
|
||||
'''
|
||||
self.conn.get_event_source_mapping.side_effect = ClientError(error_content, 'list_event_source_mappings')
|
||||
self.conn.get_event_source_mapping.side_effect = ClientError(
|
||||
error_content, 'list_event_source_mappings')
|
||||
result = boto_lambda.event_source_mapping_exists(
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'), error_message.format('list_event_source_mappings'))
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'),
|
||||
error_message.format('list_event_source_mappings'))
|
||||
|
||||
def test_that_when_describing_event_source_mapping_it_returns_the_dict_of_properties_returns_true(self):
|
||||
'''
|
||||
@ -699,9 +749,10 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
self.conn.get_event_source_mapping.return_value = event_source_mapping_ret
|
||||
result = boto_lambda.describe_event_source_mapping(
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result, {'event_source_mapping': event_source_mapping_ret})
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(
|
||||
result, {'event_source_mapping': event_source_mapping_ret})
|
||||
|
||||
def test_that_when_describing_event_source_mapping_it_returns_the_dict_of_properties_returns_false(self):
|
||||
'''
|
||||
@ -709,18 +760,19 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
self.conn.get_event_source_mapping.return_value = None
|
||||
result = boto_lambda.describe_event_source_mapping(
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
self.assertFalse(result['event_source_mapping'])
|
||||
|
||||
def test_that_when_describing_event_source_mapping_on_client_error_it_returns_error(self):
|
||||
'''
|
||||
Tests describing parameters failure
|
||||
'''
|
||||
self.conn.get_event_source_mapping.side_effect = ClientError(error_content, 'get_event_source_mapping')
|
||||
self.conn.get_event_source_mapping.side_effect = ClientError(
|
||||
error_content, 'get_event_source_mapping')
|
||||
result = boto_lambda.describe_event_source_mapping(
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
**conn_parameters)
|
||||
self.assertTrue('error' in result)
|
||||
|
||||
def test_that_when_updating_an_event_source_mapping_succeeds_the_update_event_source_mapping_method_returns_true(self):
|
||||
@ -729,9 +781,9 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
self.conn.update_event_source_mapping.return_value = event_source_mapping_ret
|
||||
result = boto_lambda.update_event_source_mapping(
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
|
||||
self.assertTrue(result['updated'])
|
||||
|
||||
@ -739,12 +791,14 @@ class BotoLambdaEventSourceMappingTestCase(BotoLambdaTestCaseBase, BotoLambdaTes
|
||||
'''
|
||||
tests False event_source_mapping not updated.
|
||||
'''
|
||||
self.conn.update_event_source_mapping.side_effect = ClientError(error_content, 'update_event_source_mapping')
|
||||
self.conn.update_event_source_mapping.side_effect = ClientError(
|
||||
error_content, 'update_event_source_mapping')
|
||||
result = boto_lambda.update_event_source_mapping(
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'), error_message.format('update_event_source_mapping'))
|
||||
UUID=event_source_mapping_ret['UUID'],
|
||||
FunctionName=event_source_mapping_ret['FunctionArn'],
|
||||
**conn_parameters)
|
||||
self.assertEqual(result.get('error', {}).get('message'),
|
||||
error_message.format('update_event_source_mapping'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
Reference in New Issue
Block a user