Repository: ansible/ansible

Issue:
rpm_key crashes on Python3
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
Module [`rpm_key`](https://github.com/ansible/ansible-modules-core/blob/d749ec91e513c40a50b539a7eaccf29c31dda4d4/packaging/os/rpm_key.py)

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.2.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```

##### CONFIGURATION
Set the python interpreter to python3 in inventory:
```ini
[xxx:vars]
ansible_python_interpreter=/usr/bin/python3
```

```yml
- name: trust rpmfusion key
  rpm_key:
    state: present
    key: https://rpmfusion.org/keys?action=AttachFile&do=view&target=RPM-GPG-KEY-rpmfusion-free-fedora-{{ansible_distribution_major_version|int}}
```

##### OS / ENVIRONMENT
Fedora:25 with Python3 only installed.

##### SUMMARY
Ansible crashes on key import with error message pasted below.

##### STEPS TO REPRODUCE
- Make sure the client uses python3
- Import a key using `rpm_key` as described above

##### EXPECTED RESULTS
- The key should be imported and it should just work

##### ACTUAL RESULTS
- Ansible crashes with this traceback:

```py

fatal: [xxx]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Shared connection to xxx closed.
", "module_stdout": "Traceback (most recent call last):
  File "/tmp/ansible_sdddnvb2/ansible_module_rpm_key.py", line 209, in <module>
    main()
  File "/tmp/ansible_sdddnvb2/ansible_module_rpm_key.py", line 201, in main
    RpmKey(module)
  File "/tmp/ansible_sdddnvb2/ansible_module_rpm_key.py", line 85, in __init__
    keyfile = self.fetch_key(key)
  File "/tmp/ansible_sdddnvb2/ansible_module_rpm_key.py", line 122, in fetch_key
    if not is_pubkey(key):
  File "/tmp/ansible_sdddnvb2/ansible_module_rpm_key.py", line 70, in is_pubkey
    return re.match(pgp_regex, string, re.DOTALL)
  File "/usr/lib64/python3.5/re.py", line 163, in match
    return _compile(pattern, flags).match(string)
TypeError: cannot use a string pattern on a bytes-like object
", "msg": "MODULE FAILURE"}
```


Discussion:
cc @hacosta
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/packaging/os/rpm_key.py b/lib/ansible/modules/packaging/os/rpm_key.py
--- a/lib/ansible/modules/packaging/os/rpm_key.py
+++ b/lib/ansible/modules/packaging/os/rpm_key.py
@@ -75,12 +75,19 @@
 import os.path
 import tempfile
 
+# import module snippets
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.urls import fetch_url
+from ansible.module_utils._text import to_native
+
+
 def is_pubkey(string):
     """Verifies if string is a pubkey"""
     pgp_regex = ".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*"
-    return re.match(pgp_regex, string, re.DOTALL)
+    return bool(re.match(pgp_regex, to_native(string, errors='surrogate_or_strict'), re.DOTALL))
+
 
-class RpmKey:
+class RpmKey(object):
 
     def __init__(self, module):
         # If the key is a url, we need to check if it's present to be idempotent,
@@ -122,7 +129,6 @@ def __init__(self, module):
             else:
                 module.exit_json(changed=False)
 
-
     def fetch_key(self, url):
         """Downloads a key from url, returns a valid path to a gpg key"""
         rsp, info = fetch_url(self.module, url)
@@ -212,9 +218,5 @@ def main():
     RpmKey(module)
 
 
-
-# import module snippets
-from ansible.module_utils.basic import *
-from ansible.module_utils.urls import *
 if __name__ == '__main__':
     main()


Test patch: