mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
aws ssm parameter lookup - change to return Nones for missing variables (#36456)
* aws ssm parameter lookup - change to return Nones for missing variables * aws ssm parameter lookup - fix error case message to dump response * aws ssm parameter lookup - fix integration test cases
This commit is contained in:
parent
b6d4fa1c96
commit
52f2057472
3 changed files with 50 additions and 22 deletions
|
@ -193,10 +193,16 @@ class LookupModule(LookupBase):
|
||||||
response = client.get_parameters(**ssm_dict)
|
response = client.get_parameters(**ssm_dict)
|
||||||
except ClientError as e:
|
except ClientError as e:
|
||||||
raise AnsibleError("SSM lookup exception: {0}".format(to_native(e)))
|
raise AnsibleError("SSM lookup exception: {0}".format(to_native(e)))
|
||||||
if len(response['Parameters']) == len(terms):
|
params = boto3_tag_list_to_ansible_dict(response['Parameters'], tag_name_key_name="Name",
|
||||||
ret = [p['Value'] for p in response['Parameters']]
|
tag_value_key_name="Value")
|
||||||
else:
|
for i in terms:
|
||||||
raise AnsibleError('Undefined AWS SSM parameter: %s ' % str(response['InvalidParameters']))
|
if i in params:
|
||||||
|
ret.append(params[i])
|
||||||
|
elif i in response['InvalidParameters']:
|
||||||
|
ret.append(None)
|
||||||
|
else:
|
||||||
|
raise AnsibleError("Ansible internal error: aws_ssm lookup failed to understand boto3 return value: {0}".format(str(response)))
|
||||||
|
return ret
|
||||||
|
|
||||||
display.vvvv("AWS_ssm path lookup returning: %s " % str(ret))
|
display.vvvv("AWS_ssm path lookup returning: %s " % str(ret))
|
||||||
return ret
|
return ret
|
||||||
|
|
|
@ -74,17 +74,10 @@
|
||||||
- "'{{lookup('aws_ssm', '/' ~ ssm_key_prefix ~ '/path', region=ec2_region, aws_access_key=ec2_access_key, aws_secret_key=ec2_secret_key, aws_security_token=security_token, bypath=True, shortnames=true ) | to_json }}' == '{\"toovar\": \"too value\", \"wonvar\": \"won value\"}'"
|
- "'{{lookup('aws_ssm', '/' ~ ssm_key_prefix ~ '/path', region=ec2_region, aws_access_key=ec2_access_key, aws_secret_key=ec2_secret_key, aws_security_token=security_token, bypath=True, shortnames=true ) | to_json }}' == '{\"toovar\": \"too value\", \"wonvar\": \"won value\"}'"
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
- name: Error in case we don't find a named parameter
|
- name: Returns empty value in case we don't find a named parameter
|
||||||
debug:
|
|
||||||
msg: "'{{lookup('aws_ssm', '/' ~ ssm_key_prefix ~ '/Goodbye', region=ec2_region, aws_access_key=ec2_access_key, aws_secret_key=ec2_secret_key, aws_security_token=security_token )}}' == 'World'"
|
|
||||||
register: result
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: assert failure from failure to find parameter
|
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- 'result.failed'
|
- "'{{lookup('aws_ssm', '/' ~ ssm_key_prefix ~ '/Goodbye', region=ec2_region, aws_access_key=ec2_access_key, aws_secret_key=ec2_secret_key, aws_security_token=security_token )}}' == ''"
|
||||||
- "'Undefined AWS SSM parameter' in result.msg"
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
- name: Handle multiple paths with one that doesn't exist - default to full names.
|
- name: Handle multiple paths with one that doesn't exist - default to full names.
|
||||||
|
@ -134,3 +127,4 @@
|
||||||
- "/{{ssm_key_prefix}}/path/wonvar"
|
- "/{{ssm_key_prefix}}/path/wonvar"
|
||||||
- "/{{ssm_key_prefix}}/path/toovar"
|
- "/{{ssm_key_prefix}}/path/toovar"
|
||||||
- "/{{ssm_key_prefix}}/path/tree/treevar"
|
- "/{{ssm_key_prefix}}/path/tree/treevar"
|
||||||
|
- "/{{ssm_key_prefix}}/deeppath/wondir/samevar"
|
||||||
|
|
|
@ -61,9 +61,16 @@ path_success_response['Parameters'] = [
|
||||||
{'Name': '/testpath/won', 'Type': 'String', 'Value': 'simple_value_won', 'Version': 1}
|
{'Name': '/testpath/won', 'Type': 'String', 'Value': 'simple_value_won', 'Version': 1}
|
||||||
]
|
]
|
||||||
|
|
||||||
missing_variable_fail_response = copy(simple_variable_success_response)
|
missing_variable_response = copy(simple_variable_success_response)
|
||||||
missing_variable_fail_response['Parameters'] = []
|
missing_variable_response['Parameters'] = []
|
||||||
missing_variable_fail_response['InvalidParameters'] = ['missing_variable']
|
missing_variable_response['InvalidParameters'] = ['missing_variable']
|
||||||
|
|
||||||
|
some_missing_variable_response = copy(simple_variable_success_response)
|
||||||
|
some_missing_variable_response['Parameters'] = [
|
||||||
|
{'Name': 'simple', 'Type': 'String', 'Value': 'simple_value', 'Version': 1},
|
||||||
|
{'Name': '/testpath/won', 'Type': 'String', 'Value': 'simple_value_won', 'Version': 1}
|
||||||
|
]
|
||||||
|
some_missing_variable_response['InvalidParameters'] = ['missing_variable']
|
||||||
|
|
||||||
|
|
||||||
dummy_credentials = {}
|
dummy_credentials = {}
|
||||||
|
@ -109,16 +116,37 @@ def test_path_lookup_variable(mocker):
|
||||||
get_path_fn.assert_called_with(Path="/testpath", Recursive=False, WithDecryption=True)
|
get_path_fn.assert_called_with(Path="/testpath", Recursive=False, WithDecryption=True)
|
||||||
|
|
||||||
|
|
||||||
def test_warn_missing_variable(mocker):
|
def test_return_none_for_missing_variable(mocker):
|
||||||
|
"""
|
||||||
|
during jinja2 templates, we can't shouldn't normally raise exceptions since this blocks the ability to use defaults.
|
||||||
|
|
||||||
|
for this reason we return ```None``` for missing variables
|
||||||
|
"""
|
||||||
lookup = aws_ssm.LookupModule()
|
lookup = aws_ssm.LookupModule()
|
||||||
lookup._load_name = "aws_ssm"
|
lookup._load_name = "aws_ssm"
|
||||||
|
|
||||||
boto3_double = mocker.MagicMock()
|
boto3_double = mocker.MagicMock()
|
||||||
boto3_double.Session.return_value.client.return_value.get_parameters.return_value = missing_variable_fail_response
|
boto3_double.Session.return_value.client.return_value.get_parameters.return_value = missing_variable_response
|
||||||
|
|
||||||
with pytest.raises(AnsibleError):
|
with mocker.patch.object(boto3, 'session', boto3_double):
|
||||||
with mocker.patch.object(boto3, 'session', boto3_double):
|
retval = lookup.run(["missing_variable"], {}, **dummy_credentials)
|
||||||
lookup.run(["missing_variable"], {}, **dummy_credentials)
|
assert(retval[0] is None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_match_retvals_to_call_params_even_with_some_missing_variables(mocker):
|
||||||
|
"""
|
||||||
|
If we get a complex list of variables with some missing and some not, we still have to return a
|
||||||
|
list which matches with the original variable list.
|
||||||
|
"""
|
||||||
|
lookup = aws_ssm.LookupModule()
|
||||||
|
lookup._load_name = "aws_ssm"
|
||||||
|
|
||||||
|
boto3_double = mocker.MagicMock()
|
||||||
|
boto3_double.Session.return_value.client.return_value.get_parameters.return_value = some_missing_variable_response
|
||||||
|
|
||||||
|
with mocker.patch.object(boto3, 'session', boto3_double):
|
||||||
|
retval = lookup.run(["simple", "missing_variable", "/testpath/won", "simple"], {}, **dummy_credentials)
|
||||||
|
assert(retval == ["simple_value", None, "simple_value_won", "simple_value"])
|
||||||
|
|
||||||
|
|
||||||
error_response = {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'Fake Testing Error'}}
|
error_response = {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'Fake Testing Error'}}
|
||||||
|
|
Loading…
Reference in a new issue