Repository: ansible/ansible

Issue:
LetsEncrypt fails to recognise Account Key
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
<!---
letsencrypt
-->

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.5.0
  config file = /Users/obyrne/aws/aws-automation/aws-infra/ansible/ansible.cfg
  configured module search path = [u'/Users/obyrne/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/obyrne/.virtualenvs/ansible2.5/lib/python2.7/site-packages/ansible
  executable location = /Users/obyrne/.virtualenvs/ansible2.5/bin/ansible
  python version = 2.7.10 (default, Jul 15 2017, 17:16:57) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
MacOS 10.13.2

Name: pyOpenSSL
Version: 17.5.0
Summary: Python wrapper module around the OpenSSL library
Home-page: https://pyopenssl.org/
Author: Hynek Schlawack
Author-email: hs@ox.cx
License: Apache License, Version 2.0
Location: /Users/obyrne/.virtualenvs/ansible2.5/lib/python2.7/site-packages
Requires: cryptography, six

Name: cryptography
Version: 2.1.4
Summary: cryptography is a package which provides cryptographic recipes and primitives to Python developers.

Name: six
Version: 1.11.0
Summary: Python 2 and 3 compatibility utilities

##### SUMMARY
<!--- Explain the problem briefly -->
LetsEncrypt request fails with: "error while parsing account key: unknown key type \"%s\" % account_key_type".

This succeeds with Ansible2.4

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: "Create LetsEncrypt Signing Key"
    openssl_privatekey:
      path: "{{ letsencrypt.private_dir }}/lets_encrypt.key"
    tags:
      - letsencrypt

  - name: "Formulating LetsEncrypt API Call"
    letsencrypt:
      remaining_days: "{{ letsencrypt.renewal_days }}" 
      acme_directory: "{{ api_url }}"
      account_email: "{{ letsencrypt.account_email }}"
      account_key_src: "{{ letsencrypt.private_dir }}/lets_encrypt.key"
      challenge: "{{ letsencrypt.challenge_type }}"
      agreement: "{{ letsencrypt.agreement }}"
      csr: "{{ letsencrypt.requests_dir }}/{{ lets_encrypt_resource_name }}.csr"
      dest: "{{ letsencrypt.certs_dir }}/{{ lets_encrypt_resource_name }}.crt"
    register: acme_data
    tags:
      - letsencrypt
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
TASK [Formulating LetsEncrypt API Call] **********************************************************************************************************************************************************************************************************************************
changed: [localhost]

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
TASK [Formulating LetsEncrypt API Call] **********************************************************************************************************************************************************************************************************************************
task path: /Users/obyrne/aws/aws-automation/aws-infra/ansible/ssl_certs.yml:191
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "error while parsing account key: unknown key type \"%s\" % account_key_type"}
        to retry, use: --limit @/Users/obyrne/aws/aws-automation/aws-infra/ansible/ssl_certs.retry
```



Discussion:
!component =lib/ansible/modules/web_infrastructure/letsencrypt.py
/cc @felixfontein 

@byrneo the letsencrypt module has significantly been changed in upcoming ansible version 2.5. Do you have any chance to test it with 2.5? 

Resolving patch:
diff --git a/lib/ansible/modules/web_infrastructure/letsencrypt.py b/lib/ansible/modules/web_infrastructure/letsencrypt.py
--- a/lib/ansible/modules/web_infrastructure/letsencrypt.py
+++ b/lib/ansible/modules/web_infrastructure/letsencrypt.py
@@ -566,8 +566,14 @@ def _parse_account_key(self, key):
                 if m is not None:
                     account_key_type = m.group(1).lower()
                     break
+        if account_key_type is None:
+            # This happens for example if openssl_privatekey created this key
+            # (as opposed to the OpenSSL binary). For now, we assume this is
+            # an RSA key.
+            # FIXME: add some kind of auto-detection
+            account_key_type = "rsa"
         if account_key_type not in ("rsa", "ec"):
-            return 'unknown key type "%s" % account_key_type', {}
+            return 'unknown key type "%s"' % account_key_type, {}
 
         openssl_keydump_cmd = [self._openssl_bin, account_key_type, "-in", key, "-noout", "-text"]
         dummy, out, dummy = self.module.run_command(openssl_keydump_cmd, check_rc=True)


Test patch: