Repository: ansible/ansible

Issue:
mysql_user fails parsing grant string for empty hosts
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
database/mysql/mysql_user

##### ANSIBLE VERSION
```
ansible 2.3.0 (devel e3c95615b2) last updated 2017/01/20 11:18:03 (GMT -400)
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```

##### CONFIGURATION
stock

##### OS / ENVIRONMENT
Host environment is debian running devel branch; managed OS is ubuntu 16.04.1, mysql 5.7 from percona

##### SUMMARY
when mysql users are defined without a host definition ('user'@'', equivalent to 'user'@'%'), the RE match fails when extracting the existing permissions.

this originally showed up testing an migration of mysql from 5.6 to 5.7. 

##### STEPS TO REPRODUCE
```
mysql> drop user 'test'@'';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privlieges;
Query OK, 0 rows affected (0.00 sec)

mysql> Bye
# user does not exist, so nothing to parse. first pass runs ok.
$ ansible-playbook test.yml [...]
TASK [test grants] 
changed: [web1]
# second pass has something to chew on
$ ansible-playbook test.yml [...]
TASK [test grants] 
fatal: [web1]: FAILED! => {"changed": false, "failed": true, "msg": "unable to parse the MySQL grant string: GRANT USAGE ON *.* TO 'test'@''"}
```

```yaml
---
- hosts: all
  tasks:
  - name: test grants
    mysql_user:
      name: "test"
      host: ''
      priv: 'mysql.*:SELECT'
```

##### EXPECTED RESULTS
user is parsed and updated as expected

##### ACTUAL RESULTS
failure with unable to parse MySQL grant string

##### 1 char patch.
can PR if needed, but seems silly for a single character change.

```
mysql/ $ git diff | cat
diff --git a/lib/ansible/modules/database/mysql/mysql_user.py b/lib/ansible/modules/database/mysql/mysql_user.py
index 286106fe7..bd3a18985 100644
--- a/lib/ansible/modules/database/mysql/mysql_user.py
+++ b/lib/ansible/modules/database/mysql/mysql_user.py
@@ -432,7 +432,7 @@ def privileges_get(cursor, user,host):
             return x
 
     for grant in grants:
-        res = re.match("GRANT (.+) ON (.+) TO '.*'@'.+'( IDENTIFIED BY PASSWORD '.+')? ?(.*)", grant[0])
+        res = re.match("GRANT (.+) ON (.+) TO '.*'@'.*'( IDENTIFIED BY PASSWORD '.+')? ?(.*)", grant[0])
         if res is None:
             raise InvalidPrivsError('unable to parse the MySQL grant string: %s' % grant[0])
         privileges = res.group(1).split(", ")
```


Discussion:
cc @Jmainguy
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Can you PR please? Thanks!

Resolving patch:
diff --git a/lib/ansible/modules/database/mysql/mysql_user.py b/lib/ansible/modules/database/mysql/mysql_user.py
--- a/lib/ansible/modules/database/mysql/mysql_user.py
+++ b/lib/ansible/modules/database/mysql/mysql_user.py
@@ -432,7 +432,7 @@ def pick(x):
             return x
 
     for grant in grants:
-        res = re.match("GRANT (.+) ON (.+) TO '.*'@'.+'( IDENTIFIED BY PASSWORD '.+')? ?(.*)", grant[0])
+        res = re.match("GRANT (.+) ON (.+) TO '.*'@'.*'( IDENTIFIED BY PASSWORD '.+')? ?(.*)", grant[0])
         if res is None:
             raise InvalidPrivsError('unable to parse the MySQL grant string: %s' % grant[0])
         privileges = res.group(1).split(", ")


Test patch: