Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the "%" character in database name #227

Merged
merged 1 commit into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/227-db-create-special-name.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- mysql_db - Fix mismatch when database name contains a ``%`` character (https://github.com/ansible-collections/community.mysql/pull/227).
5 changes: 3 additions & 2 deletions plugins/modules/mysql_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@
def db_exists(cursor, db):
res = 0
for each_db in db:
res += cursor.execute("SHOW DATABASES LIKE %s", (each_db.replace("_", r"\_"),))
res += cursor.execute("SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = %s", (each_db,))
Andersson007 marked this conversation as resolved.
Show resolved Hide resolved
return res == len(db)


Expand Down Expand Up @@ -519,7 +519,8 @@ def db_create(cursor, db, encoding, collation):
query_params = dict(enc=encoding, collate=collation)
res = 0
for each_db in db:
query = ['CREATE DATABASE %s' % mysql_quote_identifier(each_db, 'database')]
# Escape '%' since mysql cursor.execute() uses a format string
query = ['CREATE DATABASE %s' % mysql_quote_identifier(each_db, 'database').replace('%', '%%')]
Andersson007 marked this conversation as resolved.
Show resolved Hide resolved
if encoding:
query.append("CHARACTER SET %(enc)s")
if collation:
Expand Down
287 changes: 4 additions & 283 deletions tests/integration/targets/test_mysql_db/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,297 +21,18 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.

# ============================================================
- name: alias mysql command to include default options
set_fact:
mysql_command: "mysql -u{{ mysql_user }} -p{{ mysql_password }} -P{{ mysql_primary_port }} --protocol=tcp"

- name: remove database if it exists
command: >
"{{ mysql_command }} -sse 'drop database {{ db_name }}'"
ignore_errors: True
- include: state_present_absent.yml

- name: make sure the test database is not there
command: "{{ mysql_command }} {{ db_name }}"
register: mysql_db_check
failed_when: "'1049' not in mysql_db_check.stderr"
- include: state_present_absent.yml db_name="db%"

- name: test state=present for a database name (expect changed=true)
mysql_db:
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: '{{ db_name }}'
state: present
register: result

- name: assert output message that database exist
assert:
that:
- result is changed
- result.db == '{{ db_name }}'
- result.executed_commands == ["CREATE DATABASE `{{ db_name }}`"]

- name: run command to test state=present for a database name (expect db_name in stdout)
command: "{{ mysql_command }} -e \"show databases like '{{ db_name }}'\""
register: result

- name: assert database exist
assert:
that:
- "'{{ db_name }}' in result.stdout"

# ============================================================
- name: test state=absent for a database name (expect changed=true)
mysql_db:
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: '{{ db_name }}'
state: absent
register: result

- name: assert output message that database does not exist
assert:
that:
- result is changed
- result.db == '{{ db_name }}'
- result.executed_commands == ["DROP DATABASE `{{ db_name }}`"]

- name: run command to test state=absent for a database name (expect db_name not in stdout)
command: "{{ mysql_command }} -e \"show databases like '{{ db_name }}'\""
register: result

- name: assert database does not exist
assert:
that:
- "'{{ db_name }}' not in result.stdout"

# ============================================================
- name: test mysql_db encoding param not valid - issue 8075
mysql_db:
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: datanotvalid
state: present
encoding: notvalid
register: result
ignore_errors: true

- name: assert test mysql_db encoding param not valid - issue 8075 (failed=true)
assert:
that:
- "result.failed == true"
- "'Traceback' not in result.msg"
- "'Unknown character set' in result.msg"

# ============================================================
- name: test mysql_db using a valid encoding utf8 (expect changed=true)
mysql_db:
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: 'en{{ db_name }}'
state: present
encoding: utf8
register: result

- name: assert output message created a database
assert:
that:
- result is changed
- result.executed_commands == ["CREATE DATABASE `en{{ db_name }}` CHARACTER SET 'utf8'"]

- name: test database was created
command: "{{ mysql_command }} -e \"SHOW CREATE DATABASE en{{ db_name }}\""
register: result

- name: assert created database is of encoding utf8
assert:
that:
- "'utf8' in result.stdout"

- name: remove database
mysql_db:
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: 'en{{ db_name }}'
state: absent

# ============================================================
- name: test mysql_db using valid encoding binary (expect changed=true)
mysql_db:
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: 'en{{ db_name }}'
state: present
encoding: binary
register: result

- name: assert output message that database was created
assert:
that:
- result is changed
- result.executed_commands == ["CREATE DATABASE `en{{ db_name }}` CHARACTER SET 'binary'"]

- name: run command to test database was created
command: "{{ mysql_command }} -e \"SHOW CREATE DATABASE en{{ db_name }}\""
register: result

- name: assert created database is of encoding binary
assert:
that:
- "'binary' in result.stdout"

- name: remove database
mysql_db:
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: 'en{{ db_name }}'
state: absent

# ============================================================
- name: create user1 to access database dbuser1
mysql_user:
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: user1
password: 'Hfd6fds^dfA8Ga'
priv: '*.*:ALL'
state: present

- name: create database dbuser1 using user1
mysql_db:
login_user: user1
login_password: 'Hfd6fds^dfA8Ga'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: '{{ db_user1 }}'
state: present
register: result

- name: assert output message that database was created
assert:
that:
- "result.changed == true"

- name: run command to test database was created using user1
command: "{{ mysql_command }} -e \"show databases like '{{ db_user1 }}'\""
register: result

- name: assert database exist
assert:
that:
- "'{{ db_user1 }}' in result.stdout"

# ============================================================
- name: create user2 to access database with privilege select only
mysql_user:
login_user: '{{ mysql_user }}'
login_password: '{{ mysql_password }}'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: user2
password: 'kjsfd&F7safjad'
priv: '*.*:SELECT'
state: present

- name: create database dbuser2 using user2 with no privilege to create (expect failed=true)
mysql_db:
login_user: user2
login_password: 'kjsfd&F7safjad'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: '{{ db_user2 }}'
state: present
register: result
ignore_errors: true

- name: assert output message that database was not created using dbuser2
assert:
that:
- "result.failed == true"
- "'Access denied' in result.msg"

- name: run command to test that database was not created
command: "{{ mysql_command }} -e \"show databases like '{{ db_user2 }}'\""
register: result

- name: assert database does not exist
assert:
that:
- "'{{ db_user2 }}' not in result.stdout"

# ============================================================
- name: delete database using user2 with no privilege to delete (expect failed=true)
mysql_db:
login_user: user2
login_password: 'kjsfd&F7safjad'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: '{{ db_user1 }}'
state: absent
register: result
ignore_errors: true

- name: assert output message that database was not deleted using dbuser2
assert:
that:
- "result.failed == true"
- "'Access denied' in result.msg"

- name: run command to test database was not deleted
command: "{{ mysql_command }} -e \"show databases like '{{ db_user1 }}'\""
register: result

- name: assert database still exist
assert:
that:
- "'{{ db_user1 }}' in result.stdout"

# ============================================================
- name: delete database using user1 with all privilege to delete a database (expect changed=true)
mysql_db:
login_user: user1
login_password: 'Hfd6fds^dfA8Ga'
login_host: 127.0.0.1
login_port: '{{ mysql_primary_port }}'
name: '{{ db_user1 }}'
state: absent
register: result
ignore_errors: true

- name: assert output message that database was deleted using user1
assert:
that:
- result is changed
- result.executed_commands == ["DROP DATABASE `{{ db_user1 }}`"]

- name: run command to test database was deleted using user1
command: "{{ mysql_command }} -e \"show databases like '{{ db_name }}'\""
register: result

- name: assert database does not exist
assert:
that:
- "'{{ db_user1 }}' not in result.stdout"

# ============================================================
- include: state_dump_import.yml format_type=sql file=dbdata.sql format_msg_type=ASCII file2=dump2.sql file3=dump3.sql file4=dump4.sql

- include: state_dump_import.yml format_type=sql file=dbdata.sql format_msg_type=ASCII file2=dump2.sql file3=dump3.sql file4=dump4.sql db_name="db%"

- include: state_dump_import.yml format_type=gz file=dbdata.gz format_msg_type=gzip file2=dump2.gz file3=dump3.gz file4=dump4.gz

- include: state_dump_import.yml format_type=bz2 file=dbdata.bz2 format_msg_type=bzip2 file2=dump2.bz2 file3=dump3.bz2 file4=dump4.bz2
Expand Down
Loading