From c11aba6ed89fd6ad9f85be828a3bb6c55ec214ad Mon Sep 17 00:00:00 2001 From: maxstack Date: Thu, 18 Oct 2018 07:01:59 +1300 Subject: [PATCH] [aws] New key_data argument to ec2_win_password module (#45463) * add key_data argument The key_data argument helps when using a private key stored in Vault. * Add "version_added" line Add version_added line to pass automated tests. * remove unnecessary nesting --- .../modules/cloud/amazon/ec2_win_password.py | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/ansible/modules/cloud/amazon/ec2_win_password.py b/lib/ansible/modules/cloud/amazon/ec2_win_password.py index 7fa65fe4371..a8139ed08b1 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_win_password.py +++ b/lib/ansible/modules/cloud/amazon/ec2_win_password.py @@ -27,8 +27,13 @@ options: required: true key_file: description: - - Path to the file containing the key pair used on the instance. - required: true + - Path to the file containing the key pair used on the instance, conflicts with key_data. + required: false + key_data: + version_added: "2.8" + description: + - Variable that references the private key (usually stored in vault), conflicts with key_file. + required: false key_passphrase: version_added: "2.0" description: @@ -67,6 +72,14 @@ EXAMPLES = ''' region: us-east-1 key_file: "~/aws-creds/my_test_key.pem" +# Example of getting a password using a variable +- name: get the Administrator password + ec2_win_password: + profile: my-boto-profile + instance_id: i-XXXXXX + region: us-east-1 + key_data: "{{ ec2_private_key }}" + # Example of getting a password with a password protected key - name: get the Administrator password ec2_win_password: @@ -108,8 +121,9 @@ def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict( instance_id=dict(required=True), - key_file=dict(required=True, type='path'), + key_file=dict(required=False, default=None, type='path'), key_passphrase=dict(no_log=True, default=None, required=False), + key_data=dict(no_log=True, default=None, required=False), wait=dict(type='bool', default=False, required=False), wait_timeout=dict(default=120, required=False, type='int'), ) @@ -124,6 +138,7 @@ def main(): instance_id = module.params.get('instance_id') key_file = module.params.get('key_file') + key_data = module.params.get('key_data') if module.params.get('key_passphrase') is None: b_key_passphrase = None else: @@ -151,16 +166,21 @@ def main(): if wait and datetime.datetime.now() >= end: module.fail_json(msg="wait for password timeout after %d seconds" % wait_timeout) - try: - f = open(key_file, 'rb') - except IOError as e: - module.fail_json(msg="I/O error (%d) opening key file: %s" % (e.errno, e.strerror)) - else: + if key_file is not None and key_data is None: try: - with f: + with open(key_file, 'rb') as f: key = load_pem_private_key(f.read(), b_key_passphrase, default_backend()) + except IOError as e: + # Handle bad files + module.fail_json(msg="I/O error (%d) opening key file: %s" % (e.errno, e.strerror)) except (ValueError, TypeError) as e: + # Handle issues loading key module.fail_json(msg="unable to parse key file") + elif key_data is not None and key_file is None: + try: + key = load_pem_private_key(key_data, b_key_passphrase, default_backend()) + except (ValueError, TypeError) as e: + module.fail_json(msg="unable to parse key data") try: decrypted = key.decrypt(decoded, PKCS1v15())