mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
Merge pull request #36423 from kraney/boto_apigateway_usage_plan
Boto apigateway usage plan
This commit is contained in:
commit
67b78c7d97
@ -98,6 +98,7 @@ try:
|
||||
import boto3
|
||||
# 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
|
||||
@ -113,6 +114,7 @@ def __virtual__():
|
||||
'''
|
||||
required_boto_version = '2.8.0'
|
||||
required_boto3_version = '1.2.1'
|
||||
required_botocore_version = '1.4.49'
|
||||
# the boto_apigateway execution module relies on the connect_to_region() method
|
||||
# which was added in boto 2.8.0
|
||||
# https://github.com/boto/boto/commit/33ac26b416fbb48a60602542b4ce15dcc7029f12
|
||||
@ -125,6 +127,9 @@ def __virtual__():
|
||||
elif _LooseVersion(boto3.__version__) < _LooseVersion(required_boto3_version):
|
||||
return (False, 'The boto_apigateway module could not be loaded: '
|
||||
'boto3 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
|
||||
|
||||
@ -1388,3 +1393,309 @@ def create_api_integration_response(restApiId, resourcePath, httpMethod, statusC
|
||||
return {'created': False, 'error': 'no such resource'}
|
||||
except ClientError as e:
|
||||
return {'created': False, 'error': salt.utils.boto3.get_error(e)}
|
||||
|
||||
|
||||
def _filter_plans(attr, name, plans):
|
||||
'''
|
||||
Helper to return list of usage plan items matching the given attribute value.
|
||||
'''
|
||||
return [plan for plan in plans if plan[attr] == name]
|
||||
|
||||
|
||||
def describe_usage_plans(name=None, plan_id=None, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Returns a list of existing usage plans, optionally filtered to match a given plan name
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt myminion boto_apigateway.describe_usage_plans
|
||||
|
||||
salt myminion boto_apigateway.describe_usage_plans name='usage plan name'
|
||||
|
||||
salt myminion boto_apigateway.describe_usage_plans plan_id='usage plan id'
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
try:
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
plans = _multi_call(conn.get_usage_plans, 'items')
|
||||
if name:
|
||||
plans = _filter_plans('name', name, plans)
|
||||
if plan_id:
|
||||
plans = _filter_plans('id', plan_id, plans)
|
||||
|
||||
return {'plans': [_convert_datetime_str(plan) for plan in plans]}
|
||||
|
||||
except ClientError as e:
|
||||
return {'error': salt.utils.boto3.get_error(e)}
|
||||
|
||||
|
||||
def _validate_throttle(throttle):
|
||||
'''
|
||||
Helper to verify that throttling parameters are valid
|
||||
'''
|
||||
if throttle is not None:
|
||||
if not isinstance(throttle, dict):
|
||||
raise TypeError('throttle must be a dictionary, provided value: {0}'.format(throttle))
|
||||
|
||||
|
||||
def _validate_quota(quota):
|
||||
'''
|
||||
Helper to verify that quota parameters are valid
|
||||
'''
|
||||
if quota is not None:
|
||||
if not isinstance(quota, dict):
|
||||
raise TypeError('quota must be a dictionary, provided value: {0}'.format(quota))
|
||||
periods = ['DAY', 'WEEK', 'MONTH']
|
||||
if 'period' not in quota or quota['period'] not in periods:
|
||||
raise ValueError('quota must have a valid period specified, valid values are {0}'.format(','.join(periods)))
|
||||
if 'limit' not in quota:
|
||||
raise ValueError('quota limit must have a valid value')
|
||||
|
||||
|
||||
def create_usage_plan(name, description=None, throttle=None, quota=None, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Creates a new usage plan with throttling and quotas optionally applied
|
||||
|
||||
name
|
||||
Name of the usage plan
|
||||
|
||||
throttle
|
||||
A dictionary consisting of the following keys:
|
||||
|
||||
rateLimit
|
||||
requests per second at steady rate, float
|
||||
|
||||
burstLimit
|
||||
maximum number of requests per second, integer
|
||||
|
||||
quota
|
||||
A dictionary consisting of the following keys:
|
||||
|
||||
limit
|
||||
number of allowed requests per specified quota period [required if quota parameter is present]
|
||||
|
||||
offset
|
||||
number of requests to be subtracted from limit at the beginning of the period [optional]
|
||||
|
||||
period
|
||||
quota period, must be one of DAY, WEEK, or MONTH. [required if quota parameter is present
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt myminion boto_apigateway.create_usage_plan name='usage plan name' throttle='{"rateLimit": 10.0, "burstLimit": 10}'
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
try:
|
||||
_validate_throttle(throttle)
|
||||
_validate_quota(quota)
|
||||
|
||||
values = dict(name=name)
|
||||
if description:
|
||||
values['description'] = description
|
||||
if throttle:
|
||||
values['throttle'] = throttle
|
||||
if quota:
|
||||
values['quota'] = quota
|
||||
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
res = conn.create_usage_plan(**values)
|
||||
return {'created': True, 'result': res}
|
||||
except ClientError as e:
|
||||
return {'error': salt.utils.boto3.get_error(e)}
|
||||
except (TypeError, ValueError) as e:
|
||||
return {'error': '{0}'.format(e)}
|
||||
|
||||
|
||||
def update_usage_plan(plan_id, throttle=None, quota=None, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Updates an existing usage plan with throttling and quotas
|
||||
|
||||
plan_id
|
||||
Id of the created usage plan
|
||||
|
||||
throttle
|
||||
A dictionary consisting of the following keys:
|
||||
|
||||
rateLimit
|
||||
requests per second at steady rate, float
|
||||
|
||||
burstLimit
|
||||
maximum number of requests per second, integer
|
||||
|
||||
quota
|
||||
A dictionary consisting of the following keys:
|
||||
|
||||
limit
|
||||
number of allowed requests per specified quota period [required if quota parameter is present]
|
||||
|
||||
offset
|
||||
number of requests to be subtracted from limit at the beginning of the period [optional]
|
||||
|
||||
period
|
||||
quota period, must be one of DAY, WEEK, or MONTH. [required if quota parameter is present
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt myminion boto_apigateway.update_usage_plan plan_id='usage plan id' throttle='{"rateLimit": 10.0, "burstLimit": 10}'
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
try:
|
||||
_validate_throttle(throttle)
|
||||
_validate_quota(quota)
|
||||
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
patchOperations = []
|
||||
|
||||
if throttle is None:
|
||||
patchOperations.append({'op': 'remove', 'path': '/throttle'})
|
||||
else:
|
||||
if 'rateLimit' in throttle:
|
||||
patchOperations.append({'op': 'replace', 'path': '/throttle/rateLimit', 'value': str(throttle['rateLimit'])})
|
||||
if 'burstLimit' in throttle:
|
||||
patchOperations.append({'op': 'replace', 'path': '/throttle/burstLimit', 'value': str(throttle['burstLimit'])})
|
||||
|
||||
if quota is None:
|
||||
patchOperations.append({'op': 'remove', 'path': '/quota'})
|
||||
else:
|
||||
patchOperations.append({'op': 'replace', 'path': '/quota/period', 'value': str(quota['period'])})
|
||||
patchOperations.append({'op': 'replace', 'path': '/quota/limit', 'value': str(quota['limit'])})
|
||||
if 'offset' in quota:
|
||||
patchOperations.append({'op': 'replace', 'path': '/quota/offset', 'value': str(quota['offset'])})
|
||||
|
||||
if patchOperations:
|
||||
res = conn.update_usage_plan(usagePlanId=plan_id,
|
||||
patchOperations=patchOperations)
|
||||
return {'updated': True, 'result': res}
|
||||
|
||||
return {'updated': False}
|
||||
|
||||
except ClientError as e:
|
||||
return {'error': salt.utils.boto3.get_error(e)}
|
||||
except (TypeError, ValueError) as e:
|
||||
return {'error': '{0}'.format(e)}
|
||||
|
||||
|
||||
def delete_usage_plan(plan_id, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Deletes usage plan identified by plan_id
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt myminion boto_apigateway.delete_usage_plan plan_id='usage plan id'
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
try:
|
||||
existing = describe_usage_plans(plan_id=plan_id, region=region, key=key, keyid=keyid, profile=profile)
|
||||
# don't attempt to delete the usage plan if it does not exist
|
||||
if 'error' in existing:
|
||||
return {'error': existing['error']}
|
||||
|
||||
if 'plans' in existing and existing['plans']:
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
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)}
|
||||
|
||||
|
||||
def _update_usage_plan_apis(plan_id, apis, op, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Helper function that updates the usage plan identified by plan_id by adding or removing it to each of the stages, specified by apis parameter.
|
||||
|
||||
apis
|
||||
a list of dictionaries, where each dictionary contains the following:
|
||||
|
||||
apiId
|
||||
a string, which is the id of the created API in AWS ApiGateway
|
||||
|
||||
stage
|
||||
a string, which is the stage that the created API is deployed to.
|
||||
|
||||
op
|
||||
'add' or 'remove'
|
||||
'''
|
||||
try:
|
||||
patchOperations = []
|
||||
for api in apis:
|
||||
patchOperations.append({
|
||||
'op': op,
|
||||
'path': '/apiStages',
|
||||
'value': '{0}:{1}'.format(api['apiId'], api['stage'])
|
||||
})
|
||||
res = None
|
||||
if patchOperations:
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
res = conn.update_usage_plan(usagePlanId=plan_id,
|
||||
patchOperations=patchOperations)
|
||||
return {'success': True, 'result': res}
|
||||
except ClientError as e:
|
||||
return {'error': salt.utils.boto3.get_error(e)}
|
||||
except Exception as e:
|
||||
return {'error': e}
|
||||
|
||||
|
||||
def attach_usage_plan_to_apis(plan_id, apis, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Attaches given usage plan to each of the apis provided in a list of apiId and stage values
|
||||
|
||||
apis
|
||||
a list of dictionaries, where each dictionary contains the following:
|
||||
|
||||
apiId
|
||||
a string, which is the id of the created API in AWS ApiGateway
|
||||
|
||||
stage
|
||||
a string, which is the stage that the created API is deployed to.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt myminion boto_apigateway.attach_usage_plan_to_apis plan_id='usage plan id' apis='[{"apiId": "some id 1", "stage": "some stage 1"}]'
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
return _update_usage_plan_apis(plan_id, apis, 'add', region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
|
||||
def detach_usage_plan_from_apis(plan_id, apis, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Detaches given usage plan from each of the apis provided in a list of apiId and stage value
|
||||
|
||||
apis
|
||||
a list of dictionaries, where each dictionary contains the following:
|
||||
|
||||
apiId
|
||||
a string, which is the id of the created API in AWS ApiGateway
|
||||
|
||||
stage
|
||||
a string, which is the stage that the created API is deployed to.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt myminion boto_apigateway.detach_usage_plan_to_apis plan_id='usage plan id' apis='[{"apiId": "some id 1", "stage": "some stage 1"}]'
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
return _update_usage_plan_apis(plan_id, apis, 'remove', region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
@ -1615,3 +1615,393 @@ class _Swagger(object):
|
||||
ret = self._deploy_method(ret, path, method, method_data, api_key_required,
|
||||
lambda_integration_role, lambda_region, authorization_type)
|
||||
return ret
|
||||
|
||||
|
||||
def usage_plan_present(name, plan_name, description=None, throttle=None, quota=None, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Ensure the spcifieda usage plan with the corresponding metrics is deployed
|
||||
|
||||
name
|
||||
name of the state
|
||||
|
||||
plan_name
|
||||
[Required] name of the usage plan
|
||||
|
||||
throttle
|
||||
[Optional] throttling parameters expressed as a dictionary.
|
||||
If provided, at least one of the throttling parameters must be present
|
||||
|
||||
rateLimit
|
||||
rate per second at which capacity bucket is populated
|
||||
|
||||
burstLimit
|
||||
maximum rate allowed
|
||||
|
||||
quota
|
||||
[Optional] quota on the number of api calls permitted by the plan.
|
||||
If provided, limit and period must be present
|
||||
|
||||
limit
|
||||
[Required] number of calls permitted per quota period
|
||||
|
||||
offset
|
||||
[Optional] number of calls to be subtracted from the limit at the beginning of the period
|
||||
|
||||
period
|
||||
[Required] period to which quota applies. Must be DAY, WEEK or MONTH
|
||||
|
||||
.. code-block:: yaml
|
||||
UsagePlanPresent:
|
||||
boto_apigateway.usage_plan_present:
|
||||
- plan_name: my_usage_plan
|
||||
- throttle:
|
||||
rateLimit: 70
|
||||
burstLimit: 100
|
||||
- quota:
|
||||
limit: 1000
|
||||
offset: 0
|
||||
period: DAY
|
||||
- profile: my_profile
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
func_params = locals()
|
||||
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}
|
||||
}
|
||||
|
||||
try:
|
||||
common_args = dict([('region', region),
|
||||
('key', key),
|
||||
('keyid', keyid),
|
||||
('profile', profile)])
|
||||
|
||||
existing = __salt__['boto_apigateway.describe_usage_plans'](name=plan_name, **common_args)
|
||||
if 'error' in existing:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to describe existing usage plans'
|
||||
return ret
|
||||
|
||||
if not existing['plans']:
|
||||
# plan does not exist, we need to create it
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'a new usage plan {0} would be created'.format(plan_name)
|
||||
ret['result'] = None
|
||||
return ret
|
||||
|
||||
result = __salt__['boto_apigateway.create_usage_plan'](name=plan_name,
|
||||
description=description,
|
||||
throttle=throttle,
|
||||
quota=quota,
|
||||
**common_args)
|
||||
if 'error' in result:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to create a usage plan {0}, {1}'.format(plan_name, result['error'])
|
||||
return ret
|
||||
|
||||
ret['changes']['old'] = {'plan': None}
|
||||
ret['comment'] = 'A new usage plan {0} has been created'.format(plan_name)
|
||||
|
||||
else:
|
||||
# need an existing plan modified to match given value
|
||||
plan = existing['plans'][0]
|
||||
needs_updating = False
|
||||
|
||||
modifiable_params = (('throttle', ('rateLimit', 'burstLimit')), ('quota', ('limit', 'offset', 'period')))
|
||||
for p, fields in modifiable_params:
|
||||
for f in fields:
|
||||
actual_param = {} if func_params.get(p) is None else func_params.get(p)
|
||||
if plan.get(p, {}).get(f, None) != actual_param.get(f, None):
|
||||
needs_updating = True
|
||||
break
|
||||
|
||||
if not needs_updating:
|
||||
ret['comment'] = 'usage plan {0} is already in a correct state'.format(plan_name)
|
||||
ret['result'] = True
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'a new usage plan {0} would be updated'.format(plan_name)
|
||||
ret['result'] = None
|
||||
return ret
|
||||
|
||||
result = __salt__['boto_apigateway.update_usage_plan'](plan['id'],
|
||||
throttle=throttle,
|
||||
quota=quota,
|
||||
**common_args)
|
||||
if 'error' in result:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to update a usage plan {0}, {1}'.format(plan_name, result['error'])
|
||||
return ret
|
||||
|
||||
ret['changes']['old'] = {'plan': plan}
|
||||
ret['comment'] = 'usage plan {0} has been updated'.format(plan_name)
|
||||
|
||||
newstate = __salt__['boto_apigateway.describe_usage_plans'](name=plan_name, **common_args)
|
||||
if 'error' in existing:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to describe existing usage plans after updates'
|
||||
return ret
|
||||
|
||||
ret['changes']['new'] = {'plan': newstate['plans'][0]}
|
||||
|
||||
except (ValueError, IOError) as e:
|
||||
ret['result'] = False
|
||||
ret['comment'] = '{0}'.format(e.args)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def usage_plan_absent(name, plan_name, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Ensures usage plan identified by name is no longer present
|
||||
|
||||
name
|
||||
name of the state
|
||||
|
||||
plan_name
|
||||
name of the plan to remove
|
||||
|
||||
.. code-block:: yaml
|
||||
usage plan absent:
|
||||
boto_apigateway.usage_plan_absent:
|
||||
- plan_name: my_usage_plan
|
||||
- profile: my_profile
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}
|
||||
}
|
||||
|
||||
try:
|
||||
common_args = dict([('region', region),
|
||||
('key', key),
|
||||
('keyid', keyid),
|
||||
('profile', profile)])
|
||||
|
||||
existing = __salt__['boto_apigateway.describe_usage_plans'](name=plan_name, **common_args)
|
||||
if 'error' in existing:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to describe existing usage plans'
|
||||
return ret
|
||||
|
||||
if not existing['plans']:
|
||||
ret['comment'] = 'Usage plan {0} does not exist already'.format(plan_name)
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'Usage plan {0} exists and would be deleted'.format(plan_name)
|
||||
ret['result'] = None
|
||||
return ret
|
||||
|
||||
plan_id = existing['plans'][0]['id']
|
||||
result = __salt__['boto_apigateway.delete_usage_plan'](plan_id, **common_args)
|
||||
|
||||
if 'error' in result:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to delete usage plan {0}, {1}'.format(plan_name, result)
|
||||
return ret
|
||||
|
||||
ret['comment'] = 'Usage plan {0} has been deleted'.format(plan_name)
|
||||
ret['changes']['old'] = {'plan': existing['plans'][0]}
|
||||
ret['changes']['new'] = {'plan': None}
|
||||
|
||||
except (ValueError, IOError) as e:
|
||||
ret['result'] = False
|
||||
ret['comment'] = '{0}'.format(e.args)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def usage_plan_association_present(name, plan_name, api_stages, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Ensures usage plan identified by name is added to provided api_stages
|
||||
|
||||
name
|
||||
name of the state
|
||||
|
||||
plan_name
|
||||
name of the plan to use
|
||||
|
||||
api_stages
|
||||
list of dictionaries, where each dictionary consists of the following keys:
|
||||
|
||||
apiId
|
||||
apiId of the api to attach usage plan to
|
||||
|
||||
stage
|
||||
stage name of the api to attach usage plan to
|
||||
|
||||
.. code-block:: yaml
|
||||
UsagePlanAssociationPresent:
|
||||
boto_apigateway.usage_plan_association_present:
|
||||
- plan_name: my_plan
|
||||
- api_stages:
|
||||
- apiId: 9kb0404ec0
|
||||
stage: my_stage
|
||||
- apiId: l9v7o2aj90
|
||||
stage: my_stage
|
||||
- profile: my_profile
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}
|
||||
}
|
||||
try:
|
||||
common_args = dict([('region', region),
|
||||
('key', key),
|
||||
('keyid', keyid),
|
||||
('profile', profile)])
|
||||
|
||||
existing = __salt__['boto_apigateway.describe_usage_plans'](name=plan_name, **common_args)
|
||||
if 'error' in existing:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to describe existing usage plans'
|
||||
return ret
|
||||
|
||||
if not existing['plans']:
|
||||
ret['comment'] = 'Usage plan {0} does not exist'.format(plan_name)
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
if len(existing['plans']) != 1:
|
||||
ret['comment'] = 'There are multiple usage plans with the same name - it is not supported'
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
plan = existing['plans'][0]
|
||||
plan_id = plan['id']
|
||||
plan_stages = plan.get('apiStages', [])
|
||||
|
||||
stages_to_add = []
|
||||
for api in api_stages:
|
||||
if api not in plan_stages:
|
||||
stages_to_add.append(api)
|
||||
|
||||
if not stages_to_add:
|
||||
ret['comment'] = 'Usage plan is already asssociated to all api stages'
|
||||
return ret
|
||||
|
||||
result = __salt__['boto_apigateway.attach_usage_plan_to_apis'](plan_id, stages_to_add, **common_args)
|
||||
if 'error' in result:
|
||||
ret['comment'] = 'Failed to associate a usage plan {0} to the apis {1}, {2}'.format(plan_name, stages_to_add, result['error'])
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
ret['comment'] = 'successfully associated usage plan to apis'
|
||||
ret['changes']['old'] = plan_stages
|
||||
ret['changes']['new'] = result.get('result', {}).get('apiStages', [])
|
||||
|
||||
except (ValueError, IOError) as e:
|
||||
ret['result'] = False
|
||||
ret['comment'] = '{0}'.format(e.args)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def usage_plan_association_absent(name, plan_name, api_stages, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Ensures usage plan identified by name is removed from provided api_stages
|
||||
If a plan is associated to stages not listed in api_stages parameter,
|
||||
those associations remain intact
|
||||
|
||||
name
|
||||
name of the state
|
||||
|
||||
plan_name
|
||||
name of the plan to use
|
||||
|
||||
api_stages
|
||||
list of dictionaries, where each dictionary consists of the following keys:
|
||||
|
||||
apiId
|
||||
apiId of the api to detach usage plan from
|
||||
|
||||
stage
|
||||
stage name of the api to detach usage plan from
|
||||
|
||||
.. code-block:: yaml
|
||||
UsagePlanAssociationAbsent:
|
||||
boto_apigateway.usage_plan_association_absent:
|
||||
- plan_name: my_plan
|
||||
- api_stages:
|
||||
- apiId: 9kb0404ec0
|
||||
stage: my_stage
|
||||
- apiId: l9v7o2aj90
|
||||
stage: my_stage
|
||||
- profile: my_profile
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}
|
||||
}
|
||||
try:
|
||||
common_args = dict([('region', region),
|
||||
('key', key),
|
||||
('keyid', keyid),
|
||||
('profile', profile)])
|
||||
|
||||
existing = __salt__['boto_apigateway.describe_usage_plans'](name=plan_name, **common_args)
|
||||
if 'error' in existing:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to describe existing usage plans'
|
||||
return ret
|
||||
|
||||
if not existing['plans']:
|
||||
ret['comment'] = 'Usage plan {0} does not exist'.format(plan_name)
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
if len(existing['plans']) != 1:
|
||||
ret['comment'] = 'There are multiple usage plans with the same name - it is not supported'
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
plan = existing['plans'][0]
|
||||
plan_id = plan['id']
|
||||
plan_stages = plan.get('apiStages', [])
|
||||
|
||||
if not plan_stages:
|
||||
ret['comment'] = 'Usage plan {0} has no associated stages already'.format(plan_name)
|
||||
return ret
|
||||
|
||||
stages_to_remove = []
|
||||
for api in api_stages:
|
||||
if api in plan_stages:
|
||||
stages_to_remove.append(api)
|
||||
|
||||
if not stages_to_remove:
|
||||
ret['comment'] = 'Usage plan is already not asssociated to any api stages'
|
||||
return ret
|
||||
|
||||
result = __salt__['boto_apigateway.detach_usage_plan_from_apis'](plan_id, stages_to_remove, **common_args)
|
||||
if 'error' in result:
|
||||
ret['comment'] = 'Failed to disassociate a usage plan {0} from the apis {1}, {2}'.format(plan_name, stages_to_remove, result['error'])
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
ret['comment'] = 'successfully disassociated usage plan from apis'
|
||||
ret['changes']['old'] = plan_stages
|
||||
ret['changes']['new'] = result.get('result', {}).get('apiStages', [])
|
||||
|
||||
except (ValueError, IOError) as e:
|
||||
ret['result'] = False
|
||||
ret['comment'] = '{0}'.format(e.args)
|
||||
|
||||
return ret
|
||||
|
@ -24,6 +24,7 @@ from salt.modules import boto_apigateway
|
||||
# pylint: disable=import-error,no-name-in-module
|
||||
try:
|
||||
import boto3
|
||||
import botocore
|
||||
from botocore.exceptions import ClientError
|
||||
HAS_BOTO = True
|
||||
except ImportError:
|
||||
@ -37,6 +38,7 @@ from salt.ext.six.moves import range, zip
|
||||
# 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.4.49'
|
||||
|
||||
region = 'us-east-1'
|
||||
access_key = 'GKTADJGHEIQSXMKKRBJ08H'
|
||||
@ -91,6 +93,57 @@ api_create_resource_ret = {
|
||||
u'pathPart': u'api3',
|
||||
'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': '2d31072c-9d15-11e5-9977-6d9fcfda9c0a'}}
|
||||
|
||||
usage_plan1 = dict(
|
||||
id='plan1_id',
|
||||
name='plan1_name',
|
||||
description='plan1_desc',
|
||||
apiStages=[],
|
||||
throttle=dict(
|
||||
burstLimit=123,
|
||||
rateLimit=123.0
|
||||
),
|
||||
quota=dict(
|
||||
limit=123,
|
||||
offset=123,
|
||||
period='DAY'
|
||||
)
|
||||
)
|
||||
usage_plan2 = dict(
|
||||
id='plan2_id',
|
||||
name='plan2_name',
|
||||
description='plan2_desc',
|
||||
apiStages=[],
|
||||
throttle=dict(
|
||||
burstLimit=123,
|
||||
rateLimit=123.0
|
||||
),
|
||||
quota=dict(
|
||||
limit=123,
|
||||
offset=123,
|
||||
period='DAY'
|
||||
)
|
||||
)
|
||||
usage_plan1b = dict(
|
||||
id='another_plan1_id',
|
||||
name='plan1_name',
|
||||
description='another_plan1_desc',
|
||||
apiStages=[],
|
||||
throttle=dict(
|
||||
burstLimit=123,
|
||||
rateLimit=123.0
|
||||
),
|
||||
quota=dict(
|
||||
limit=123,
|
||||
offset=123,
|
||||
period='DAY'
|
||||
)
|
||||
)
|
||||
usage_plans_ret = dict(
|
||||
items=[
|
||||
usage_plan1, usage_plan2, usage_plan1b
|
||||
]
|
||||
)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
opts = salt.config.DEFAULT_MINION_OPTS
|
||||
@ -115,6 +168,18 @@ def _has_required_boto():
|
||||
return True
|
||||
|
||||
|
||||
def _has_required_botocore():
|
||||
'''
|
||||
Returns True/False boolean depending on if botocore supports usage plan
|
||||
'''
|
||||
if not HAS_BOTO:
|
||||
return False
|
||||
elif LooseVersion(botocore.__version__) < LooseVersion(required_botocore_version):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class BotoApiGatewayTestCaseBase(TestCase):
|
||||
conn = None
|
||||
|
||||
@ -154,9 +219,12 @@ class BotoApiGatewayTestCaseMixin(object):
|
||||
|
||||
@skipIf(True, 'Skip these tests while investigating failures')
|
||||
@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
|
||||
@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
|
||||
' or equal to version {0}'
|
||||
.format(required_boto3_version))
|
||||
@skipIf(_has_required_boto() is False,
|
||||
'The boto3 module must be greater than'
|
||||
' or equal to version {0}'.format(required_boto3_version))
|
||||
@skipIf(_has_required_botocore() is False,
|
||||
'The botocore module must be greater than'
|
||||
' or equal to version {0}'.format(required_botocore_version))
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class BotoApiGatewayTestCase(BotoApiGatewayTestCaseBase, BotoApiGatewayTestCaseMixin):
|
||||
'''
|
||||
@ -1379,6 +1447,205 @@ class BotoApiGatewayTestCase(BotoApiGatewayTestCaseBase, BotoApiGatewayTestCaseM
|
||||
**conn_parameters)
|
||||
self.assertTrue(result.get('error'))
|
||||
|
||||
def test_that_when_describing_usage_plans_and_an_exception_is_thrown_in_get_usage_plans(self):
|
||||
'''
|
||||
Tests True for existence of 'error'
|
||||
'''
|
||||
self.conn.get_usage_plans.side_effect = ClientError(error_content, 'get_usage_plans_exception')
|
||||
result = boto_apigateway.describe_usage_plans(name='some plan', **conn_parameters)
|
||||
self.assertEqual(result.get('error').get('message'), error_message.format('get_usage_plans_exception'))
|
||||
|
||||
def test_that_when_describing_usage_plans_and_plan_name_or_id_does_not_exist_that_results_have_empty_plans_list(self):
|
||||
'''
|
||||
Tests for plans equaling empty list
|
||||
'''
|
||||
self.conn.get_usage_plans.return_value = usage_plans_ret
|
||||
|
||||
result = boto_apigateway.describe_usage_plans(name='does not exist', **conn_parameters)
|
||||
self.assertEqual(result.get('plans'), [])
|
||||
|
||||
result = boto_apigateway.describe_usage_plans(plan_id='does not exist', **conn_parameters)
|
||||
self.assertEqual(result.get('plans'), [])
|
||||
|
||||
result = boto_apigateway.describe_usage_plans(name='does not exist', plan_id='does not exist', **conn_parameters)
|
||||
self.assertEqual(result.get('plans'), [])
|
||||
|
||||
result = boto_apigateway.describe_usage_plans(name='plan1_name', plan_id='does not exist', **conn_parameters)
|
||||
self.assertEqual(result.get('plans'), [])
|
||||
|
||||
result = boto_apigateway.describe_usage_plans(name='does not exist', plan_id='plan1_id', **conn_parameters)
|
||||
self.assertEqual(result.get('plans'), [])
|
||||
|
||||
def test_that_when_describing_usage_plans_for_plans_that_exist_that_the_function_returns_all_matching_plans(self):
|
||||
'''
|
||||
Tests for plans filtering properly if they exist
|
||||
'''
|
||||
self.conn.get_usage_plans.return_value = usage_plans_ret
|
||||
|
||||
result = boto_apigateway.describe_usage_plans(name=usage_plan1['name'], **conn_parameters)
|
||||
self.assertEqual(len(result.get('plans')), 2)
|
||||
for plan in result['plans']:
|
||||
self.assertTrue(plan in [usage_plan1, usage_plan1b])
|
||||
|
||||
def test_that_when_creating_or_updating_a_usage_plan_and_throttle_or_quota_failed_to_validate_that_an_error_is_returned(self):
|
||||
'''
|
||||
Tests for TypeError and ValueError in throttle and quota
|
||||
'''
|
||||
for throttle, quota in (([], None), (None, []), ('abc', None), (None, 'def')):
|
||||
res = boto_apigateway.create_usage_plan('plan1_name', description=None, throttle=throttle, quota=quota, **conn_parameters)
|
||||
self.assertNotEqual(None, res.get('error'))
|
||||
res = boto_apigateway.update_usage_plan('plan1_id', throttle=throttle, quota=quota, **conn_parameters)
|
||||
self.assertNotEqual(None, res.get('error'))
|
||||
|
||||
for quota in ({'limit': 123}, {'period': 123}, {'period': 'DAY'}):
|
||||
res = boto_apigateway.create_usage_plan('plan1_name', description=None, throttle=None, quota=quota, **conn_parameters)
|
||||
self.assertNotEqual(None, res.get('error'))
|
||||
res = boto_apigateway.update_usage_plan('plan1_id', quota=quota, **conn_parameters)
|
||||
self.assertNotEqual(None, res.get('error'))
|
||||
|
||||
self.conn.get_usage_plans.assert_not_called()
|
||||
self.conn.create_usage_plan.assert_not_called()
|
||||
self.conn.update_usage_plan.assert_not_called()
|
||||
|
||||
def test_that_when_creating_a_usage_plan_and_create_usage_plan_throws_an_exception_that_an_error_is_returned(self):
|
||||
'''
|
||||
tests for ClientError
|
||||
'''
|
||||
self.conn.create_usage_plan.side_effect = ClientError(error_content, 'create_usage_plan_exception')
|
||||
result = boto_apigateway.create_usage_plan(name='some plan', **conn_parameters)
|
||||
self.assertEqual(result.get('error').get('message'), error_message.format('create_usage_plan_exception'))
|
||||
|
||||
def test_that_create_usage_plan_succeeds(self):
|
||||
'''
|
||||
tests for success user plan creation
|
||||
'''
|
||||
res = 'unit test create_usage_plan succeeded'
|
||||
self.conn.create_usage_plan.return_value = res
|
||||
result = boto_apigateway.create_usage_plan(name='some plan', **conn_parameters)
|
||||
self.assertEqual(result.get('created'), True)
|
||||
self.assertEqual(result.get('result'), res)
|
||||
|
||||
def test_that_when_udpating_a_usage_plan_and_update_usage_plan_throws_an_exception_that_an_error_is_returned(self):
|
||||
'''
|
||||
tests for ClientError
|
||||
'''
|
||||
self.conn.update_usage_plan.side_effect = ClientError(error_content, 'update_usage_plan_exception')
|
||||
result = boto_apigateway.update_usage_plan(plan_id='plan1_id', **conn_parameters)
|
||||
self.assertEqual(result.get('error').get('message'), error_message.format('update_usage_plan_exception'))
|
||||
|
||||
def test_that_when_updating_a_usage_plan_and_if_throttle_and_quota_parameters_are_none_update_usage_plan_removes_throttle_and_quota(self):
|
||||
'''
|
||||
tests for throttle and quota removal
|
||||
'''
|
||||
ret = 'some success status'
|
||||
self.conn.update_usage_plan.return_value = ret
|
||||
result = boto_apigateway.update_usage_plan(plan_id='plan1_id', throttle=None, quota=None, **conn_parameters)
|
||||
self.assertEqual(result.get('updated'), True)
|
||||
self.assertEqual(result.get('result'), ret)
|
||||
self.conn.update_usage_plan.assert_called_once()
|
||||
|
||||
def test_that_when_deleting_usage_plan_and_describe_usage_plans_had_error_that_the_same_error_is_returned(self):
|
||||
'''
|
||||
tests for error in describe_usage_plans returns error
|
||||
'''
|
||||
ret = 'get_usage_plans_exception'
|
||||
self.conn.get_usage_plans.side_effect = ClientError(error_content, ret)
|
||||
result = boto_apigateway.delete_usage_plan(plan_id='some plan id', **conn_parameters)
|
||||
self.assertEqual(result.get('error').get('message'), error_message.format(ret))
|
||||
self.conn.delete_usage_plan.assert_not_called()
|
||||
|
||||
def test_that_when_deleting_usage_plan_and_plan_exists_that_the_functions_returns_deleted_true(self):
|
||||
self.conn.get_usage_plans.return_value = usage_plans_ret
|
||||
ret = 'delete_usage_plan_retval'
|
||||
self.conn.delete_usage_plan.return_value = ret
|
||||
result = boto_apigateway.delete_usage_plan(plan_id='plan1_id', **conn_parameters)
|
||||
self.assertEqual(result.get('deleted'), True)
|
||||
self.assertEqual(result.get('usagePlanId'), 'plan1_id')
|
||||
self.conn.delete_usage_plan.assert_called_once()
|
||||
|
||||
def test_that_when_deleting_usage_plan_and_plan_does_not_exist_that_the_functions_returns_deleted_true(self):
|
||||
'''
|
||||
tests for ClientError
|
||||
'''
|
||||
self.conn.get_usage_plans.return_value = dict(
|
||||
items=[]
|
||||
)
|
||||
ret = 'delete_usage_plan_retval'
|
||||
self.conn.delete_usage_plan.return_value = ret
|
||||
result = boto_apigateway.delete_usage_plan(plan_id='plan1_id', **conn_parameters)
|
||||
self.assertEqual(result.get('deleted'), True)
|
||||
self.assertEqual(result.get('usagePlanId'), 'plan1_id')
|
||||
self.conn.delete_usage_plan.assert_not_called()
|
||||
|
||||
def test_that_when_deleting_usage_plan_and_delete_usage_plan_throws_exception_that_an_error_is_returned(self):
|
||||
'''
|
||||
tests for ClientError
|
||||
'''
|
||||
self.conn.get_usage_plans.return_value = usage_plans_ret
|
||||
error_msg = 'delete_usage_plan_exception'
|
||||
self.conn.delete_usage_plan.side_effect = ClientError(error_content, error_msg)
|
||||
result = boto_apigateway.delete_usage_plan(plan_id='plan1_id', **conn_parameters)
|
||||
self.assertEqual(result.get('error').get('message'), error_message.format(error_msg))
|
||||
self.conn.delete_usage_plan.assert_called_once()
|
||||
|
||||
def test_that_attach_or_detach_usage_plan_when_apis_is_empty_that_success_is_returned(self):
|
||||
'''
|
||||
tests for border cases when apis is empty list
|
||||
'''
|
||||
result = boto_apigateway.attach_usage_plan_to_apis(plan_id='plan1_id', apis=[], **conn_parameters)
|
||||
self.assertEqual(result.get('success'), True)
|
||||
self.assertEqual(result.get('result', 'no result?'), None)
|
||||
self.conn.update_usage_plan.assert_not_called()
|
||||
|
||||
result = boto_apigateway.detach_usage_plan_from_apis(plan_id='plan1_id', apis=[], **conn_parameters)
|
||||
self.assertEqual(result.get('success'), True)
|
||||
self.assertEqual(result.get('result', 'no result?'), None)
|
||||
self.conn.update_usage_plan.assert_not_called()
|
||||
|
||||
def test_that_attach_or_detach_usage_plan_when_api_does_not_contain_apiId_or_stage_that_an_error_is_returned(self):
|
||||
'''
|
||||
tests for invalid key in api object
|
||||
'''
|
||||
for api in ({'apiId': 'some Id'}, {'stage': 'some stage'}, {}):
|
||||
result = boto_apigateway.attach_usage_plan_to_apis(plan_id='plan1_id', apis=[api], **conn_parameters)
|
||||
self.assertNotEqual(result.get('error'), None)
|
||||
|
||||
result = boto_apigateway.detach_usage_plan_from_apis(plan_id='plan1_id', apis=[api], **conn_parameters)
|
||||
self.assertNotEqual(result.get('error'), None)
|
||||
|
||||
self.conn.update_usage_plan.assert_not_called()
|
||||
|
||||
def test_that_attach_or_detach_usage_plan_and_update_usage_plan_throws_exception_that_an_error_is_returned(self):
|
||||
'''
|
||||
tests for ClientError
|
||||
'''
|
||||
api = {'apiId': 'some_id', 'stage': 'some_stage'}
|
||||
error_msg = 'update_usage_plan_exception'
|
||||
self.conn.update_usage_plan.side_effect = ClientError(error_content, error_msg)
|
||||
|
||||
result = boto_apigateway.attach_usage_plan_to_apis(plan_id='plan1_id', apis=[api], **conn_parameters)
|
||||
self.assertEqual(result.get('error').get('message'), error_message.format(error_msg))
|
||||
|
||||
result = boto_apigateway.detach_usage_plan_from_apis(plan_id='plan1_id', apis=[api], **conn_parameters)
|
||||
self.assertEqual(result.get('error').get('message'), error_message.format(error_msg))
|
||||
|
||||
def test_that_attach_or_detach_usage_plan_updated_successfully(self):
|
||||
'''
|
||||
tests for update_usage_plan called
|
||||
'''
|
||||
api = {'apiId': 'some_id', 'stage': 'some_stage'}
|
||||
attach_ret = 'update_usage_plan_add_op_succeeded'
|
||||
detach_ret = 'update_usage_plan_remove_op_succeeded'
|
||||
self.conn.update_usage_plan.side_effect = [attach_ret, detach_ret]
|
||||
|
||||
result = boto_apigateway.attach_usage_plan_to_apis(plan_id='plan1_id', apis=[api], **conn_parameters)
|
||||
self.assertEqual(result.get('success'), True)
|
||||
self.assertEqual(result.get('result'), attach_ret)
|
||||
|
||||
result = boto_apigateway.detach_usage_plan_from_apis(plan_id='plan1_id', apis=[api], **conn_parameters)
|
||||
self.assertEqual(result.get('success'), True)
|
||||
self.assertEqual(result.get('result'), detach_ret)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests # pylint: disable=import-error
|
||||
run_tests(BotoApiGatewayTestCase, needs_daemon=False)
|
||||
|
@ -29,6 +29,7 @@ from unit.modules.boto_apigateway_test import BotoApiGatewayTestCaseMixin
|
||||
# Import 3rd-party libs
|
||||
try:
|
||||
import boto3
|
||||
import botocore
|
||||
from botocore.exceptions import ClientError
|
||||
HAS_BOTO = True
|
||||
except ImportError:
|
||||
@ -36,12 +37,20 @@ except ImportError:
|
||||
|
||||
from salt.ext.six.moves import range
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.states import boto_apigateway
|
||||
|
||||
boto_apigateway.__salt__ = {}
|
||||
boto_apigateway.__opts__ = {}
|
||||
|
||||
|
||||
# pylint: enable=import-error,no-name-in-module
|
||||
|
||||
# the boto_apigateway module relies on the connect_to_region() method
|
||||
# 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.4.49'
|
||||
|
||||
region = 'us-east-1'
|
||||
access_key = 'GKTADJGHEIQSXMKKRBJ08H'
|
||||
@ -298,6 +307,10 @@ method_ret = dict(apiKeyRequired=False,
|
||||
requestModels={'application/json': 'User'},
|
||||
requestParameters={})
|
||||
|
||||
throttle_rateLimit = 10.0
|
||||
association_stage_1 = {'apiId': 'apiId1', 'stage': 'stage1'}
|
||||
association_stage_2 = {'apiId': 'apiId1', 'stage': 'stage2'}
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
opts = salt.config.DEFAULT_MINION_OPTS
|
||||
@ -321,6 +334,18 @@ def _has_required_boto():
|
||||
return True
|
||||
|
||||
|
||||
def _has_required_botocore():
|
||||
'''
|
||||
Returns True/False boolean depending on if botocore supports usage plan
|
||||
'''
|
||||
if not HAS_BOTO:
|
||||
return False
|
||||
elif LooseVersion(botocore.__version__) < LooseVersion(required_botocore_version):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class TempSwaggerFile(object):
|
||||
_tmp_swagger_dict = {'info': {'version': '0.0.0',
|
||||
'description': 'salt boto apigateway unit test service',
|
||||
@ -975,3 +1000,611 @@ class BotoApiGatewayTestCase(BotoApiGatewayStateTestCaseBase, BotoApiGatewayTest
|
||||
|
||||
self.assertIs(result.get('result'), True)
|
||||
self.assertIsNot(result.get('abort'), True)
|
||||
|
||||
|
||||
@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
|
||||
@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
|
||||
' or equal to version {0}'
|
||||
.format(required_boto3_version))
|
||||
@skipIf(_has_required_botocore() is False,
|
||||
'The botocore module must be greater than'
|
||||
' or equal to version {0}'.format(required_botocore_version))
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class BotoApiGatewayUsagePlanTestCase(BotoApiGatewayStateTestCaseBase, BotoApiGatewayTestCaseMixin):
|
||||
'''
|
||||
TestCase for salt.modules.boto_apigateway state.module, usage_plans portion
|
||||
'''
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_present_if_describe_fails(self, *args):
|
||||
'''
|
||||
Tests correct error processing for describe_usage_plan failure
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Failed to describe existing usage plans')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': []})})
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': True})
|
||||
def test_usage_plan_present_if_there_is_no_such_plan_and_test_option_is_set(self, *args):
|
||||
'''
|
||||
TestCse for salt.modules.boto_apigateway state.module, checking that if __opts__['test'] is set
|
||||
and usage plan does not exist, correct diagnostic will be returned
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', **conn_parameters)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'a new usage plan plan_name would be created')
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], None)
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': []})})
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': False})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.create_usage_plan': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_present_if_create_usage_plan_fails(self, *args):
|
||||
'''
|
||||
Tests behavior for the case when creating a new usage plan fails
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Failed to create a usage plan plan_name, error')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{
|
||||
'id': 'planid',
|
||||
'name': 'planname'
|
||||
}]})})
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': False})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.update_usage_plan': MagicMock()})
|
||||
def test_usage_plan_present_if_plan_is_there_and_needs_no_updates(self, *args):
|
||||
'''
|
||||
Tests behavior for the case when plan is present and needs no updates
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'usage plan plan_name is already in a correct state')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
boto_apigateway.__salt__['boto_apigateway.update_usage_plan'].assert_not_called()
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{
|
||||
'id': 'planid',
|
||||
'name': 'planname',
|
||||
'throttle': {'rateLimit': 10.0}
|
||||
}]})})
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': True})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.update_usage_plan': MagicMock()})
|
||||
def test_usage_plan_present_if_plan_is_there_and_needs_updates_but_test_is_set(self, *args):
|
||||
'''
|
||||
Tests behavior when usage plan needs to be updated by tests option is set
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'a new usage plan plan_name would be updated')
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], None)
|
||||
boto_apigateway.__salt__['boto_apigateway.update_usage_plan'].assert_not_called()
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{
|
||||
'id': 'planid',
|
||||
'name': 'planname',
|
||||
'throttle': {'rateLimit': 10.0}
|
||||
}]})})
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': False})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.update_usage_plan': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_present_if_plan_is_there_and_needs_updates_but_update_fails(self, *args):
|
||||
'''
|
||||
Tests error processing for the case when updating an existing usage plan fails
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Failed to update a usage plan plan_name, error')
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=[{'plans': []}, {'plans': [{'id': 'id'}]}])})
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': False})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.create_usage_plan': MagicMock(return_value={'created': True})})
|
||||
# @patch.dict(boto_apigateway.__salt__, {'boto_apigateway.update_usage_plan': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_present_if_plan_has_been_created(self, *args):
|
||||
'''
|
||||
Tests successful case for creating a new usage plan
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'A new usage plan plan_name has been created')
|
||||
self.assertEqual(result['changes']['old'], {'plan': None})
|
||||
self.assertEqual(result['changes']['new'], {'plan': {'id': 'id'}})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=[{'plans': [{'id': 'id'}]},
|
||||
{'plans': [{'id': 'id',
|
||||
'throttle': {'rateLimit': throttle_rateLimit}}]}])})
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': False})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.update_usage_plan': MagicMock(return_value={'updated': True})})
|
||||
def test_usage_plan_present_if_plan_has_been_updated(self, *args):
|
||||
'''
|
||||
Tests successful case for updating a usage plan
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', throttle={'rateLimit': throttle_rateLimit}, **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'usage plan plan_name has been updated')
|
||||
self.assertEqual(result['changes']['old'], {'plan': {'id': 'id'}})
|
||||
self.assertEqual(result['changes']['new'], {'plan': {'id': 'id', 'throttle': {'rateLimit': throttle_rateLimit}}})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=ValueError('error'))})
|
||||
def test_usage_plan_present_if_ValueError_is_raised(self, *args):
|
||||
'''
|
||||
Tests error processing for the case when ValueError is raised when creating a usage plan
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', throttle={'rateLimit': throttle_rateLimit}, **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], "('error',)")
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=IOError('error'))})
|
||||
def test_usage_plan_present_if_IOError_is_raised(self, *args):
|
||||
'''
|
||||
Tests error processing for the case when IOError is raised when creating a usage plan
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_present('name', 'plan_name', throttle={'rateLimit': throttle_rateLimit}, **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], "('error',)")
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_absent_if_describe_fails(self, *args):
|
||||
'''
|
||||
Tests correct error processing for describe_usage_plan failure
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_absent('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Failed to describe existing usage plans')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': []})})
|
||||
def test_usage_plan_absent_if_plan_is_not_present(self, *args):
|
||||
'''
|
||||
Tests behavior for the case when the plan that needs to be absent does not exist
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_absent('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Usage plan plan_name does not exist already')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': True})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id'}]})})
|
||||
def test_usage_plan_absent_if_plan_is_present_but_test_option_is_set(self, *args):
|
||||
'''
|
||||
Tests behavior for the case when usage plan needs to be deleted by tests option is set
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_absent('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], None)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Usage plan plan_name exists and would be deleted')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': False})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id'}]})})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.delete_usage_plan': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_absent_if_plan_is_present_but_delete_fails(self, *args):
|
||||
'''
|
||||
Tests correct error processing when deleting a usage plan fails
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_absent('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Failed to delete usage plan plan_name, {\'error\': \'error\'}')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__opts__, {'test': False})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id'}]})})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.delete_usage_plan': MagicMock(return_value={'deleted': True})})
|
||||
def test_usage_plan_absent_if_plan_has_been_deleted(self, *args):
|
||||
'''
|
||||
Tests successful case for deleting a usage plan
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_absent('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Usage plan plan_name has been deleted')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {'new': {'plan': None}, 'old': {'plan': {'id': 'id'}}})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=ValueError('error'))})
|
||||
def test_usage_plan_absent_if_ValueError_is_raised(self, *args):
|
||||
'''
|
||||
Tests correct error processing for the case when ValueError is raised when deleting a usage plan
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_absent('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], "('error',)")
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=IOError('error'))})
|
||||
def test_usage_plan_absent_if_IOError_is_raised(self, *args):
|
||||
'''
|
||||
Tests correct error processing for the case when IOError is raised when deleting a usage plan
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_absent('name', 'plan_name', **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], "('error',)")
|
||||
|
||||
|
||||
@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
|
||||
@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
|
||||
' or equal to version {0}'
|
||||
.format(required_boto3_version))
|
||||
@skipIf(_has_required_botocore() is False,
|
||||
'The botocore module must be greater than'
|
||||
' or equal to version {0}'.format(required_botocore_version))
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class BotoApiGatewayUsagePlanAssociationTestCase(BotoApiGatewayStateTestCaseBase, BotoApiGatewayTestCaseMixin):
|
||||
'''
|
||||
TestCase for salt.modules.boto_apigateway state.module, usage_plans_association portion
|
||||
'''
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_association_present_if_describe_fails(self, *args):
|
||||
'''
|
||||
Tests correct error processing for describe_usage_plan failure
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_present('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Failed to describe existing usage plans')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': []})})
|
||||
def test_usage_plan_association_present_if_plan_is_not_present(self, *args):
|
||||
'''
|
||||
Tests correct error processing if a plan for which association has been requested is not present
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_present('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Usage plan plan_name does not exist')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id1'},
|
||||
{'id': 'id2'}]})})
|
||||
def test_usage_plan_association_present_if_multiple_plans_with_the_same_name_exist(self, *args):
|
||||
'''
|
||||
Tests correct error processing for the case when multiple plans with the same name exist
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_present('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'There are multiple usage plans with the same name - it is not supported')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id1',
|
||||
'apiStages':
|
||||
[association_stage_1]}]})})
|
||||
def test_usage_plan_association_present_if_association_already_exists(self, *args):
|
||||
'''
|
||||
Tests the behavior for the case when requested association is already present
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_present('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Usage plan is already asssociated to all api stages')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id1',
|
||||
'apiStages':
|
||||
[association_stage_1]}]})})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.attach_usage_plan_to_apis': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_association_present_if_update_fails(self, *args):
|
||||
'''
|
||||
Tests correct error processing for the case when adding associations fails
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_present('name', 'plan_name', [association_stage_2], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertTrue(result['comment'].startswith('Failed to associate a usage plan'))
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id1',
|
||||
'apiStages':
|
||||
[association_stage_1]}]})})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.attach_usage_plan_to_apis': MagicMock(return_value={'result': {'apiStages': [association_stage_1,
|
||||
association_stage_2]}})})
|
||||
def test_usage_plan_association_present_success(self, *args):
|
||||
'''
|
||||
Tests successful case for adding usage plan associations to a given api stage
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_present('name', 'plan_name', [association_stage_2], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'successfully associated usage plan to apis')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {'new': [association_stage_1, association_stage_2], 'old': [association_stage_1]})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=ValueError('error'))})
|
||||
def test_usage_plan_association_present_if_value_error_is_thrown(self, *args):
|
||||
'''
|
||||
Tests correct error processing for the case when IOError is raised while trying to set usage plan associations
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_present('name', 'plan_name', [], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], "('error',)")
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=IOError('error'))})
|
||||
def test_usage_plan_association_present_if_io_error_is_thrown(self, *args):
|
||||
'''
|
||||
Tests correct error processing for the case when IOError is raised while trying to set usage plan associations
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_present('name', 'plan_name', [], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], "('error',)")
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_association_absent_if_describe_fails(self, *args):
|
||||
'''
|
||||
Tests correct error processing for describe_usage_plan failure
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_absent('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Failed to describe existing usage plans')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': []})})
|
||||
def test_usage_plan_association_absent_if_plan_is_not_present(self, *args):
|
||||
'''
|
||||
Tests error processing for the case when plan for which associations need to be modified is not present
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_absent('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Usage plan plan_name does not exist')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id1'},
|
||||
{'id': 'id2'}]})})
|
||||
def test_usage_plan_association_absent_if_multiple_plans_with_the_same_name_exist(self, *args):
|
||||
'''
|
||||
Tests the case when there are multiple plans with the same name but different Ids
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_absent('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'There are multiple usage plans with the same name - it is not supported')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id1', 'apiStages': []}]})})
|
||||
def test_usage_plan_association_absent_if_plan_has_no_associations(self, *args):
|
||||
'''
|
||||
Tests the case when the plan has no associations at all
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_absent('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Usage plan plan_name has no associated stages already')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id1', 'apiStages': [association_stage_1]}]})})
|
||||
def test_usage_plan_association_absent_if_plan_has_no_specific_association(self, *args):
|
||||
'''
|
||||
Tests the case when requested association is not present already
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_absent('name', 'plan_name', [association_stage_2], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'Usage plan is already not asssociated to any api stages')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id1', 'apiStages': [association_stage_1,
|
||||
association_stage_2]}]})})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.detach_usage_plan_from_apis': MagicMock(return_value={'error': 'error'})})
|
||||
def test_usage_plan_association_absent_if_detaching_association_fails(self, *args):
|
||||
'''
|
||||
Tests correct error processing when detaching the usage plan from the api function is called
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_absent('name', 'plan_name', [association_stage_2], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertTrue(result['comment'].startswith('Failed to disassociate a usage plan plan_name from the apis'))
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(return_value={'plans': [{'id': 'id1', 'apiStages': [association_stage_1,
|
||||
association_stage_2]}]})})
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.detach_usage_plan_from_apis': MagicMock(return_value={'result': {'apiStages': [association_stage_1]}})})
|
||||
def test_usage_plan_association_absent_success(self, *args):
|
||||
'''
|
||||
Tests successful case of disaccosiation the usage plan from api stages
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_absent('name', 'plan_name', [association_stage_2], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], True)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], 'successfully disassociated usage plan from apis')
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {'new': [association_stage_1], 'old': [association_stage_1, association_stage_2]})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=ValueError('error'))})
|
||||
def test_usage_plan_association_absent_if_ValueError_is_raised(self, *args):
|
||||
'''
|
||||
Tests correct error processing for the case where ValueError is raised while trying to remove plan associations
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_absent('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], "('error',)")
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
||||
@patch.dict(boto_apigateway.__salt__, {'boto_apigateway.describe_usage_plans': MagicMock(side_effect=IOError('error'))})
|
||||
def test_usage_plan_association_absent_if_IOError_is_raised(self, *args):
|
||||
'''
|
||||
Tests correct error processing for the case where IOError exception is raised while trying to remove plan associations
|
||||
'''
|
||||
result = {}
|
||||
|
||||
result = boto_apigateway.usage_plan_association_absent('name', 'plan_name', [association_stage_1], **conn_parameters)
|
||||
|
||||
self.assertIn('result', result)
|
||||
self.assertEqual(result['result'], False)
|
||||
self.assertIn('comment', result)
|
||||
self.assertEqual(result['comment'], "('error',)")
|
||||
self.assertIn('changes', result)
|
||||
self.assertEqual(result['changes'], {})
|
||||
|
Loading…
Reference in New Issue
Block a user